From d36603d882f87fd06a91dab0b28f4e468bf99d79 Mon Sep 17 00:00:00 2001 From: Rens Rooimans Date: Wed, 23 Oct 2024 16:40:47 +0200 Subject: [PATCH] gas estimates for token exec --- .../v0.8/ccip/test/MOAFT/CCIPTestSuite.sol | 93 +++++-------------- .../{chainLoading.sol => ChainLoading.sol} | 76 +++++++-------- .../v0.8/ccip/test/MOAFT/ChainSelectors.sol | 84 +++++++++++++++++ 3 files changed, 137 insertions(+), 116 deletions(-) rename contracts/src/v0.8/ccip/test/MOAFT/{chainLoading.sol => ChainLoading.sol} (77%) create mode 100644 contracts/src/v0.8/ccip/test/MOAFT/ChainSelectors.sol diff --git a/contracts/src/v0.8/ccip/test/MOAFT/CCIPTestSuite.sol b/contracts/src/v0.8/ccip/test/MOAFT/CCIPTestSuite.sol index 243bb27b4b..3c1dc6dea5 100644 --- a/contracts/src/v0.8/ccip/test/MOAFT/CCIPTestSuite.sol +++ b/contracts/src/v0.8/ccip/test/MOAFT/CCIPTestSuite.sol @@ -7,6 +7,7 @@ import {Client} from "../../libraries/Client.sol"; import {Internal} from "../../libraries/Internal.sol"; import {EVM2EVMOffRamp} from "../../offRamp/EVM2EVMOffRamp.sol"; import {EVM2EVMOnRamp} from "../../onRamp/EVM2EVMOnRamp.sol"; +import {ChainSelectors} from "./ChainSelectors.sol"; import {EnumerableSet} from "../../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/structs/EnumerableSet.sol"; @@ -16,61 +17,6 @@ import {Test} from "forge-std/Test.sol"; import {Vm} from "forge-std/Vm.sol"; import {IERC20} from "forge-std/interfaces/IERC20.sol"; -library Constants { - function _resolveChainSelector( - uint64 chainSelector - ) internal pure returns (string memory) { - // Testnets - if (chainSelector == 3478487238524512106) { - return "Arbitrum Sepolia"; - } else if (chainSelector == 8871595565390010547) { - return "Gnosis Chiado"; - } else if (chainSelector == 16281711391670634445) { - return "Polygon Amoy"; - } else if (chainSelector == 13264668187771770619) { - return "BNB Testnet"; - } else if (chainSelector == 10344971235874465080) { - return "Base Testnet"; - } else if (chainSelector == 829525985033418733) { - return "Mode Sepolia"; - } else if (chainSelector == 5224473277236331295) { - return "Optimism Sepolia"; - } else if (chainSelector == 16015286601757825753) { - return "Sepolia"; - } else if (chainSelector == 6898391096552792247) { - return "ZKSync Testnet"; - } else if (chainSelector == 14767482510784806043) { - return "Avax Fuji"; - } - // Mainnets - if (chainSelector == 5009297550715157269) { - return "Ethereum mainnet"; - } else if (chainSelector == 4411394078118774322) { - return "Blast"; - } else if (chainSelector == 5009297550715157269) { - return "Ethereum mainnet"; - } else if (chainSelector == 465200170687744372) { - return "Gnosis"; - } else if (chainSelector == 11344663589394136015) { - return "Binance Smart Chain"; - } else if (chainSelector == 7264351850409363825) { - return "Mode"; - } else if (chainSelector == 3734403246176062136) { - return "Optimism"; - } else if (chainSelector == 4051577828743386545) { - return "Polygon"; - } else if (chainSelector == 4949039107694359620) { - return "Arbitrum"; - } else if (chainSelector == 6433500567565415381) { - return "Avalanche"; - } else if (chainSelector == 15971525489660198786) { - return "Base"; - } - - return "Unknown"; - } -} - contract CCIPTestSuite is Test { using stdStorage for StdStorage; using EnumerableSet for EnumerableSet.UintSet; @@ -185,7 +131,7 @@ contract CCIPTestSuite is Test { if (i_fullLogging) { console2.log( - "Sending tokens to chain: ", remoteChainSelector, Constants._resolveChainSelector(remoteChainSelector) + "Sending tokens to chain: ", remoteChainSelector, ChainSelectors._resolveChainSelector(remoteChainSelector) ); } RemoteChainConfig storage remoteChainConfig = s_remoteChainConfigs[remoteChainSelector]; @@ -275,9 +221,6 @@ contract CCIPTestSuite is Test { vm.startPrank(address(offRamp)); - uint32[] memory gasOverrides = new uint32[](1); - gasOverrides[0] = 100_000; - // uint32[] memory gasOverrides = new uint32[](0); uint256 succeeded = 0; for (uint256 i = 0; i < messages.length; ++i) { @@ -285,18 +228,26 @@ contract CCIPTestSuite is Test { bytes memory destTokenAddressBytes = abi.decode(message.sourceTokenData[0], (Internal.SourceTokenData)).destTokenAddress; address destTokenAddress = abi.decode(destTokenAddressBytes, (address)); - try offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length), gasOverrides) { - console2.log( - unicode"✅ Executed message with source token", message.tokenAmounts[0].token, s_tokenNames[destTokenAddress] - ); - succeeded++; - } catch (bytes memory reason) { - console2.log( - unicode"❌ Failed to execute message with token", - message.tokenAmounts[0].token, - s_tokenNames[destTokenAddress] - ); - console2.logBytes(reason); + + uint256 startingGas = 80_000; + uint256 maxGasToTest = 250_000; + uint256 increment = 10_000; + uint32[] memory gasOverrides = new uint32[](1); + + for (uint256 j = startingGas; j <= maxGasToTest; j += increment) { + gasOverrides[0] = uint32(j); + try offRamp.executeSingleMessage(message, new bytes[](message.tokenAmounts.length), gasOverrides) { + console2.log(unicode"✅ source_token", message.tokenAmounts[0].token, s_tokenNames[destTokenAddress], j); + succeeded++; + break; + } catch (bytes memory reason) { + if (j == maxGasToTest) { + console2.log(unicode"❌ source_token", message.tokenAmounts[0].token, s_tokenNames[destTokenAddress], j); + if (startingGas == maxGasToTest) { + console2.logBytes(reason); + } + } + } } } diff --git a/contracts/src/v0.8/ccip/test/MOAFT/chainLoading.sol b/contracts/src/v0.8/ccip/test/MOAFT/ChainLoading.sol similarity index 77% rename from contracts/src/v0.8/ccip/test/MOAFT/chainLoading.sol rename to contracts/src/v0.8/ccip/test/MOAFT/ChainLoading.sol index 01f3667dec..4beb51d127 100644 --- a/contracts/src/v0.8/ccip/test/MOAFT/chainLoading.sol +++ b/contracts/src/v0.8/ccip/test/MOAFT/ChainLoading.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.24; import {Internal} from "../../libraries/Internal.sol"; import {CCIPTestSuite} from "./CCIPTestSuite.sol"; +import {ChainSelectors} from "./ChainSelectors.sol"; import {ForkedChain} from "./ForkedChain.sol"; import {ManyChainMultiSig} from "./ccip-owner-contracts/ManyChainMultiSig.sol"; import {RBACTimelock} from "./ccip-owner-contracts/RBACTimelock.sol"; @@ -29,44 +30,32 @@ import {Test} from "forge-std/Test.sol"; /// # Any block after the migration was applied. Use 0 if the migration has not been applied yet. /// _POST_BLOCK=6904314 contract ChainLoading is Test { - // Testnets - string internal constant SEPOLIA = "SEPOLIA"; - string internal constant GNOSIS_TESTNET = "GNOSIS_TESTNET"; - string internal constant BNB_TESTNET = "BNB_TESTNET"; - string internal constant MODE_TESTNET = "MODE_TESTNET"; - string internal constant OPT_SEPOLIA = "OPT_SEPOLIA"; - string internal constant POLYGON_AMOY = "POLYGON_AMOY"; - string internal constant ARB_SEPOLIA = "ARB_SEPOLIA"; - string internal constant AVAX_FUJI = "AVAX_FUJI"; - string internal constant BASE_SEPOLIA = "BASE_SEPOLIA"; - - // Mainnets - string internal constant BLAST = "BLAST"; - string internal constant ETHEREUM = "ETHEREUM"; - string internal constant GNOSIS = "GNOSIS"; - string internal constant BNB = "BNB"; - string internal constant MODE = "MODE"; - string internal constant OPTIMISM = "OPTIMISM"; - string internal constant POLYGON = "POLYGON"; - string internal constant ARBITRUM = "ARBITRUM"; - string internal constant AVAX = "AVAX"; - string internal constant BASE = "BASE"; + string[] public AllTestnets = [ + ChainSelectors.SEPOLIA, + ChainSelectors.GNOSIS_TESTNET, + ChainSelectors.BNB_TESTNET, + ChainSelectors.MODE_TESTNET, + ChainSelectors.OPT_SEPOLIA, + ChainSelectors.POLYGON_AMOY, + ChainSelectors.ARB_SEPOLIA, + ChainSelectors.AVAX_FUJI, + ChainSelectors.BASE_SEPOLIA + ]; + string[] public AllMainnets = [ + ChainSelectors.BLAST, + ChainSelectors.ETHEREUM, + ChainSelectors.GNOSIS, + ChainSelectors.BNB, + ChainSelectors.MODE, + ChainSelectors.OPTIMISM, + ChainSelectors.POLYGON, + ChainSelectors.ARBITRUM, + ChainSelectors.AVAX, + ChainSelectors.BASE + ]; uint256 internal constant FourHours = 4 * 60 * 60; - string[] internal s_allTestnets = [ - SEPOLIA, - GNOSIS_TESTNET, - BNB_TESTNET, - MODE_TESTNET, - OPT_SEPOLIA, - POLYGON_AMOY, - ARB_SEPOLIA, - AVAX_FUJI, - BASE_SEPOLIA - ]; - string[] internal s_allMainnets = [BLAST, ETHEREUM, GNOSIS, BNB, MODE, OPTIMISM, POLYGON, ARBITRUM, AVAX, BASE]; - mapping(string chainName => ForkedChainTestSetup) public s_chains; struct ForkedChainTestSetup { @@ -94,18 +83,21 @@ contract ChainLoading is Test { } function test_env_lane() public { - _run_lane(vm.envString("SOURCE_CHAIN"), vm.envString("DEST_CHAIN")); + string memory destChain = ChainSelectors._resolveChainSelector(uint64(vm.envUint("REMOTE_CHAIN_SELECTOR"))); + _run_lane(vm.envString("SOURCE_CHAIN"), destChain); } function test_all_chains() public { - for (uint256 i = 0; i < s_allMainnets.length; ++i) { - run(s_allMainnets[i]); + string[] memory chains = AllMainnets; + for (uint256 i = 0; i < chains.length; ++i) { + run(chains[i]); } } function _run_lane(string memory sourceChainName, string memory destChainName) internal { _loadSingleChain(sourceChainName); _loadSingleChain(destChainName); + uint64 remoteChainSelector = uint64(vm.envUint("REMOTE_CHAIN_SELECTOR")); ForkedChainTestSetup memory sourceChain = _activateFork(sourceChainName); @@ -114,7 +106,7 @@ contract ChainLoading is Test { _executeProposalOnTimeLock(sourceChain); // Send messages - Internal.EVM2EVMMessage[] memory msgs = sourceChain.testSuite.sendTokensSingleLane(3478487238524512106); + Internal.EVM2EVMMessage[] memory msgs = sourceChain.testSuite.sendTokensSingleLane(remoteChainSelector); ForkedChainTestSetup memory destChain = _activateFork(destChainName); @@ -172,12 +164,6 @@ contract ChainLoading is Test { vm.rollFork(chain.postMigrationBlock); } - function _loadAllChains() internal { - for (uint256 i = 0; i < s_allTestnets.length; ++i) { - _loadSingleChain(s_allTestnets[i]); - } - } - function _loadSingleChain( string memory name ) internal returns (ForkedChainTestSetup memory) { diff --git a/contracts/src/v0.8/ccip/test/MOAFT/ChainSelectors.sol b/contracts/src/v0.8/ccip/test/MOAFT/ChainSelectors.sol new file mode 100644 index 0000000000..cad004296f --- /dev/null +++ b/contracts/src/v0.8/ccip/test/MOAFT/ChainSelectors.sol @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.10; + +library ChainSelectors { + // Testnets + string public constant SEPOLIA = "SEPOLIA"; + string public constant GNOSIS_TESTNET = "GNOSIS_TESTNET"; + string public constant BNB_TESTNET = "BNB_TESTNET"; + string public constant MODE_TESTNET = "MODE_TESTNET"; + string public constant OPT_SEPOLIA = "OPT_SEPOLIA"; + string public constant POLYGON_AMOY = "POLYGON_AMOY"; + string public constant ARB_SEPOLIA = "ARB_SEPOLIA"; + string public constant AVAX_FUJI = "AVAX_FUJI"; + string public constant BASE_SEPOLIA = "BASE_SEPOLIA"; + string public constant ZKSYNC_TESTNET = "ZKSYNC_TESTNET"; + + // Mainnets + string public constant BLAST = "BLAST"; + string public constant ETHEREUM = "ETHEREUM"; + string public constant GNOSIS = "GNOSIS"; + string public constant BNB = "BNB"; + string public constant MODE = "MODE"; + string public constant OPTIMISM = "OPTIMISM"; + string public constant POLYGON = "POLYGON"; + string public constant ARBITRUM = "ARBITRUM"; + string public constant AVAX = "AVAX"; + string public constant BASE = "BASE"; + string public constant METIS = "METIS"; + + function _resolveChainSelector( + uint64 chainSelector + ) internal pure returns (string memory) { + // Testnets + if (chainSelector == 3478487238524512106) { + return ARB_SEPOLIA; + } else if (chainSelector == 8871595565390010547) { + return GNOSIS_TESTNET; + } else if (chainSelector == 16281711391670634445) { + return POLYGON_AMOY; + } else if (chainSelector == 13264668187771770619) { + return BNB_TESTNET; + } else if (chainSelector == 10344971235874465080) { + return BASE_SEPOLIA; + } else if (chainSelector == 829525985033418733) { + return MODE_TESTNET; + } else if (chainSelector == 5224473277236331295) { + return OPT_SEPOLIA; + } else if (chainSelector == 16015286601757825753) { + return SEPOLIA; + } else if (chainSelector == 6898391096552792247) { + return ZKSYNC_TESTNET; + } else if (chainSelector == 14767482510784806043) { + return AVAX_FUJI; + } + // Mainnets + if (chainSelector == 5009297550715157269) { + return ETHEREUM; + } else if (chainSelector == 4411394078118774322) { + return BLAST; + } else if (chainSelector == 5009297550715157269) { + return "Ethereum mainnet"; + } else if (chainSelector == 465200170687744372) { + return GNOSIS; + } else if (chainSelector == 11344663589394136015) { + return BNB; + } else if (chainSelector == 7264351850409363825) { + return MODE; + } else if (chainSelector == 3734403246176062136) { + return OPTIMISM; + } else if (chainSelector == 4051577828743386545) { + return POLYGON; + } else if (chainSelector == 4949039107694359620) { + return ARBITRUM; + } else if (chainSelector == 6433500567565415381) { + return AVAX; + } else if (chainSelector == 15971525489660198786) { + return BASE; + } else if (chainSelector == 8805746078405598895) { + return METIS; + } + + return "Unknown"; + } +}