From efc97db4f3bed438e5ac14393b767748aa9b2f7e Mon Sep 17 00:00:00 2001 From: yruej301 <114962854+yruej301@users.noreply.github.com> Date: Mon, 14 Oct 2024 11:15:37 -0400 Subject: [PATCH 1/3] bump: v2.4.0 (#56) (#57) --- contracts/Clearinghouse.sol | 11 + contracts/Endpoint.sol | 195 ++++++++++-------- .../clearinghouse/IClearinghouse.sol | 2 + 3 files changed, 118 insertions(+), 90 deletions(-) diff --git a/contracts/Clearinghouse.sol b/contracts/Clearinghouse.sol index 2f37308..f28036b 100644 --- a/contracts/Clearinghouse.sol +++ b/contracts/Clearinghouse.sol @@ -613,4 +613,15 @@ contract Clearinghouse is EndpointGated, ClearinghouseStorage, IClearinghouse { require(_withdrawPool != address(0)); withdrawPool = _withdrawPool; } + + function getSlowModeFee() external view returns (uint256) { + ISpotEngine spotEngine = ISpotEngine( + address(engineByType[IProductEngine.EngineType.SPOT]) + ); + IERC20Base token = IERC20Base( + spotEngine.getConfig(QUOTE_PRODUCT_ID).token + ); + int256 multiplier = int256(10**(token.decimals() - 6)); + return uint256(int256(SLOW_MODE_FEE) * multiplier); + } } diff --git a/contracts/Endpoint.sol b/contracts/Endpoint.sol index 1ce852e..ba6fe3f 100644 --- a/contracts/Endpoint.sol +++ b/contracts/Endpoint.sol @@ -164,6 +164,18 @@ contract Endpoint is IEndpoint, EIP712Upgradeable, OwnableUpgradeable { sequencerFee[productId] += fee; } + function chargeSlowModeFee(IERC20Base token, address from) + internal + virtual + { + require(address(token) != address(0)); + token.safeTransferFrom( + from, + address(this), + clearinghouse.getSlowModeFee() + ); + } + function getLinkedSigner(bytes32 subaccount) public view @@ -193,14 +205,6 @@ contract Endpoint is IEndpoint, EIP712Upgradeable, OwnableUpgradeable { ); } - function increaseAllowance( - IERC20Base token, - address to, - uint256 amount - ) internal virtual { - token.increaseAllowance(to, amount); - } - function safeTransferFrom( IERC20Base token, address from, @@ -222,6 +226,7 @@ contract Endpoint is IEndpoint, EIP712Upgradeable, OwnableUpgradeable { address from, uint256 amount ) internal { + require(address(token) != address(0)); safeTransferFrom(token, from, amount); safeTransferTo(token, address(clearinghouse), amount); } @@ -293,16 +298,16 @@ contract Endpoint is IEndpoint, EIP712Upgradeable, OwnableUpgradeable { clearinghouse.requireMinDeposit(productId, amount); } - IERC20Base token = IERC20Base(spotEngine.getToken(productId)); - require(address(token) != address(0)); - handleDepositTransfer(token, msg.sender, uint256(amount)); + handleDepositTransfer( + IERC20Base(spotEngine.getToken(productId)), + msg.sender, + uint256(amount) + ); // copy from submitSlowModeTransaction SlowModeConfig memory _slowModeConfig = slowModeConfig; - // hardcoded to three days - uint64 executableAt = uint64(block.timestamp) + 259200; slowModeTxs[_slowModeConfig.txCount++] = SlowModeTx({ - executableAt: executableAt, + executableAt: uint64(block.timestamp) + 259200, // hardcoded to three days sender: sender, tx: abi.encodePacked( uint8(TransactionType.DepositCollateral), @@ -338,9 +343,7 @@ contract Endpoint is IEndpoint, EIP712Upgradeable, OwnableUpgradeable { transaction[1:], (DepositInsurance) ); - IERC20Base token = _getQuote(); - require(address(token) != address(0)); - handleDepositTransfer(token, sender, uint256(txn.amount)); + handleDepositTransfer(_getQuote(), sender, uint256(txn.amount)); } else if (txType == TransactionType.UpdateProduct) { require(sender == owner()); } else if (txType == TransactionType.BurnLpAndTransfer) { @@ -356,17 +359,14 @@ contract Endpoint is IEndpoint, EIP712Upgradeable, OwnableUpgradeable { } else if (txType == TransactionType.WithdrawInsurance) { require(sender == owner()); } else { - IERC20Base token = _getQuote(); - safeTransferFrom(token, sender, uint256(int256(SLOW_MODE_FEE))); + chargeSlowModeFee(_getQuote(), sender); slowModeFees += SLOW_MODE_FEE; } SlowModeConfig memory _slowModeConfig = slowModeConfig; - // hardcoded to three days - uint64 executableAt = uint64(block.timestamp) + 259200; requireUnsanctioned(sender); slowModeTxs[_slowModeConfig.txCount++] = SlowModeTx({ - executableAt: executableAt, + executableAt: uint64(block.timestamp) + 259200, // hardcoded to three days sender: sender, tx: transaction }); @@ -517,20 +517,23 @@ contract Endpoint is IEndpoint, EIP712Upgradeable, OwnableUpgradeable { (SignedLiquidateSubaccount) ); validateNonce(signedTx.tx.sender, signedTx.tx.nonce); - bytes32 digest = _hashTypedDataV4( - keccak256( - abi.encode( - keccak256(bytes(LIQUIDATE_SUBACCOUNT_SIGNATURE)), - signedTx.tx.sender, - signedTx.tx.liquidatee, - signedTx.tx.productId, - signedTx.tx.isEncodedSpread, - signedTx.tx.amount, - signedTx.tx.nonce + validateSignature( + signedTx.tx.sender, + _hashTypedDataV4( + keccak256( + abi.encode( + keccak256(bytes(LIQUIDATE_SUBACCOUNT_SIGNATURE)), + signedTx.tx.sender, + signedTx.tx.liquidatee, + signedTx.tx.productId, + signedTx.tx.isEncodedSpread, + signedTx.tx.amount, + signedTx.tx.nonce + ) ) - ) + ), + signedTx.signature ); - validateSignature(signedTx.tx.sender, digest, signedTx.signature); requireSubaccount(signedTx.tx.sender); chargeFee(signedTx.tx.sender, LIQUIDATION_FEE); clearinghouse.liquidateSubaccount(signedTx.tx); @@ -540,18 +543,21 @@ contract Endpoint is IEndpoint, EIP712Upgradeable, OwnableUpgradeable { (SignedWithdrawCollateral) ); validateNonce(signedTx.tx.sender, signedTx.tx.nonce); - bytes32 digest = _hashTypedDataV4( - keccak256( - abi.encode( - keccak256(bytes(WITHDRAW_COLLATERAL_SIGNATURE)), - signedTx.tx.sender, - signedTx.tx.productId, - signedTx.tx.amount, - signedTx.tx.nonce + validateSignature( + signedTx.tx.sender, + _hashTypedDataV4( + keccak256( + abi.encode( + keccak256(bytes(WITHDRAW_COLLATERAL_SIGNATURE)), + signedTx.tx.sender, + signedTx.tx.productId, + signedTx.tx.amount, + signedTx.tx.nonce + ) ) - ) + ), + signedTx.signature ); - validateSignature(signedTx.tx.sender, digest, signedTx.signature); chargeFee( signedTx.tx.sender, spotEngine.getWithdrawFee(signedTx.tx.productId), @@ -616,20 +622,23 @@ contract Endpoint is IEndpoint, EIP712Upgradeable, OwnableUpgradeable { (SignedMintLp) ); validateNonce(signedTx.tx.sender, signedTx.tx.nonce); - bytes32 digest = _hashTypedDataV4( - keccak256( - abi.encode( - keccak256(bytes(MINT_LP_SIGNATURE)), - signedTx.tx.sender, - signedTx.tx.productId, - signedTx.tx.amountBase, - signedTx.tx.quoteAmountLow, - signedTx.tx.quoteAmountHigh, - signedTx.tx.nonce + validateSignature( + signedTx.tx.sender, + _hashTypedDataV4( + keccak256( + abi.encode( + keccak256(bytes(MINT_LP_SIGNATURE)), + signedTx.tx.sender, + signedTx.tx.productId, + signedTx.tx.amountBase, + signedTx.tx.quoteAmountLow, + signedTx.tx.quoteAmountHigh, + signedTx.tx.nonce + ) ) - ) + ), + signedTx.signature ); - validateSignature(signedTx.tx.sender, digest, signedTx.signature); chargeFee(signedTx.tx.sender, HEALTHCHECK_FEE); clearinghouse.mintLp(signedTx.tx); } else if (txType == TransactionType.BurnLp) { @@ -638,18 +647,21 @@ contract Endpoint is IEndpoint, EIP712Upgradeable, OwnableUpgradeable { (SignedBurnLp) ); validateNonce(signedTx.tx.sender, signedTx.tx.nonce); - bytes32 digest = _hashTypedDataV4( - keccak256( - abi.encode( - keccak256(bytes(BURN_LP_SIGNATURE)), - signedTx.tx.sender, - signedTx.tx.productId, - signedTx.tx.amount, - signedTx.tx.nonce + validateSignature( + signedTx.tx.sender, + _hashTypedDataV4( + keccak256( + abi.encode( + keccak256(bytes(BURN_LP_SIGNATURE)), + signedTx.tx.sender, + signedTx.tx.productId, + signedTx.tx.amount, + signedTx.tx.nonce + ) ) - ) + ), + signedTx.signature ); - validateSignature(signedTx.tx.sender, digest, signedTx.signature); chargeFee(signedTx.tx.sender, HEALTHCHECK_FEE); clearinghouse.burnLp(signedTx.tx); } else if (txType == TransactionType.DumpFees) { @@ -675,17 +687,20 @@ contract Endpoint is IEndpoint, EIP712Upgradeable, OwnableUpgradeable { (SignedLinkSigner) ); validateNonce(signedTx.tx.sender, signedTx.tx.nonce); - bytes32 digest = _hashTypedDataV4( - keccak256( - abi.encode( - keccak256(bytes(LINK_SIGNER_SIGNATURE)), - signedTx.tx.sender, - signedTx.tx.signer, - signedTx.tx.nonce + validateSignature( + signedTx.tx.sender, + _hashTypedDataV4( + keccak256( + abi.encode( + keccak256(bytes(LINK_SIGNER_SIGNATURE)), + signedTx.tx.sender, + signedTx.tx.signer, + signedTx.tx.nonce + ) ) - ) + ), + signedTx.signature ); - validateSignature(signedTx.tx.sender, digest, signedTx.signature); linkedSigners[signedTx.tx.sender] = address( uint160(bytes20(signedTx.tx.signer)) ); @@ -705,21 +720,22 @@ contract Endpoint is IEndpoint, EIP712Upgradeable, OwnableUpgradeable { transaction[1:], (SignedTransferQuote) ); - - bytes32 digest = _hashTypedDataV4( - keccak256( - abi.encode( - keccak256(bytes(TRANSFER_QUOTE_SIGNATURE)), - signedTx.tx.sender, - signedTx.tx.recipient, - signedTx.tx.amount, - signedTx.tx.nonce + _recordSubaccount(signedTx.tx.recipient); + validateSignature( + signedTx.tx.sender, + _hashTypedDataV4( + keccak256( + abi.encode( + keccak256(bytes(TRANSFER_QUOTE_SIGNATURE)), + signedTx.tx.sender, + signedTx.tx.recipient, + signedTx.tx.amount, + signedTx.tx.nonce + ) ) - ) + ), + signedTx.signature ); - - _recordSubaccount(signedTx.tx.recipient); - validateSignature(signedTx.tx.sender, digest, signedTx.signature); validateNonce(signedTx.tx.sender, signedTx.tx.nonce); chargeFee(signedTx.tx.sender, HEALTHCHECK_FEE); clearinghouse.transferQuote(signedTx.tx); @@ -804,8 +820,7 @@ contract Endpoint is IEndpoint, EIP712Upgradeable, OwnableUpgradeable { } function _getQuote() internal view returns (IERC20Base) { - IERC20Base token = IERC20Base(spotEngine.getToken(QUOTE_PRODUCT_ID)); - return token; + return IERC20Base(spotEngine.getToken(QUOTE_PRODUCT_ID)); } function getPriceX18(uint32 productId) diff --git a/contracts/interfaces/clearinghouse/IClearinghouse.sol b/contracts/interfaces/clearinghouse/IClearinghouse.sol index 672489d..76359dc 100644 --- a/contracts/interfaces/clearinghouse/IClearinghouse.sol +++ b/contracts/interfaces/clearinghouse/IClearinghouse.sol @@ -88,5 +88,7 @@ interface IClearinghouse is IClearinghouseEventEmitter, IEndpointGated { function getWithdrawPool() external view returns (address); + function getSlowModeFee() external view returns (uint256); + function setWithdrawPool(address _withdrawPool) external; } From bcd3bf81b3f90e49c43d4db794c48a989df49e4f Mon Sep 17 00:00:00 2001 From: yruej301 <114962854+yruej301@users.noreply.github.com> Date: Thu, 20 Mar 2025 10:47:37 -0400 Subject: [PATCH 2/3] chore: readme (#84) --- README.md | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..602188a --- /dev/null +++ b/README.md @@ -0,0 +1,49 @@ +# Vertex Protocol + +This repository contains the smart contract implementations for the Vertex Protocol ecosystem. + +## Project Structure + +The repository is organized into two main projects: + +- **[vertex-contracts/core](./vertex-contracts/core)**: EVM implementation of Vertex core functionality +- **[vertex-contracts/lba](./vertex-contracts/lba)**: Vertex LBA (Liquidity Bootstrap Auction) contracts + +## Requirements + +- Node.js >=16 +- [Yarn](https://yarnpkg.com/) + +## Getting Started + +Each project has its own setup and development commands. Navigate to the respective directories for project-specific instructions: + +``` +# For Vertex EVM Core Contracts +cd vertex-contracts/core +yarn install +yarn compile + +# For Vertex LBA Contracts +cd vertex-contracts/lba +yarn install +# Follow the .env setup instructions +``` + +## Available Commands + +### Core Contracts + +- `yarn compile`: Compile Vertex EVM contracts +- See project-specific README for more details + +### LBA Contracts + +- `yarn lint`: Run prettier & SolHint +- `yarn contracts:force-compile`: Compile contracts and generate TS bindings + ABIs +- `yarn run-local-node`: Run a persistent local Hardhat node for testing +- See project-specific README for more details + +## Further Documentation + +For more detailed information about each project, please refer to their respective README files. \ No newline at end of file From ae9cee6e3cf062191e598893a8047c3288eb17b0 Mon Sep 17 00:00:00 2001 From: yruej301 Date: Mon, 21 Apr 2025 10:30:24 -0400 Subject: [PATCH 3/3] bump/3.2.0 --- core/contracts/Clearinghouse.sol | 9 +++++++-- core/package.json | 2 +- lba/package.json | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/core/contracts/Clearinghouse.sol b/core/contracts/Clearinghouse.sol index 5eb3430..9b6288f 100644 --- a/core/contracts/Clearinghouse.sol +++ b/core/contracts/Clearinghouse.sol @@ -531,8 +531,13 @@ contract Clearinghouse is EndpointGated, ClearinghouseStorage, IClearinghouse { spotEngine.updateBalance(VLP_PRODUCT_ID, V_ACCOUNT, vlpAmount); int128 quoteAmount = vlpAmount.mul(oraclePriceX18); - spotEngine.updateBalance(QUOTE_PRODUCT_ID, txn.sender, quoteAmount); - spotEngine.updateBalance(QUOTE_PRODUCT_ID, V_ACCOUNT, -quoteAmount); + int128 burnFee = MathHelper.max(ONE, quoteAmount / 1000); + quoteAmount = MathHelper.max(0, quoteAmount - burnFee); + + if (quoteAmount != 0) { + spotEngine.updateBalance(QUOTE_PRODUCT_ID, txn.sender, quoteAmount); + spotEngine.updateBalance(QUOTE_PRODUCT_ID, V_ACCOUNT, -quoteAmount); + } require( spotEngine.getBalance(VLP_PRODUCT_ID, txn.sender).amount >= 0, diff --git a/core/package.json b/core/package.json index 374d640..8326bb1 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "vertex-core", - "version": "3.1.0", + "version": "3.2.0", "license": "UNLICENSED", "description": "EVM implementation of Vertex", "scripts": { diff --git a/lba/package.json b/lba/package.json index 04868fa..884c5af 100644 --- a/lba/package.json +++ b/lba/package.json @@ -1,6 +1,6 @@ { "name": "vertex-lba", - "version": "3.1.0", + "version": "3.2.0", "license": "UNLICENSED", "description": "Vertex LBA contracts", "scripts": {