Skip to content

Commit

Permalink
last patches and tests added
Browse files Browse the repository at this point in the history
  • Loading branch information
proletesseract committed Oct 25, 2023
1 parent ea4dcdc commit 853c365
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 4 deletions.
3 changes: 3 additions & 0 deletions src/root/RootERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -258,5 +258,8 @@ contract RootERC20Bridge is
rootBridgeAdaptor = IRootERC20BridgeAdaptor(newRootBridgeAdaptor);
}

/**
* @dev method to receive the ETH back from the WETH contract when it is unwrapped
*/
receive() external payable {}
}
62 changes: 61 additions & 1 deletion test/integration/root/RootERC20Bridge.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {MockAxelarGasService} from "../../../src/test/root/MockAxelarGasService.
import {RootERC20Bridge, IRootERC20BridgeEvents, IERC20Metadata} from "../../../src/root/RootERC20Bridge.sol";
import {RootAxelarBridgeAdaptor, IRootAxelarBridgeAdaptorEvents} from "../../../src/root/RootAxelarBridgeAdaptor.sol";
import {Utils} from "../../utils.t.sol";
import {WETH} from "../../../src/test/root/WETH.sol";

contract RootERC20BridgeIntegrationTest is Test, IRootERC20BridgeEvents, IRootAxelarBridgeAdaptorEvents, Utils {
address constant CHILD_BRIDGE = address(3);
Expand All @@ -18,7 +19,7 @@ contract RootERC20BridgeIntegrationTest is Test, IRootERC20BridgeEvents, IRootAx
bytes32 public constant MAP_TOKEN_SIG = keccak256("MAP_TOKEN");
address constant IMX_TOKEN_ADDRESS = address(0xccc);
address constant NATIVE_ETH = address(0xeee);
address constant WRAPPED_ETH = address(0xeee);
address constant WRAPPED_ETH = address(0xddd);

uint256 constant mapTokenFee = 300;
uint256 constant depositFee = 200;
Expand All @@ -31,6 +32,9 @@ contract RootERC20BridgeIntegrationTest is Test, IRootERC20BridgeEvents, IRootAx
MockAxelarGasService public axelarGasService;

function setUp() public {

deployCodeTo("WETH.sol", abi.encode("Wrapped ETH", "WETH"), WRAPPED_ETH);

(imxToken, token, rootBridge, axelarAdaptor, mockAxelarGateway, axelarGasService) =
integrationSetup(CHILD_BRIDGE, CHILD_BRIDGE_ADAPTOR, CHILD_CHAIN_NAME, IMX_TOKEN_ADDRESS, WRAPPED_ETH);
}
Expand Down Expand Up @@ -214,6 +218,62 @@ contract RootERC20BridgeIntegrationTest is Test, IRootERC20BridgeEvents, IRootAx
assertEq(gasServiceNativePreBal + depositFee, address(axelarGasService).balance, "ETH not paid to adaptor");
}

// TODO split into multiple tests
function test_depositWETH() public {
uint256 tokenAmount = 300;
string memory childBridgeAdaptorString = Strings.toHexString(CHILD_BRIDGE_ADAPTOR);
(, bytes memory predictedPayload) =
setupDeposit(WRAPPED_ETH, rootBridge, mapTokenFee, depositFee, tokenAmount, false);

vm.expectEmit(address(axelarAdaptor));
emit MapTokenAxelarMessage(CHILD_CHAIN_NAME, childBridgeAdaptorString, predictedPayload);
vm.expectEmit(address(rootBridge));
emit NativeEthDeposit(
address(NATIVE_ETH), rootBridge.childETHToken(), address(this), address(this), tokenAmount
);
vm.expectCall(
address(axelarAdaptor),
depositFee,
abi.encodeWithSelector(axelarAdaptor.sendMessage.selector, predictedPayload, address(this))
);

vm.expectCall(
address(axelarGasService),
depositFee,
abi.encodeWithSelector(
axelarGasService.payNativeGasForContractCall.selector,
address(axelarAdaptor),
CHILD_CHAIN_NAME,
childBridgeAdaptorString,
predictedPayload,
address(this)
)
);

vm.expectCall(
address(mockAxelarGateway),
0,
abi.encodeWithSelector(
mockAxelarGateway.callContract.selector, CHILD_CHAIN_NAME, childBridgeAdaptorString, predictedPayload
)
);

uint256 thisPreBal = IERC20Metadata(WRAPPED_ETH).balanceOf(address(this));
uint256 bridgePreBal = address(rootBridge).balance;

uint256 thisNativePreBal = address(this).balance;
uint256 gasServiceNativePreBal = address(axelarGasService).balance;

rootBridge.deposit{value: depositFee}(IERC20Metadata(WRAPPED_ETH), tokenAmount);

// Check that tokens are transferred
assertEq(thisPreBal - tokenAmount, IERC20Metadata(WRAPPED_ETH).balanceOf(address(this)), "Tokens not transferred from user");
assertEq(bridgePreBal + tokenAmount, address(rootBridge).balance, "ETH not transferred to Bridge");
// Check that native asset transferred to gas service
assertEq(thisNativePreBal - depositFee, address(this).balance, "ETH for fee not paid from user");
assertEq(gasServiceNativePreBal + depositFee, address(axelarGasService).balance, "ETH not paid to adaptor");
}

