forked from scroll-tech/scroll
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathL2GatewayRouter.sol
207 lines (169 loc) · 6.61 KB
/
L2GatewayRouter.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
// SPDX-License-Identifier: MIT
pragma solidity =0.8.24;
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import {IL2GatewayRouter} from "./IL2GatewayRouter.sol";
import {IL2ETHGateway} from "./IL2ETHGateway.sol";
import {IL2ERC20Gateway} from "./IL2ERC20Gateway.sol";
/// @title L2GatewayRouter
/// @notice The `L2GatewayRouter` is the main entry for withdrawing Ether and ERC20 tokens.
/// All deposited tokens are routed to corresponding gateways.
/// @dev One can also use this contract to query L1/L2 token address mapping.
/// In the future, ERC-721 and ERC-1155 tokens will be added to the router too.
contract L2GatewayRouter is OwnableUpgradeable, IL2GatewayRouter {
/*************
* Variables *
*************/
/// @notice The address of L2ETHGateway.
address public ethGateway;
/// @notice The addess of default L2 ERC20 gateway, normally the L2StandardERC20Gateway contract.
address public defaultERC20Gateway;
/// @notice Mapping from L2 ERC20 token address to corresponding L2ERC20Gateway.
// solhint-disable-next-line var-name-mixedcase
mapping(address => address) public ERC20Gateway;
/***************
* Constructor *
***************/
constructor() {
_disableInitializers();
}
function initialize(address _ethGateway, address _defaultERC20Gateway) external initializer {
OwnableUpgradeable.__Ownable_init();
// it can be zero during initialization
if (_defaultERC20Gateway != address(0)) {
defaultERC20Gateway = _defaultERC20Gateway;
emit SetDefaultERC20Gateway(address(0), _defaultERC20Gateway);
}
// it can be zero during initialization
if (_ethGateway != address(0)) {
ethGateway = _ethGateway;
emit SetETHGateway(address(0), _ethGateway);
}
}
/*************************
* Public View Functions *
*************************/
/// @inheritdoc IL2ERC20Gateway
function getL2ERC20Address(address) external pure override returns (address) {
revert("unsupported");
}
/// @inheritdoc IL2ERC20Gateway
function getL1ERC20Address(address _l2Address) external view override returns (address) {
address _gateway = getERC20Gateway(_l2Address);
if (_gateway == address(0)) {
return address(0);
}
return IL2ERC20Gateway(_gateway).getL1ERC20Address(_l2Address);
}
/// @notice Return the corresponding gateway address for given token address.
/// @param _token The address of token to query.
function getERC20Gateway(address _token) public view returns (address) {
address _gateway = ERC20Gateway[_token];
if (_gateway == address(0)) {
_gateway = defaultERC20Gateway;
}
return _gateway;
}
/*****************************
* Public Mutating Functions *
*****************************/
/// @inheritdoc IL2ERC20Gateway
function withdrawERC20(
address _token,
uint256 _amount,
uint256 _gasLimit
) external payable override {
withdrawERC20AndCall(_token, _msgSender(), _amount, new bytes(0), _gasLimit);
}
/// @inheritdoc IL2ERC20Gateway
function withdrawERC20(
address _token,
address _to,
uint256 _amount,
uint256 _gasLimit
) external payable override {
withdrawERC20AndCall(_token, _to, _amount, new bytes(0), _gasLimit);
}
/// @inheritdoc IL2ERC20Gateway
function withdrawERC20AndCall(
address _token,
address _to,
uint256 _amount,
bytes memory _data,
uint256 _gasLimit
) public payable override {
address _gateway = getERC20Gateway(_token);
require(_gateway != address(0), "no gateway available");
// encode msg.sender with _data
bytes memory _routerData = abi.encode(_msgSender(), _data);
IL2ERC20Gateway(_gateway).withdrawERC20AndCall{value: msg.value}(_token, _to, _amount, _routerData, _gasLimit);
}
/// @inheritdoc IL2ETHGateway
function withdrawETH(uint256 _amount, uint256 _gasLimit) external payable override {
withdrawETHAndCall(_msgSender(), _amount, new bytes(0), _gasLimit);
}
/// @inheritdoc IL2ETHGateway
function withdrawETH(
address _to,
uint256 _amount,
uint256 _gasLimit
) external payable override {
withdrawETHAndCall(_to, _amount, new bytes(0), _gasLimit);
}
/// @inheritdoc IL2ETHGateway
function withdrawETHAndCall(
address _to,
uint256 _amount,
bytes memory _data,
uint256 _gasLimit
) public payable override {
address _gateway = ethGateway;
require(_gateway != address(0), "eth gateway available");
// encode msg.sender with _data
bytes memory _routerData = abi.encode(_msgSender(), _data);
IL2ETHGateway(_gateway).withdrawETHAndCall{value: msg.value}(_to, _amount, _routerData, _gasLimit);
}
/// @inheritdoc IL2ETHGateway
function finalizeDepositETH(
address,
address,
uint256,
bytes calldata
) external payable virtual override {
revert("should never be called");
}
/// @inheritdoc IL2ERC20Gateway
function finalizeDepositERC20(
address,
address,
address,
address,
uint256,
bytes calldata
) external payable virtual override {
revert("should never be called");
}
/************************
* Restricted Functions *
************************/
/// @inheritdoc IL2GatewayRouter
function setETHGateway(address _newEthGateway) external onlyOwner {
address _oldEthGateway = ethGateway;
ethGateway = _newEthGateway;
emit SetETHGateway(_oldEthGateway, _newEthGateway);
}
/// @inheritdoc IL2GatewayRouter
function setDefaultERC20Gateway(address _newDefaultERC20Gateway) external onlyOwner {
address _oldDefaultERC20Gateway = defaultERC20Gateway;
defaultERC20Gateway = _newDefaultERC20Gateway;
emit SetDefaultERC20Gateway(_oldDefaultERC20Gateway, _newDefaultERC20Gateway);
}
/// @inheritdoc IL2GatewayRouter
function setERC20Gateway(address[] memory _tokens, address[] memory _gateways) external onlyOwner {
require(_tokens.length == _gateways.length, "length mismatch");
for (uint256 i = 0; i < _tokens.length; i++) {
address _oldGateway = ERC20Gateway[_tokens[i]];
ERC20Gateway[_tokens[i]] = _gateways[i];
emit SetERC20Gateway(_tokens[i], _oldGateway, _gateways[i]);
}
}
}