@arbitrum/nitro-contracts 1.0.0-beta.8 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +10 -2
- package/src/bridge/Bridge.sol +39 -30
- package/src/bridge/IBridge.sol +56 -29
- package/src/bridge/IInbox.sol +130 -15
- package/src/bridge/IOutbox.sol +55 -7
- package/src/bridge/ISequencerInbox.sol +84 -7
- package/src/bridge/Inbox.sol +154 -92
- package/src/bridge/Outbox.sol +23 -47
- package/src/bridge/SequencerInbox.sol +132 -62
- package/src/challenge/ChallengeManager.sol +0 -9
- package/src/challenge/IChallengeManager.sol +0 -2
- package/src/libraries/AdminFallbackProxy.sol +4 -4
- package/src/libraries/Constants.sol +3 -0
- package/src/libraries/{SecondaryLogicUUPSUpgradeable.sol → DoubleLogicUUPSUpgradeable.sol} +2 -1
- package/src/libraries/Error.sol +12 -0
- package/src/libraries/IGasRefunder.sol +11 -5
- package/src/libraries/MerkleLib.sol +5 -3
- package/src/mocks/BridgeStub.sol +20 -1
- package/src/mocks/BridgeUnproxied.sol +17 -0
- package/src/mocks/InboxStub.sol +48 -3
- package/src/mocks/SequencerInboxStub.sol +13 -3
- package/src/mocks/Simple.sol +69 -0
- package/src/node-interface/NodeInterface.sol +35 -4
- package/src/precompiles/ArbGasInfo.sol +7 -4
- package/src/precompiles/ArbOwner.sol +9 -0
- package/src/precompiles/ArbOwnerPublic.sol +3 -0
- package/src/precompiles/ArbSys.sol +5 -2
- package/src/rollup/IRollupCore.sol +2 -0
- package/src/rollup/IRollupLogic.sol +10 -0
- package/src/rollup/RollupAdminLogic.sol +27 -3
- package/src/rollup/RollupCore.sol +3 -0
- package/src/rollup/RollupCreator.sol +3 -3
- package/src/rollup/RollupEventInbox.sol +3 -6
- package/src/{libraries/ArbitrumProxy.sol → rollup/RollupProxy.sol} +3 -3
- package/src/rollup/RollupUserLogic.sol +47 -10
- package/src/test-helpers/BridgeTester.sol +7 -1
- package/src/test-helpers/OutboxWithoutOptTester.sol +8 -8
@@ -8,6 +8,7 @@ pragma experimental ABIEncoderV2;
|
|
8
8
|
|
9
9
|
import "../libraries/IGasRefunder.sol";
|
10
10
|
import "./IDelayedMessageProvider.sol";
|
11
|
+
import "./IBridge.sol";
|
11
12
|
|
12
13
|
interface ISequencerInbox is IDelayedMessageProvider {
|
13
14
|
struct MaxTimeVariation {
|
@@ -51,33 +52,109 @@ interface ISequencerInbox is IDelayedMessageProvider {
|
|
51
52
|
/// @dev a keyset was invalidated
|
52
53
|
event InvalidateKeyset(bytes32 indexed keysetHash);
|
53
54
|
|
55
|
+
function totalDelayedMessagesRead() external view returns (uint256);
|
56
|
+
|
57
|
+
function bridge() external view returns (IBridge);
|
58
|
+
|
59
|
+
/// @dev The size of the batch header
|
60
|
+
// solhint-disable-next-line func-name-mixedcase
|
61
|
+
function HEADER_LENGTH() external view returns (uint256);
|
62
|
+
|
63
|
+
/// @dev If the first batch data byte after the header has this bit set,
|
64
|
+
/// the sequencer inbox has authenticated the data. Currently not used.
|
65
|
+
// solhint-disable-next-line func-name-mixedcase
|
66
|
+
function DATA_AUTHENTICATED_FLAG() external view returns (bytes1);
|
67
|
+
|
68
|
+
function rollup() external view returns (IOwnable);
|
69
|
+
|
70
|
+
function isBatchPoster(address) external view returns (bool);
|
71
|
+
|
72
|
+
struct DasKeySetInfo {
|
73
|
+
bool isValidKeyset;
|
74
|
+
uint64 creationBlock;
|
75
|
+
}
|
76
|
+
|
77
|
+
// https://github.com/ethereum/solidity/issues/11826
|
78
|
+
// function maxTimeVariation() external view returns (MaxTimeVariation calldata);
|
79
|
+
// function dasKeySetInfo(bytes32) external view returns (DasKeySetInfo calldata);
|
80
|
+
|
81
|
+
/// @notice Remove force inclusion delay after a L1 chainId fork
|
82
|
+
function removeDelayAfterFork() external;
|
83
|
+
|
84
|
+
/// @notice Force messages from the delayed inbox to be included in the chain
|
85
|
+
/// Callable by any address, but message can only be force-included after maxTimeVariation.delayBlocks and
|
86
|
+
/// maxTimeVariation.delaySeconds has elapsed. As part of normal behaviour the sequencer will include these
|
87
|
+
/// messages so it's only necessary to call this if the sequencer is down, or not including any delayed messages.
|
88
|
+
/// @param _totalDelayedMessagesRead The total number of messages to read up to
|
89
|
+
/// @param kind The kind of the last message to be included
|
90
|
+
/// @param l1BlockAndTime The l1 block and the l1 timestamp of the last message to be included
|
91
|
+
/// @param baseFeeL1 The l1 gas price of the last message to be included
|
92
|
+
/// @param sender The sender of the last message to be included
|
93
|
+
/// @param messageDataHash The messageDataHash of the last message to be included
|
94
|
+
function forceInclusion(
|
95
|
+
uint256 _totalDelayedMessagesRead,
|
96
|
+
uint8 kind,
|
97
|
+
uint64[2] calldata l1BlockAndTime,
|
98
|
+
uint256 baseFeeL1,
|
99
|
+
address sender,
|
100
|
+
bytes32 messageDataHash
|
101
|
+
) external;
|
102
|
+
|
54
103
|
function inboxAccs(uint256 index) external view returns (bytes32);
|
55
104
|
|
56
105
|
function batchCount() external view returns (uint256);
|
57
106
|
|
58
|
-
function
|
107
|
+
function isValidKeysetHash(bytes32 ksHash) external view returns (bool);
|
108
|
+
|
109
|
+
/// @notice the creation block is intended to still be available after a keyset is deleted
|
110
|
+
function getKeysetCreationBlock(bytes32 ksHash) external view returns (uint256);
|
111
|
+
|
112
|
+
// ---------- BatchPoster functions ----------
|
113
|
+
|
114
|
+
function addSequencerL2BatchFromOrigin(
|
59
115
|
uint256 sequenceNumber,
|
60
116
|
bytes calldata data,
|
61
117
|
uint256 afterDelayedMessagesRead,
|
62
118
|
IGasRefunder gasRefunder
|
63
119
|
) external;
|
64
120
|
|
65
|
-
|
121
|
+
function addSequencerL2Batch(
|
122
|
+
uint256 sequenceNumber,
|
123
|
+
bytes calldata data,
|
124
|
+
uint256 afterDelayedMessagesRead,
|
125
|
+
IGasRefunder gasRefunder,
|
126
|
+
uint256 prevMessageCount,
|
127
|
+
uint256 newMessageCount
|
128
|
+
) external;
|
129
|
+
|
130
|
+
// ---------- onlyRollupOrOwner functions ----------
|
66
131
|
|
67
132
|
/**
|
68
|
-
* @notice Set max
|
69
|
-
* @param
|
133
|
+
* @notice Set max delay for sequencer inbox
|
134
|
+
* @param maxTimeVariation_ the maximum time variation parameters
|
70
135
|
*/
|
71
|
-
function setMaxTimeVariation(MaxTimeVariation memory
|
136
|
+
function setMaxTimeVariation(MaxTimeVariation memory maxTimeVariation_) external;
|
72
137
|
|
73
138
|
/**
|
74
139
|
* @notice Updates whether an address is authorized to be a batch poster at the sequencer inbox
|
75
140
|
* @param addr the address
|
76
|
-
* @param
|
141
|
+
* @param isBatchPoster_ if the specified address should be authorized as a batch poster
|
77
142
|
*/
|
78
|
-
function setIsBatchPoster(address addr, bool
|
143
|
+
function setIsBatchPoster(address addr, bool isBatchPoster_) external;
|
79
144
|
|
145
|
+
/**
|
146
|
+
* @notice Makes Data Availability Service keyset valid
|
147
|
+
* @param keysetBytes bytes of the serialized keyset
|
148
|
+
*/
|
80
149
|
function setValidKeyset(bytes calldata keysetBytes) external;
|
81
150
|
|
151
|
+
/**
|
152
|
+
* @notice Invalidates a Data Availability Service keyset
|
153
|
+
* @param ksHash hash of the keyset
|
154
|
+
*/
|
82
155
|
function invalidateKeysetHash(bytes32 ksHash) external;
|
156
|
+
|
157
|
+
// ---------- initializer ----------
|
158
|
+
|
159
|
+
function initialize(IBridge bridge_, MaxTimeVariation calldata maxTimeVariation_) external;
|
83
160
|
}
|
package/src/bridge/Inbox.sol
CHANGED
@@ -15,7 +15,10 @@ import {
|
|
15
15
|
InsufficientSubmissionCost,
|
16
16
|
NotAllowedOrigin,
|
17
17
|
RetryableData,
|
18
|
-
NotRollupOrOwner
|
18
|
+
NotRollupOrOwner,
|
19
|
+
L1Forked,
|
20
|
+
NotForked,
|
21
|
+
GasLimitTooLarge
|
19
22
|
} from "../libraries/Error.sol";
|
20
23
|
import "./IInbox.sol";
|
21
24
|
import "./ISequencerInbox.sol";
|
@@ -33,6 +36,7 @@ import {
|
|
33
36
|
L2MessageType_unsignedContractTx
|
34
37
|
} from "../libraries/MessageTypes.sol";
|
35
38
|
import {MAX_DATA_SIZE} from "../libraries/Constants.sol";
|
39
|
+
import "../precompiles/ArbSys.sol";
|
36
40
|
|
37
41
|
import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
|
38
42
|
import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
|
@@ -43,7 +47,7 @@ import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
|
|
43
47
|
* to await inclusion in the SequencerInbox
|
44
48
|
*/
|
45
49
|
contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
|
46
|
-
IBridge public
|
50
|
+
IBridge public bridge;
|
47
51
|
ISequencerInbox public sequencerInbox;
|
48
52
|
|
49
53
|
/// ------------------------------------ allow list start ------------------------------------ ///
|
@@ -92,12 +96,18 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
|
|
92
96
|
_;
|
93
97
|
}
|
94
98
|
|
95
|
-
|
99
|
+
uint256 internal immutable deployTimeChainId = block.chainid;
|
100
|
+
|
101
|
+
function _chainIdChanged() internal view returns (bool) {
|
102
|
+
return deployTimeChainId != block.chainid;
|
103
|
+
}
|
104
|
+
|
105
|
+
/// @inheritdoc IInbox
|
96
106
|
function pause() external onlyRollupOrOwner {
|
97
107
|
_pause();
|
98
108
|
}
|
99
109
|
|
100
|
-
/// @
|
110
|
+
/// @inheritdoc IInbox
|
101
111
|
function unpause() external onlyRollupOrOwner {
|
102
112
|
_unpause();
|
103
113
|
}
|
@@ -107,37 +117,23 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
|
|
107
117
|
initializer
|
108
118
|
onlyDelegated
|
109
119
|
{
|
110
|
-
if (address(bridge) != address(0)) revert AlreadyInit();
|
111
120
|
bridge = _bridge;
|
112
121
|
sequencerInbox = _sequencerInbox;
|
113
122
|
allowListEnabled = false;
|
114
123
|
__Pausable_init();
|
115
124
|
}
|
116
125
|
|
117
|
-
/// @
|
118
|
-
|
119
|
-
function postUpgradeInit(IBridge _bridge) external onlyDelegated onlyProxyOwner {
|
120
|
-
uint8 slotsToWipe = 3;
|
121
|
-
for (uint8 i = 0; i < slotsToWipe; i++) {
|
122
|
-
assembly {
|
123
|
-
sstore(i, 0)
|
124
|
-
}
|
125
|
-
}
|
126
|
-
allowListEnabled = false;
|
127
|
-
bridge = _bridge;
|
128
|
-
}
|
126
|
+
/// @inheritdoc IInbox
|
127
|
+
function postUpgradeInit(IBridge) external onlyDelegated onlyProxyOwner {}
|
129
128
|
|
130
|
-
|
131
|
-
* @notice Send a generic L2 message to the chain
|
132
|
-
* @dev This method is an optimization to avoid having to emit the entirety of the messageData in a log. Instead validators are expected to be able to parse the data from the transaction's input
|
133
|
-
* @param messageData Data of the message being sent
|
134
|
-
*/
|
129
|
+
/// @inheritdoc IInbox
|
135
130
|
function sendL2MessageFromOrigin(bytes calldata messageData)
|
136
131
|
external
|
137
132
|
whenNotPaused
|
138
133
|
onlyAllowed
|
139
134
|
returns (uint256)
|
140
135
|
{
|
136
|
+
if (_chainIdChanged()) revert L1Forked();
|
141
137
|
// solhint-disable-next-line avoid-tx-origin
|
142
138
|
if (msg.sender != tx.origin) revert NotOrigin();
|
143
139
|
if (messageData.length > MAX_DATA_SIZE)
|
@@ -147,18 +143,14 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
|
|
147
143
|
return msgNum;
|
148
144
|
}
|
149
145
|
|
150
|
-
|
151
|
-
* @notice Send a generic L2 message to the chain
|
152
|
-
* @dev This method can be used to send any type of message that doesn't require L1 validation
|
153
|
-
* @param messageData Data of the message being sent
|
154
|
-
*/
|
146
|
+
/// @inheritdoc IInbox
|
155
147
|
function sendL2Message(bytes calldata messageData)
|
156
148
|
external
|
157
|
-
override
|
158
149
|
whenNotPaused
|
159
150
|
onlyAllowed
|
160
151
|
returns (uint256)
|
161
152
|
{
|
153
|
+
if (_chainIdChanged()) revert L1Forked();
|
162
154
|
return _deliverMessage(L2_MSG, msg.sender, messageData);
|
163
155
|
}
|
164
156
|
|
@@ -168,7 +160,11 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
|
|
168
160
|
uint256 nonce,
|
169
161
|
address to,
|
170
162
|
bytes calldata data
|
171
|
-
) external payable
|
163
|
+
) external payable whenNotPaused onlyAllowed returns (uint256) {
|
164
|
+
// arbos will discard unsigned tx with gas limit too large
|
165
|
+
if (gasLimit > type(uint64).max) {
|
166
|
+
revert GasLimitTooLarge();
|
167
|
+
}
|
172
168
|
return
|
173
169
|
_deliverMessage(
|
174
170
|
L1MessageType_L2FundedByL1,
|
@@ -190,7 +186,11 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
|
|
190
186
|
uint256 maxFeePerGas,
|
191
187
|
address to,
|
192
188
|
bytes calldata data
|
193
|
-
) external payable
|
189
|
+
) external payable whenNotPaused onlyAllowed returns (uint256) {
|
190
|
+
// arbos will discard unsigned tx with gas limit too large
|
191
|
+
if (gasLimit > type(uint64).max) {
|
192
|
+
revert GasLimitTooLarge();
|
193
|
+
}
|
194
194
|
return
|
195
195
|
_deliverMessage(
|
196
196
|
L1MessageType_L2FundedByL1,
|
@@ -213,7 +213,11 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
|
|
213
213
|
address to,
|
214
214
|
uint256 value,
|
215
215
|
bytes calldata data
|
216
|
-
) external
|
216
|
+
) external whenNotPaused onlyAllowed returns (uint256) {
|
217
|
+
// arbos will discard unsigned tx with gas limit too large
|
218
|
+
if (gasLimit > type(uint64).max) {
|
219
|
+
revert GasLimitTooLarge();
|
220
|
+
}
|
217
221
|
return
|
218
222
|
_deliverMessage(
|
219
223
|
L2_MSG,
|
@@ -236,7 +240,11 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
|
|
236
240
|
address to,
|
237
241
|
uint256 value,
|
238
242
|
bytes calldata data
|
239
|
-
) external
|
243
|
+
) external whenNotPaused onlyAllowed returns (uint256) {
|
244
|
+
// arbos will discard unsigned tx with gas limit too large
|
245
|
+
if (gasLimit > type(uint64).max) {
|
246
|
+
revert GasLimitTooLarge();
|
247
|
+
}
|
240
248
|
return
|
241
249
|
_deliverMessage(
|
242
250
|
L2_MSG,
|
@@ -252,13 +260,104 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
|
|
252
260
|
);
|
253
261
|
}
|
254
262
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
263
|
+
/// @inheritdoc IInbox
|
264
|
+
function sendL1FundedUnsignedTransactionToFork(
|
265
|
+
uint256 gasLimit,
|
266
|
+
uint256 maxFeePerGas,
|
267
|
+
uint256 nonce,
|
268
|
+
address to,
|
269
|
+
bytes calldata data
|
270
|
+
) external payable whenNotPaused onlyAllowed returns (uint256) {
|
271
|
+
if (!_chainIdChanged()) revert NotForked();
|
272
|
+
// solhint-disable-next-line avoid-tx-origin
|
273
|
+
if (msg.sender != tx.origin) revert NotOrigin();
|
274
|
+
// arbos will discard unsigned tx with gas limit too large
|
275
|
+
if (gasLimit > type(uint64).max) {
|
276
|
+
revert GasLimitTooLarge();
|
277
|
+
}
|
278
|
+
return
|
279
|
+
_deliverMessage(
|
280
|
+
L1MessageType_L2FundedByL1,
|
281
|
+
// undoing sender alias here to cancel out the aliasing
|
282
|
+
AddressAliasHelper.undoL1ToL2Alias(msg.sender),
|
283
|
+
abi.encodePacked(
|
284
|
+
L2MessageType_unsignedEOATx,
|
285
|
+
gasLimit,
|
286
|
+
maxFeePerGas,
|
287
|
+
nonce,
|
288
|
+
uint256(uint160(to)),
|
289
|
+
msg.value,
|
290
|
+
data
|
291
|
+
)
|
292
|
+
);
|
293
|
+
}
|
294
|
+
|
295
|
+
/// @inheritdoc IInbox
|
296
|
+
function sendUnsignedTransactionToFork(
|
297
|
+
uint256 gasLimit,
|
298
|
+
uint256 maxFeePerGas,
|
299
|
+
uint256 nonce,
|
300
|
+
address to,
|
301
|
+
uint256 value,
|
302
|
+
bytes calldata data
|
303
|
+
) external whenNotPaused onlyAllowed returns (uint256) {
|
304
|
+
if (!_chainIdChanged()) revert NotForked();
|
305
|
+
// solhint-disable-next-line avoid-tx-origin
|
306
|
+
if (msg.sender != tx.origin) revert NotOrigin();
|
307
|
+
// arbos will discard unsigned tx with gas limit too large
|
308
|
+
if (gasLimit > type(uint64).max) {
|
309
|
+
revert GasLimitTooLarge();
|
310
|
+
}
|
311
|
+
return
|
312
|
+
_deliverMessage(
|
313
|
+
L2_MSG,
|
314
|
+
// undoing sender alias here to cancel out the aliasing
|
315
|
+
AddressAliasHelper.undoL1ToL2Alias(msg.sender),
|
316
|
+
abi.encodePacked(
|
317
|
+
L2MessageType_unsignedEOATx,
|
318
|
+
gasLimit,
|
319
|
+
maxFeePerGas,
|
320
|
+
nonce,
|
321
|
+
uint256(uint160(to)),
|
322
|
+
value,
|
323
|
+
data
|
324
|
+
)
|
325
|
+
);
|
326
|
+
}
|
327
|
+
|
328
|
+
/// @inheritdoc IInbox
|
329
|
+
function sendWithdrawEthToFork(
|
330
|
+
uint256 gasLimit,
|
331
|
+
uint256 maxFeePerGas,
|
332
|
+
uint256 nonce,
|
333
|
+
uint256 value,
|
334
|
+
address withdrawTo
|
335
|
+
) external whenNotPaused onlyAllowed returns (uint256) {
|
336
|
+
if (!_chainIdChanged()) revert NotForked();
|
337
|
+
// solhint-disable-next-line avoid-tx-origin
|
338
|
+
if (msg.sender != tx.origin) revert NotOrigin();
|
339
|
+
// arbos will discard unsigned tx with gas limit too large
|
340
|
+
if (gasLimit > type(uint64).max) {
|
341
|
+
revert GasLimitTooLarge();
|
342
|
+
}
|
343
|
+
return
|
344
|
+
_deliverMessage(
|
345
|
+
L2_MSG,
|
346
|
+
// undoing sender alias here to cancel out the aliasing
|
347
|
+
AddressAliasHelper.undoL1ToL2Alias(msg.sender),
|
348
|
+
abi.encodePacked(
|
349
|
+
L2MessageType_unsignedEOATx,
|
350
|
+
gasLimit,
|
351
|
+
maxFeePerGas,
|
352
|
+
nonce,
|
353
|
+
uint256(uint160(address(100))), // ArbSys address
|
354
|
+
value,
|
355
|
+
abi.encode(ArbSys.withdrawEth.selector, withdrawTo)
|
356
|
+
)
|
357
|
+
);
|
358
|
+
}
|
359
|
+
|
360
|
+
/// @inheritdoc IInbox
|
262
361
|
function calculateRetryableSubmissionFee(uint256 dataLength, uint256 baseFee)
|
263
362
|
public
|
264
363
|
view
|
@@ -268,20 +367,13 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
|
|
268
367
|
return (1400 + 6 * dataLength) * (baseFee == 0 ? block.basefee : baseFee);
|
269
368
|
}
|
270
369
|
|
271
|
-
/// @
|
272
|
-
|
273
|
-
/// Look into retryable tickets if you are interested in this functionality.
|
274
|
-
/// @dev this function should not be called inside contract constructors
|
275
|
-
function depositEth() public payable override whenNotPaused onlyAllowed returns (uint256) {
|
370
|
+
/// @inheritdoc IInbox
|
371
|
+
function depositEth() public payable whenNotPaused onlyAllowed returns (uint256) {
|
276
372
|
address dest = msg.sender;
|
277
373
|
|
278
374
|
// solhint-disable-next-line avoid-tx-origin
|
279
375
|
if (AddressUpgradeable.isContract(msg.sender) || tx.origin != msg.sender) {
|
280
376
|
// isContract check fails if this function is called during a contract's constructor.
|
281
|
-
// We don't adjust the address for calls coming from L1 contracts since their addresses get remapped
|
282
|
-
// If the caller is an EOA, we adjust the address.
|
283
|
-
// This is needed because unsigned messages to the L2 (such as retryables)
|
284
|
-
// have the L1 sender address mapped.
|
285
377
|
dest = AddressAliasHelper.applyL1ToL2Alias(msg.sender);
|
286
378
|
}
|
287
379
|
|
@@ -294,15 +386,7 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
|
|
294
386
|
}
|
295
387
|
|
296
388
|
/// @notice deprecated in favour of depositEth with no parameters
|
297
|
-
function depositEth(uint256)
|
298
|
-
external
|
299
|
-
payable
|
300
|
-
virtual
|
301
|
-
override
|
302
|
-
whenNotPaused
|
303
|
-
onlyAllowed
|
304
|
-
returns (uint256)
|
305
|
-
{
|
389
|
+
function depositEth(uint256) external payable whenNotPaused onlyAllowed returns (uint256) {
|
306
390
|
return depositEth();
|
307
391
|
}
|
308
392
|
|
@@ -318,7 +402,7 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
|
|
318
402
|
* @param gasLimit Max gas deducted from user's L2 balance to cover L2 execution. Should not be set to 1 (magic value used to trigger the RetryableData error)
|
319
403
|
* @param maxFeePerGas price bid for L2 execution. Should not be set to 1 (magic value used to trigger the RetryableData error)
|
320
404
|
* @param data ABI encoded data of L2 message
|
321
|
-
* @return unique
|
405
|
+
* @return unique message number of the retryable transaction
|
322
406
|
*/
|
323
407
|
function createRetryableTicketNoRefundAliasRewrite(
|
324
408
|
address to,
|
@@ -329,7 +413,8 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
|
|
329
413
|
uint256 gasLimit,
|
330
414
|
uint256 maxFeePerGas,
|
331
415
|
bytes calldata data
|
332
|
-
) external payable
|
416
|
+
) external payable whenNotPaused onlyAllowed returns (uint256) {
|
417
|
+
// gas limit is validated to be within uint64 in unsafeCreateRetryableTicket
|
333
418
|
return
|
334
419
|
unsafeCreateRetryableTicket(
|
335
420
|
to,
|
@@ -343,20 +428,7 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
|
|
343
428
|
);
|
344
429
|
}
|
345
430
|
|
346
|
-
|
347
|
-
* @notice Put a message in the L2 inbox that can be reexecuted for some fixed amount of time if it reverts
|
348
|
-
* @dev all msg.value will deposited to callValueRefundAddress on L2
|
349
|
-
* @dev Gas limit and maxFeePerGas should not be set to 1 as that is used to trigger the RetryableData error
|
350
|
-
* @param to destination L2 contract address
|
351
|
-
* @param l2CallValue call value for retryable L2 message
|
352
|
-
* @param maxSubmissionCost Max gas deducted from user's L2 balance to cover base submission fee
|
353
|
-
* @param excessFeeRefundAddress gasLimit x maxFeePerGas - execution cost gets credited here on L2 balance
|
354
|
-
* @param callValueRefundAddress l2Callvalue gets credited here on L2 if retryable txn times out or gets cancelled
|
355
|
-
* @param gasLimit Max gas deducted from user's L2 balance to cover L2 execution. Should not be set to 1 (magic value used to trigger the RetryableData error)
|
356
|
-
* @param maxFeePerGas price bid for L2 execution. Should not be set to 1 (magic value used to trigger the RetryableData error)
|
357
|
-
* @param data ABI encoded data of L2 message
|
358
|
-
* @return unique id for retryable transaction (keccak256(requestID, uint(0) )
|
359
|
-
*/
|
431
|
+
/// @inheritdoc IInbox
|
360
432
|
function createRetryableTicket(
|
361
433
|
address to,
|
362
434
|
uint256 l2CallValue,
|
@@ -366,7 +438,7 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
|
|
366
438
|
uint256 gasLimit,
|
367
439
|
uint256 maxFeePerGas,
|
368
440
|
bytes calldata data
|
369
|
-
) external payable
|
441
|
+
) external payable whenNotPaused onlyAllowed returns (uint256) {
|
370
442
|
// ensure the user's deposit alone will make submission succeed
|
371
443
|
if (msg.value < (maxSubmissionCost + l2CallValue + gasLimit * maxFeePerGas)) {
|
372
444
|
revert InsufficientValue(
|
@@ -386,6 +458,7 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
|
|
386
458
|
callValueRefundAddress = AddressAliasHelper.applyL1ToL2Alias(callValueRefundAddress);
|
387
459
|
}
|
388
460
|
|
461
|
+
// gas limit is validated to be within uint64 in unsafeCreateRetryableTicket
|
389
462
|
return
|
390
463
|
unsafeCreateRetryableTicket(
|
391
464
|
to,
|
@@ -399,23 +472,7 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
|
|
399
472
|
);
|
400
473
|
}
|
401
474
|
|
402
|
-
|
403
|
-
* @notice Put a message in the L2 inbox that can be reexecuted for some fixed amount of time if it reverts
|
404
|
-
* @dev Same as createRetryableTicket, but does not guarantee that submission will succeed by requiring the needed funds
|
405
|
-
* come from the deposit alone, rather than falling back on the user's L2 balance
|
406
|
-
* @dev Advanced usage only (does not rewrite aliases for excessFeeRefundAddress and callValueRefundAddress).
|
407
|
-
* createRetryableTicket method is the recommended standard.
|
408
|
-
* @dev Gas limit and maxFeePerGas should not be set to 1 as that is used to trigger the RetryableData error
|
409
|
-
* @param to destination L2 contract address
|
410
|
-
* @param l2CallValue call value for retryable L2 message
|
411
|
-
* @param maxSubmissionCost Max gas deducted from user's L2 balance to cover base submission fee
|
412
|
-
* @param excessFeeRefundAddress gasLimit x maxFeePerGas - execution cost gets credited here on L2 balance
|
413
|
-
* @param callValueRefundAddress l2Callvalue gets credited here on L2 if retryable txn times out or gets cancelled
|
414
|
-
* @param gasLimit Max gas deducted from user's L2 balance to cover L2 execution. Should not be set to 1 (magic value used to trigger the RetryableData error)
|
415
|
-
* @param maxFeePerGas price bid for L2 execution. Should not be set to 1 (magic value used to trigger the RetryableData error)
|
416
|
-
* @param data ABI encoded data of L2 message
|
417
|
-
* @return unique id for retryable transaction (keccak256(requestID, uint(0) )
|
418
|
-
*/
|
475
|
+
/// @inheritdoc IInbox
|
419
476
|
function unsafeCreateRetryableTicket(
|
420
477
|
address to,
|
421
478
|
uint256 l2CallValue,
|
@@ -425,7 +482,7 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
|
|
425
482
|
uint256 gasLimit,
|
426
483
|
uint256 maxFeePerGas,
|
427
484
|
bytes calldata data
|
428
|
-
) public payable
|
485
|
+
) public payable whenNotPaused onlyAllowed returns (uint256) {
|
429
486
|
// gas price and limit of 1 should never be a valid input, so instead they are used as
|
430
487
|
// magic values to trigger a revert in eth calls that surface data without requiring a tx trace
|
431
488
|
if (gasLimit == 1 || maxFeePerGas == 1)
|
@@ -442,6 +499,11 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
|
|
442
499
|
data
|
443
500
|
);
|
444
501
|
|
502
|
+
// arbos will discard retryable with gas limit too large
|
503
|
+
if (gasLimit > type(uint64).max) {
|
504
|
+
revert GasLimitTooLarge();
|
505
|
+
}
|
506
|
+
|
445
507
|
uint256 submissionFee = calculateRetryableSubmissionFee(data.length, block.basefee);
|
446
508
|
if (maxSubmissionCost < submissionFee)
|
447
509
|
revert InsufficientSubmissionCost(submissionFee, maxSubmissionCost);
|