@@ -10,16 +10,32 @@ contract Passage {
10
10
uint256 public immutable defaultRollupChainId;
11
11
12
12
/// @notice The address that is allowed to withdraw funds from the contract.
13
- address public immutable withdrawalAdmin ;
13
+ address public immutable tokenAdmin ;
14
14
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 );
17
23
18
24
/// @notice Emitted when Ether enters the rollup.
25
+ /// @param rollupChainId - The chainId of the destination rollup.
19
26
/// @param rollupRecipient - The recipient of Ether on the rollup.
20
27
/// @param amount - The amount of Ether entering the rollup.
21
28
event Enter (uint256 indexed rollupChainId , address indexed rollupRecipient , uint256 amount );
22
29
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
+
23
39
/// @notice Emitted to send a special transaction to the rollup.
24
40
event Transact (
25
41
uint256 indexed rollupChainId ,
@@ -34,11 +50,17 @@ contract Passage {
34
50
/// @notice Emitted when the admin withdraws tokens from the contract.
35
51
event Withdrawal (address indexed token , address indexed recipient , uint256 amount );
36
52
53
+ /// @notice Emitted when the admin allow/disallow ERC20 Enters for a given token.
54
+ event EnterConfigured (address indexed token , bool indexed canEnter );
55
+
37
56
/// @param _defaultRollupChainId - the chainId of the rollup that Ether will be sent to by default
38
57
/// when entering the rollup via fallback() or receive() fns.
39
- constructor (uint256 _defaultRollupChainId , address _withdrawalAdmin ) {
58
+ constructor (uint256 _defaultRollupChainId , address _tokenAdmin , address [] memory initialEnterTokens ) {
40
59
defaultRollupChainId = _defaultRollupChainId;
41
- withdrawalAdmin = _withdrawalAdmin;
60
+ tokenAdmin = _tokenAdmin;
61
+ for (uint256 i; i < initialEnterTokens.length ; i++ ) {
62
+ _configureEnter (initialEnterTokens[i], true );
63
+ }
42
64
}
43
65
44
66
/// @notice Allows native Ether to enter the rollup by being sent directly to the contract.
@@ -66,6 +88,23 @@ contract Passage {
66
88
enter (defaultRollupChainId, rollupRecipient);
67
89
}
68
90
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
+
69
108
/// @notice Allows a special transaction to be sent to the rollup with sender == L1 msg.sender.
70
109
/// @dev Transaction is processed after normal rollup block execution.
71
110
/// @dev See `enterTransact` for docs.
@@ -114,15 +153,27 @@ contract Passage {
114
153
emit Transact (rollupChainId, msg .sender , to, data, value, gas, maxFeePerGas);
115
154
}
116
155
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
+
117
162
/// @notice Allows the admin to withdraw ETH or ERC20 tokens from the contract.
118
163
/// @dev Only the admin can call this function.
119
164
function withdraw (address token , address recipient , uint256 amount ) external {
120
- if (msg .sender != withdrawalAdmin ) revert OnlyWithdrawalAdmin ();
165
+ if (msg .sender != tokenAdmin ) revert OnlyTokenAdmin ();
121
166
if (token == address (0 )) {
122
167
payable (recipient).transfer (amount);
123
168
} else {
124
169
IERC20 (token).transfer (recipient, amount);
125
170
}
126
171
emit Withdrawal (token, recipient, amount);
127
172
}
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
+ }
128
179
}
0 commit comments