// TODO split into multiple tests
function test_depositToken() public {
uint256 tokenAmount = 300;
Expand Down
56 changes: 53 additions & 3 deletions test/unit/root/RootERC20Bridge.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -325,16 +325,66 @@ contract RootERC20BridgeUnitTest is Test, IRootERC20BridgeEvents, IRootERC20Brid
(, bytes memory predictedPayload) =
setupDeposit(WRAPPED_ETH, rootBridge, mapTokenFee, depositFee, amount, false);

bytes memory pp = abi.encode(rootBridge.DEPOSIT_SIG(), NATIVE_ETH, address(this), address(this), amount);

vm.expectCall(
address(mockAxelarAdaptor),
abi.encodeWithSelector(mockAxelarAdaptor.sendMessage.selector, pp, address(this))
abi.encodeWithSelector(mockAxelarAdaptor.sendMessage.selector, predictedPayload, address(this))
);

rootBridge.deposit{value: depositFee}(IERC20Metadata(WRAPPED_ETH), amount);
}

function test_depositWETHEmitsNativeDepositEvent() public {
uint256 amount = 100;
setupDeposit(WRAPPED_ETH, rootBridge, mapTokenFee, depositFee, amount, false);

vm.expectEmit();
emit NativeEthDeposit(NATIVE_ETH, rootBridge.childETHToken(), address(this), address(this), amount);
rootBridge.deposit{value: depositFee}(IERC20Metadata(WRAPPED_ETH), amount);
}

function test_depositToWETHEmitsNativeEthDepositEvent() public {
uint256 amount = 1000;
address receiver = address(12345);
setupDepositTo(WRAPPED_ETH, rootBridge, mapTokenFee, depositFee, amount, receiver, false);

vm.expectEmit();
emit NativeEthDeposit(NATIVE_ETH, rootBridge.childETHToken(), address(this), receiver, amount);
rootBridge.depositTo{value: depositFee}(IERC20Metadata(WRAPPED_ETH), receiver, amount);
}

function test_depositWETHTransfersTokens() public {
uint256 amount = 100;

setupDeposit(WRAPPED_ETH, rootBridge, mapTokenFee, depositFee, amount, false);

uint256 thisPreBal = IERC20Metadata(WRAPPED_ETH).balanceOf(address(this));
uint256 bridgePreBal = address(rootBridge).balance;

rootBridge.deposit{value: depositFee}(IERC20Metadata(WRAPPED_ETH), amount);

// Check that tokens are transferred
assertEq(thisPreBal - amount, IERC20Metadata(WRAPPED_ETH).balanceOf(address(this)), "Tokens not transferred from user");
assertEq(bridgePreBal + amount, address(rootBridge).balance, "ETH not transferred to Bridge");

}

function test_depositToWETHTransfersTokens() public {
uint256 amount = 100;
address receiver = address(12345);

setupDepositTo(WRAPPED_ETH, rootBridge, mapTokenFee, depositFee, amount, receiver, false);

uint256 thisPreBal = IERC20Metadata(WRAPPED_ETH).balanceOf(address(this));
uint256 bridgePreBal = address(rootBridge).balance;

rootBridge.depositTo{value: depositFee}(IERC20Metadata(WRAPPED_ETH), receiver, amount);

// Check that tokens are transferred
assertEq(thisPreBal - amount, IERC20Metadata(WRAPPED_ETH).balanceOf(address(this)), "Tokens not transferred from user");
assertEq(bridgePreBal + amount, address(rootBridge).balance, "ETH not transferred to Bridge");

}

/**
* DEPOSIT TOKEN
*/
Expand Down
3 changes: 3 additions & 0 deletions test/utils.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,16 @@ contract Utils is Test {
bool saveTokenMapping
) public returns (address childToken, bytes memory predictedPayload) {
predictedPayload = abi.encode(rootBridge.DEPOSIT_SIG(), token, address(this), to, tokenAmount);

if (saveTokenMapping) {
childToken = rootBridge.mapToken{value: mapTokenFee}(ERC20PresetMinterPauser(token));
}

if (token == address(0xeee)) {
vm.deal(to, tokenAmount + depositFee);
} else if (address(token) == address(0xddd)) {
// set the payload to expect native eth when depositing wrapped eth
predictedPayload = abi.encode(rootBridge.DEPOSIT_SIG(), address(0xeee), address(this), to, tokenAmount);
vm.deal(to, tokenAmount + depositFee);
IWETH(token).deposit{value: tokenAmount}();
IWETH(token).approve(address(rootBridge), tokenAmount);
Expand Down

0 comments on commit 853c365

Please sign in to comment.