Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
wcgcyx committed Nov 7, 2023
1 parent 753b1bc commit 4224bd6
Show file tree
Hide file tree
Showing 3 changed files with 379 additions and 0 deletions.
148 changes: 148 additions & 0 deletions test/integration/child/withdrawals/ChildAxelarBridgeWithdrawWIMX.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// SPDX-License-Identifier: Apache 2.0
pragma solidity ^0.8.19;

import {Test, console2} from "forge-std/Test.sol";
import {ERC20PresetMinterPauser} from "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol";
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {MockAxelarGateway} from "../../../../src/test/root/MockAxelarGateway.sol";
import {MockAxelarGasService} from "../../../../src/test/root/MockAxelarGasService.sol";
import {ChildERC20Bridge, IChildERC20BridgeEvents} from "../../../../src/child/ChildERC20Bridge.sol";
import {
ChildAxelarBridgeAdaptor,
IChildAxelarBridgeAdaptorEvents,
IChildAxelarBridgeAdaptorErrors
} from "../../../../src/child/ChildAxelarBridgeAdaptor.sol";
import {Utils} from "../../../utils.t.sol";
import {WETH} from "../../../../src/test/root/WETH.sol";
import {WIMX} from "../../../../src/child/WIMX.sol";
import {ChildERC20} from "../../../../src/child/ChildERC20.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";

