diff --git a/test/integration/root/withdrawals.t.sol/RootERC20BridgeWithdraw.t.sol b/test/integration/root/withdrawals.t.sol/RootERC20BridgeWithdraw.t.sol index 56ed6051..b05e46c7 100644 --- a/test/integration/root/withdrawals.t.sol/RootERC20BridgeWithdraw.t.sol +++ b/test/integration/root/withdrawals.t.sol/RootERC20BridgeWithdraw.t.sol @@ -75,11 +75,13 @@ contract RootERC20BridgeWithdrawIntegrationTest is //Need to setup the flowRate rootBridgeFlowRate.setRateControlThreshold(address(token), 1000 ether, 100 ether, 10 ether); rootBridgeFlowRate.setRateControlThreshold(IMX_TOKEN_ADDRESS, 1000 ether, 100 ether, 10 ether); + rootBridgeFlowRate.setRateControlThreshold(NATIVE_ETH, 1000 ether, 100 ether, 10 ether); + // And give the bridge some tokens - token.transfer(address(rootBridge), 100 ether); - imxToken.transfer(address(rootBridge), 100 ether); + token.transfer(address(rootBridgeFlowRate), 100 ether); + imxToken.transfer(address(rootBridgeFlowRate), 100 ether); // Give bridge some ETH - deal(address(rootBridge), 100 ether); + deal(address(rootBridgeFlowRate), 100 ether); } function test_RevertsIf_WithdrawWithInvalidSourceChain() public { @@ -162,15 +164,15 @@ contract RootERC20BridgeWithdrawIntegrationTest is bytes memory data = abi.encode(WITHDRAW_SIG, NATIVE_ETH, address(this), address(this), withdrawAmount); bytes32 commandId = bytes32("testCommandId"); - string memory sourceAddress = rootBridge.childBridgeAdaptor(); + string memory sourceAddress = rootBridgeFlowRate.childBridgeAdaptor(); uint256 thisPreBal = address(this).balance; - uint256 bridgePreBal = address(rootBridge).balance; + uint256 bridgePreBal = address(rootBridgeFlowRate).balance; axelarAdaptor.execute(commandId, CHILD_CHAIN_NAME, sourceAddress, data); uint256 thisPostBal = address(this).balance; - uint256 bridgePostBal = address(rootBridge).balance; + uint256 bridgePostBal = address(rootBridgeFlowRate).balance; assertEq(thisPostBal, thisPreBal + withdrawAmount, "Incorrect user balance after withdraw"); assertEq(bridgePostBal, bridgePreBal - withdrawAmount, "Incorrect bridge balance after withdraw"); @@ -219,15 +221,15 @@ contract RootERC20BridgeWithdrawIntegrationTest is bytes memory data = abi.encode(WITHDRAW_SIG, NATIVE_ETH, address(this), receiver, withdrawAmount); bytes32 commandId = bytes32("testCommandId"); - string memory sourceAddress = rootBridge.childBridgeAdaptor(); + string memory sourceAddress = rootBridgeFlowRate.childBridgeAdaptor(); uint256 receiverPreBal = address(receiver).balance; - uint256 bridgePreBal = address(rootBridge).balance; + uint256 bridgePreBal = address(rootBridgeFlowRate).balance; axelarAdaptor.execute(commandId, CHILD_CHAIN_NAME, sourceAddress, data); uint256 receiverPostBal = address(receiver).balance; - uint256 bridgePostBal = address(rootBridge).balance; + uint256 bridgePostBal = address(rootBridgeFlowRate).balance; assertEq(receiverPostBal, receiverPreBal + withdrawAmount, "Incorrect user balance after withdraw"); assertEq(bridgePostBal, bridgePreBal - withdrawAmount, "Incorrect bridge balance after withdraw"); @@ -265,11 +267,11 @@ contract RootERC20BridgeWithdrawIntegrationTest is bytes memory data = abi.encode(WITHDRAW_SIG, NATIVE_ETH, address(this), address(this), withdrawAmount); bytes32 commandId = bytes32("testCommandId"); - string memory sourceAddress = rootBridge.childBridgeAdaptor(); + string memory sourceAddress = rootBridgeFlowRate.childBridgeAdaptor(); vm.expectEmit(); emit RootChainETHWithdraw( - NATIVE_ETH, address(rootBridge.childETHToken()), address(this), address(this), withdrawAmount + NATIVE_ETH, address(rootBridgeFlowRate.childETHToken()), address(this), address(this), withdrawAmount ); axelarAdaptor.execute(commandId, CHILD_CHAIN_NAME, sourceAddress, data); } @@ -309,11 +311,11 @@ contract RootERC20BridgeWithdrawIntegrationTest is bytes memory data = abi.encode(WITHDRAW_SIG, NATIVE_ETH, address(this), receiver, withdrawAmount); bytes32 commandId = bytes32("testCommandId"); - string memory sourceAddress = rootBridge.childBridgeAdaptor(); + string memory sourceAddress = rootBridgeFlowRate.childBridgeAdaptor(); vm.expectEmit(); emit RootChainETHWithdraw( - NATIVE_ETH, address(rootBridge.childETHToken()), address(this), receiver, withdrawAmount + NATIVE_ETH, address(rootBridgeFlowRate.childETHToken()), address(this), receiver, withdrawAmount ); axelarAdaptor.execute(commandId, CHILD_CHAIN_NAME, sourceAddress, data); } diff --git a/test/unit/root/flowrate/RootERC20BridgeFlowRate.t.sol b/test/unit/root/flowrate/RootERC20BridgeFlowRate.t.sol index 9dfe066b..bceff9a3 100644 --- a/test/unit/root/flowrate/RootERC20BridgeFlowRate.t.sol +++ b/test/unit/root/flowrate/RootERC20BridgeFlowRate.t.sol @@ -127,8 +127,9 @@ contract RootERC20BridgeFlowRateUnitTest is } function activateWithdrawalQueue() internal { - vm.prank(rateAdmin); + vm.startPrank(rateAdmin); rootBridgeFlowRate.activateWithdrawalQueue(); + vm.stopPrank(); } function configureFlowRate() internal { @@ -137,6 +138,13 @@ contract RootERC20BridgeFlowRateUnitTest is rootBridgeFlowRate.setRateControlThreshold(NATIVE_ETH, CAPACITY_ETH, REFILL_RATE_ETH, LARGE_ETH); vm.stopPrank(); } + function transferTokensToChild() internal { + vm.deal(address(this), 1 ether); + // Need to first map the token. + rootBridgeFlowRate.mapToken{value: 100}(token); + // And give the bridge some tokens + token.transfer(address(rootBridgeFlowRate), BRIDGED_VALUE); + } /** * INITIALIZE @@ -269,10 +277,7 @@ contract RootERC20BridgeFlowRateUnitTest is function testWithdrawalUnconfiguredToken() public { - // Need to first map the token. - rootBridgeFlowRate.mapToken(token); - // And give the bridge some tokens - token.transfer(address(rootBridgeFlowRate), BRIDGED_VALUE); + transferTokensToChild(); uint256 amount = 5; @@ -304,10 +309,7 @@ contract RootERC20BridgeFlowRateUnitTest is function testWithdrawalLargeWithdrawal() public { configureFlowRate(); - // Need to first map the token. - rootBridgeFlowRate.mapToken(token); - // And give the bridge some tokens - token.transfer(address(rootBridgeFlowRate), BRIDGED_VALUE); + transferTokensToChild(); uint256 amount = LARGE; @@ -339,10 +341,7 @@ contract RootERC20BridgeFlowRateUnitTest is function testHighFlowRate() public { vm.warp(100); configureFlowRate(); - // Need to first map the token. - rootBridgeFlowRate.mapToken(token); - // And give the bridge some tokens - token.transfer(address(rootBridgeFlowRate), BRIDGED_VALUE); + transferTokensToChild(); uint256 amount = LARGE - 1; uint256 timesBeforeHighFlowRate = CAPACITY / amount; @@ -378,11 +377,7 @@ contract RootERC20BridgeFlowRateUnitTest is function testFinaliseQueuedWithdrawalERC20() public { configureFlowRate(); - // Need to first map the token. - rootBridgeFlowRate.mapToken(token); - // And give the bridge some tokens - token.transfer(address(rootBridgeFlowRate), BRIDGED_VALUE); - + transferTokensToChild(); activateWithdrawalQueue(); uint256 amount = 5; @@ -428,10 +423,7 @@ contract RootERC20BridgeFlowRateUnitTest is function testFinaliseQueuedWithdrawalEther() public { configureFlowRate(); - // Need to first map the token. - rootBridgeFlowRate.mapToken(token); - // And give the bridge some tokens - token.transfer(address(rootBridgeFlowRate), BRIDGED_VALUE); + vm.deal(address(rootBridgeFlowRate), BRIDGED_VALUE_ETH); @@ -477,6 +469,35 @@ contract RootERC20BridgeFlowRateUnitTest is assertEq(bob.balance, amount, "after bob"); } + function testFinaliseQueuedWithdrawalOutOfBounds() public { + configureFlowRate(); + transferTokensToChild(); + activateWithdrawalQueue(); + + uint256 amount = 5; + + uint256 now1 = 100; + vm.warp(now1); + + // Fake a crosschain transfer from the child chain to the root chain. + bytes memory data = abi.encode(WITHDRAW_SIG, token, alice, bob, amount); + + vm.prank(address(mockAxelarAdaptor)); + vm.expectEmit(true, true, true, true, address(rootBridgeFlowRate)); + emit QueuedWithdrawal(address(token), alice, bob, amount, now1, 0); + rootBridgeFlowRate.onMessageReceive(CHILD_CHAIN_NAME, CHILD_BRIDGE_ADAPTOR_STRING, data); + + uint256 queueLen = rootBridgeFlowRate.getPendingWithdrawalsLength(bob); + assertEq(queueLen, 1, "bob's queue length"); + + uint256 outOfBoundsIndex = 1; + + uint256 now2 = now1 + withdrawalDelay; + vm.warp(now2); + vm.expectRevert(abi.encodeWithSelector(FlowRateWithdrawalQueue.IndexOutsideWithdrawalQueue.selector, 1, outOfBoundsIndex)); + rootBridgeFlowRate.finaliseQueuedWithdrawal(bob, outOfBoundsIndex); + } + // function testWithdrawalWhenPaused() public { // // Need to first map the token.