Skip to content

Commit

Permalink
feat: RollupPassage contract (#60)
Browse files Browse the repository at this point in the history
* feat: RollupPassage contract

* test: RollupPassage

* add RollupPassage to deploy script
  • Loading branch information
anna-carroll authored Jul 15, 2024
1 parent 81e9690 commit a24ddde
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 9 deletions.
10 changes: 7 additions & 3 deletions .gas-snapshot
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ OrdersTest:test_fill_underflowETH() (gas: 115281)
OrdersTest:test_initiate_ERC20() (gas: 81435)
OrdersTest:test_initiate_ETH() (gas: 44949)
OrdersTest:test_initiate_both() (gas: 118677)
OrdersTest:test_initiate_multiERC20() (gas: 688417)
OrdersTest:test_initiate_multiERC20() (gas: 722408)
OrdersTest:test_initiate_multiETH() (gas: 75304)
OrdersTest:test_onlyBuilder() (gas: 12815)
OrdersTest:test_orderExpired() (gas: 27956)
OrdersTest:test_sweepERC20() (gas: 60402)
OrdersTest:test_sweepERC20() (gas: 60446)
OrdersTest:test_sweepETH() (gas: 81940)
OrdersTest:test_underflowETH() (gas: 63528)
PassageTest:test_configureEnter() (gas: 82311)
Expand All @@ -26,7 +26,11 @@ PassageTest:test_receive() (gas: 21384)
PassageTest:test_setUp() (gas: 16968)
PassageTest:test_transact() (gas: 58562)
PassageTest:test_transact_defaultChain() (gas: 57475)
PassageTest:test_withdraw() (gas: 59033)
PassageTest:test_withdraw() (gas: 59166)
RollupPassageTest:test_exit() (gas: 22347)
RollupPassageTest:test_exitToken() (gas: 50183)
RollupPassageTest:test_fallback() (gas: 19883)
RollupPassageTest:test_receive() (gas: 19844)
ZenithTest:test_addSequencer() (gas: 88121)
ZenithTest:test_badSignature() (gas: 37241)
ZenithTest:test_incorrectHostBlock() (gas: 35086)
Expand Down
5 changes: 3 additions & 2 deletions script/Zenith.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pragma solidity ^0.8.24;

import {Script} from "forge-std/Script.sol";
import {Zenith} from "../src/Zenith.sol";
import {Passage} from "../src/Passage.sol";
import {Passage, RollupPassage} from "../src/Passage.sol";
import {HostOrders, RollupOrders} from "../src/Orders.sol";

contract ZenithScript is Script {
Expand All @@ -23,8 +23,9 @@ contract ZenithScript is Script {

// deploy:
// forge script ZenithScript --sig "deployL2()" --rpc-url $L2_RPC_URL --private-key $PRIVATE_KEY --broadcast
function deployL2() public returns (RollupOrders m) {
function deployL2() public returns (RollupPassage p, RollupOrders m) {
vm.startBroadcast();
p = new RollupPassage();
m = new RollupOrders();
}

Expand Down
47 changes: 45 additions & 2 deletions src/Passage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
pragma solidity ^0.8.24;

import {IERC20} from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import {ERC20Burnable} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol";

/// @notice A contract deployed to Host chain that allows tokens to enter the rollup,
/// and enables Builders to fulfill requests to exchange tokens on the Rollup for tokens on the Host.
/// @notice A contract deployed to Host chain that allows tokens to enter the rollup.
contract Passage {
/// @notice The chainId of rollup that Ether will be sent to by default when entering the rollup via fallback() or receive().
uint256 public immutable defaultRollupChainId;
Expand Down Expand Up @@ -178,3 +178,46 @@ contract Passage {
emit EnterConfigured(token, _canEnter);
}
}

/// @notice Enables tokens to Exit the rollup.
contract RollupPassage {
/// @notice Emitted when native Ether exits the rollup.
/// @param hostRecipient - The *requested* recipient of tokens on the host chain.
/// @param amount - The amount of Ether exiting the rollup.
event Exit(address indexed hostRecipient, uint256 amount);

/// @notice Emitted when ERC20 tokens exit the rollup.
/// @param hostRecipient - The *requested* recipient of tokens on the host chain.
/// @param token - The token exiting the rollup.
/// @param amount - The amount of ERC20s exiting the rollup.
event ExitToken(address indexed hostRecipient, address indexed token, uint256 amount);

/// @notice Allows native Ether to exit the rollup by being sent directly to the contract.
fallback() external payable {
exit(msg.sender);
}

/// @notice Allows native Ether to exit the rollup by being sent directly to the contract.
receive() external payable {
exit(msg.sender);
}

/// @notice Allows native Ether to exit the rollup.
/// @param hostRecipient - The *requested* recipient of tokens on the host chain.
/// @custom:emits Exit indicating the amount of Ether that was locked on the rollup & the requested host recipient.
function exit(address hostRecipient) public payable {
if (msg.value == 0) return;
emit Exit(hostRecipient, msg.value);
}

/// @notice Allows ERC20 tokens to exit the rollup.
/// @param hostRecipient - The *requested* recipient of tokens on the host chain.
/// @param token - The rollup address of the token exiting the rollup.
/// @param amount - The amount of tokens exiting the rollup.
function exitToken(address hostRecipient, address token, uint256 amount) public {
if (amount == 0) return;
IERC20(token).transferFrom(msg.sender, address(this), amount);
ERC20Burnable(token).burn(amount);
emit ExitToken(hostRecipient, token, amount);
}
}
3 changes: 2 additions & 1 deletion test/Helpers.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ pragma solidity ^0.8.24;
import {Test, console2} from "forge-std/Test.sol";
import {Zenith} from "../src/Zenith.sol";
import {ERC20} from "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";
import {ERC20Burnable} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol";

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

function mint(address recipient, uint256 amount) external {
Expand Down
52 changes: 51 additions & 1 deletion test/Passage.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
pragma solidity ^0.8.24;

import {Test, console2} from "forge-std/Test.sol";
import {Passage} from "../src/Passage.sol";
import {Passage, RollupPassage} from "../src/Passage.sol";
import {TestERC20} from "./Helpers.t.sol";
import {ERC20} from "openzeppelin-contracts/contracts/token/ERC20/ERC20.sol";
import {ERC20Burnable} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol";

contract PassageTest is Test {
Passage public target;
Expand Down Expand Up @@ -189,3 +190,52 @@ contract PassageTest is Test {
target.withdraw(token, recipient, amount);
}
}

contract RollupPassageTest is Test {
RollupPassage public target;
address token;
address recipient = address(0x123);
uint256 amount = 200;

event Exit(address indexed hostRecipient, uint256 amount);

event ExitToken(address indexed hostRecipient, address indexed token, uint256 amount);

function setUp() public {
// deploy target
target = new RollupPassage();

// deploy token
token = address(new TestERC20("hi", "HI"));
TestERC20(token).mint(address(this), amount * 10000);
TestERC20(token).approve(address(target), amount * 10000);
}

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

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

function test_exit() public {
vm.expectEmit();
emit Exit(recipient, amount);
target.exit{value: amount}(recipient);
}

function test_exitToken() public {
vm.expectEmit();
emit ExitToken(recipient, token, amount);
vm.expectCall(
token, abi.encodeWithSelector(ERC20.transferFrom.selector, address(this), address(target), amount)
);
vm.expectCall(token, abi.encodeWithSelector(ERC20Burnable.burn.selector, amount));
target.exitToken(recipient, token, amount);
}
}

0 comments on commit a24ddde

Please sign in to comment.