@@ -3,10 +3,12 @@ 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 {
11
+ contract Passage is AccessControlDefaultAdminRules {
10
12
/// @notice The chainId of the default rollup chain.
11
13
uint256 immutable defaultRollupChainId;
12
14
@@ -25,6 +27,16 @@ 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
+ struct Withdrawal {
34
+ address recipient;
35
+ uint256 ethAmount;
36
+ address [] tokens;
37
+ uint256 [] tokenAmounts;
38
+ }
39
+
28
40
/// @notice Details of an exit order to be fulfilled by the Builder.
29
41
/// @param token - The address of the token to be transferred to the recipient.
30
42
/// If token is the zero address, the amount is native Ether.
@@ -40,7 +52,12 @@ contract Passage {
40
52
uint256 amount;
41
53
}
42
54
43
- constructor (uint256 _defaultRollupChainId ) {
55
+ /// @notice Initializes the Admin role.
56
+ /// @dev See `AccessControlDefaultAdminRules` for information on contract administration.
57
+ /// - Admin role can grant and revoke Sequencer roles.
58
+ /// - Admin role can be transferred via two-step process with a 1 day timelock.
59
+ /// @param admin - the address that will be the initial admin.
60
+ constructor (uint256 _defaultRollupChainId , address admin ) AccessControlDefaultAdminRules (1 days, admin) {
44
61
defaultRollupChainId = _defaultRollupChainId;
45
62
}
46
63
@@ -111,6 +128,22 @@ contract Passage {
111
128
emit ExitFilled (orders[i].rollupChainId, orders[i].token, orders[i].recipient, orders[i].amount);
112
129
}
113
130
}
131
+
132
+ /// @notice Allows the admin to withdraw tokens from the contract.
133
+ /// @dev Only the admin can call this function.
134
+ function withdraw (Withdrawal[] calldata withdrawals ) external onlyRole (DEFAULT_ADMIN_ROLE) {
135
+ for (uint256 i = 0 ; i < withdrawals.length ; i++ ) {
136
+ // transfer ether
137
+ if (withdrawals[i].ethAmount > 0 ) {
138
+ payable (withdrawals[i].recipient).transfer (withdrawals[i].ethAmount);
139
+ }
140
+ // transfer ERC20 tokens
141
+ for (uint256 j = 0 ; j < withdrawals[i].tokens.length ; j++ ) {
142
+ IERC20 (withdrawals[i].tokens[j]).transfer (withdrawals[i].recipient, withdrawals[i].tokenAmounts[j]);
143
+ }
144
+ emit Withdraw (withdrawals[i]);
145
+ }
146
+ }
114
147
}
115
148
116
149
/// @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