diff --git a/.env.example b/.env.example index 345ab592..73bbb8a4 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,6 @@ # anvil --port 8646 or via docker compose up in eth-pos-devnet CLIENT_CHAIN_RPC=http://localhost:8646 -EXOCORE_TESETNET_RPC=http://localhost:8545 +EXOCORE_TESTNET_RPC=http://localhost:8545 EXOCORE_LOCAL_RPC=http://localhost:8545 # The following are default Anvil keys - not real keys! TEST_ACCOUNT_ONE_PRIVATE_KEY=0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d @@ -10,13 +10,14 @@ TEST_ACCOUNT_FOUR_PRIVATE_KEY=0x7c852118294e51e653712a81e05800f419141751be58f605 # Use 'exocored keys unsafe-export-eth-key "dev0" --home ~/.tmp-exocored' to get the privatekey EXOCORE_GENESIS_PRIVATE_KEY=0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a -USE_ENDPOINT_MOCK=true -USE_EXOCORE_PRECOMPILE_MOCK=true +USE_ENDPOINT_MOCK=false +USE_EXOCORE_PRECOMPILE_MOCK=false # For contract verification ETHERSCAN_API_KEY= +EXOCORE_TESTNET_EXPLORER= -# These are used for integration testing the Bootstrap contract, in addition to +# These are used for integration testing the Bootstrap contract, in addition to # CLIENT_CHAIN_RPC and BEACON_CHAIN_ENDPOINT above. INTEGRATION_VALIDATOR_KEYS=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80,0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d,0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a INTEGRATION_STAKERS=0x7c852118294e51e653712a81e05800f419141751be58f605c371e15141b007a6,0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a,0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba,0x92db14e403b83dfe3df233f83dfa3a0d7096f21ca9b0d6d6b8d88b2b4ec1564e,0x4bbbf85ce3377467afe5d46f804f221813b2bb87f24d81f60f1fcdbf7cbf4356,0xdbda1821b80551c9d65939329250298aa3472ba22feea921c0cf5d620ea67b97,0x2a871d0798f97d79848a013d4936a73bf4cc922c825d33c1cf7073dff6d409c6 diff --git a/.github/workflows/forge-ci.yml b/.github/workflows/forge-ci.yml index d38ac05f..d6bf1777 100644 --- a/.github/workflows/forge-ci.yml +++ b/.github/workflows/forge-ci.yml @@ -80,10 +80,17 @@ jobs: ./cache ./broadcast key: build-${{ github.event.pull_request.head.sha || github.event.after || github.sha }} - - name: Test - run: forge test -vvv + - name: Clear out the `etherscan` section in `foundry.toml` for missing env vars + run: sed -i '/\[etherscan\]/,/^\[/ s/^/#/' foundry.toml + - name: Run tests + env: + FOUNDRY_PROFILE: test + run: forge test - name: Set test snapshot as summary - run: NO_COLOR=1 forge snapshot >> $GITHUB_STEP_SUMMARY + env: + FOUNDRY_PROFILE: test + NO_COLOR: 1 + run: forge snapshot >> "$GITHUB_STEP_SUMMARY" format: # Takes less than 30s diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..43e6aacd --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +# Makefile for Foundry commands + +# Variables +FOUNDRY_PROFILE=test + +# Targets +.PHONY: test build fmt + +test: + FOUNDRY_PROFILE=$(FOUNDRY_PROFILE) forge test -vvv + +build: + forge build + +fmt: + forge fmt diff --git a/foundry.toml b/foundry.toml index 2759d258..369041a0 100644 --- a/foundry.toml +++ b/foundry.toml @@ -13,12 +13,12 @@ ignored_warnings_from = ["script", "test"] # fail compilation if the warnings are not fixed. # this is super useful for the code size warning. deny_warnings = true -# for tests, use the mainnet chain_id for NetworkConstants to work. -chain_id = 1 -[rpc_endpoints] -ethereum_local_rpc = "${ETHEREUM_LOCAL_RPC}" -exocore_local_rpc = "${EXOCORE_LOCAL_RPC}" +[profile.test] +# for tests, use the Eth mainnet chain_id for NetworkConstants to work. +# do not specify this in the default profile to pacify forge script +# running on non-Eth mainnet chains. +chain_id = 1 [fmt] number_underscore = "thousands" @@ -26,4 +26,27 @@ sort_imports = true wrap_comments = true single_line_statement_blocks = "multi" contract_new_lines = true + +[rpc_endpoints] +# We do not distinguish between Holesky / Sepolia / mainnet here, since that is +# handled within the scripts as an environment variable. This is more of a convenience +# mechanism to specify the chain name via command line; for example: +# cast balance $ADDRESS --rpc-url client +client = "${CLIENT_CHAIN_RPC}" +exocore_local = "${EXOCORE_LOCAL_RPC}" +exocore_testnet = "${EXOCORE_TESTNET_RPC}" + +[etherscan] +# Similar shortcut as `rpc_endpoints` to verify contracts by name and not URL. +# Example: +# forge verify-contract --etherscan-api-key exocore_testnet <...usual args...> +# However, defining this section with these env vars makes `forge test` complain +# if they are missing. It is because it tries to fetch debugging context from +# the block explorer. To avoid this, either ensure these vars are set, or comment +# out this section. +mainnet = { key = "${ETHERSCAN_API_KEY}" } +sepolia = { key = "${ETHERSCAN_API_KEY}" } +holesky = { key = "${ETHERSCAN_API_KEY}" } +exocore_testnet = { key = "${ETHERSCAN_API_KEY}", chain = 233, url = "${EXOCORE_TESTNET_EXPLORER_API}" } + # See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/lib/forge-std b/lib/forge-std index 1d9650e9..b5a86914 160000 --- a/lib/forge-std +++ b/lib/forge-std @@ -1 +1 @@ -Subproject commit 1d9650e951204a0ddce9ff89c32f1997984cef4d +Subproject commit b5a86914561f38735ef1fc357685de3e7c92dc48 diff --git a/script/12_RedeployClientChainGateway.s.sol b/script/12_RedeployClientChainGateway.s.sol index 423dd4bb..a772c6e7 100644 --- a/script/12_RedeployClientChainGateway.s.sol +++ b/script/12_RedeployClientChainGateway.s.sol @@ -73,9 +73,8 @@ contract RedeployClientChainGateway is BaseScript { new ClientChainGateway(address(clientChainLzEndpoint), config, address(rewardVaultBeacon)); // then the client chain initialization - address[] memory emptyList; bytes memory initialization = - abi.encodeWithSelector(clientGatewayLogic.initialize.selector, exocoreValidatorSet.addr, emptyList); + abi.encodeWithSelector(clientGatewayLogic.initialize.selector, exocoreValidatorSet.addr); bootstrap.setClientChainGatewayLogic(address(clientGatewayLogic), initialization); vm.stopBroadcast(); diff --git a/script/20_DeployCreate3.s.sol b/script/20_DeployCreate3.s.sol new file mode 100644 index 00000000..f85484e2 --- /dev/null +++ b/script/20_DeployCreate3.s.sol @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import "forge-std/Script.sol"; + +/// @title DeployCreate3 +/// @author ExocoreNetwork +/// @notice This script is used to deploy the deterministic Create2 and Create3 factories to any network. +/// The Create2 factory is deployed using a raw transaction and the Create3 factory is deployed using a Create2 call. +/// @dev The advantage of using the Create3 factory over the Create2 factory for further deployments is that the +/// contract address for Create3-deployments is only dependent on the salt and the sender and not the code. This allows +/// for omni-chain deployments at the same address regardless of the contract code version that is deployed. +contract DeployCreate3 is Script { + + // Unfortunately this is a pre-EIP155 transaction, so it will not work on most chains (which have blocked them). + // In that case, such a chain should add the contract as a predeploy. + bytes public constant CREATE2_RAW_TRANSACTION = + // solhint-disable-next-line + hex"f8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222"; + address public constant CREATE2_DEPLOYER = address(0x3fAB184622Dc19b6109349B94811493BF2a45362); + // this param is contained in the signed transaction already + uint256 public constant CREATE2_BALANCE = 100 gwei * 100_000; + address public constant CREATE2_DESTINATION = address(0x4e59b44847b379578588920cA78FbF26c0B4956C); + bytes public constant CREATE2_RUNTIME_CODE = + // solhint-disable-next-line + hex"7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3"; + // https://github.com/ZeframLou/create3-factory + bytes public constant CREATE3_INIT_CODE = + // solhint-disable-next-line + hex"608060405234801561001057600080fd5b5061063b806100206000396000f3fe6080604052600436106100295760003560e01c806350f1c4641461002e578063cdcb760a14610077575b600080fd5b34801561003a57600080fd5b5061004e610049366004610489565b61008a565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b61004e6100853660046104fd565b6100ee565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084901b166020820152603481018290526000906054016040516020818303038152906040528051906020012091506100e78261014c565b9392505050565b6040517fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003360601b166020820152603481018390526000906054016040516020818303038152906040528051906020012092506100e78383346102b2565b604080518082018252601081527f67363d3d37363d34f03d5260086018f30000000000000000000000000000000060209182015290517fff00000000000000000000000000000000000000000000000000000000000000918101919091527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b166021820152603581018290527f21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f60558201526000908190610228906075015b6040516020818303038152906040528051906020012090565b6040517fd69400000000000000000000000000000000000000000000000000000000000060208201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606083901b1660228201527f010000000000000000000000000000000000000000000000000000000000000060368201529091506100e79060370161020f565b6000806040518060400160405280601081526020017f67363d3d37363d34f03d5260086018f30000000000000000000000000000000081525090506000858251602084016000f5905073ffffffffffffffffffffffffffffffffffffffff811661037d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4445504c4f594d454e545f4641494c454400000000000000000000000000000060448201526064015b60405180910390fd5b6103868661014c565b925060008173ffffffffffffffffffffffffffffffffffffffff1685876040516103b091906105d6565b60006040518083038185875af1925050503d80600081146103ed576040519150601f19603f3d011682016040523d82523d6000602084013e6103f2565b606091505b50509050808015610419575073ffffffffffffffffffffffffffffffffffffffff84163b15155b61047f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f494e495449414c495a4154494f4e5f4641494c454400000000000000000000006044820152606401610374565b5050509392505050565b6000806040838503121561049c57600080fd5b823573ffffffffffffffffffffffffffffffffffffffff811681146104c057600080fd5b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806040838503121561051057600080fd5b82359150602083013567ffffffffffffffff8082111561052f57600080fd5b818501915085601f83011261054357600080fd5b813581811115610555576105556104ce565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561059b5761059b6104ce565b816040528281528860208487010111156105b457600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6000825160005b818110156105f757602081860181015185830152016105dd565b50600092019182525091905056fea2646970667358221220fd377c185926b3110b7e8a544f897646caf36a0e82b2629de851045e2a5f937764736f6c63430008100033"; + bytes32 public constant CREATE3_SALT = bytes32(0); + address public constant CREATE3_DESTINATION = address(0x6aA3D87e99286946161dCA02B97C5806fC5eD46F); + bytes public constant CREATE3_RUNTIME_CODE = + // solhint-disable-next-line + hex"6080604052600436106100295760003560e01c806350f1c4641461002e578063cdcb760a14610077575b600080fd5b34801561003a57600080fd5b5061004e610049366004610489565b61008a565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b61004e6100853660046104fd565b6100ee565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606084901b166020820152603481018290526000906054016040516020818303038152906040528051906020012091506100e78261014c565b9392505050565b6040517fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003360601b166020820152603481018390526000906054016040516020818303038152906040528051906020012092506100e78383346102b2565b604080518082018252601081527f67363d3d37363d34f03d5260086018f30000000000000000000000000000000060209182015290517fff00000000000000000000000000000000000000000000000000000000000000918101919091527fffffffffffffffffffffffffffffffffffffffff0000000000000000000000003060601b166021820152603581018290527f21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f60558201526000908190610228906075015b6040516020818303038152906040528051906020012090565b6040517fd69400000000000000000000000000000000000000000000000000000000000060208201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606083901b1660228201527f010000000000000000000000000000000000000000000000000000000000000060368201529091506100e79060370161020f565b6000806040518060400160405280601081526020017f67363d3d37363d34f03d5260086018f30000000000000000000000000000000081525090506000858251602084016000f5905073ffffffffffffffffffffffffffffffffffffffff811661037d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4445504c4f594d454e545f4641494c454400000000000000000000000000000060448201526064015b60405180910390fd5b6103868661014c565b925060008173ffffffffffffffffffffffffffffffffffffffff1685876040516103b091906105d6565b60006040518083038185875af1925050503d80600081146103ed576040519150601f19603f3d011682016040523d82523d6000602084013e6103f2565b606091505b50509050808015610419575073ffffffffffffffffffffffffffffffffffffffff84163b15155b61047f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f494e495449414c495a4154494f4e5f4641494c454400000000000000000000006044820152606401610374565b5050509392505050565b6000806040838503121561049c57600080fd5b823573ffffffffffffffffffffffffffffffffffffffff811681146104c057600080fd5b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806040838503121561051057600080fd5b82359150602083013567ffffffffffffffff8082111561052f57600080fd5b818501915085601f83011261054357600080fd5b813581811115610555576105556104ce565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561059b5761059b6104ce565b816040528281528860208487010111156105b457600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b6000825160005b818110156105f757602081860181015185830152016105dd565b50600092019182525091905056fea2646970667358221220fd377c185926b3110b7e8a544f897646caf36a0e82b2629de851045e2a5f937764736f6c63430008100033"; + + function setUp() public virtual { + // do nothing + } + + function run() public { + vm.startBroadcast(); + // only deploy if the destination is not already deployed + // with Anvil, pass `--disable-default-create2-deployer` to test this case + if (CREATE2_DESTINATION.code.length == 0) { + deployCreate2Factory(); + console.log("Deployed create2 factory"); + } else { + vm.assertEq(CREATE2_DESTINATION.code, CREATE2_RUNTIME_CODE); + console.log("Create2 factory already deployed"); + } + // only deploy if the destination i1s not already deployed + if (CREATE3_DESTINATION.code.length == 0) { + deployCreate3Factory(); + console.log("Deployed create3 factory"); + } else { + vm.assertEq(CREATE3_DESTINATION.code, CREATE3_RUNTIME_CODE); + console.log("Create3 factory already deployed"); + } + vm.stopBroadcast(); + } + + function deployCreate2Factory() public { + // provide gas funds to the deployer + uint256 currentBalance = CREATE2_DEPLOYER.balance; + if (currentBalance < CREATE2_BALANCE) { + payable(CREATE2_DEPLOYER).transfer(CREATE2_BALANCE - currentBalance); + } + // forge-std lib added this function in newer versions + vm.broadcastRawTransaction(CREATE2_RAW_TRANSACTION); + } + + function deployCreate3Factory() public { + // any sender can deploy the create3 factory because it is deployed via create2 + // the address will be the same across all chains as long as the code and + // the salt are the same. that is why we use a constant code instead of compilation. + (bool success,) = CREATE2_DESTINATION.call(abi.encodePacked(CREATE3_SALT, CREATE3_INIT_CODE)); + require(success, "DeployCreate3: failed to deploy create3 factory"); + } + +} diff --git a/script/7_DeployBootstrap.s.sol b/script/7_DeployBootstrap.s.sol index 22d5b2e2..978c62ab 100644 --- a/script/7_DeployBootstrap.s.sol +++ b/script/7_DeployBootstrap.s.sol @@ -92,9 +92,8 @@ contract DeployBootstrapOnly is BaseScript { new ClientChainGateway(address(clientChainLzEndpoint), config, address(rewardVaultBeacon)); // then the client chain initialization - address[] memory emptyList; bytes memory initialization = - abi.encodeWithSelector(clientGatewayLogic.initialize.selector, exocoreValidatorSet.addr, emptyList); + abi.encodeWithSelector(clientGatewayLogic.initialize.selector, exocoreValidatorSet.addr); // bootstrap implementation Bootstrap bootstrap = Bootstrap( diff --git a/script/BaseScript.sol b/script/BaseScript.sol index 24ac9aa1..3c602ace 100644 --- a/script/BaseScript.sol +++ b/script/BaseScript.sol @@ -107,7 +107,7 @@ contract BaseScript is Script, StdCheats { console.log("NOTICE: using exocore precompiles mock", useExocorePrecompileMock); clientChainRPCURL = vm.envString("CLIENT_CHAIN_RPC"); - exocoreRPCURL = vm.envString("EXOCORE_TESETNET_RPC"); + exocoreRPCURL = vm.envString("EXOCORE_TESTNET_RPC"); } function _bindPrecompileMocks() internal { diff --git a/script/TokenTransfer.s.sol b/script/TokenTransfer.s.sol index c1505e99..d7e9b27b 100644 --- a/script/TokenTransfer.s.sol +++ b/script/TokenTransfer.s.sol @@ -64,7 +64,7 @@ contract DeployScript is Script { relayer.addr = vm.addr(relayer.privateKey); clientChainRPCURL = vm.envString("CLIENT_CHAIN_RPC"); - exocoreRPCURL = vm.envString("EXOCORE_TESETNET_RPC"); + exocoreRPCURL = vm.envString("EXOCORE_TESTNET_RPC"); string memory deployedContracts = vm.readFile("script/deployedContracts.json"); diff --git a/script/integration/1_DeployBootstrap.s.sol b/script/integration/1_DeployBootstrap.s.sol index 154f0cdf..7b389dc7 100644 --- a/script/integration/1_DeployBootstrap.s.sol +++ b/script/integration/1_DeployBootstrap.s.sol @@ -241,9 +241,8 @@ contract DeployContracts is Script { ClientChainGateway clientGatewayLogic = new ClientChainGateway(address(clientChainLzEndpoint), config, address(rewardVaultBeacon)); - address[] memory emptyList; bytes memory initialization = - abi.encodeWithSelector(clientGatewayLogic.initialize.selector, vm.addr(contractDeployer), emptyList); + abi.encodeWithSelector(clientGatewayLogic.initialize.selector, vm.addr(contractDeployer)); bootstrap.setClientChainGatewayLogic(address(clientGatewayLogic), initialization); diff --git a/src/utils/BeaconProxyBytecode.sol b/src/utils/BeaconProxyBytecode.sol index b9e3575d..dc569b2c 100644 --- a/src/utils/BeaconProxyBytecode.sol +++ b/src/utils/BeaconProxyBytecode.sol @@ -12,6 +12,22 @@ contract BeaconProxyBytecode { /// cause /// addresses of ExoCapsules that are pre-computed with Create2 to change, even upon upgrading this contract, /// changing compiler version, etc. + // It is not possible to verify the init bytecode against a specific version of the contract + // because it appears to be deployed using a mix of versions of the imported contracts or + // another reason we don't understand yet. + // However, once deployed, the runtime bytecode (excluding the metadata) can be compared to that of a contract + // deployed manually using these details. + // OpenZeppelin-contracts v4.9.1 (or any other version before v5.0.0) + // solc 0.8.12+commit.f00d7308 + // optimizer enabled + // optimizer-runs 200 + // The metadata can be stripped from the runtime bytecode fetched via `eth_getCode` by using + // the last 2 bytes as the length of the metadata, and then removing that many bytes + 2 + // from the runtime bytecode. + // Given that it matches, the above provided details are correct. + // However, it would be great to either verify the init bytecode, or understand the reason + // behind the mismatch, or regenerate it for verification (which will likely introduce a + // split between mainnet and testnet deployments). bytes public constant BEACON_PROXY_BYTECODE = // solhint-disable-next-line hex"608060405260405161090e38038061090e83398101604081905261002291610460565b61002e82826000610035565b505061058a565b61003e83610100565b6040516001600160a01b038416907f1cf3b03a6cf19fa2baba4df148e9dcabedea7f8a5c07840e207e5c089be95d3e90600090a260008251118061007f5750805b156100fb576100f9836001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100e99190610520565b836102a360201b6100291760201c565b505b505050565b610113816102cf60201b6100551760201c565b6101725760405162461bcd60e51b815260206004820152602560248201527f455243313936373a206e657720626561636f6e206973206e6f74206120636f6e6044820152641d1c9858dd60da1b60648201526084015b60405180910390fd5b6101e6816001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101d79190610520565b6102cf60201b6100551760201c565b61024b5760405162461bcd60e51b815260206004820152603060248201527f455243313936373a20626561636f6e20696d706c656d656e746174696f6e206960448201526f1cc81b9bdd08184818dbdb9d1c9858dd60821b6064820152608401610169565b806102827fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d5060001b6102de60201b6100641760201c565b80546001600160a01b0319166001600160a01b039290921691909117905550565b60606102c883836040518060600160405280602781526020016108e7602791396102e1565b9392505050565b6001600160a01b03163b151590565b90565b6060600080856001600160a01b0316856040516102fe919061053b565b600060405180830381855af49150503d8060008114610339576040519150601f19603f3d011682016040523d82523d6000602084013e61033e565b606091505b5090925090506103508683838761035a565b9695505050505050565b606083156103c65782516103bf576001600160a01b0385163b6103bf5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610169565b50816103d0565b6103d083836103d8565b949350505050565b8151156103e85781518083602001fd5b8060405162461bcd60e51b81526004016101699190610557565b80516001600160a01b038116811461041957600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60005b8381101561044f578181015183820152602001610437565b838111156100f95750506000910152565b6000806040838503121561047357600080fd5b61047c83610402565b60208401519092506001600160401b038082111561049957600080fd5b818501915085601f8301126104ad57600080fd5b8151818111156104bf576104bf61041e565b604051601f8201601f19908116603f011681019083821181831017156104e7576104e761041e565b8160405282815288602084870101111561050057600080fd5b610511836020830160208801610434565b80955050505050509250929050565b60006020828403121561053257600080fd5b6102c882610402565b6000825161054d818460208701610434565b9190910192915050565b6020815260008251806020840152610576816040850160208701610434565b601f01601f19169190910160400192915050565b61034e806105996000396000f3fe60806040523661001357610011610017565b005b6100115b610027610022610067565b610100565b565b606061004e83836040518060600160405280602781526020016102f260279139610124565b9392505050565b6001600160a01b03163b151590565b90565b600061009a7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50546001600160a01b031690565b6001600160a01b0316635c60da1b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100fb9190610249565b905090565b3660008037600080366000845af43d6000803e80801561011f573d6000f35b3d6000fd5b6060600080856001600160a01b03168560405161014191906102a2565b600060405180830381855af49150503d806000811461017c576040519150601f19603f3d011682016040523d82523d6000602084013e610181565b606091505b50915091506101928683838761019c565b9695505050505050565b6060831561020d578251610206576001600160a01b0385163b6102065760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064015b60405180910390fd5b5081610217565b610217838361021f565b949350505050565b81511561022f5781518083602001fd5b8060405162461bcd60e51b81526004016101fd91906102be565b60006020828403121561025b57600080fd5b81516001600160a01b038116811461004e57600080fd5b60005b8381101561028d578181015183820152602001610275565b8381111561029c576000848401525b50505050565b600082516102b4818460208701610272565b9190910192915050565b60208152600082518060208401526102dd816040850160208701610272565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220d51e81d3bc5ed20a26aeb05dce7e825c503b2061aa78628027300c8d65b9d89a64736f6c634300080c0033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564"; diff --git a/test/foundry/BootstrapDepositNST.t.sol b/test/foundry/BootstrapDepositNST.t.sol index 67e36d36..9bbc2e00 100644 --- a/test/foundry/BootstrapDepositNST.t.sol +++ b/test/foundry/BootstrapDepositNST.t.sol @@ -287,8 +287,11 @@ contract BootstrapDepositNSTTest is Test { address capsuleAddress = _getCapsuleFromWithdrawalCredentials(_getWithdrawalCredentials(validatorContainer)); vm.etch(capsuleAddress, address(createdCapsule).code); capsule = ExoCapsule(payable(capsuleAddress)); - stdstore.target(capsuleAddress).sig("_beacon()").checked_write(address(capsuleBeacon)); - assertEq(stdstore.target(capsuleAddress).sig("_beacon()").read_address(), address(capsuleBeacon)); + // TODO: load this dynamically somehow instead of hardcoding it + bytes32 beaconSlotInCapsule = bytes32(uint256(keccak256("eip1967.proxy.beacon")) - 1); + bytes32 beaconAddress = bytes32(uint256(uint160(address(capsuleBeacon)))); + vm.store(capsuleAddress, beaconSlotInCapsule, beaconAddress); + assertEq(vm.load(capsuleAddress, beaconSlotInCapsule), beaconAddress); /// replace expectedCapsule with capsule bytes32 capsuleSlotInGateway = diff --git a/test/foundry/Delegation.t.sol b/test/foundry/Delegation.t.sol index d2f45c0c..40788145 100644 --- a/test/foundry/Delegation.t.sol +++ b/test/foundry/Delegation.t.sol @@ -12,8 +12,6 @@ import "@layerzero-v2/protocol/contracts/libs/AddressCast.sol"; import "@layerzerolabs/lz-evm-protocol-v2/contracts/libs/GUID.sol"; import "forge-std/Test.sol"; -import "forge-std/console.sol"; - contract DelegateTest is ExocoreDeployer { using AddressCast for address; diff --git a/test/foundry/DepositThenDelegateTo.t.sol b/test/foundry/DepositThenDelegateTo.t.sol index 39904ccb..654a740a 100644 --- a/test/foundry/DepositThenDelegateTo.t.sol +++ b/test/foundry/DepositThenDelegateTo.t.sol @@ -15,8 +15,6 @@ import "@layerzerolabs/lz-evm-protocol-v2/contracts/libs/GUID.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "forge-std/Test.sol"; -import "forge-std/console.sol"; - contract DepositThenDelegateToTest is ExocoreDeployer { using AddressCast for address; diff --git a/test/foundry/DepositWithdrawPrinciple.t.sol b/test/foundry/DepositWithdrawPrinciple.t.sol index 4278005a..ee0d0d35 100644 --- a/test/foundry/DepositWithdrawPrinciple.t.sol +++ b/test/foundry/DepositWithdrawPrinciple.t.sol @@ -284,9 +284,6 @@ contract DepositWithdrawPrincipalTest is ExocoreDeployer { withdrawalAmount = withdrawalAmountGwei * GWEI_TO_WEI; } - console.log("deposit amount:", depositAmount); - console.log("withdrawal amount:", withdrawalAmount); - principalBalanceBefore = _getPrincipalBalance(clientChainId, depositor.addr, VIRTUAL_STAKED_ETH_ADDRESS); withdrawableBefore = capsule.withdrawableBalance(); _testNativeWithdraw(depositor, relayer, lastlyUpdatedPrincipalBalance); @@ -413,8 +410,11 @@ contract DepositWithdrawPrincipalTest is ExocoreDeployer { address capsuleAddress = _getCapsuleFromWithdrawalCredentials(_getWithdrawalCredentials(validatorContainer)); vm.etch(capsuleAddress, address(createdCapsule).code); capsule = ExoCapsule(payable(capsuleAddress)); - stdstore.target(capsuleAddress).sig("_beacon()").checked_write(address(capsuleBeacon)); - assertEq(stdstore.target(capsuleAddress).sig("_beacon()").read_address(), address(capsuleBeacon)); + // TODO: load this dynamically somehow instead of hardcoding it + bytes32 beaconSlotInCapsule = bytes32(uint256(keccak256("eip1967.proxy.beacon")) - 1); + bytes32 beaconAddress = bytes32(uint256(uint160(address(capsuleBeacon)))); + vm.store(capsuleAddress, beaconSlotInCapsule, beaconAddress); + assertEq(vm.load(capsuleAddress, beaconSlotInCapsule), beaconAddress); /// replace expectedCapsule with capsule bytes32 capsuleSlotInGateway = bytes32( diff --git a/test/foundry/ExocoreDeployer.t.sol b/test/foundry/ExocoreDeployer.t.sol index 91b0fc25..86784adc 100644 --- a/test/foundry/ExocoreDeployer.t.sol +++ b/test/foundry/ExocoreDeployer.t.sol @@ -12,7 +12,6 @@ import "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol"; import "@openzeppelin/contracts/utils/Create2.sol"; import "forge-std/Test.sol"; -import "forge-std/console.sol"; import "../../src/core/ClientChainGateway.sol"; diff --git a/test/foundry/unit/Bootstrap.t.sol b/test/foundry/unit/Bootstrap.t.sol index 19f1cdcc..9c7d1ddf 100644 --- a/test/foundry/unit/Bootstrap.t.sol +++ b/test/foundry/unit/Bootstrap.t.sol @@ -34,7 +34,6 @@ import {Create2} from "@openzeppelin/contracts/utils/Create2.sol"; import "@openzeppelin/contracts/utils/Create2.sol"; import "forge-std/Test.sol"; -import "forge-std/console.sol"; import "src/libraries/Errors.sol"; import "src/core/ExoCapsule.sol"; @@ -1446,7 +1445,6 @@ contract BootstrapTest is Test { function test16_SetSpawnTime_LockTimeNotInFuture() public { vm.startPrank(deployer); vm.warp(offsetDuration - 1); - console.log(block.timestamp, offsetDuration, spawnTime); vm.expectRevert(Errors.BootstrapLockTimeAlreadyPast.selector); // the initial block.timestamp is 1, so subtract 2 here - 1 for // the test and 1 for the warp offset above. diff --git a/test/foundry/unit/ClientChainGateway.t.sol b/test/foundry/unit/ClientChainGateway.t.sol index 73624752..4508f5c0 100644 --- a/test/foundry/unit/ClientChainGateway.t.sol +++ b/test/foundry/unit/ClientChainGateway.t.sol @@ -17,7 +17,6 @@ import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.so import "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol"; import "forge-std/Test.sol"; -import "forge-std/console.sol"; import "src/core/ClientChainGateway.sol"; diff --git a/test/foundry/unit/CustomProxyAdmin.t.sol b/test/foundry/unit/CustomProxyAdmin.t.sol index 43eaccd7..8227aa3b 100644 --- a/test/foundry/unit/CustomProxyAdmin.t.sol +++ b/test/foundry/unit/CustomProxyAdmin.t.sol @@ -5,7 +5,6 @@ import {ICustomProxyAdmin} from "src/interfaces/ICustomProxyAdmin.sol"; import {CustomProxyAdmin} from "src/utils/CustomProxyAdmin.sol"; import "forge-std/Test.sol"; -import "forge-std/console.sol"; import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; diff --git a/test/foundry/unit/ExoCapsule.t.sol b/test/foundry/unit/ExoCapsule.t.sol index 017a96d1..4a76bf9f 100644 --- a/test/foundry/unit/ExoCapsule.t.sol +++ b/test/foundry/unit/ExoCapsule.t.sol @@ -221,7 +221,7 @@ contract VerifyDepositProof is DepositSetup { abi.encode(beaconBlockRoot) ); - uint256 snapshot = vm.snapshot(); + uint256 snapshot = vm.snapshotState(); // construct malformed validator container that has extra fields validatorContainer.push(bytes32(uint256(123))); @@ -230,7 +230,7 @@ contract VerifyDepositProof is DepositSetup { ); capsule.verifyDepositProof(validatorContainer, validatorProof); - vm.revertTo(snapshot); + vm.revertToState(snapshot); // construct malformed validator container that misses fields validatorContainer.pop(); vm.expectRevert( diff --git a/test/foundry/unit/ExocoreGateway.t.sol b/test/foundry/unit/ExocoreGateway.t.sol index bc2d8d07..be4c1293 100644 --- a/test/foundry/unit/ExocoreGateway.t.sol +++ b/test/foundry/unit/ExocoreGateway.t.sol @@ -18,7 +18,6 @@ import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol"; import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; import "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol"; import "forge-std/Test.sol"; -import "forge-std/console.sol"; import "src/core/ClientChainGateway.sol"; import "src/core/ClientChainGateway.sol";