From cd5c46dc5efab5fa082973076851b3af6ec7ce4a Mon Sep 17 00:00:00 2001 From: wcgcyx Date: Tue, 20 Feb 2024 12:54:45 +1000 Subject: [PATCH] Fix --- test/invariant/InvariantBridge.t.sol | 103 +++++++++++++++++++++++---- 1 file changed, 91 insertions(+), 12 deletions(-) diff --git a/test/invariant/InvariantBridge.t.sol b/test/invariant/InvariantBridge.t.sol index 5974c220..96509d66 100644 --- a/test/invariant/InvariantBridge.t.sol +++ b/test/invariant/InvariantBridge.t.sol @@ -8,13 +8,20 @@ import {IChildERC20Bridge, ChildERC20Bridge} from "../../src/child/ChildERC20Bri import {IRootERC20Bridge, IERC20Metadata} from "../../src/root/RootERC20Bridge.sol"; import {RootERC20BridgeFlowRate} from "../../src/root/flowrate/RootERC20BridgeFlowRate.sol"; import {MockAdaptor} from "./MockAdaptor.sol"; +import {ChildHelper} from "./child/ChildHelper.sol"; +import {RootHelper} from "./root/RootHelper.sol"; +import {ChildERC20BridgeHandler} from "./child/ChildERC20BridgeHandler.sol"; +import {RootERC20BridgeFlowRateHandler} from "./root/RootERC20BridgeFlowRateHandler.sol"; import "forge-std/console.sol"; contract InvariantBridge is Test { string public constant ROOT_CHAIN_URL = "http://127.0.0.1:8500"; string public constant CHILD_CHAIN_URL = "http://127.0.0.1:8501"; uint256 public constant IMX_DEPOSIT_LIMIT = 10000 ether; + uint256 public constant MAX_AMOUNT = 10000; address public constant ADMIN = address(0x111); + uint256 public constant NO_OF_USERS = 20; + uint256 public constant NO_OF_TOKENS = 20; uint256 childId; uint256 rootId; @@ -22,6 +29,12 @@ contract InvariantBridge is Test { RootERC20BridgeFlowRate rootBridge; MockAdaptor childAdaptor; MockAdaptor rootAdaptor; + ChildHelper childHelper; + RootHelper rootHelper; + address[] users; + address[] rootTokens; + + RootERC20BridgeFlowRateHandler rootBridgeHandler; function setUp() public { childId = vm.createFork(CHILD_CHAIN_URL); @@ -33,8 +46,9 @@ contract InvariantBridge is Test { ChildERC20 childTokenTemplate = new ChildERC20(); childTokenTemplate.initialize(address(123), "Test", "TST", 18); childAdaptor = new MockAdaptor(); - vm.stopPrank(); childBridge = new ChildERC20Bridge(address(this)); + new RootERC20BridgeFlowRate(address(this)); + vm.stopPrank(); WIMX wIMX = new WIMX(); // Deploy contracts on root chain. @@ -43,15 +57,29 @@ contract InvariantBridge is Test { ChildERC20 rootTokenTemplate = new ChildERC20(); rootTokenTemplate.initialize(address(123), "Test", "TST", 18); rootAdaptor = new MockAdaptor(); - vm.stopPrank(); + new ChildERC20Bridge(address(this)); rootBridge = new RootERC20BridgeFlowRate(address(this)); + vm.stopPrank(); ChildERC20 rootIMXToken = new ChildERC20(); rootIMXToken.initialize(address(123), "Immutable X", "IMX", 18); WIMX wETH = new WIMX(); + + // Deploy both helpers on both chains. + vm.selectFork(childId); + vm.startPrank(ADMIN); + childHelper = new ChildHelper(childId, payable(childBridge)); + address(new RootHelper(rootId, ADMIN, payable(rootBridge))); + vm.stopPrank(); + + vm.selectFork(rootId); + vm.startPrank(ADMIN); + address(new ChildHelper(childId, payable(childBridge))); + rootHelper = new RootHelper(rootId, ADMIN, payable(rootBridge)); + vm.stopPrank(); // Configure contracts on child chain. vm.selectFork(childId); - childAdaptor.initialize(rootId, address(childBridge), address(rootAdaptor)); + childAdaptor.initialize(rootId, address(childBridge)); IChildERC20Bridge.InitializationRoles memory childRoles = IChildERC20Bridge.InitializationRoles({ defaultAdmin: address(this), pauser: address(this), @@ -66,7 +94,7 @@ contract InvariantBridge is Test { // Configure contracts on root chain. vm.selectFork(rootId); - rootAdaptor.initialize(childId, address(rootBridge), address(childAdaptor)); + rootAdaptor.initialize(childId, address(rootBridge)); IRootERC20Bridge.InitializationRoles memory rootRoles = IRootERC20Bridge.InitializationRoles({ defaultAdmin: address(this), pauser: address(this), @@ -85,17 +113,68 @@ contract InvariantBridge is Test { ADMIN ); - // Try to map one token - ChildERC20 testRootToken = new ChildERC20(); - testRootToken.initialize(address(123), "Test", "TST", 18); + // Create users. + for (uint256 i = 0; i < NO_OF_USERS; i++) { + address user = vm.addr(0x10000 + i); + // Mint ETH token + vm.deal(user, MAX_AMOUNT); + // Mint IMX token + rootIMXToken.mint(user, MAX_AMOUNT); + users.push(user); + } - rootBridge.mapToken{value: 1}(IERC20Metadata(address(testRootToken))); + // Create tokens. + for (uint256 i = 0; i < NO_OF_TOKENS; i++) { + vm.prank(address(0x234)); + ChildERC20 rootToken = new ChildERC20(); + vm.prank(address(0x234)); + rootToken.initialize(address(123), "Test", "TST", 18); + // Mint token to user + for (uint256 j = 0; j < NO_OF_USERS; j++) { + vm.prank(address(0x234)); + rootToken.mint(users[j], MAX_AMOUNT); + } + rootBridge.mapToken{value: 1}(IERC20Metadata(address(rootToken))); + // Configure rate for half tokens + if (i % 2 == 0) { + vm.prank(ADMIN); + rootBridge.setRateControlThreshold(address(rootToken), MAX_AMOUNT, MAX_AMOUNT / 3600, MAX_AMOUNT / 2); + } + // Verify + address childTokenL1 = rootBridge.rootTokenToChildToken(address(rootToken)); + vm.selectFork(childId); + address childTokenL2 = childBridge.rootTokenToChildToken(address(rootToken)); + vm.selectFork(rootId); + assertEq(childTokenL1, childTokenL2, "Child token address mismatch between L1 and L2"); + rootTokens.push(address(rootToken)); + } - // Verify - console.log(rootBridge.rootTokenToChildToken(address(testRootToken))); + // Deploy handlers vm.selectFork(childId); - console.log(childBridge.rootTokenToChildToken(address(testRootToken))); + ChildERC20BridgeHandler childBridgeHandler = new ChildERC20BridgeHandler(childId, users, rootTokens, address(childHelper), address(rootHelper)); + + vm.selectFork(rootId); + rootBridgeHandler = new RootERC20BridgeFlowRateHandler(rootId, users, rootTokens, address(childHelper), address(rootHelper)); + + // Target contracts + bytes4[] memory childSelectors = new bytes4[](1); + childSelectors[0] = childBridgeHandler.withdraw.selector; + targetSelector(FuzzSelector({ + addr: address(childBridgeHandler), + selectors: childSelectors + })); + + bytes4[] memory rootSelectors = new bytes4[](1); + rootSelectors[0] = rootBridgeHandler.deposit.selector; + targetSelector(FuzzSelector({ + addr: address(rootBridgeHandler), + selectors: rootSelectors + })); + + targetContract(address(childBridgeHandler)); + targetContract(address(rootBridgeHandler)); } - function test1() public {} + function invariant_A() external { + } }