-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Smr 1814 Part 2 imx withdraw on L1 #22
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,6 +32,7 @@ contract RootERC20BridgeWithdrawIntegrationTest is | |
address constant IMX_TOKEN_ADDRESS = address(0xccc); | ||
address constant NATIVE_ETH = address(0xeee); | ||
address constant WRAPPED_ETH = address(0xddd); | ||
address public constant NATIVE_IMX = address(0xfff); | ||
uint256 constant UNLIMITED_IMX_DEPOSIT_LIMIT = 0; | ||
|
||
uint256 constant withdrawAmount = 0.5 ether; | ||
|
@@ -59,6 +60,7 @@ contract RootERC20BridgeWithdrawIntegrationTest is | |
rootBridge.mapToken{value: 1}(token); | ||
// And give the bridge some tokens | ||
token.transfer(address(rootBridge), 100 ether); | ||
imxToken.transfer(address(rootBridge), 100 ether); | ||
} | ||
|
||
function test_RevertsIf_WithdrawWithInvalidSourceAddress() public { | ||
|
@@ -119,6 +121,24 @@ contract RootERC20BridgeWithdrawIntegrationTest is | |
assertEq(bridgePostBal, bridgePreBal - withdrawAmount, "Incorrect bridge balance after withdraw"); | ||
} | ||
|
||
function test_withdrawIMX_TransfersIMX() public { | ||
bytes memory data = abi.encode(WITHDRAW_SIG, IMX_TOKEN_ADDRESS, address(this), address(this), withdrawAmount); | ||
|
||
bytes32 commandId = bytes32("testCommandId"); | ||
string memory sourceAddress = rootBridge.childBridgeAdaptor(); | ||
|
||
uint256 thisPreBal = imxToken.balanceOf(address(this)); | ||
uint256 bridgePreBal = imxToken.balanceOf(address(rootBridge)); | ||
|
||
axelarAdaptor.execute(commandId, CHILD_CHAIN_NAME, sourceAddress, data); | ||
|
||
uint256 thisPostBal = imxToken.balanceOf(address(this)); | ||
uint256 bridgePostBal = imxToken.balanceOf(address(rootBridge)); | ||
|
||
assertEq(thisPostBal, thisPreBal + withdrawAmount, "Incorrect user balance after withdraw"); | ||
assertEq(bridgePostBal, bridgePreBal - withdrawAmount, "Incorrect bridge balance after withdraw"); | ||
} | ||
|
||
function test_withdraw_TransfersTokens_DifferentReceiver() public { | ||
address receiver = address(987654321); | ||
bytes memory data = abi.encode(WITHDRAW_SIG, address(token), address(this), receiver, withdrawAmount); | ||
|
@@ -138,6 +158,25 @@ contract RootERC20BridgeWithdrawIntegrationTest is | |
assertEq(bridgePostBal, bridgePreBal - withdrawAmount, "Incorrect bridge balance after withdraw"); | ||
} | ||
|
||
function test_withdrawIMX_TransfersIMX_DifferentReceiver() public { | ||
address receiver = address(987654321); | ||
bytes memory data = abi.encode(WITHDRAW_SIG, IMX_TOKEN_ADDRESS, address(this), receiver, withdrawAmount); | ||
|
||
bytes32 commandId = bytes32("testCommandId"); | ||
string memory sourceAddress = rootBridge.childBridgeAdaptor(); | ||
|
||
uint256 thisPreBal = imxToken.balanceOf(receiver); | ||
uint256 bridgePreBal = imxToken.balanceOf(address(rootBridge)); | ||
|
||
axelarAdaptor.execute(commandId, CHILD_CHAIN_NAME, sourceAddress, data); | ||
|
||
uint256 thisPostBal = imxToken.balanceOf(receiver); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: |
||
uint256 bridgePostBal = imxToken.balanceOf(address(rootBridge)); | ||
|
||
assertEq(thisPostBal, thisPreBal + withdrawAmount, "Incorrect user balance after withdraw"); | ||
assertEq(bridgePostBal, bridgePreBal - withdrawAmount, "Incorrect bridge balance after withdraw"); | ||
} | ||
|
||
function test_withdraw_EmitsRootChainERC20WithdrawEvent() public { | ||
bytes memory data = abi.encode(WITHDRAW_SIG, address(token), address(this), address(this), withdrawAmount); | ||
|
||
|
@@ -155,6 +194,17 @@ contract RootERC20BridgeWithdrawIntegrationTest is | |
axelarAdaptor.execute(commandId, CHILD_CHAIN_NAME, sourceAddress, data); | ||
} | ||
|
||
function test_withdrawIMX_EmitsRootChainERC20WithdrawEvent() public { | ||
bytes memory data = abi.encode(WITHDRAW_SIG, IMX_TOKEN_ADDRESS, address(this), address(this), withdrawAmount); | ||
|
||
bytes32 commandId = bytes32("testCommandId"); | ||
string memory sourceAddress = rootBridge.childBridgeAdaptor(); | ||
|
||
vm.expectEmit(); | ||
emit RootChainERC20Withdraw(address(imxToken), NATIVE_IMX, address(this), address(this), withdrawAmount); | ||
axelarAdaptor.execute(commandId, CHILD_CHAIN_NAME, sourceAddress, data); | ||
} | ||
|
||
function test_withdraw_EmitsRootChainERC20WithdrawEvent_DifferentReceiver() public { | ||
address receiver = address(987654321); | ||
bytes memory data = abi.encode(WITHDRAW_SIG, address(token), address(this), receiver, withdrawAmount); | ||
|
@@ -168,4 +218,16 @@ contract RootERC20BridgeWithdrawIntegrationTest is | |
); | ||
axelarAdaptor.execute(commandId, CHILD_CHAIN_NAME, sourceAddress, data); | ||
} | ||
|
||
function test_withdrawIMX_EmitsRootChainERC20WithdrawEvent_DifferentReceiver() public { | ||
address receiver = address(987654321); | ||
bytes memory data = abi.encode(WITHDRAW_SIG, IMX_TOKEN_ADDRESS, address(this), receiver, withdrawAmount); | ||
|
||
bytes32 commandId = bytes32("testCommandId"); | ||
string memory sourceAddress = rootBridge.childBridgeAdaptor(); | ||
|
||
vm.expectEmit(); | ||
emit RootChainERC20Withdraw(address(imxToken), NATIVE_IMX, address(this), receiver, withdrawAmount); | ||
axelarAdaptor.execute(commandId, CHILD_CHAIN_NAME, sourceAddress, data); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,13 +17,16 @@ contract RootERC20BridgeWithdrawUnitTest is Test, IRootERC20BridgeEvents, IRootE | |
address constant CHILD_BRIDGE_ADAPTOR = address(4); | ||
string CHILD_BRIDGE_ADAPTOR_STRING = Strings.toHexString(CHILD_BRIDGE_ADAPTOR); | ||
string constant CHILD_CHAIN_NAME = "test"; | ||
address constant UnmappedToken = address(0xbbb); | ||
address constant IMX_TOKEN = address(0xccc); | ||
address constant WRAPPED_ETH = address(0xddd); | ||
address public constant NATIVE_IMX = address(0xfff); | ||
uint256 constant mapTokenFee = 300; | ||
uint256 constant withdrawAmount = 0.5 ether; | ||
uint256 constant UNLIMITED_IMX_DEPOSIT_LIMIT = 0; | ||
|
||
ERC20PresetMinterPauser public token; | ||
ERC20PresetMinterPauser public imxToken; | ||
RootERC20Bridge public rootBridge; | ||
MockAdaptor public mockAxelarAdaptor; | ||
MockAxelarGateway public mockAxelarGateway; | ||
|
@@ -33,6 +36,8 @@ contract RootERC20BridgeWithdrawUnitTest is Test, IRootERC20BridgeEvents, IRootE | |
token = new ERC20PresetMinterPauser("Test", "TST"); | ||
token.mint(address(this), 100 ether); | ||
deployCodeTo("ERC20PresetMinterPauser.sol", abi.encode("ImmutableX", "IMX"), IMX_TOKEN); | ||
imxToken = ERC20PresetMinterPauser(IMX_TOKEN); | ||
imxToken.mint(address(this), 100 ether); | ||
|
||
deployCodeTo("WETH.sol", abi.encode("Wrapped ETH", "WETH"), WRAPPED_ETH); | ||
|
||
|
@@ -56,22 +61,22 @@ contract RootERC20BridgeWithdrawUnitTest is Test, IRootERC20BridgeEvents, IRootE | |
} | ||
|
||
function test_RevertsIf_WithdrawWithInvalidSender() public { | ||
bytes memory data = abi.encode(WITHDRAW_SIG, IMX_TOKEN, address(this), address(this), withdrawAmount); | ||
bytes memory data = abi.encode(WITHDRAW_SIG, token, address(this), address(this), withdrawAmount); | ||
|
||
vm.expectRevert(NotBridgeAdaptor.selector); | ||
rootBridge.onMessageReceive(CHILD_CHAIN_NAME, CHILD_BRIDGE_ADAPTOR_STRING, data); | ||
} | ||
|
||
function test_RevertsIf_OnMessageReceiveWithInvalidSourceChain() public { | ||
bytes memory data = abi.encode(WITHDRAW_SIG, IMX_TOKEN, address(this), address(this), withdrawAmount); | ||
bytes memory data = abi.encode(WITHDRAW_SIG, token, address(this), address(this), withdrawAmount); | ||
|
||
vm.prank(address(mockAxelarAdaptor)); | ||
vm.expectRevert(InvalidSourceChain.selector); | ||
rootBridge.onMessageReceive("ding_dong", CHILD_BRIDGE_ADAPTOR_STRING, data); | ||
} | ||
|
||
function test_RevertsIf_OnMessageReceiveWithInvalidSourceAddress() public { | ||
bytes memory data = abi.encode(WITHDRAW_SIG, IMX_TOKEN, address(this), address(this), withdrawAmount); | ||
bytes memory data = abi.encode(WITHDRAW_SIG, token, address(this), address(this), withdrawAmount); | ||
|
||
console2.log(CHILD_CHAIN_NAME); | ||
console2.log(rootBridge.childChain()); | ||
|
@@ -89,14 +94,14 @@ contract RootERC20BridgeWithdrawUnitTest is Test, IRootERC20BridgeEvents, IRootE | |
} | ||
|
||
function test_RevertsIf_OnMessageReceiveWithInvalidSignature() public { | ||
bytes memory data = abi.encode(keccak256("RANDOM"), IMX_TOKEN, address(this), address(this), withdrawAmount); | ||
bytes memory data = abi.encode(keccak256("RANDOM"), token, address(this), address(this), withdrawAmount); | ||
vm.prank(address(mockAxelarAdaptor)); | ||
vm.expectRevert(InvalidData.selector); | ||
rootBridge.onMessageReceive(CHILD_CHAIN_NAME, CHILD_BRIDGE_ADAPTOR_STRING, data); | ||
} | ||
|
||
function test_RevertsIf_OnMessageReceiveWithUnmappedToken() public { | ||
bytes memory data = abi.encode(WITHDRAW_SIG, IMX_TOKEN, address(this), address(this), withdrawAmount); | ||
bytes memory data = abi.encode(WITHDRAW_SIG, UnmappedToken, address(this), address(this), withdrawAmount); | ||
vm.prank(address(mockAxelarAdaptor)); | ||
vm.expectRevert(NotMapped.selector); | ||
rootBridge.onMessageReceive(CHILD_CHAIN_NAME, CHILD_BRIDGE_ADAPTOR_STRING, data); | ||
|
@@ -121,6 +126,23 @@ contract RootERC20BridgeWithdrawUnitTest is Test, IRootERC20BridgeEvents, IRootE | |
); | ||
} | ||
|
||
function test_onMessageReceive_TransfersIMXTokens() public { | ||
// Give bridge some IMX tokens | ||
imxToken.transfer(address(rootBridge), 100 ether); | ||
|
||
uint256 thisPreBal = imxToken.balanceOf(address(this)); | ||
uint256 bridgePreBal = imxToken.balanceOf(address(rootBridge)); | ||
|
||
bytes memory data = abi.encode(WITHDRAW_SIG, imxToken, address(this), address(this), withdrawAmount); | ||
vm.prank(address(mockAxelarAdaptor)); | ||
rootBridge.onMessageReceive(CHILD_CHAIN_NAME, CHILD_BRIDGE_ADAPTOR_STRING, data); | ||
|
||
assertEq(imxToken.balanceOf(address(this)), thisPreBal + withdrawAmount, "IMX not transferred to receiver"); | ||
assertEq( | ||
imxToken.balanceOf(address(rootBridge)), bridgePreBal - withdrawAmount, "IMX not transferred from bridge" | ||
); | ||
} | ||
|
||
function test_onMessageReceive_TransfersTokens_DifferentReceiver() public { | ||
address receiver = address(123456); | ||
// Need to first map the token. | ||
|
@@ -141,6 +163,24 @@ contract RootERC20BridgeWithdrawUnitTest is Test, IRootERC20BridgeEvents, IRootE | |
); | ||
} | ||
|
||
function test_onMessageReceive_TransfersIMXTokens_DifferentReceiver() public { | ||
address receiver = address(123456); | ||
// Give bridge some IMX tokens | ||
imxToken.transfer(address(rootBridge), 100 ether); | ||
|
||
uint256 thisPreBal = imxToken.balanceOf(address(receiver)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: same comment as above on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you, updated. |
||
uint256 bridgePreBal = imxToken.balanceOf(address(rootBridge)); | ||
|
||
bytes memory data = abi.encode(WITHDRAW_SIG, imxToken, address(this), receiver, withdrawAmount); | ||
vm.prank(address(mockAxelarAdaptor)); | ||
rootBridge.onMessageReceive(CHILD_CHAIN_NAME, CHILD_BRIDGE_ADAPTOR_STRING, data); | ||
|
||
assertEq(imxToken.balanceOf(address(receiver)), thisPreBal + withdrawAmount, "IMX not transferred to receiver"); | ||
assertEq( | ||
imxToken.balanceOf(address(rootBridge)), bridgePreBal - withdrawAmount, "IMX not transferred from bridge" | ||
); | ||
} | ||
|
||
function test_onMessageReceive_EmitsRootChainERC20WithdrawEvent() public { | ||
// Need to first map the token. | ||
rootBridge.mapToken(token); | ||
|
@@ -160,6 +200,17 @@ contract RootERC20BridgeWithdrawUnitTest is Test, IRootERC20BridgeEvents, IRootE | |
rootBridge.onMessageReceive(CHILD_CHAIN_NAME, CHILD_BRIDGE_ADAPTOR_STRING, data); | ||
} | ||
|
||
function test_onMessageReceive_EmitsRootChainERC20WithdrawEventForIMX() public { | ||
// Give bridge some IMX tokens | ||
imxToken.transfer(address(rootBridge), 100 ether); | ||
|
||
bytes memory data = abi.encode(WITHDRAW_SIG, imxToken, address(this), address(this), withdrawAmount); | ||
vm.expectEmit(); | ||
emit RootChainERC20Withdraw(address(imxToken), NATIVE_IMX, address(this), address(this), withdrawAmount); | ||
vm.prank(address(mockAxelarAdaptor)); | ||
rootBridge.onMessageReceive(CHILD_CHAIN_NAME, CHILD_BRIDGE_ADAPTOR_STRING, data); | ||
} | ||
|
||
function test_onMessageReceive_EmitsRootChainERC20WithdrawEvent_DifferentReceiver() public { | ||
address receiver = address(123456); | ||
// Need to first map the token. | ||
|
@@ -175,4 +226,16 @@ contract RootERC20BridgeWithdrawUnitTest is Test, IRootERC20BridgeEvents, IRootE | |
vm.prank(address(mockAxelarAdaptor)); | ||
rootBridge.onMessageReceive(CHILD_CHAIN_NAME, CHILD_BRIDGE_ADAPTOR_STRING, data); | ||
} | ||
|
||
function test_onMessageReceive_EmitsRootChainERC20WithdrawEventForIMX_DifferentReceiver() public { | ||
address receiver = address(123456); | ||
// Give bridge some IMX tokens | ||
imxToken.transfer(address(rootBridge), 100 ether); | ||
|
||
bytes memory data = abi.encode(WITHDRAW_SIG, imxToken, address(this), receiver, withdrawAmount); | ||
vm.expectEmit(); | ||
emit RootChainERC20Withdraw(address(imxToken), NATIVE_IMX, address(this), receiver, withdrawAmount); | ||
vm.prank(address(mockAxelarAdaptor)); | ||
rootBridge.onMessageReceive(CHILD_CHAIN_NAME, CHILD_BRIDGE_ADAPTOR_STRING, data); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
thisPreBal
is a bit misleading on this test, since it is thereceiver
's balance notthis
contract's balance like the previous test