@@ -10,16 +10,32 @@ contract Passage {
1010 uint256 public immutable defaultRollupChainId;
1111
1212 /// @notice The address that is allowed to withdraw funds from the contract.
13- address public immutable withdrawalAdmin ;
13+ address public immutable tokenAdmin ;
1414
15- /// @notice Thrown when attempting to withdraw funds if not withdrawal admin.
16- error OnlyWithdrawalAdmin ();
15+ /// @notice tokenAddress => whether new EnterToken events are currently allowed for that token.
16+ mapping (address => bool ) public canEnter;
17+
18+ /// @notice Thrown when attempting to call admin functions if not the token admin.
19+ error OnlyTokenAdmin ();
20+
21+ /// @notice Thrown when attempting to enter the rollup with an ERC20 token that is not currently allowed.
22+ error DisallowedEnter (address token );
1723
1824 /// @notice Emitted when Ether enters the rollup.
25+ /// @param rollupChainId - The chainId of the destination rollup.
1926 /// @param rollupRecipient - The recipient of Ether on the rollup.
2027 /// @param amount - The amount of Ether entering the rollup.
2128 event Enter (uint256 indexed rollupChainId , address indexed rollupRecipient , uint256 amount );
2229
30+ /// @notice Emitted when ERC20 tokens enter the rollup.
31+ /// @param rollupChainId - The chainId of the destination rollup.
32+ /// @param rollupRecipient - The recipient of tokens on the rollup.
33+ /// @param token - The host chain address of the token entering the rollup.
34+ /// @param amount - The amount of tokens entering the rollup.
35+ event EnterToken (
36+ uint256 indexed rollupChainId , address indexed rollupRecipient , address indexed token , uint256 amount
37+ );
38+
2339 /// @notice Emitted to send a special transaction to the rollup.
2440 event Transact (
2541 uint256 indexed rollupChainId ,
@@ -34,11 +50,17 @@ contract Passage {
3450 /// @notice Emitted when the admin withdraws tokens from the contract.
3551 event Withdrawal (address indexed token , address indexed recipient , uint256 amount );
3652
53+ /// @notice Emitted when the admin allow/disallow ERC20 Enters for a given token.
54+ event EnterConfigured (address indexed token , bool indexed canEnter );
55+
3756 /// @param _defaultRollupChainId - the chainId of the rollup that Ether will be sent to by default
3857 /// when entering the rollup via fallback() or receive() fns.
39- constructor (uint256 _defaultRollupChainId , address _withdrawalAdmin ) {
58+ constructor (uint256 _defaultRollupChainId , address _tokenAdmin , address [] memory initialEnterTokens ) {
4059 defaultRollupChainId = _defaultRollupChainId;
41- withdrawalAdmin = _withdrawalAdmin;
60+ tokenAdmin = _tokenAdmin;
61+ for (uint256 i; i < initialEnterTokens.length ; i++ ) {
62+ _configureEnter (initialEnterTokens[i], true );
63+ }
4264 }
4365
4466 /// @notice Allows native Ether to enter the rollup by being sent directly to the contract.
@@ -66,6 +88,23 @@ contract Passage {
6688 enter (defaultRollupChainId, rollupRecipient);
6789 }
6890
91+ /// @notice Allows ERC20 tokens to enter the rollup.
92+ /// @param rollupChainId - The rollup chain to enter.
93+ /// @param rollupRecipient - The recipient of tokens on the rollup.
94+ /// @param token - The host chain address of the token entering the rollup.
95+ /// @param amount - The amount of tokens entering the rollup.
96+ function enterToken (uint256 rollupChainId , address rollupRecipient , address token , uint256 amount ) public {
97+ if (! canEnter[token]) revert DisallowedEnter (token);
98+ IERC20 (token).transferFrom (msg .sender , address (this ), amount);
99+ emit EnterToken (rollupChainId, rollupRecipient, token, amount);
100+ }
101+
102+ /// @notice Allows ERC20 tokens to enter the default rollup.
103+ /// @dev see `enterToken` for docs.
104+ function enterToken (address rollupRecipient , address token , uint256 amount ) external {
105+ enterToken (defaultRollupChainId, rollupRecipient, token, amount);
106+ }
107+
69108 /// @notice Allows a special transaction to be sent to the rollup with sender == L1 msg.sender.
70109 /// @dev Transaction is processed after normal rollup block execution.
71110 /// @dev See `enterTransact` for docs.
@@ -114,15 +153,27 @@ contract Passage {
114153 emit Transact (rollupChainId, msg .sender , to, data, value, gas, maxFeePerGas);
115154 }
116155
156+ /// @notice Alow/Disallow a given ERC20 token to enter the rollup.
157+ function configureEnter (address token , bool _canEnter ) external {
158+ if (msg .sender != tokenAdmin) revert OnlyTokenAdmin ();
159+ if (canEnter[token] != _canEnter) _configureEnter (token, _canEnter);
160+ }
161+
117162 /// @notice Allows the admin to withdraw ETH or ERC20 tokens from the contract.
118163 /// @dev Only the admin can call this function.
119164 function withdraw (address token , address recipient , uint256 amount ) external {
120- if (msg .sender != withdrawalAdmin ) revert OnlyWithdrawalAdmin ();
165+ if (msg .sender != tokenAdmin ) revert OnlyTokenAdmin ();
121166 if (token == address (0 )) {
122167 payable (recipient).transfer (amount);
123168 } else {
124169 IERC20 (token).transfer (recipient, amount);
125170 }
126171 emit Withdrawal (token, recipient, amount);
127172 }
173+
174+ /// @notice Helper to configure ERC20 enters on deploy & via admin function
175+ function _configureEnter (address token , bool _canEnter ) internal {
176+ canEnter[token] = _canEnter;
177+ emit EnterConfigured (token, _canEnter);
178+ }
128179}
0 commit comments