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

test: Passage #51

Merged
merged 4 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions src/Passage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ contract Passage {
/// @param amount - The amount of tokens entering the rollup.
function enterToken(uint256 rollupChainId, address rollupRecipient, address token, uint256 amount) public {
if (!canEnter[token]) revert DisallowedEnter(token);
if (amount == 0) return;
IERC20(token).transferFrom(msg.sender, address(this), amount);
emit EnterToken(rollupChainId, rollupRecipient, token, amount);
}
Expand Down
199 changes: 199 additions & 0 deletions test/Passage.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.24;

import {Test, console2} from "forge-std/Test.sol";
import {Passage} from "../src/Passage.sol";
import {ERC20} from "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";

contract TestERC20 is ERC20 {
constructor(string memory name_, string memory symbol_) ERC20(name_, symbol_) {}

function mint(address recipient, uint256 amount) external {
_mint(recipient, amount);
}
}

contract ZenithTest is Test {
Passage public target;
address token;
address newToken;
uint256 chainId = 3;
address recipient = address(0x123);
uint256 amount = 200;

// TODO: do we need to do checks on these vals?
address to = address(0x01);
bytes data = abi.encodeWithSelector(ERC20.transfer.selector, recipient, amount);
uint256 value = 100;
uint256 gas = 10_000_000;
uint256 maxFeePerGas = 50;

uint256 tokenAdminKey = 123;

event Enter(uint256 indexed rollupChainId, address indexed rollupRecipient, uint256 amount);

event EnterToken(
uint256 indexed rollupChainId, address indexed rollupRecipient, address indexed token, uint256 amount
);

event Transact(
uint256 indexed rollupChainId,
address indexed sender,
address indexed to,
bytes data,
uint256 value,
uint256 gas,
uint256 maxFeePerGas
);

event Withdrawal(address indexed token, address indexed recipient, uint256 amount);

event EnterConfigured(address indexed token, bool indexed canEnter);

function setUp() public {
address[] memory initialEnterTokens;
target = new Passage(block.chainid + 1, address(this), initialEnterTokens);

// deploy token one, to be configured at deploy time
token = address(new TestERC20("hi", "HI"));
TestERC20(token).mint(address(this), amount * 10000);
TestERC20(token).approve(address(target), amount * 10000);
// TODO: change to intializer setup
target.configureEnter(token, true);

// deploy token two, don't configure
newToken = address(new TestERC20("bye", "BYE"));
TestERC20(newToken).mint(address(this), amount * 10000);
TestERC20(newToken).approve(address(target), amount * 10000);
}

function test_setUp() public {
assertEq(target.defaultRollupChainId(), block.chainid + 1);
assertEq(target.tokenAdmin(), address(this));
assertTrue(target.canEnter(token));
assertFalse(target.canEnter(newToken));
}

function test_onlyTokenAdmin() public {
vm.startPrank(address(0x01));
vm.expectRevert(Passage.OnlyTokenAdmin.selector);
target.withdraw(token, recipient, amount);

vm.expectRevert(Passage.OnlyTokenAdmin.selector);
target.configureEnter(token, true);
}

function test_disallowedEnter() public {
vm.expectRevert(abi.encodeWithSelector(Passage.DisallowedEnter.selector, newToken));
target.enterToken(recipient, newToken, amount);
}

function test_configureEnter() public {
// enter not allowed by default
assertFalse(target.canEnter(newToken));
vm.expectRevert(abi.encodeWithSelector(Passage.DisallowedEnter.selector, newToken));
target.enterToken(chainId, recipient, newToken, amount);

// allow enter
vm.expectEmit();
emit EnterConfigured(newToken, true);
target.configureEnter(newToken, true);

// enter is allowed
assertTrue(target.canEnter(newToken));
vm.expectEmit();
emit EnterToken(chainId, recipient, newToken, amount);
target.enterToken(chainId, recipient, newToken, amount);

// disallow enter
vm.expectEmit();
emit EnterConfigured(newToken, false);
target.configureEnter(newToken, false);

// enter not allowed again
assertFalse(target.canEnter(newToken));
vm.expectRevert(abi.encodeWithSelector(Passage.DisallowedEnter.selector, newToken));
target.enterToken(chainId, recipient, newToken, amount);
}

function test_receive() public {
vm.expectEmit();
emit Enter(target.defaultRollupChainId(), address(this), amount);
address(target).call{value: amount}("");
}

function test_fallback() public {
vm.expectEmit();
emit Enter(target.defaultRollupChainId(), address(this), amount);
address(target).call{value: amount}("0xabcd");
}

function test_enter() public {
vm.expectEmit();
emit Enter(chainId, recipient, amount);
target.enter{value: amount}(chainId, recipient);
}

function test_enter_defaultChain() public {
vm.expectEmit();
emit Enter(target.defaultRollupChainId(), recipient, amount);
target.enter{value: amount}(recipient);
}

function test_enterToken() public {
vm.expectEmit();
emit EnterToken(chainId, recipient, token, amount);
vm.expectCall(
token, abi.encodeWithSelector(ERC20.transferFrom.selector, address(this), address(target), amount)
);
target.enterToken(chainId, recipient, token, amount);
}

function test_enterToken_defaultChain() public {
vm.expectEmit();
emit EnterToken(target.defaultRollupChainId(), recipient, token, amount);
vm.expectCall(
token, abi.encodeWithSelector(ERC20.transferFrom.selector, address(this), address(target), amount)
);
target.enterToken(recipient, token, amount);
}

function test_transact() public {
vm.expectEmit();
emit Transact(chainId, address(this), to, data, value, gas, maxFeePerGas);
target.transact(chainId, to, data, value, gas, maxFeePerGas);

vm.expectEmit();
emit Enter(chainId, address(this), amount);
target.transact{value: amount}(chainId, to, data, value, gas, maxFeePerGas);
}

function test_transact_defaultChain() public {
vm.expectEmit();
emit Transact(target.defaultRollupChainId(), address(this), to, data, value, gas, maxFeePerGas);
target.transact(to, data, value, gas, maxFeePerGas);

vm.expectEmit();
emit Enter(target.defaultRollupChainId(), address(this), amount);
target.transact{value: amount}(to, data, value, gas, maxFeePerGas);
}

function test_enterTransact() public {
vm.expectEmit();
emit Transact(chainId, address(this), to, data, value, gas, maxFeePerGas);
target.enterTransact(chainId, recipient, to, data, value, gas, maxFeePerGas);

vm.expectEmit();
emit Enter(chainId, recipient, amount);
target.enterTransact{value: amount}(chainId, recipient, to, data, value, gas, maxFeePerGas);
}

function test_withdraw() public {
TestERC20(token).mint(address(target), amount);

vm.expectEmit();
emit Withdrawal(token, recipient, amount);
vm.expectCall(token, abi.encodeWithSelector(ERC20.transfer.selector, recipient, amount));
target.withdraw(token, recipient, amount);
}
}
Loading