contract ChildERC20BridgeWithdrawWIMXIntegrationTest is
Test,
IChildERC20BridgeEvents,
IChildAxelarBridgeAdaptorEvents,
IChildAxelarBridgeAdaptorErrors,
Utils
{
address constant CHILD_BRIDGE = address(3);
address constant CHILD_BRIDGE_ADAPTOR = address(4);
string constant CHILD_CHAIN_NAME = "test";
address constant ROOT_IMX_TOKEN = address(555555);
address constant NATIVE_ETH = address(0xeee);
address constant WRAPPED_ETH = address(0xddd);
address constant WRAPPED_IMX = address(0xabc);

ChildERC20Bridge public childBridge;
ChildAxelarBridgeAdaptor public axelarAdaptor;
address public rootToken;
address public rootImxToken;
ChildERC20 public childTokenTemplate;
MockAxelarGasService public axelarGasService;
MockAxelarGateway public mockAxelarGateway;
WIMX public wIMXToken;

function setUp() public {
(childBridge, axelarAdaptor, rootToken, rootImxToken, childTokenTemplate, axelarGasService, mockAxelarGateway) =
childIntegrationSetup();
wIMXToken = WIMX(payable(WRAPPED_IMX));
Address.sendValue(payable(wIMXToken), 100 ether);
}

function test_WithdrawWIMX_CallsBridgeAdaptor() public {
uint256 withdrawFee = 300;
uint256 withdrawAmount = 7 ether;

wIMXToken.approve(address(childBridge), withdrawAmount);
bytes memory predictedPayload =
abi.encode(WITHDRAW_SIG, ROOT_IMX_TOKEN, address(this), address(this), withdrawAmount);
vm.expectCall(
address(axelarAdaptor),
withdrawFee,
abi.encodeWithSelector(axelarAdaptor.sendMessage.selector, predictedPayload, address(this))
);


childBridge.withdrawWIMX{value: withdrawFee}(withdrawAmount);
}

function test_WithdrawWIMX_CallsAxelarGateway() public {
uint256 withdrawFee = 300;
uint256 withdrawAmount = 7 ether;

wIMXToken.approve(address(childBridge), withdrawAmount);
bytes memory predictedPayload =
abi.encode(WITHDRAW_SIG, ROOT_IMX_TOKEN, address(this), address(this), withdrawAmount);
vm.expectCall(
address(mockAxelarGateway),
0,
abi.encodeWithSelector(
mockAxelarGateway.callContract.selector,
childBridge.rootChain(),
childBridge.rootERC20BridgeAdaptor(),
predictedPayload
)
);

childBridge.withdrawWIMX{value: withdrawFee}(withdrawAmount);
}

function test_WithdrawWIMX_CallsGasService() public {
uint256 withdrawFee = 300;
uint256 withdrawAmount = 7 ether;

wIMXToken.approve(address(childBridge), withdrawAmount);
bytes memory predictedPayload =
abi.encode(WITHDRAW_SIG, ROOT_IMX_TOKEN, address(this), address(this), withdrawAmount);

vm.expectCall(
address(axelarGasService),
withdrawFee,
abi.encodeWithSelector(
axelarGasService.payNativeGasForContractCall.selector,
address(axelarAdaptor),
childBridge.rootChain(),
childBridge.rootERC20BridgeAdaptor(),
predictedPayload,
address(this)
)
);

childBridge.withdrawWIMX{value: withdrawFee}(withdrawAmount);
}

function test_WithdrawWIMX_EmitsAxelarMessageSentEvent() public {
uint256 withdrawFee = 300;
uint256 withdrawAmount = 7 ether;

wIMXToken.approve(address(childBridge), withdrawAmount);
bytes memory predictedPayload =
abi.encode(WITHDRAW_SIG, ROOT_IMX_TOKEN, address(this), address(this), withdrawAmount);

vm.expectEmit(address(axelarAdaptor));
emit AxelarMessageSent(childBridge.rootChain(), childBridge.rootERC20BridgeAdaptor(), predictedPayload);

childBridge.withdrawWIMX{value: withdrawFee}(withdrawAmount);
}

function test_WithdrawWIMX_ReducesBalance() public {
uint256 withdrawFee = 300;
uint256 withdrawAmount = 7 ether;

uint256 preBal = address(this).balance;
uint256 preTokenBal = wIMXToken.balanceOf(address(this));
uint256 preGasBal = address(axelarGasService).balance;

wIMXToken.approve(address(childBridge), withdrawAmount);
childBridge.withdrawWIMX{value: withdrawFee}(withdrawAmount);

uint256 postBal = address(this).balance;
uint256 postTokenBal = wIMXToken.balanceOf(address(this));
uint256 postGasBal = address(axelarGasService).balance;

assertEq(postBal, preBal - withdrawFee, "Balance not reduced");
assertEq(postTokenBal, preTokenBal - withdrawAmount);
assertEq(postGasBal, preGasBal + withdrawFee, "Gas service not getting paid");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
// SPDX-License-Identifier: Apache 2.0
pragma solidity ^0.8.19;

import {Test, console2} from "forge-std/Test.sol";
import {ERC20PresetMinterPauser} from "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol";
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {MockAxelarGateway} from "../../../../src/test/root/MockAxelarGateway.sol";
import {MockAxelarGasService} from "../../../../src/test/root/MockAxelarGasService.sol";
import {ChildERC20Bridge, IChildERC20BridgeEvents} from "../../../../src/child/ChildERC20Bridge.sol";
import {
ChildAxelarBridgeAdaptor,
IChildAxelarBridgeAdaptorEvents,
IChildAxelarBridgeAdaptorErrors
} from "../../../../src/child/ChildAxelarBridgeAdaptor.sol";
import {Utils} from "../../../utils.t.sol";
import {WETH} from "../../../../src/test/root/WETH.sol";
import {WIMX} from "../../../../src/child/WIMX.sol";
import {ChildERC20} from "../../../../src/child/ChildERC20.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";

contract ChildERC20BridgeWithdrawWIMXToIntegrationTest is
Test,
IChildERC20BridgeEvents,
IChildAxelarBridgeAdaptorEvents,
IChildAxelarBridgeAdaptorErrors,
Utils
{
address constant CHILD_BRIDGE = address(3);
address constant CHILD_BRIDGE_ADAPTOR = address(4);
string constant CHILD_CHAIN_NAME = "test";
address constant ROOT_IMX_TOKEN = address(555555);
address constant NATIVE_ETH = address(0xeee);
address constant WRAPPED_ETH = address(0xddd);
address constant WRAPPED_IMX = address(0xabc);

ChildERC20Bridge public childBridge;
ChildAxelarBridgeAdaptor public axelarAdaptor;
address public rootToken;
address public rootImxToken;
ChildERC20 public childTokenTemplate;
MockAxelarGasService public axelarGasService;
MockAxelarGateway public mockAxelarGateway;
WIMX public wIMXToken;

function setUp() public {
(childBridge, axelarAdaptor, rootToken, rootImxToken, childTokenTemplate, axelarGasService, mockAxelarGateway) =
childIntegrationSetup();
wIMXToken = WIMX(payable(WRAPPED_IMX));
Address.sendValue(payable(wIMXToken), 100 ether);
}

function test_WithdrawWIMXTo_CallsBridgeAdaptor() public {
uint256 withdrawFee = 300;
uint256 withdrawAmount = 7 ether;

wIMXToken.approve(address(childBridge), withdrawAmount);
bytes memory predictedPayload =
abi.encode(WITHDRAW_SIG, ROOT_IMX_TOKEN, address(this), address(this), withdrawAmount);
vm.expectCall(
address(axelarAdaptor),
withdrawFee,
abi.encodeWithSelector(axelarAdaptor.sendMessage.selector, predictedPayload, address(this))
);


childBridge.withdrawWIMXTo{value: withdrawFee}(address(this), withdrawAmount);
}

function test_WithdrawWIMXToWithDifferentAccount_CallsBridgeAdaptor() public {
address receiver = address(0xabcd);
uint256 withdrawFee = 300;
uint256 withdrawAmount = 7 ether;

wIMXToken.approve(address(childBridge), withdrawAmount);
bytes memory predictedPayload =
abi.encode(WITHDRAW_SIG, ROOT_IMX_TOKEN, address(this), receiver, withdrawAmount);
vm.expectCall(
address(axelarAdaptor),
withdrawFee,
abi.encodeWithSelector(axelarAdaptor.sendMessage.selector, predictedPayload, address(this))
);


childBridge.withdrawWIMXTo{value: withdrawFee}(receiver, withdrawAmount);
}

function test_WithdrawWIMXTo_CallsAxelarGateway() public {
uint256 withdrawFee = 300;
uint256 withdrawAmount = 7 ether;

wIMXToken.approve(address(childBridge), withdrawAmount);
bytes memory predictedPayload =
abi.encode(WITHDRAW_SIG, ROOT_IMX_TOKEN, address(this), address(this), withdrawAmount);
vm.expectCall(
address(mockAxelarGateway),
0,
abi.encodeWithSelector(
mockAxelarGateway.callContract.selector,
childBridge.rootChain(),
childBridge.rootERC20BridgeAdaptor(),
predictedPayload
)
);

childBridge.withdrawWIMXTo{value: withdrawFee}(address(this), withdrawAmount);
}

function test_WithdrawWIMXToWithDifferentAccount_CallsAxelarGateway() public {
address receiver = address(0xabcd);
uint256 withdrawFee = 300;
uint256 withdrawAmount = 7 ether;

wIMXToken.approve(address(childBridge), withdrawAmount);
bytes memory predictedPayload =
abi.encode(WITHDRAW_SIG, ROOT_IMX_TOKEN, address(this), receiver, withdrawAmount);
vm.expectCall(
address(mockAxelarGateway),
0,
abi.encodeWithSelector(
mockAxelarGateway.callContract.selector,
childBridge.rootChain(),
childBridge.rootERC20BridgeAdaptor(),
predictedPayload
)
);

childBridge.withdrawWIMXTo{value: withdrawFee}(receiver, withdrawAmount);
}

function test_WithdrawWIMXTo_CallsGasService() public {
uint256 withdrawFee = 300;
uint256 withdrawAmount = 7 ether;

wIMXToken.approve(address(childBridge), withdrawAmount);
bytes memory predictedPayload =
abi.encode(WITHDRAW_SIG, ROOT_IMX_TOKEN, address(this), address(this), withdrawAmount);

vm.expectCall(
address(axelarGasService),
withdrawFee,
abi.encodeWithSelector(
axelarGasService.payNativeGasForContractCall.selector,
address(axelarAdaptor),
childBridge.rootChain(),
childBridge.rootERC20BridgeAdaptor(),
predictedPayload,
address(this)
)
);

childBridge.withdrawWIMXTo{value: withdrawFee}(address(this), withdrawAmount);
}

function test_WithdrawWIMXToWithDifferentAccount_CallsGasService() public {
address receiver = address(0xabcd);
uint256 withdrawFee = 300;
uint256 withdrawAmount = 7 ether;

wIMXToken.approve(address(childBridge), withdrawAmount);
bytes memory predictedPayload =
abi.encode(WITHDRAW_SIG, ROOT_IMX_TOKEN, address(this), receiver, withdrawAmount);

vm.expectCall(
address(axelarGasService),
withdrawFee,
abi.encodeWithSelector(
axelarGasService.payNativeGasForContractCall.selector,
address(axelarAdaptor),
childBridge.rootChain(),
childBridge.rootERC20BridgeAdaptor(),
predictedPayload,
address(this)
)
);

childBridge.withdrawWIMXTo{value: withdrawFee}(receiver, withdrawAmount);
}

function test_WithdrawWIMXTo_EmitsAxelarMessageSentEvent() public {
uint256 withdrawFee = 300;
uint256 withdrawAmount = 7 ether;

wIMXToken.approve(address(childBridge), withdrawAmount);
bytes memory predictedPayload =
abi.encode(WITHDRAW_SIG, ROOT_IMX_TOKEN, address(this), address(this), withdrawAmount);

vm.expectEmit(address(axelarAdaptor));
emit AxelarMessageSent(childBridge.rootChain(), childBridge.rootERC20BridgeAdaptor(), predictedPayload);

childBridge.withdrawWIMXTo{value: withdrawFee}(address(this), withdrawAmount);
}

function test_WithdrawWIMXToWithDifferentAccount_EmitsAxelarMessageSentEvent() public {
address receiver = address(0xabcd);
uint256 withdrawFee = 300;
uint256 withdrawAmount = 7 ether;

wIMXToken.approve(address(childBridge), withdrawAmount);
bytes memory predictedPayload =
abi.encode(WITHDRAW_SIG, ROOT_IMX_TOKEN, address(this), receiver, withdrawAmount);

vm.expectEmit(address(axelarAdaptor));
emit AxelarMessageSent(childBridge.rootChain(), childBridge.rootERC20BridgeAdaptor(), predictedPayload);

childBridge.withdrawWIMXTo{value: withdrawFee}(receiver, withdrawAmount);
}

function test_WithdrawWIMXTo_ReducesBalance() public {
uint256 withdrawFee = 300;
uint256 withdrawAmount = 7 ether;

uint256 preBal = address(this).balance;
uint256 preTokenBal = wIMXToken.balanceOf(address(this));
uint256 preGasBal = address(axelarGasService).balance;

wIMXToken.approve(address(childBridge), withdrawAmount);
childBridge.withdrawWIMXTo{value: withdrawFee}(address(this), withdrawAmount);

uint256 postBal = address(this).balance;
uint256 postTokenBal = wIMXToken.balanceOf(address(this));
uint256 postGasBal = address(axelarGasService).balance;

assertEq(postBal, preBal - withdrawFee, "Balance not reduced");
assertEq(postTokenBal, preTokenBal - withdrawAmount);
assertEq(postGasBal, preGasBal + withdrawFee, "Gas service not getting paid");
}
}
3 changes: 3 additions & 0 deletions test/utils.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {ChildERC20Bridge} from "../src/child/ChildERC20Bridge.sol";
import {ChildAxelarBridgeAdaptor} from "../src/child/ChildAxelarBridgeAdaptor.sol";
import {WETH} from "../src/test/root/WETH.sol";
import {IWETH} from "../src/interfaces/root/IWETH.sol";
import {WIMX} from "../src/child/WIMX.sol";

import {IChildERC20, ChildERC20} from "../src/child/ChildERC20.sol";
import {RootAxelarBridgeAdaptor} from "../src/root/RootAxelarBridgeAdaptor.sol";
Expand All @@ -36,6 +37,8 @@ contract Utils is Test {
rootToken = address(44444);
address childWIMX = address(0xabc);

deployCodeTo("WIMX.sol", childWIMX);

axelarGasService = new MockAxelarGasService();
mockAxelarGateway = new MockAxelarGateway();
childTokenTemplate = new ChildERC20();
Expand Down

0 comments on commit 4224bd6

Please sign in to comment.