Skip to content
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

Nojira lint in ci #11

Merged
merged 2 commits into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Lint Check

on: [push]

env:
FOUNDRY_PROFILE: ci

jobs:
check:
strategy:
fail-fast: true

name: Forge Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: recursive

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly

- name: Run Forge fmt --check
run: |
forge fmt --check
id: fmt
3 changes: 2 additions & 1 deletion .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ jobs:
- uses: crytic/[email protected]
with:
fail-on: high
slither-args: --filter-paths "./lib|./test"
slither-args: --filter-paths "./lib|./test"
node-version: 18
8 changes: 4 additions & 4 deletions script/InitializeChildContracts.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ contract InitializeChildContracts is Script {
function run() public {
uint256 deployerPrivateKey = vm.envUint("CHILD_PRIVATE_KEY");
ChildERC20Bridge childERC20Bridge = ChildERC20Bridge(vm.envAddress("CHILD_ERC20_BRIDGE"));
ChildAxelarBridgeAdaptor childAxelarBridgeAdaptor = ChildAxelarBridgeAdaptor(vm.envAddress("CHILD_BRIDGE_ADAPTOR"));
ChildAxelarBridgeAdaptor childAxelarBridgeAdaptor =
ChildAxelarBridgeAdaptor(vm.envAddress("CHILD_BRIDGE_ADAPTOR"));
address childTokenTemplate = vm.envAddress("CHILDCHAIN_CHILD_TOKEN_TEMPLATE");
address rootERC20BridgeAdaptor = vm.envAddress("ROOT_BRIDGE_ADAPTOR");
string memory childRpcUrl = vm.envString("CHILD_RPC_URL");
Expand All @@ -27,8 +28,8 @@ contract InitializeChildContracts is Script {
vm.startBroadcast(deployerPrivateKey);

childERC20Bridge.initialize(
address(childAxelarBridgeAdaptor),
Strings.toHexString(rootERC20BridgeAdaptor),
address(childAxelarBridgeAdaptor),
Strings.toHexString(rootERC20BridgeAdaptor),
childTokenTemplate,
rootChainName,
rootIMXToken
Expand All @@ -37,6 +38,5 @@ contract InitializeChildContracts is Script {
childAxelarBridgeAdaptor.setRootBridgeAdaptor();

vm.stopBroadcast();

}
}
2 changes: 1 addition & 1 deletion script/InitializeRootContracts.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ contract InitializeRootContracts is Script {
string memory rootRpcUrl = vm.envString("ROOT_RPC_URL");
uint256 rootPrivateKey = vm.envUint("ROOT_PRIVATE_KEY");
address rootIMXToken = vm.envAddress("ROOT_IMX_ADDRESS");
address childETHToken = vm.envAddress("CHILD_ETH_ADDRESS");
address childETHToken = vm.envAddress("CHILD_ETH_ADDRESS");

/**
* INITIALIZE ROOT CHAIN CONTRACTS
Expand Down
6 changes: 2 additions & 4 deletions src/child/ChildERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,7 @@ contract ChildERC20Bridge is
string memory newRootChain,
address newIMXToken
) public initializer {
if (newBridgeAdaptor == address(0)
|| newChildTokenTemplate == address(0)
|| newIMXToken == address(0)) {
if (newBridgeAdaptor == address(0) || newChildTokenTemplate == address(0) || newIMXToken == address(0)) {
revert ZeroAddress();
}

Expand Down Expand Up @@ -165,7 +163,7 @@ contract ChildERC20Bridge is
} else {
Address.sendValue(payable(receiver), amount);
emit IMXDeposit(address(rootToken), sender, receiver, amount);
}
}
}

function updateBridgeAdaptor(address newBridgeAdaptor) external override onlyOwner {
Expand Down
7 changes: 1 addition & 6 deletions src/interfaces/child/IChildERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,7 @@ interface IChildERC20BridgeEvents {
address indexed receiver,
uint256 amount
);
event IMXDeposit(
address indexed rootToken,
address depositor,
address indexed receiver,
uint256 amount
);
event IMXDeposit(address indexed rootToken, address depositor, address indexed receiver, uint256 amount);
event NativeDeposit(
address indexed rootToken,
address indexed childToken,
Expand Down
7 changes: 1 addition & 6 deletions src/interfaces/root/IRootERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,7 @@ interface IRootERC20BridgeEvents {
address indexed receiver,
uint256 amount
);
event IMXDeposit(
address indexed rootToken,
address depositor,
address indexed receiver,
uint256 amount
);
event IMXDeposit(address indexed rootToken, address depositor, address indexed receiver, uint256 amount);
event NativeDeposit(
address indexed rootToken,
address indexed childToken,
Expand Down
32 changes: 15 additions & 17 deletions src/root/RootERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,15 @@ contract RootERC20Bridge is
address newRootBridgeAdaptor,
address newChildERC20Bridge,
address newChildBridgeAdaptor,
address newChildTokenTemplate,
address newChildTokenTemplate,
address newRootIMXToken,
address newChildETHToken)
public
initializer
{
if (newRootBridgeAdaptor == address(0)
|| newChildERC20Bridge == address(0)
|| newChildTokenTemplate == address(0)
|| newChildBridgeAdaptor == address(0)
|| newRootIMXToken == address(0)
|| newChildETHToken == address(0))
{
address newChildETHToken
) public initializer {
if (
newRootBridgeAdaptor == address(0) || newChildERC20Bridge == address(0)
|| newChildTokenTemplate == address(0) || newChildBridgeAdaptor == address(0)
|| newRootIMXToken == address(0) || newChildETHToken == address(0)
) {
revert ZeroAddress();
}
childERC20Bridge = newChildERC20Bridge;
Expand All @@ -95,11 +91,13 @@ contract RootERC20Bridge is
return _mapToken(rootToken);
}

function depositETH(uint256 amount) external payable { //override removed?
function depositETH(uint256 amount) external payable {
//override removed?
_depositETH(msg.sender, amount);
}

function depositToETH(address receiver, uint256 amount) external payable { //override removed?
function depositToETH(address receiver, uint256 amount) external payable {
//override removed?
_depositETH(receiver, amount);
}

Expand All @@ -109,7 +107,7 @@ contract RootERC20Bridge is
}

uint256 expectedBalance = address(this).balance - (msg.value - amount);

_deposit(IERC20Metadata(NATIVE_TOKEN), receiver, amount);

// invariant check to ensure that the root native balance has increased by the amount deposited
Expand Down Expand Up @@ -186,7 +184,7 @@ contract RootERC20Bridge is
// TODO We can call _mapToken here, but ordering in the GMP is not guaranteed.
// Therefore, we need to decide how to handle this and it may be a UI decision to wait until map token message is executed on child chain.
// Discuss this, and add this decision to the design doc.
if (address(rootToken) != NATIVE_TOKEN) {
if (address(rootToken) != NATIVE_TOKEN) {
if (address(rootToken) != rootIMXToken) {
childToken = rootTokenToChildToken[address(rootToken)];
if (childToken == address(0)) {
Expand All @@ -199,7 +197,7 @@ contract RootERC20Bridge is
} else {
feeAmount = msg.value - amount;
}

// Deposit sig, root token address, depositor, receiver, amount
bytes memory payload = abi.encode(DEPOSIT_SIG, rootToken, msg.sender, receiver, amount);
// TODO investigate using delegatecall to keep the axelar message sender as the bridge contract, since adaptor can change.
Expand Down
3 changes: 2 additions & 1 deletion test/integration/root/RootERC20Bridge.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ contract RootERC20BridgeIntegrationTest is Test, IRootERC20BridgeEvents, IRootAx
function test_depositToken() public {
uint256 tokenAmount = 300;
string memory childBridgeAdaptorString = Strings.toHexString(CHILD_BRIDGE_ADAPTOR);
(address childToken, bytes memory predictedPayload) = setupDeposit(token, rootBridge, mapTokenFee, depositFee, tokenAmount, true);
(address childToken, bytes memory predictedPayload) =
setupDeposit(token, rootBridge, mapTokenFee, depositFee, tokenAmount, true);

vm.expectEmit(address(axelarAdaptor));
emit MapTokenAxelarMessage(CHILD_CHAIN_NAME, childBridgeAdaptorString, predictedPayload);
Expand Down
15 changes: 8 additions & 7 deletions test/unit/child/ChildERC20Bridge.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ contract ChildERC20BridgeUnitTest is Test, IChildERC20BridgeEvents, IChildERC20B

childBridge = new ChildERC20Bridge();

childBridge.initialize(address(this), ROOT_BRIDGE_ADAPTOR, address(childTokenTemplate), ROOT_CHAIN_NAME, IMX_TOKEN);
childBridge.initialize(
address(this), ROOT_BRIDGE_ADAPTOR, address(childTokenTemplate), ROOT_CHAIN_NAME, IMX_TOKEN
);
}

function test_Initialize() public {
Expand All @@ -45,7 +47,9 @@ contract ChildERC20BridgeUnitTest is Test, IChildERC20BridgeEvents, IChildERC20B

function test_RevertIfInitializeTwice() public {
vm.expectRevert("Initializable: contract is already initialized");
childBridge.initialize(address(this), ROOT_BRIDGE_ADAPTOR, address(childTokenTemplate), ROOT_CHAIN_NAME, IMX_TOKEN);
childBridge.initialize(
address(this), ROOT_BRIDGE_ADAPTOR, address(childTokenTemplate), ROOT_CHAIN_NAME, IMX_TOKEN
);
}

function test_RevertIf_InitializeWithAZeroAddressAdapter() public {
Expand Down Expand Up @@ -182,9 +186,7 @@ contract ChildERC20BridgeUnitTest is Test, IChildERC20BridgeEvents, IChildERC20B
}

function test_RevertIf_mapTokenCalledWithIMXAddress() public {
bytes memory data = abi.encode(
childBridge.MAP_TOKEN_SIG(), IMX_TOKEN, "ImmutableX", "IMX", 18
);
bytes memory data = abi.encode(childBridge.MAP_TOKEN_SIG(), IMX_TOKEN, "ImmutableX", "IMX", 18);
vm.expectRevert(CantMapIMX.selector);
childBridge.onMessageReceive(ROOT_CHAIN_NAME, ROOT_BRIDGE_ADAPTOR, data);
}
Expand Down Expand Up @@ -220,7 +222,6 @@ contract ChildERC20BridgeUnitTest is Test, IChildERC20BridgeEvents, IChildERC20B
//Deposit

function test_onMessageReceive_DepositIMX_EmitsIMXDepositEvent() public {

uint256 fundedAmount = 10 ether;
vm.deal(address(childBridge), fundedAmount);

Expand Down Expand Up @@ -251,7 +252,7 @@ contract ChildERC20BridgeUnitTest is Test, IChildERC20BridgeEvents, IChildERC20B
assertEq(receiver.balance, amount, "receiver balance not increased");
}

function test_RevertIf_onMessageReceive_DepositIMX_InsufficientBalance() public {
function test_RevertIf_onMessageReceive_DepositIMX_InsufficientBalance() public {
uint256 fundedAmount = 1 ether;
vm.deal(address(childBridge), fundedAmount);

Expand Down
45 changes: 28 additions & 17 deletions test/unit/root/RootERC20Bridge.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ contract RootERC20BridgeUnitTest is Test, IRootERC20BridgeEvents, IRootERC20Brid
mockAxelarAdaptor = new MockAdaptor();

// The specific ERC20 token template does not matter for these unit tests
rootBridge.initialize(address(mockAxelarAdaptor), CHILD_BRIDGE, CHILD_BRIDGE_ADAPTOR, address(token), IMX_TOKEN, CHILD_ETH_TOKEN);
rootBridge.initialize(
address(mockAxelarAdaptor), CHILD_BRIDGE, CHILD_BRIDGE_ADAPTOR, address(token), IMX_TOKEN, CHILD_ETH_TOKEN
);
}

/**
Expand All @@ -58,7 +60,9 @@ contract RootERC20BridgeUnitTest is Test, IRootERC20BridgeEvents, IRootERC20Brid

function test_RevertIfInitializeTwice() public {
vm.expectRevert("Initializable: contract is already initialized");
rootBridge.initialize(address(mockAxelarAdaptor), CHILD_BRIDGE, CHILD_BRIDGE_ADAPTOR, address(token), IMX_TOKEN, CHILD_ETH_TOKEN);
rootBridge.initialize(
address(mockAxelarAdaptor), CHILD_BRIDGE, CHILD_BRIDGE_ADAPTOR, address(token), IMX_TOKEN, CHILD_ETH_TOKEN
);
}

function test_RevertIf_InitializeWithAZeroAddressRootAdapter() public {
Expand Down Expand Up @@ -118,7 +122,6 @@ contract RootERC20BridgeUnitTest is Test, IRootERC20BridgeEvents, IRootERC20Brid
}

function test_mapToken_CallsAdaptor() public {

bytes memory payload =
abi.encode(rootBridge.MAP_TOKEN_SIG(), token, token.name(), token.symbol(), token.decimals());

Expand Down Expand Up @@ -201,15 +204,16 @@ contract RootERC20BridgeUnitTest is Test, IRootERC20BridgeEvents, IRootERC20Brid

function test_depositETHCallsSendMessage() public {
uint256 amount = 1000;
(, bytes memory predictedPayload) = setupDeposit(ERC20PresetMinterPauser(NATIVE_TOKEN), rootBridge, mapTokenFee, depositFee, amount, false);
(, bytes memory predictedPayload) =
setupDeposit(ERC20PresetMinterPauser(NATIVE_TOKEN), rootBridge, mapTokenFee, depositFee, amount, false);

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

rootBridge.depositETH{value: amount+depositFee}(amount);
rootBridge.depositETH{value: amount + depositFee}(amount);
}

function test_depositETHEmitsNativeDepositEvent() public {
Expand All @@ -218,51 +222,57 @@ contract RootERC20BridgeUnitTest is Test, IRootERC20BridgeEvents, IRootERC20Brid

vm.expectEmit();
emit NativeDeposit(NATIVE_TOKEN, CHILD_ETH_TOKEN, address(this), address(this), amount);
rootBridge.depositETH{value: amount+depositFee}(amount);
rootBridge.depositETH{value: amount + depositFee}(amount);
}

function test_RevertIf_depositETHInsufficientValue() public {
uint256 amount = 1000;
setupDeposit(ERC20PresetMinterPauser(NATIVE_TOKEN), rootBridge, mapTokenFee, depositFee, amount, false);

vm.expectRevert(InsufficientValue.selector);
rootBridge.depositETH{value: (amount/2)+depositFee}(amount);
rootBridge.depositETH{value: (amount / 2) + depositFee}(amount);
}

/**
/**
* DEPOSIT TO ETH
*/

function test_depositToETHCallsSendMessage() public {
uint256 amount = 1000;
address receiver = address(12345);
(, bytes memory predictedPayload) = setupDepositTo(ERC20PresetMinterPauser(NATIVE_TOKEN), rootBridge, mapTokenFee, depositFee, amount, receiver, false);
(, bytes memory predictedPayload) = setupDepositTo(
ERC20PresetMinterPauser(NATIVE_TOKEN), rootBridge, mapTokenFee, depositFee, amount, receiver, false
);
vm.expectCall(
address(mockAxelarAdaptor),
depositFee,
abi.encodeWithSelector(mockAxelarAdaptor.sendMessage.selector, predictedPayload, address(this))
);

rootBridge.depositToETH{value: amount+depositFee}(receiver, amount);
rootBridge.depositToETH{value: amount + depositFee}(receiver, amount);
}

function test_depositToETHEmitsNativeDepositEvent() public {
uint256 amount = 1000;
address receiver = address(12345);
setupDepositTo(ERC20PresetMinterPauser(NATIVE_TOKEN), rootBridge, mapTokenFee, depositFee, amount, receiver, false);
setupDepositTo(
ERC20PresetMinterPauser(NATIVE_TOKEN), rootBridge, mapTokenFee, depositFee, amount, receiver, false
);

vm.expectEmit();
emit NativeDeposit(NATIVE_TOKEN, CHILD_ETH_TOKEN, address(this), receiver, amount);
rootBridge.depositToETH{value: amount+depositFee}(receiver, amount);
rootBridge.depositToETH{value: amount + depositFee}(receiver, amount);
}

function test_RevertIf_depositToETHInsufficientValue() public {
uint256 amount = 1000;
address receiver = address(12345);
setupDepositTo(ERC20PresetMinterPauser(NATIVE_TOKEN), rootBridge, mapTokenFee, depositFee, amount, receiver, false);
setupDepositTo(
ERC20PresetMinterPauser(NATIVE_TOKEN), rootBridge, mapTokenFee, depositFee, amount, receiver, false
);

vm.expectRevert(InsufficientValue.selector);
rootBridge.depositToETH{value: (amount/2)+depositFee}(receiver, amount);
rootBridge.depositToETH{value: (amount / 2) + depositFee}(receiver, amount);
}

/**
Expand All @@ -274,7 +284,7 @@ contract RootERC20BridgeUnitTest is Test, IRootERC20BridgeEvents, IRootERC20Brid
setupDeposit(ERC20PresetMinterPauser(NATIVE_TOKEN), rootBridge, mapTokenFee, depositFee, amount, false);

vm.expectRevert(ZeroAmount.selector);
rootBridge.depositETH{value: amount+depositFee}(amount);
rootBridge.depositETH{value: amount + depositFee}(amount);
}

function test_RevertIf_depositToETHAmountIsZero() public {
Expand All @@ -284,7 +294,7 @@ contract RootERC20BridgeUnitTest is Test, IRootERC20BridgeEvents, IRootERC20Brid
setupDeposit(ERC20PresetMinterPauser(NATIVE_TOKEN), rootBridge, mapTokenFee, depositFee, amount, false);

vm.expectRevert(ZeroAmount.selector);
rootBridge.depositToETH{value: amount+depositFee}(receiver, amount);
rootBridge.depositToETH{value: amount + depositFee}(receiver, amount);
}

function test_RevertIf_depositAmountIsZero() public {
Expand Down Expand Up @@ -406,7 +416,8 @@ contract RootERC20BridgeUnitTest is Test, IRootERC20BridgeEvents, IRootERC20Brid
uint256 amount = 100;
address receiver = address(12345);

(, bytes memory predictedPayload) = setupDepositTo(token, rootBridge, mapTokenFee, depositFee, amount, receiver, true);
(, bytes memory predictedPayload) =
setupDepositTo(token, rootBridge, mapTokenFee, depositFee, amount, receiver, true);

vm.expectCall(
address(mockAxelarAdaptor),
Expand Down
Loading