@@ -122,6 +122,65 @@ contract L2GraphTokenGateway is GraphTokenGateway, L2ArbitrumMessenger, Reentran
122
122
emit L1CounterpartAddressSet (_l1Counterpart);
123
123
}
124
124
125
+ /**
126
+ * @notice Burns L2 tokens and initiates a transfer to L1.
127
+ * The tokens will be received on L1 only after the wait period (7 days) is over,
128
+ * and will require an Outbox.executeTransaction to finalize.
129
+ * @dev no additional callhook data is allowed
130
+ * @param _l1Token L1 Address of GRT (needed for compatibility with Arbitrum Gateway Router)
131
+ * @param _to Recipient address on L1
132
+ * @param _amount Amount of tokens to burn
133
+ * @param _data Contains sender and additional data to send to L1
134
+ * @return ID of the withdraw tx
135
+ */
136
+ function outboundTransfer (
137
+ address _l1Token ,
138
+ address _to ,
139
+ uint256 _amount ,
140
+ bytes calldata _data
141
+ ) external returns (bytes memory ) {
142
+ return outboundTransfer (_l1Token, _to, _amount, 0 , 0 , _data);
143
+ }
144
+
145
+ /**
146
+ * @notice Receives token amount from L1 and mints the equivalent tokens to the receiving address
147
+ * @dev Only accepts transactions from the L1 GRT Gateway.
148
+ * The function is payable for ITokenGateway compatibility, but msg.value must be zero.
149
+ * Note that allowlisted senders (some protocol contracts) can include additional calldata
150
+ * for a callhook to be executed on the L2 side when the tokens are received. In this case, the L2 transaction
151
+ * can revert if the callhook reverts, potentially locking the tokens on the bridge if the callhook
152
+ * never succeeds. This requires extra care when adding contracts to the allowlist, but is necessary to ensure that
153
+ * the tickets can be retried in the case of a temporary failure, and to ensure the atomicity of callhooks
154
+ * with token transfers.
155
+ * @param _l1Token L1 Address of GRT
156
+ * @param _from Address of the sender on L1
157
+ * @param _to Recipient address on L2
158
+ * @param _amount Amount of tokens transferred
159
+ * @param _data Extra callhook data, only used when the sender is allowlisted
160
+ */
161
+ function finalizeInboundTransfer (
162
+ address _l1Token ,
163
+ address _from ,
164
+ address _to ,
165
+ uint256 _amount ,
166
+ bytes calldata _data
167
+ ) external payable override nonReentrant notPaused onlyL1Counterpart {
168
+ require (_l1Token == l1GRT, "TOKEN_NOT_GRT " );
169
+ require (msg .value == 0 , "INVALID_NONZERO_VALUE " );
170
+
171
+ L2GraphToken (calculateL2TokenAddress (l1GRT)).bridgeMint (_to, _amount);
172
+
173
+ if (_data.length > 0 ) {
174
+ bytes memory callhookData;
175
+ {
176
+ (, callhookData) = abi.decode (_data, (bytes , bytes ));
177
+ }
178
+ ICallhookReceiver (_to).onTokenTransfer (_from, _amount, callhookData);
179
+ }
180
+
181
+ emit DepositFinalized (_l1Token, _from, _to, _amount);
182
+ }
183
+
125
184
/**
126
185
* @notice Burns L2 tokens and initiates a transfer to L1.
127
186
* The tokens will be available on L1 only after the wait period (7 days) is over,
@@ -151,7 +210,7 @@ contract L2GraphTokenGateway is GraphTokenGateway, L2ArbitrumMessenger, Reentran
151
210
152
211
OutboundCalldata memory outboundCalldata;
153
212
154
- (outboundCalldata.from, outboundCalldata.extraData) = parseOutboundData (_data);
213
+ (outboundCalldata.from, outboundCalldata.extraData) = _parseOutboundData (_data);
155
214
require (outboundCalldata.extraData.length == 0 , "CALL_HOOK_DATA_NOT_ALLOWED " );
156
215
157
216
// from needs to approve this contract to burn the amount first
@@ -176,26 +235,6 @@ contract L2GraphTokenGateway is GraphTokenGateway, L2ArbitrumMessenger, Reentran
176
235
return abi.encode (id);
177
236
}
178
237
179
- /**
180
- * @notice Burns L2 tokens and initiates a transfer to L1.
181
- * The tokens will be received on L1 only after the wait period (7 days) is over,
182
- * and will require an Outbox.executeTransaction to finalize.
183
- * @dev no additional callhook data is allowed
184
- * @param _l1Token L1 Address of GRT (needed for compatibility with Arbitrum Gateway Router)
185
- * @param _to Recipient address on L1
186
- * @param _amount Amount of tokens to burn
187
- * @param _data Contains sender and additional data to send to L1
188
- * @return ID of the withdraw tx
189
- */
190
- function outboundTransfer (
191
- address _l1Token ,
192
- address _to ,
193
- uint256 _amount ,
194
- bytes calldata _data
195
- ) external returns (bytes memory ) {
196
- return outboundTransfer (_l1Token, _to, _amount, 0 , 0 , _data);
197
- }
198
-
199
238
/**
200
239
* @notice Calculate the L2 address of a bridged token
201
240
* @dev In our case, this would only work for GRT.
@@ -209,45 +248,6 @@ contract L2GraphTokenGateway is GraphTokenGateway, L2ArbitrumMessenger, Reentran
209
248
return address (graphToken ());
210
249
}
211
250
212
- /**
213
- * @notice Receives token amount from L1 and mints the equivalent tokens to the receiving address
214
- * @dev Only accepts transactions from the L1 GRT Gateway.
215
- * The function is payable for ITokenGateway compatibility, but msg.value must be zero.
216
- * Note that allowlisted senders (some protocol contracts) can include additional calldata
217
- * for a callhook to be executed on the L2 side when the tokens are received. In this case, the L2 transaction
218
- * can revert if the callhook reverts, potentially locking the tokens on the bridge if the callhook
219
- * never succeeds. This requires extra care when adding contracts to the allowlist, but is necessary to ensure that
220
- * the tickets can be retried in the case of a temporary failure, and to ensure the atomicity of callhooks
221
- * with token transfers.
222
- * @param _l1Token L1 Address of GRT
223
- * @param _from Address of the sender on L1
224
- * @param _to Recipient address on L2
225
- * @param _amount Amount of tokens transferred
226
- * @param _data Extra callhook data, only used when the sender is allowlisted
227
- */
228
- function finalizeInboundTransfer (
229
- address _l1Token ,
230
- address _from ,
231
- address _to ,
232
- uint256 _amount ,
233
- bytes calldata _data
234
- ) external payable override nonReentrant notPaused onlyL1Counterpart {
235
- require (_l1Token == l1GRT, "TOKEN_NOT_GRT " );
236
- require (msg .value == 0 , "INVALID_NONZERO_VALUE " );
237
-
238
- L2GraphToken (calculateL2TokenAddress (l1GRT)).bridgeMint (_to, _amount);
239
-
240
- if (_data.length > 0 ) {
241
- bytes memory callhookData;
242
- {
243
- (, callhookData) = abi.decode (_data, (bytes , bytes ));
244
- }
245
- ICallhookReceiver (_to).onTokenTransfer (_from, _amount, callhookData);
246
- }
247
-
248
- emit DepositFinalized (_l1Token, _from, _to, _amount);
249
- }
250
-
251
251
/**
252
252
* @notice Creates calldata required to send tx to L1
253
253
* @dev encodes the target function with its params which
@@ -277,14 +277,24 @@ contract L2GraphTokenGateway is GraphTokenGateway, L2ArbitrumMessenger, Reentran
277
277
);
278
278
}
279
279
280
+ /**
281
+ * @dev Runs state validation before unpausing, reverts if
282
+ * something is not set properly
283
+ */
284
+ function _checksBeforeUnpause () internal view override {
285
+ require (l2Router != address (0 ), "ROUTER_NOT_SET " );
286
+ require (l1Counterpart != address (0 ), "L1_COUNTERPART_NOT_SET " );
287
+ require (l1GRT != address (0 ), "L1GRT_NOT_SET " );
288
+ }
289
+
280
290
/**
281
291
* @notice Decodes calldata required for migration of tokens
282
292
* @dev extraData can be left empty
283
293
* @param _data Encoded callhook data
284
294
* @return Sender of the tx
285
295
* @return Any other data sent to L1
286
296
*/
287
- function parseOutboundData (bytes calldata _data ) private view returns (address , bytes memory ) {
297
+ function _parseOutboundData (bytes calldata _data ) private view returns (address , bytes memory ) {
288
298
address from;
289
299
bytes memory extraData;
290
300
if (msg .sender == l2Router) {
@@ -295,14 +305,4 @@ contract L2GraphTokenGateway is GraphTokenGateway, L2ArbitrumMessenger, Reentran
295
305
}
296
306
return (from, extraData);
297
307
}
298
-
299
- /**
300
- * @dev Runs state validation before unpausing, reverts if
301
- * something is not set properly
302
- */
303
- function _checksBeforeUnpause () internal view override {
304
- require (l2Router != address (0 ), "ROUTER_NOT_SET " );
305
- require (l1Counterpart != address (0 ), "L1_COUNTERPART_NOT_SET " );
306
- require (l1GRT != address (0 ), "L1GRT_NOT_SET " );
307
- }
308
308
}
0 commit comments