Skip to content

Commit

Permalink
make tests pass after rebasing
Browse files Browse the repository at this point in the history
  • Loading branch information
tsnewnami committed Nov 14, 2023
1 parent cc99568 commit 941d911
Show file tree
Hide file tree
Showing 12 changed files with 81 additions and 38 deletions.
4 changes: 3 additions & 1 deletion script/DeployChildContracts.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ contract DeployChildContracts is Script {
});

ChildERC20Bridge childERC20BridgeImplementation = new ChildERC20Bridge();
childERC20BridgeImplementation.initialize(roles, address(1), "0x123", address(1), "root", address(1), address(wrappedIMX));
childERC20BridgeImplementation.initialize(
roles, address(1), "0x123", address(1), "root", address(1), address(wrappedIMX)
);

TransparentUpgradeableProxy childERC20BridgeProxy = new TransparentUpgradeableProxy(
address(childERC20BridgeImplementation),
Expand Down
14 changes: 6 additions & 8 deletions src/child/ChildERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,8 @@ contract ChildERC20Bridge is

/**
* @notice Fallback function on recieving native IMX.
* @dev Will revert as direct native IMX transfers are not supported.
*/
receive() external payable {
revert DirectNativeTransfer();
}
receive() external payable {}

/**
* @notice Initialization function for ChildERC20Bridge.
Expand All @@ -95,7 +92,8 @@ contract ChildERC20Bridge is
if (
newBridgeAdaptor == address(0) || newChildTokenTemplate == address(0) || newRootIMXToken == address(0)
|| newRoles.defaultAdmin == address(0) || newRoles.pauser == address(0) || newRoles.unpauser == address(0)
|| newRoles.variableManager == address(0) || newRoles.adaptorManager == address(0) || newWIMXToken == address(0)
|| newRoles.variableManager == address(0) || newRoles.adaptorManager == address(0)
|| newWIMXToken == address(0)
) {
revert ZeroAddress();
}
Expand Down Expand Up @@ -194,7 +192,7 @@ contract ChildERC20Bridge is
_withdraw(NATIVE_IMX, msg.sender, amount);
}

/**
/**
* @inheritdoc IChildERC20Bridge
*/
function withdrawIMXTo(address receiver, uint256 amount) external payable {
Expand Down Expand Up @@ -343,7 +341,7 @@ contract ChildERC20Bridge is

// Deploy child chain token
IChildERC20 childToken =
IChildERC20(Clones.cloneDeterministic(childTokenTemplate, keccak256(abi.encodePacked(rootToken))));
IChildERC20(Clones.cloneDeterministic(childTokenTemplate, keccak256(abi.encodePacked(rootToken))));
// Map token
rootTokenToChildToken[rootToken] = address(childToken);

Expand Down Expand Up @@ -388,7 +386,7 @@ contract ChildERC20Bridge is
revert EmptyTokenContract();
}

if (childToken.mint(receiver, amount)) {
if (!childToken.mint(receiver, amount)) {
revert MintFailed();
}

Expand Down
3 changes: 2 additions & 1 deletion src/interfaces/child/IChildERC20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

pragma solidity 0.8.19;

import {IERC20MetadataUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol";
import {IERC20MetadataUpgradeable} from
"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol";

/**
* @dev Interface of IChildERC20
Expand Down
5 changes: 1 addition & 4 deletions src/interfaces/child/IChildERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ interface IChildERC20Bridge {
*/
function withdraw(IChildERC20 childToken, uint256 amount) external payable;


/**
* @notice Withdraws `amount` of `childToken` to `receiver` on the rootchain.
* @param childToken The address of the child token to withdraw.
Expand All @@ -45,7 +44,7 @@ interface IChildERC20Bridge {
*/
function withdrawTo(IChildERC20 childToken, address receiver, uint256 amount) external payable;

/**
/**
* @notice Withdraws `amount` of IMX to `msg.sender` on the rootchain.
* @param amount The amount of IMX to withdraw.
*/
Expand Down Expand Up @@ -161,6 +160,4 @@ interface IChildERC20BridgeErrors {
error TransferWIMXFailed();
/// @notice Error when token balance invariant check fails.
error BalanceInvariantCheckFailed(uint256 actualBalance, uint256 expectedBalance);
/// @notice Error when native IMX is directly transferred to the bridge.
error DirectNativeTransfer();
}
5 changes: 4 additions & 1 deletion src/root/RootERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,10 @@ contract RootERC20Bridge is
* @dev Can only be called by VARIABLE_MANAGER_ROLE.
* @dev The limit can decrease, but it can never decrease to below the contract's IMX balance.
*/
function updateImxCumulativeDepositLimit(uint256 newImxCumulativeDepositLimit) external onlyRole(VARIABLE_MANAGER_ROLE) {
function updateImxCumulativeDepositLimit(uint256 newImxCumulativeDepositLimit)
external
onlyRole(VARIABLE_MANAGER_ROLE)
{
if (
newImxCumulativeDepositLimit != UNLIMITED_DEPOSIT
&& newImxCumulativeDepositLimit < IERC20Metadata(rootIMXToken).balanceOf(address(this))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ contract ChildERC20BridgeWithdrawIntegrationTest is
IChildAxelarBridgeAdaptorEvents,
IChildAxelarBridgeAdaptorErrors,
Utils
{
{
// Define here to avoid error collisions between IChildERC20BridgeErrors and IChildAxelarBridgeAdaptorErrors
error ZeroValue();

address constant CHILD_BRIDGE = address(3);
address constant CHILD_BRIDGE_ADAPTOR = address(4);
string constant CHILD_CHAIN_NAME = "test";
Expand Down Expand Up @@ -133,9 +136,10 @@ contract ChildERC20BridgeWithdrawIntegrationTest is
}

function test_RevertIf_WithdrawWithNoGas() public {

ChildERC20 childToken = ChildERC20(childBridge.rootTokenToChildToken(rootToken));

vm.expectRevert(NoGas.selector);
vm.expectRevert(ZeroValue.selector);
childBridge.withdraw(childToken, withdrawAmount);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ contract ChildERC20BridgeWithdrawWIMXToIntegrationTest is
}

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

wIMXToken.approve(address(childBridge), withdrawAmount);
Expand Down
40 changes: 33 additions & 7 deletions test/unit/child/ChildERC20Bridge.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity 0.8.19;

import {Test, console2} from "forge-std/Test.sol";
import "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.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";
Expand All @@ -17,6 +18,8 @@ import {ChildERC20} from "../../../src/child/ChildERC20.sol";
import {Utils} from "../../utils.t.sol";

contract ChildERC20BridgeUnitTest is Test, IChildERC20BridgeEvents, IChildERC20BridgeErrors, Utils {
// TODO: move me to roles contract
bytes32 constant ADAPTOR_MANAGER_ROLE = keccak256("ADAPTOR_MANAGER_ROLE");
address constant ROOT_BRIDGE = address(3);
string public ROOT_BRIDGE_ADAPTOR = Strings.toHexString(address(4));
string constant ROOT_CHAIN_NAME = "test";
Expand Down Expand Up @@ -44,7 +47,13 @@ contract ChildERC20BridgeUnitTest is Test, IChildERC20BridgeEvents, IChildERC20B
adaptorManager: address(this)
});
childBridge.initialize(
roles, address(this), ROOT_BRIDGE_ADAPTOR, address(childTokenTemplate), ROOT_CHAIN_NAME, ROOT_IMX_TOKEN, CHILD_WIMX_TOKEN
roles,
address(this),
ROOT_BRIDGE_ADAPTOR,
address(childTokenTemplate),
ROOT_CHAIN_NAME,
ROOT_IMX_TOKEN,
CHILD_WIMX_TOKEN
);
}

Expand All @@ -69,7 +78,13 @@ contract ChildERC20BridgeUnitTest is Test, IChildERC20BridgeEvents, IChildERC20B
});
vm.expectRevert("Initializable: contract is already initialized");
childBridge.initialize(
roles, address(this), ROOT_BRIDGE_ADAPTOR, address(childTokenTemplate), ROOT_CHAIN_NAME, ROOT_IMX_TOKEN, CHILD_WIMX_TOKEN
roles,
address(this),
ROOT_BRIDGE_ADAPTOR,
address(childTokenTemplate),
ROOT_CHAIN_NAME,
ROOT_IMX_TOKEN,
CHILD_WIMX_TOKEN
);
}

Expand Down Expand Up @@ -210,7 +225,9 @@ contract ChildERC20BridgeUnitTest is Test, IChildERC20BridgeEvents, IChildERC20B
});

