| 
2 | 2 | pragma solidity ^0.8.24;  | 
3 | 3 | 
 
  | 
4 | 4 | import {IERC20} from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";  | 
 | 5 | +import {ERC20Burnable} from "openzeppelin-contracts/contracts/token/ERC20/extensions/ERC20Burnable.sol";  | 
5 | 6 | 
 
  | 
6 |  | -/// @notice A contract deployed to Host chain that allows tokens to enter the rollup,  | 
7 |  | -///         and enables Builders to fulfill requests to exchange tokens on the Rollup for tokens on the Host.  | 
 | 7 | +/// @notice A contract deployed to Host chain that allows tokens to enter the rollup.  | 
8 | 8 | contract Passage {  | 
9 | 9 |     /// @notice The chainId of rollup that Ether will be sent to by default when entering the rollup via fallback() or receive().  | 
10 | 10 |     uint256 public immutable defaultRollupChainId;  | 
@@ -178,3 +178,46 @@ contract Passage {  | 
178 | 178 |         emit EnterConfigured(token, _canEnter);  | 
179 | 179 |     }  | 
180 | 180 | }  | 
 | 181 | + | 
 | 182 | +/// @notice Enables tokens to Exit the rollup.  | 
 | 183 | +contract RollupPassage {  | 
 | 184 | +    /// @notice Emitted when native Ether exits the rollup.  | 
 | 185 | +    /// @param hostRecipient - The *requested* recipient of tokens on the host chain.  | 
 | 186 | +    /// @param amount - The amount of Ether exiting the rollup.  | 
 | 187 | +    event Exit(address indexed hostRecipient, uint256 amount);  | 
 | 188 | + | 
 | 189 | +    /// @notice Emitted when ERC20 tokens exit the rollup.  | 
 | 190 | +    /// @param hostRecipient - The *requested* recipient of tokens on the host chain.  | 
 | 191 | +    /// @param token - The token exiting the rollup.  | 
 | 192 | +    /// @param amount - The amount of ERC20s exiting the rollup.  | 
 | 193 | +    event ExitToken(address indexed hostRecipient, address indexed token, uint256 amount);  | 
 | 194 | + | 
 | 195 | +    /// @notice Allows native Ether to exit the rollup by being sent directly to the contract.  | 
 | 196 | +    fallback() external payable {  | 
 | 197 | +        exit(msg.sender);  | 
 | 198 | +    }  | 
 | 199 | + | 
 | 200 | +    /// @notice Allows native Ether to exit the rollup by being sent directly to the contract.  | 
 | 201 | +    receive() external payable {  | 
 | 202 | +        exit(msg.sender);  | 
 | 203 | +    }  | 
 | 204 | + | 
 | 205 | +    /// @notice Allows native Ether to exit the rollup.  | 
 | 206 | +    /// @param hostRecipient - The *requested* recipient of tokens on the host chain.  | 
 | 207 | +    /// @custom:emits Exit indicating the amount of Ether that was locked on the rollup & the requested host recipient.  | 
 | 208 | +    function exit(address hostRecipient) public payable {  | 
 | 209 | +        if (msg.value == 0) return;  | 
 | 210 | +        emit Exit(hostRecipient, msg.value);  | 
 | 211 | +    }  | 
 | 212 | + | 
 | 213 | +    /// @notice Allows ERC20 tokens to exit the rollup.  | 
 | 214 | +    /// @param hostRecipient - The *requested* recipient of tokens on the host chain.  | 
 | 215 | +    /// @param token - The rollup address of the token exiting the rollup.  | 
 | 216 | +    /// @param amount - The amount of tokens exiting the rollup.  | 
 | 217 | +    function exitToken(address hostRecipient, address token, uint256 amount) public {  | 
 | 218 | +        if (amount == 0) return;  | 
 | 219 | +        IERC20(token).transferFrom(msg.sender, address(this), amount);  | 
 | 220 | +        ERC20Burnable(token).burn(amount);  | 
 | 221 | +        emit ExitToken(hostRecipient, token, amount);  | 
 | 222 | +    }  | 
 | 223 | +}  | 
0 commit comments