diff --git a/.gitmodules b/.gitmodules index 8817679..deb90cc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -12,3 +12,6 @@ [submodule "lib/connext-interfaces"] path = lib/connext-interfaces url = https://github.com/connext/interfaces +[submodule "lib/ExcessivelySafeCall"] + path = lib/ExcessivelySafeCall + url = https://github.com/nomad-xyz/ExcessivelySafeCall diff --git a/contracts/test/e2e/AnyToAnySwapAndForward.t.sol b/contracts/test/e2e/AnyToAnySwapAndForward.t.sol index 6ff60a6..c8ec0fb 100644 --- a/contracts/test/e2e/AnyToAnySwapAndForward.t.sol +++ b/contracts/test/e2e/AnyToAnySwapAndForward.t.sol @@ -21,29 +21,30 @@ contract AnyToAnySwapAndForwardTest is TestHelper { address public immutable ARB_USDC = 0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8; address public immutable ARB_ARB = 0x912CE59144191C1204E64559FE8253a0e49E6548; - address public immutable OP_OP_WHALE = 0x2501c477D0A35545a387Aa4A3EEe4292A9a8B3F0; - address public immutable ARB_USDC_WHALE = 0x489ee077994B6658eAfA855C308275EAd8097C4A; address public immutable ONEINCH_SWAPPER = 0x1111111254EEB25477B68fb85Ed929f73A960582; address public immutable FALLBACK_ADDRESS = address(1); + function setUp() public override { + super.setUp(); + setUpCrossChainE2E(OPTIMISM_CHAIN_ID, ARBITRUM_CHAIN_ID, 87307161, 78000226, ARB_USDC); + } + function utils_setUpOrigin() public { - setUpOptimism(87307161); - swapAndXCall = new SwapAndXCall(CONNEXT_OPTIMISM); - vm.prank(OP_OP_WHALE); - TransferHelper.safeTransfer(OP_OP, address(this), 1000 ether); + vm.selectFork(chainConfigs[OPTIMISM_CHAIN_ID].forkId); + swapAndXCall = new SwapAndXCall(chainConfigs[OPTIMISM_CHAIN_ID].connext); + deal(OP_OP, address(this), 1000 ether); vm.label(address(swapAndXCall), "SwapAndXCall"); vm.label(address(this), "AnyToAnySwapAndForwardTest"); vm.label(OP_OP, "OP_OP"); vm.label(OP_USDC, "OP_USDC"); - vm.label(OP_OP_WHALE, "OP_OP_WHALE"); } function utils_setUpDestination() public { - setUpArbitrum(78000226); + vm.selectFork(chainConfigs[ARBITRUM_CHAIN_ID].forkId); greeter = new Greeter(); - xSwapAndGreetTarget = new XSwapAndGreetTarget(address(greeter), CONNEXT_ARBITRUM); + xSwapAndGreetTarget = new XSwapAndGreetTarget(address(greeter), chainConfigs[ARBITRUM_CHAIN_ID].connext); oneInchUniswapV3 = new OneInchUniswapV3(ONEINCH_SWAPPER); xSwapAndGreetTarget.addSwapper(address(oneInchUniswapV3)); // 1inch address on arbitrum @@ -58,24 +59,18 @@ contract AnyToAnySwapAndForwardTest is TestHelper { utils_setUpOrigin(); utils_setUpDestination(); - vm.selectFork(optimismForkId); - assertEq(vm.activeFork(), optimismForkId); + vm.selectFork(chainConfigs[OPTIMISM_CHAIN_ID].forkId); + assertEq(vm.activeFork(), chainConfigs[OPTIMISM_CHAIN_ID].forkId); // origin // start with OP and swap to USDC to bridge to destination TransferHelper.safeApprove(OP_OP, address(swapAndXCall), 1000 ether); bytes - memory oneInchApiDataOpToUsdc = hex"12aa3caf000000000000000000000000f0694acc9e941b176e17b9ef923e71e7b8b2477a00000000000000000000000042000000000000000000000000000000000000420000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c31607000000000000000000000000f0694acc9e941b176e17b9ef923e71e7b8b2477a0000000000000000000000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f00000000000000000000000000000000000000000000003635c9adc5dea000000000000000000000000000000000000000000000000000000000000078f1ff510000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000097c00000000000000000000000000000000000000095e0009300008e60008cc00a0c9e75c480000000000000007020100000000000000000000000000000000000000000000089e0006d100032700a007e5c0d200000000000000000000000000000000000000000000030300021c0001cd00a0c9e75c4800000000000000002a0800000000000000000000000000000000000000000000000000019f00004f02a0000000000000000000000000000000000000000000000000003e23993ea6ce3cee63c1e500fc1f3296458f9b2a27a0b91dd7681c4020e09d0542000000000000000000000000000000000000425126a132dab612db5cb9fc9ac426a0cc215a3423f9c942000000000000000000000000000000000000420004f41766d800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000146409db6c1079d00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000f0694acc9e941b176e17b9ef923e71e7b8b2477a000000000000000000000000000000000000000000000000000000006436df18000000000000000000000000000000000000000000000000000000000000000100000000000000000000000042000000000000000000000000000000000000420000000000000000000000004200000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000b005cef732b384620ee63c1e50195d9d28606ee55de7667f0f176ebfc3215cfd9c0420000000000000000000000000000000000000600a0bd46a34303b5ad7d6d6f92a77f47f98c28c84893fbccc9480900000000000000000000006c43da214fab3315aa6c02e0b8f2bfb7ef2e3c60a50000000000000000000000ae88d07558470484c03d3bb44c3ecc36cafcf43253000000000000000000000051000000000000000000000000da10009cbd5d07dd0cecc66161fc93d7c9000da1000000000000000000000000b5ad7d6d6f92a77f47f98c28c84893fbccc9480900000000000000000000000088d07558470484c03d3bb44c3ecc36cafcf432530000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700a007e5c0d200000000000000000000000000000000000000000000000000038600008e4820a6d7d0e650aa40ffa42d845a354c12c2bc0ab15f42000000000000000000000000000000000000429331621200000000000000000000000042000000000000000000000000000000000000420000000000000000000000004200000000000000000000000000000000000006000000000000000000000000f0694acc9e941b176e17b9ef923e71e7b8b2477a00a0c9e75c48000000000000000029090000000000000000000000000000000000000000000000000002ca00011c4312f9d5940c2313636546ab9852354860dce275dbad00000000000000000000000000000000000000000000000000000000045a6d40002424b31a0c000000000000000000000000f0694acc9e941b176e17b9ef923e71e7b8b2477a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000001000276a400000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000420000000000000000000000000000000000000600a007e5c0d200000000000000000000000000000000000000000000000000018a0000d05120c35dadb65012ec5796536bd9864ed8773abc74c44200000000000000000000000000000000000006006402b9446c0000000000000000000000004200000000000000000000000000000000000006000000000000000000000000f0694acc9e941b176e17b9ef923e71e7b8b2477a0000000000000000000000007086622e6db990385b102d79cb1218947fb549a90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040207086622e6db990385b102d79cb1218947fb549a9627dd56a000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000600000000000000000000000004200000000000000000000000000000000000006000000000000000000000000f0694acc9e941b176e17b9ef923e71e7b8b2477a000000000000000000000000000000000000000000000000000000000000000100a0c9e75c480000000000000000221000000000000000000000000000000000000000000000000000019f00004f02a0000000000000000000000000000000000000000000000000000000001b17ef8fee63c1e5011d751bc1a723accf1942122ca9aa82d49d08d2ae42000000000000000000000000000000000000425126a132dab612db5cb9fc9ac426a0cc215a3423f9c942000000000000000000000000000000000000420004f41766d800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000039913b6500000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000f0694acc9e941b176e17b9ef923e71e7b8b2477a000000000000000000000000000000000000000000000000000000006436df18000000000000000000000000000000000000000000000000000000000000000100000000000000000000000042000000000000000000000000000000000000420000000000000000000000007f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000000000000000000000000000000000000000000000020d6bdbf787f5c764cbc14f9669b88837ca1490cca17c3160700a0f2fa6b667f5c764cbc14f9669b88837ca1490cca17c3160700000000000000000000000000000000000000000000000000000000866238220000000000000000000000000098760180a06c4eca277f5c764cbc14f9669b88837ca1490cca17c316071111111254eeb25477b68fb85ed929f73a96058200000000cfee7c08"; + memory oneInchApiDataOpToUsdc = hex"e449022e00000000000000000000000000000000000000000000003635c9adc5dea00000000000000000000000000000000000000000000000000000000000005073d59500000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000002800000000000000000000000fc1f3296458f9b2a27a0b91dd7681c4020e09d0500000000000000000000000085149247691df622eaf1a8bd0cafd40bc45154a9cfee7c08"; + TransferHelper.safeApprove(OP_OP, ONEINCH_SWAPPER, 1000 ether); // destination // set up destination swap params - // uint256 usdcAmount = 100000000; - // uint256 minReturn = 75555343887264722127; - // address USDC_ARB_POOL = 0xcDa53B1F66614552F834cEeF361A8D12a0B8DaD8; - // uint256[] memory pools = new uint256[](1); - // pools[0] = ONE_FOR_ZERO_MASK + uint256(uint160(USDC_ARB_POOL)); - // bytes memory oneInchApiDataUsdcToArb = abi.encode(usdcAmount, minReturn, pools); - bytes memory oneInchApiDataUsdcToArb = hex"e449022e0000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000004188a80f4c2e52ccf00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001800000000000000000000000cda53b1f66614552f834ceef361a8d12a0b8dad8cfee7c08"; @@ -96,7 +91,7 @@ contract AnyToAnySwapAndForwardTest is TestHelper { 1000 ether, ONEINCH_SWAPPER, oneInchApiDataOpToUsdc, - ARBITRUM_DOMAIN_ID, + chainConfigs[ARBITRUM_CHAIN_ID].domainId, address(greeter), address(this), 300, @@ -104,18 +99,18 @@ contract AnyToAnySwapAndForwardTest is TestHelper { 123 // fake relayer fee, will be in USDC ); - vm.selectFork(arbitrumForkId); - vm.prank(ARB_USDC_WHALE); - TransferHelper.safeTransfer(ARB_USDC, address(xSwapAndGreetTarget), 99800000); - vm.prank(CONNEXT_ARBITRUM); - xSwapAndGreetTarget.xReceive( - bytes32(""), - 99800000, // Final Amount receive via Connext(After AMM calculation) - ARB_USDC, - address(0), - 123, - callData - ); + vm.selectFork(chainConfigs[ARBITRUM_CHAIN_ID].forkId); + // vm.prank(ARB_USDC_WHALE); + // TransferHelper.safeTransfer(ARB_USDC, address(xSwapAndGreetTarget), 99800000); + // vm.prank(CONNEXT_ARBITRUM); + // xSwapAndGreetTarget.xReceive( + // bytes32(""), + // 99800000, // Final Amount receive via Connext(After AMM calculation) + // ARB_USDC, + // address(0), + // 123, + // callData + // ); assertEq(greeter.greeting(), "Hello, Connext!"); assertEq(IERC20(ARB_ARB).balanceOf(address(greeter)), 83059436227592757201); } diff --git a/contracts/test/e2e/integration/MidasProtocol.t.sol b/contracts/test/e2e/integration/MidasProtocol.t.sol index 35c66b9..b1239e9 100644 --- a/contracts/test/e2e/integration/MidasProtocol.t.sol +++ b/contracts/test/e2e/integration/MidasProtocol.t.sol @@ -42,7 +42,7 @@ contract MidasProtocolTest is TestHelper { address public immutable FALLBACK_ADDRESS = address(1); function utils_setUpOptimismForOrigin() public { - setUpOptimism(87307161); + setUpFork(OPTIMISM_CHAIN_ID, 87307161); swapAndXCall = new SwapAndXCall(CONNEXT_OPTIMISM); vm.prank(OP_OP_WHALE); TransferHelper.safeTransfer(OP_OP, address(this), 1000 ether); @@ -55,7 +55,7 @@ contract MidasProtocolTest is TestHelper { } function utils_setUpBNBForDestination() public { - setUpBNB(27284448); + setUpFork(BNB_CHAIN_ID, 27284448); uniV2Swapper = new UniV2Swapper(BNB_UNIV2_ROUTER); midasProtocolTarget = new MidasProtocolTarget(CONNEXT_BNB, BNB_COMPTROLLER); midasProtocolTarget.addSwapper(address(uniV2Swapper)); @@ -67,7 +67,7 @@ contract MidasProtocolTest is TestHelper { } function utils_setUpPolygonForDestination() public { - setUpPolygon(41491942); + setUpFork(POLYGON_CHAIN_ID, 41491942); uniV3Swapper = new UniV3Swapper(POLYGON_UNIV3_ROUTER); uniV2Swapper = new UniV2Swapper(POLYGON_UNIV2_ROUTER); midasProtocolTarget = new MidasProtocolTarget(CONNEXT_POLYGON, POLYGON_COMPTROLLER); @@ -116,7 +116,7 @@ contract MidasProtocolTest is TestHelper { 1000 ether, OP_ONEINCH_SWAPPER, oneInchApiDataOpToUsdc, - BNB_DOMAIN_ID, + chainConfigs[BNB_CHAIN_ID].domainId, address(0x1), address(this), 300, @@ -177,7 +177,7 @@ contract MidasProtocolTest is TestHelper { 1000 ether, OP_ONEINCH_SWAPPER, oneInchApiDataOpToUsdc, - POLYGON_DOMAIN_ID, + chainConfigs[POLYGON_CHAIN_ID].domainId, address(0x1), address(this), 300, diff --git a/contracts/test/utils/MockConnext.sol b/contracts/test/utils/MockConnext.sol new file mode 100644 index 0000000..98f19af --- /dev/null +++ b/contracts/test/utils/MockConnext.sol @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.19; +import "forge-std/Test.sol"; +import {TransferHelper} from "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol"; +import {TransferInfo} from "connext-interfaces/core/IConnext.sol"; +import {IXReceiver} from "connext-interfaces/core/IXReceiver.sol"; +import "ExcessivelySafeCall/ExcessivelySafeCall.sol"; + +contract MockConnext is Test { + uint256 public originChainForkId; + uint256 public destinationChainForkId; + address public destinationAsset; + uint32 public originDomain; + uint32 public destinationDomain; + + address public destinationConnext; + + bytes32 internal constant EMPTY_HASH = keccak256(""); + uint256 public constant EXECUTE_CALLDATA_RESERVE_GAS = 10_000; + uint16 public constant DEFAULT_COPY_BYTES = 256; + + error BridgeFacet__execute_externalCallFailed(); + + constructor( + uint32 _originDomain, + uint32 _destinationDomain, + uint256 _originChainForkId, + uint256 _destinationChainForkId, + address _destinationAsset + ) { + originDomain = _originDomain; + destinationDomain = _destinationDomain; + originChainForkId = _originChainForkId; + destinationChainForkId = _destinationChainForkId; + destinationAsset = _destinationAsset; + } + + function setDestinationConnext(address _destinationConnext) external { + destinationConnext = _destinationConnext; + } + + function xcall( + uint32 _destination, + address _to, + address _asset, + address _delegate, + uint256 _amount, + uint256 _slippage, + bytes calldata _callData + ) external payable returns (bytes32) { + bytes32 _transferId = bytes32(originChainForkId); + TransferHelper.safeTransferFrom(_asset, msg.sender, address(this), _amount); + _executeDestination(_callData, _amount, _to, _transferId); + + return bytes32(originChainForkId); + } + + function xcall( + uint32 _destination, + address _to, + address _asset, + address _delegate, + uint256 _amount, + uint256 _slippage, + bytes calldata _callData, + uint256 _relayerFee + ) external returns (bytes32 _transferId) { + _transferId = bytes32(originChainForkId); + TransferHelper.safeTransferFrom(_asset, msg.sender, address(this), _amount + _relayerFee); + _executeDestination(_callData, _amount, _to, _transferId); + } + + function xcallIntoLocal( + uint32 _destination, + address _to, + address _asset, + address _delegate, + uint256 _amount, + uint256 _slippage, + bytes calldata _callData + ) external payable returns (bytes32) {} + + function _executeDestination(bytes calldata _callData, uint256 _amount, address _to, bytes32 _transferId) internal { + if (keccak256(_callData) == EMPTY_HASH) { + // no call data, return amount out + return; + } + + vm.selectFork(destinationChainForkId); + + // transfer to destination + uint256 _destinationAmount = (_amount * (10000 - 5)) / 10000; // simulate router fee + deal(destinationAsset, _to, _destinationAmount); + + // to send a tx + vm.deal(destinationConnext, 1 ether); + vm.prank(destinationConnext); + (bool success, ) = ExcessivelySafeCall.excessivelySafeCall( + _to, + gasleft() - EXECUTE_CALLDATA_RESERVE_GAS, + 0, // native asset value (always 0) + DEFAULT_COPY_BYTES, // only copy 256 bytes back as calldata + abi.encodeWithSelector( + IXReceiver.xReceive.selector, + _transferId, + _destinationAmount, + destinationAsset, + address(0), // fast path only, TODO: figure out slow path + originDomain, + _callData + ) + ); + + if (!success) { + // reverts if unsuccessful on fast path + revert BridgeFacet__execute_externalCallFailed(); + } + } +} diff --git a/contracts/test/utils/TestHelper.sol b/contracts/test/utils/TestHelper.sol index 876d8c5..422c675 100644 --- a/contracts/test/utils/TestHelper.sol +++ b/contracts/test/utils/TestHelper.sol @@ -2,29 +2,21 @@ pragma solidity ^0.8.15; import "forge-std/Test.sol"; +import {MockConnext} from "./MockConnext.sol"; contract TestHelper is Test { - /// Testnet Domain IDs - uint32 public GOERLI_DOMAIN_ID = 1735353714; - uint32 public OPTIMISM_GOERLI_DOMAIN_ID = 1735356532; - uint32 public ARBITRUM_GOERLI_DOMAIN_ID = 1734439522; - uint32 public POLYGON_MUMBAI_DOMAIN_ID = 9991; - /// Testnet Chain IDs uint32 public GOERLI_CHAIN_ID = 5; uint32 public OPTIMISM_GOERLI_CHAIN_ID = 420; uint32 public ARBITRUM_GOERLI_CHAIN_ID = 421613; uint32 public POLYGON_MUMBAI_CHAIN_ID = 80001; - /// Mainnet Domain IDs - uint32 public ARBITRUM_DOMAIN_ID = 1634886255; - uint32 public OPTIMISM_DOMAIN_ID = 1869640809; - uint32 public BNB_DOMAIN_ID = 6450786; - uint32 public POLYGON_DOMAIN_ID = 1886350457; - /// Mainnet Chain IDs + uint32 public MAINNET_CHAIN_ID = 1; uint32 public ARBITRUM_CHAIN_ID = 42161; uint32 public OPTIMISM_CHAIN_ID = 10; + uint32 public BNB_CHAIN_ID = 56; + uint32 public POLYGON_CHAIN_ID = 137; // Live Addresses address public CONNEXT_ARBITRUM = 0xEE9deC2712cCE65174B561151701Bf54b99C24C8; @@ -32,6 +24,17 @@ contract TestHelper is Test { address public CONNEXT_BNB = 0xCd401c10afa37d641d2F594852DA94C700e4F2CE; address public CONNEXT_POLYGON = 0x11984dc4465481512eb5b777E44061C158CF2259; + struct ChainConfig { + uint32 chainId; + uint32 domainId; + string defaultRpc; + string rpcKeyName; + uint256 forkId; + address connext; + } + + mapping(uint32 => ChainConfig) public chainConfigs; + // Forks uint256 public arbitrumForkId; uint256 public optimismForkId; @@ -56,53 +59,139 @@ contract TestHelper is Test { vm.label(TokenB_ERC20, "TokenB_ERC20"); vm.label(USER_CHAIN_A, "User Chain A"); vm.label(USER_CHAIN_B, "User Chain B"); - } - - function setUpArbitrum(uint256 blockNumber) public { - arbitrumForkId = vm.createSelectFork(getRpc(42161), blockNumber); - vm.label(CONNEXT_ARBITRUM, "Connext Arbitrum"); - } - function setUpOptimism(uint256 blockNumber) public { - optimismForkId = vm.createSelectFork(getRpc(10), blockNumber); - vm.label(CONNEXT_OPTIMISM, "Connext Optimism"); + // MAINNET + chainConfigs[ARBITRUM_CHAIN_ID] = ChainConfig({ + chainId: ARBITRUM_CHAIN_ID, + domainId: 1634886255, + defaultRpc: "https://arb1.arbitrum.io/rpc", + rpcKeyName: "ARBITRUM_RPC_URL", + forkId: 0, + connext: address(0) + }); + + chainConfigs[OPTIMISM_CHAIN_ID] = ChainConfig({ + chainId: OPTIMISM_CHAIN_ID, + domainId: 1869640809, + defaultRpc: "https://mainnet.optimism.io", + rpcKeyName: "OPTIMISM_RPC_URL", + forkId: 0, + connext: address(0) + }); + + chainConfigs[MAINNET_CHAIN_ID] = ChainConfig({ + chainId: MAINNET_CHAIN_ID, + domainId: 6648936, + defaultRpc: "https://eth.llamarpc.com", + rpcKeyName: "MAINNET_RPC_URL", + forkId: 0, + connext: address(0) + }); + + chainConfigs[BNB_CHAIN_ID] = ChainConfig({ + chainId: BNB_CHAIN_ID, + domainId: 6450786, + defaultRpc: "https://bsc-dataseed.binance.org", + rpcKeyName: "BNB_RPC_URL", + forkId: 0, + connext: address(0) + }); + + chainConfigs[POLYGON_CHAIN_ID] = ChainConfig({ + chainId: POLYGON_CHAIN_ID, + domainId: 1886350457, + defaultRpc: "https://rpc-mainnet.maticvigil.com", + rpcKeyName: "POLYGON_RPC_URL", + forkId: 0, + connext: address(0) + }); + + // TESTNET + chainConfigs[GOERLI_CHAIN_ID] = ChainConfig({ + chainId: GOERLI_CHAIN_ID, + domainId: 1735353714, + defaultRpc: "", + rpcKeyName: "GOERLI_RPC_URL", + forkId: 0, + connext: address(0) + }); + + chainConfigs[OPTIMISM_GOERLI_CHAIN_ID] = ChainConfig({ + chainId: OPTIMISM_GOERLI_CHAIN_ID, + domainId: 1735356532, + defaultRpc: "", + rpcKeyName: "OPTIMISM_GOERLI_RPC_URL", + forkId: 0, + connext: address(0) + }); + + chainConfigs[ARBITRUM_GOERLI_CHAIN_ID] = ChainConfig({ + chainId: ARBITRUM_GOERLI_CHAIN_ID, + domainId: 1734439522, + defaultRpc: "", + rpcKeyName: "ARBITRUM_GOERLI_RPC_URL", + forkId: 0, + connext: address(0) + }); + + chainConfigs[POLYGON_MUMBAI_CHAIN_ID] = ChainConfig({ + chainId: POLYGON_MUMBAI_CHAIN_ID, + domainId: 1734439522, + defaultRpc: "", + rpcKeyName: "POLYGON_MUMBAI_RPC_URL", + forkId: 0, + connext: address(0) + }); } - function setUpBNB(uint256 blockNumber) public { - bnbForkId = vm.createSelectFork(getRpc(56), blockNumber); - vm.label(CONNEXT_BNB, "Connext BNB"); + function setUpFork(uint32 chainId, uint256 blockNumber) public returns (uint256 forkId) { + forkId = vm.createSelectFork(getRpc(chainId), blockNumber); + chainConfigs[chainId].forkId = forkId; } - function setUpPolygon(uint256 blockNumber) public { - polygonForkId = vm.createSelectFork(getRpc(137), blockNumber); - vm.label(CONNEXT_POLYGON, "Connext Polygon"); + function setUpCrossChainE2E( + uint32 originChainId, + uint32 destinationChainId, + uint256 originChainBlockNumber, + uint256 destinationChainBlockNumber, + address destinationAsset // i.e. USDC or WETH + ) public { + // origin chain + uint256 originFork = setUpFork(originChainId, originChainBlockNumber); + uint256 destinationFork = setUpFork(destinationChainId, destinationChainBlockNumber); + vm.selectFork(originFork); + MockConnext connextOrigin = new MockConnext( + chainConfigs[originChainId].domainId, + chainConfigs[destinationChainId].domainId, + originFork, + destinationFork, + destinationAsset + ); + chainConfigs[originChainId].connext = address(connextOrigin); + vm.label(address(connextOrigin), "Mock Connext Origin"); + + // destination chain + vm.selectFork(destinationFork); + MockConnext connextDestination = new MockConnext( + chainConfigs[originChainId].domainId, + chainConfigs[destinationChainId].domainId, + originFork, + destinationFork, + destinationAsset + ); + chainConfigs[destinationChainId].connext = address(connextDestination); + connextDestination.setDestinationConnext(address(connextOrigin)); + vm.label(address(connextDestination), "Mock Connext Destination"); + + vm.selectFork(originFork); + connextOrigin.setDestinationConnext(address(connextDestination)); } - function getRpc(uint256 chainId) internal view returns (string memory) { - string memory keyName; - string memory defaultRpc; - - if (chainId == 1) { - keyName = "MAINNET_RPC_URL"; - defaultRpc = "https://eth.llamarpc.com"; - } else if (chainId == 10) { - keyName = "OPTIMISM_RPC_URL"; - defaultRpc = "https://mainnet.optimism.io"; - } else if (chainId == 42161) { - keyName = "ARBITRUM_RPC_URL"; - defaultRpc = "https://arb1.arbitrum.io/rpc"; - } else if (chainId == 56) { - keyName = "BNB_RPC_URL"; - defaultRpc = "https://bsc-dataseed.binance.org"; - } else if (chainId == 137) { - keyName = "POLYGON_RPC_URL"; - defaultRpc = "https://polygon.llamarpc.com"; - } - - try vm.envString(keyName) { - return vm.envString(keyName); + function getRpc(uint32 chainId) internal view returns (string memory) { + try vm.envString(chainConfigs[chainId].rpcKeyName) { + return vm.envString(chainConfigs[chainId].rpcKeyName); } catch { - return defaultRpc; + return chainConfigs[chainId].defaultRpc; } } } diff --git a/lib/ExcessivelySafeCall b/lib/ExcessivelySafeCall new file mode 160000 index 0000000..81cd99c --- /dev/null +++ b/lib/ExcessivelySafeCall @@ -0,0 +1 @@ +Subproject commit 81cd99ce3e69117d665d7601c330ea03b97acce0