vm.expectRevert(InvalidRootERC20BridgeAdaptor.selector);
bridge.initialize(roles, address(this), "", address(childTokenTemplate), ROOT_CHAIN_NAME, ROOT_IMX_TOKEN, CHILD_WIMX_TOKEN);
bridge.initialize(
roles, address(this), "", address(childTokenTemplate), ROOT_CHAIN_NAME, ROOT_IMX_TOKEN, CHILD_WIMX_TOKEN
);
}

function test_RevertIf_InitializeWithAnEmptyChainNameString() public {
Expand All @@ -224,7 +241,9 @@ contract ChildERC20BridgeUnitTest is Test, IChildERC20BridgeEvents, IChildERC20B
});

vm.expectRevert(InvalidRootChain.selector);
bridge.initialize(roles, address(this), ROOT_BRIDGE_ADAPTOR, address(childTokenTemplate), "", ROOT_IMX_TOKEN, CHILD_WIMX_TOKEN);
bridge.initialize(
roles, address(this), ROOT_BRIDGE_ADAPTOR, address(childTokenTemplate), "", ROOT_IMX_TOKEN, CHILD_WIMX_TOKEN
);
}

function test_onMessageReceive_EmitsTokenMappedEvent() public {
Expand Down Expand Up @@ -354,9 +373,16 @@ contract ChildERC20BridgeUnitTest is Test, IChildERC20BridgeEvents, IChildERC20B
}

