@@ -3,11 +3,13 @@ pragma solidity ^0.8.24;
3
3
4
4
// import IERC20 from OpenZeppelin
5
5
import {IERC20 } from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol " ;
6
+ import {AccessControlDefaultAdminRules} from
7
+ "openzeppelin-contracts/contracts/access/extensions/AccessControlDefaultAdminRules.sol " ;
6
8
7
9
/// @notice A contract deployed to Host chain that allows tokens to enter the rollup,
8
10
/// and enables Builders to fulfill requests to exchange tokens on the Rollup for tokens on the Host.
9
- contract Passage {
10
- /// @notice The chainId of the default rollup chain .
11
+ contract Passage is AccessControlDefaultAdminRules {
12
+ /// @notice The chainId of rollup that Ether will be sent to by default when entering the rollup via fallback() or receive() .
11
13
uint256 immutable defaultRollupChainId;
12
14
13
15
/// @notice Thrown when attempting to fulfill an exit order with a deadline that has passed.
@@ -25,6 +27,21 @@ contract Passage {
25
27
/// @param amount - The amount of the token transferred to the recipient.
26
28
event ExitFilled (uint256 rollupChainId , address indexed token , address indexed hostRecipient , uint256 amount );
27
29
30
+ /// @notice Emitted when the admin withdraws tokens from the contract.
31
+ event Withdraw (Withdrawal withdrawal );
32
+
33
+ /// @notice A bundled withdrawal of Ether and ERC20 tokens.
34
+ /// @param recipient - The address to receive the Ether and ERC20 tokens.
35
+ /// @param ethAmount - The amount of Ether to transfer to the recipient. Zero if no Ether to transfer.
36
+ /// @param tokens - The addresses of the ERC20 tokens to transfer to the recipient.
37
+ /// @param tokenAmounts - The amounts of the ERC20 tokens to transfer to the recipient.
38
+ struct Withdrawal {
39
+ address recipient;
40
+ uint256 ethAmount;
41
+ address [] tokens;
42
+ uint256 [] tokenAmounts;
43
+ }
44
+
28
45
/// @notice Details of an exit order to be fulfilled by the Builder.
29
46
/// @param token - The address of the token to be transferred to the recipient.
30
47
/// If token is the zero address, the amount is native Ether.
@@ -40,7 +57,14 @@ contract Passage {
40
57
uint256 amount;
41
58
}
42
59
43
- constructor (uint256 _defaultRollupChainId ) {
60
+ /// @notice Initializes the Admin role.
61
+ /// @dev See `AccessControlDefaultAdminRules` for information on contract administration.
62
+ /// - Admin role can grant and revoke Sequencer roles.
63
+ /// - Admin role can be transferred via two-step process with a 1 day timelock.
64
+ /// @param _defaultRollupChainId - the chainId of the rollup that Ether will be sent to by default
65
+ /// when entering the rollup via fallback() or receive() fns.
66
+ /// @param admin - the address that will be the initial admin.
67
+ constructor (uint256 _defaultRollupChainId , address admin ) AccessControlDefaultAdminRules (1 days, admin) {
44
68
defaultRollupChainId = _defaultRollupChainId;
45
69
}
46
70
@@ -111,6 +135,23 @@ contract Passage {
111
135
emit ExitFilled (orders[i].rollupChainId, orders[i].token, orders[i].recipient, orders[i].amount);
112
136
}
113
137
}
138
+
139
+ /// @notice Allows the admin to withdraw tokens from the contract.
140
+ /// @dev Only the admin can call this function.
141
+ /// @param withdrawals - The withdrawals to process. See Withdrawal struct docs for details.
142
+ function withdraw (Withdrawal[] calldata withdrawals ) external onlyRole (DEFAULT_ADMIN_ROLE) {
143
+ for (uint256 i = 0 ; i < withdrawals.length ; i++ ) {
144
+ // transfer ether
145
+ if (withdrawals[i].ethAmount > 0 ) {
146
+ payable (withdrawals[i].recipient).transfer (withdrawals[i].ethAmount);
147
+ }
148
+ // transfer ERC20 tokens
149
+ for (uint256 j = 0 ; j < withdrawals[i].tokens.length ; j++ ) {
150
+ IERC20 (withdrawals[i].tokens[j]).transfer (withdrawals[i].recipient, withdrawals[i].tokenAmounts[j]);
151
+ }
152
+ emit Withdraw (withdrawals[i]);
153
+ }
154
+ }
114
155
}
115
156
116
157
/// @notice A contract deployed to the Rollup that allows users to atomically exchange tokens on the Rollup for tokens on the Host.
0 commit comments