function test_RevertIf_updateBridgeAdaptorCalledByNotAdaptorManager() public {
vm.prank(address(0xf00f00));
// FIXME:!!!
// vm.expectRevert(abi.encodeWithSelector(NotVariableManager.selector, 0xf00f00));
address caller = address(0xf00f00);
vm.prank(caller);
vm.expectRevert(
abi.encodePacked(
"AccessControl: account ",
StringsUpgradeable.toHexString(caller),
" is missing role ",
StringsUpgradeable.toHexString(uint256(ADAPTOR_MANAGER_ROLE), 32)
)
);
childBridge.updateBridgeAdaptor(address(0x11111));
}

Expand Down
2 changes: 2 additions & 0 deletions test/unit/child/WIMX.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ contract WIMXTest is Test {
"Token supply should be 0.55 after 2nd deposit"
);

vm.stopPrank();

// Withdraw 0.5 IMX
uint256 withdrawlAmt2 = 0.5 ether;
vm.startPrank(user2);
Expand Down
10 changes: 5 additions & 5 deletions test/unit/child/withdrawals/ChildERC20BridgeWithdraw.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,14 @@ contract ChildERC20BridgeWithdrawUnitTest is Test, IChildERC20BridgeEvents, IChi

function test_RevertsIf_WithdrawCalledWithEmptyChildToken() public {
vm.expectRevert(EmptyTokenContract.selector);
childBridge.withdraw(IChildERC20(address(2222222)), 100);
childBridge.withdraw{value: 1 ether}(IChildERC20(address(2222222)), 100);
}

function test_RevertsIf_WithdrawCalledWithUnmappedToken() public {
ChildERC20 newToken = new ChildERC20();
newToken.initialize(address(123), "Test", "TST", 18);
vm.expectRevert(NotMapped.selector);
childBridge.withdraw(IChildERC20(address(newToken)), 100);
childBridge.withdraw{value: 1 ether}(IChildERC20(address(newToken)), 100);
}

function test_RevertsIf_WithdrawCalledWithAChildTokenWithUnsetRootToken() public {
Expand All @@ -101,7 +101,7 @@ contract ChildERC20BridgeWithdrawUnitTest is Test, IChildERC20BridgeEvents, IChi
vm.store(address(childBridge), slot, data);

vm.expectRevert(ZeroAddressRootToken.selector);
childBridge.withdraw(IChildERC20(address(childToken)), 100);
childBridge.withdraw{value: 1 ether}(IChildERC20(address(childToken)), 100);
}

function test_RevertsIf_WithdrawCalledWithAChildTokenThatHasWrongBridge() public {
Expand All @@ -111,15 +111,15 @@ contract ChildERC20BridgeWithdrawUnitTest is Test, IChildERC20BridgeEvents, IChi
vm.store(address(childToken), bridgeSlotBytes32, bytes32(uint256(uint160(address(0x123)))));

vm.expectRevert(IncorrectBridgeAddress.selector);
childBridge.withdraw(IChildERC20(address(childToken)), 100);
childBridge.withdraw{value: 1 ether}(IChildERC20(address(childToken)), 100);
}

function test_RevertsIf_WithdrawWhenBurnFails() public {
// Replace the childToken with one that always returns `false` on failure.
deployCodeTo("ChildERC20FailOnBurn.sol", address(childToken));

vm.expectRevert(BurnFailed.selector);
childBridge.withdraw(IChildERC20(address(childToken)), 100);
childBridge.withdraw{value: 1 ether}(IChildERC20(address(childToken)), 100);
}

function test_withdraw_CallsBridgeAdaptor() public {
Expand Down
10 changes: 5 additions & 5 deletions test/unit/child/withdrawals/ChildERC20BridgeWithdrawTo.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,14 @@ contract ChildERC20BridgeWithdrawToUnitTest is Test, IChildERC20BridgeEvents, IC

function test_RevertsIf_WithdrawToCalledWithEmptyChildToken() public {
vm.expectRevert(EmptyTokenContract.selector);
childBridge.withdrawTo(IChildERC20(address(2222222)), address(this), 100);
childBridge.withdrawTo{value: 1 ether}(IChildERC20(address(2222222)), address(this), 100);
}

function test_RevertsIf_WithdrawToCalledWithUnmappedToken() public {
ChildERC20 newToken = new ChildERC20();
newToken.initialize(address(123), "Test", "TST", 18);
vm.expectRevert(NotMapped.selector);
childBridge.withdrawTo(IChildERC20(address(newToken)), address(this), 100);
childBridge.withdrawTo{value: 1 ether}(IChildERC20(address(newToken)), address(this), 100);
}

function test_RevertsIf_WithdrawToCalledWithAChildTokenWithUnsetRootToken() public {
Expand All @@ -100,7 +100,7 @@ contract ChildERC20BridgeWithdrawToUnitTest is Test, IChildERC20BridgeEvents, IC
vm.store(address(childBridge), slot, data);

vm.expectRevert(ZeroAddressRootToken.selector);
childBridge.withdrawTo(IChildERC20(address(childToken)), address(this), 100);
childBridge.withdrawTo{value: 1 ether}(IChildERC20(address(childToken)), address(this), 100);
}

function test_RevertsIf_WithdrawToCalledWithAChildTokenThatHasWrongBridge() public {
Expand All @@ -110,15 +110,15 @@ contract ChildERC20BridgeWithdrawToUnitTest is Test, IChildERC20BridgeEvents, IC
vm.store(address(childToken), bridgeSlotBytes32, bytes32(uint256(uint160(address(0x123)))));

vm.expectRevert(IncorrectBridgeAddress.selector);
childBridge.withdrawTo(IChildERC20(address(childToken)), address(this), 100);
childBridge.withdrawTo{value: 1 ether}(IChildERC20(address(childToken)), address(this), 100);
}

function test_RevertsIf_WithdrawToWhenBurnFails() public {
// Replace the childToken with one that always returns `false` on failure.
deployCodeTo("ChildERC20FailOnBurn.sol", address(childToken));

vm.expectRevert(BurnFailed.selector);
childBridge.withdrawTo(IChildERC20(address(childToken)), address(this), 100);
childBridge.withdrawTo{value: 1 ether}(IChildERC20(address(childToken)), address(this), 100);
}

function test_withdrawTo_CallsBridgeAdaptor() public {
Expand Down
16 changes: 13 additions & 3 deletions test/unit/root/RootERC20Bridge.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity 0.8.19;

import {Test, console2} from "forge-std/Test.sol";
import "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.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";
Expand All @@ -19,6 +20,8 @@ import {Utils} from "../../utils.t.sol";
import {WETH} from "../../../src/test/root/WETH.sol";

contract RootERC20BridgeUnitTest is Test, IRootERC20BridgeEvents, IRootERC20BridgeErrors, Utils {
// TODO: move me to roles contract
bytes32 constant ADAPTOR_MANAGER_ROLE = keccak256("ADAPTOR_MANAGER_ROLE");
address constant CHILD_BRIDGE = address(3);
address constant CHILD_BRIDGE_ADAPTOR = address(4);
string CHILD_BRIDGE_ADAPTOR_STRING = Strings.toHexString(CHILD_BRIDGE_ADAPTOR);
Expand Down Expand Up @@ -525,9 +528,16 @@ contract RootERC20BridgeUnitTest is Test, IRootERC20BridgeEvents, IRootERC20Brid
}

function test_RevertIf_updateRootBridgeAdaptorCalledByNonOwner() public {
vm.prank(address(0xf00f00));
// FIXME: !!!
// vm.expectRevert(abi.encodeWithSelector(NotVariableManager.selector, 0xf00f00));
address caller = address(0xf00f00);
vm.prank(caller);
vm.expectRevert(
abi.encodePacked(
"AccessControl: account ",
StringsUpgradeable.toHexString(caller),
" is missing role ",
StringsUpgradeable.toHexString(uint256(ADAPTOR_MANAGER_ROLE), 32)
)
);
rootBridge.updateRootBridgeAdaptor(address(0x11111));
}

Expand Down

0 comments on commit 941d911

Please sign in to comment.