@arbitrum/nitro-contracts 1.0.0-beta.5 → 1.0.0-beta.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. package/package.json +6 -2
  2. package/src/bridge/Bridge.sol +138 -32
  3. package/src/bridge/IBridge.sol +34 -14
  4. package/src/bridge/IDelayedMessageProvider.sol +15 -0
  5. package/src/bridge/IInbox.sol +8 -19
  6. package/src/bridge/IOutbox.sol +43 -23
  7. package/src/bridge/IOwnable.sol +10 -0
  8. package/src/bridge/ISequencerInbox.sol +30 -32
  9. package/src/bridge/Inbox.sol +133 -35
  10. package/src/bridge/Outbox.sol +145 -33
  11. package/src/bridge/SequencerInbox.sol +179 -60
  12. package/src/challenge/ChallengeLib.sol +0 -2
  13. package/src/challenge/ChallengeManager.sol +4 -8
  14. package/src/challenge/IChallengeManager.sol +1 -1
  15. package/src/libraries/Error.sol +113 -0
  16. package/src/libraries/IGasRefunder.sol +15 -14
  17. package/src/libraries/MerkleLib.sol +11 -2
  18. package/src/libraries/MessageTypes.sol +1 -0
  19. package/src/mocks/BridgeStub.sol +69 -21
  20. package/src/mocks/InboxStub.sol +2 -0
  21. package/src/mocks/SequencerInboxStub.sol +10 -8
  22. package/src/mocks/Simple.sol +8 -0
  23. package/src/node-interface/NodeInterface.sol +62 -4
  24. package/src/osp/IOneStepProver.sol +1 -2
  25. package/src/osp/OneStepProver0.sol +1 -87
  26. package/src/osp/OneStepProverHostIo.sol +5 -6
  27. package/src/osp/OneStepProverMath.sol +37 -27
  28. package/src/osp/OneStepProverMemory.sol +3 -4
  29. package/src/precompiles/ArbAggregator.sol +23 -33
  30. package/src/precompiles/ArbBLS.sol +1 -43
  31. package/src/precompiles/ArbGasInfo.sol +10 -19
  32. package/src/precompiles/ArbOwner.sol +21 -15
  33. package/src/precompiles/ArbRetryableTx.sol +10 -1
  34. package/src/precompiles/ArbSys.sol +4 -4
  35. package/src/precompiles/ArbosActs.sol +9 -2
  36. package/src/rollup/BridgeCreator.sol +23 -28
  37. package/src/rollup/IRollupCore.sol +3 -3
  38. package/src/rollup/{IRollupEventBridge.sol → IRollupEventInbox.sol} +2 -2
  39. package/src/rollup/IRollupLogic.sol +21 -18
  40. package/src/rollup/RollupAdminLogic.sol +72 -34
  41. package/src/rollup/RollupCore.sol +20 -9
  42. package/src/rollup/RollupCreator.sol +21 -11
  43. package/src/rollup/{RollupEventBridge.sol → RollupEventInbox.sol} +10 -10
  44. package/src/rollup/RollupLib.sol +21 -5
  45. package/src/rollup/RollupUserLogic.sol +10 -18
  46. package/src/rollup/ValidatorWallet.sol +125 -8
  47. package/src/rollup/ValidatorWalletCreator.sol +11 -6
  48. package/src/state/Deserialize.sol +3 -22
  49. package/src/state/GlobalState.sol +7 -0
  50. package/src/state/Instructions.sol +2 -10
  51. package/src/state/Machine.sol +0 -4
  52. package/src/state/ModuleMemory.sol +2 -1
  53. package/src/state/Value.sol +2 -3
  54. package/src/test-helpers/BridgeTester.sol +233 -0
  55. package/src/test-helpers/InterfaceCompatibilityTester.sol +11 -0
  56. package/src/test-helpers/OutboxWithoutOptTester.sol +214 -0
  57. package/src/test-helpers/RollupMock.sol +21 -0
  58. package/src/bridge/IMessageProvider.sol +0 -11
  59. package/src/state/PcStack.sol +0 -32
@@ -4,10 +4,30 @@
4
4
 
5
5
  pragma solidity ^0.8.0;
6
6
 
7
+ import {
8
+ AlreadyInit,
9
+ HadZeroInit,
10
+ NotOrigin,
11
+ DataTooLarge,
12
+ NotRollup,
13
+ DelayedBackwards,
14
+ DelayedTooFar,
15
+ ForceIncludeBlockTooSoon,
16
+ ForceIncludeTimeTooSoon,
17
+ IncorrectMessagePreimage,
18
+ NotBatchPoster,
19
+ BadSequencerNumber,
20
+ DataNotAuthenticated,
21
+ AlreadyValidDASKeyset,
22
+ NoSuchKeyset
23
+ } from "../libraries/Error.sol";
7
24
  import "./IBridge.sol";
25
+ import "./IInbox.sol";
8
26
  import "./ISequencerInbox.sol";
27
+ import "../rollup/IRollupLogic.sol";
9
28
  import "./Messages.sol";
10
29
 
30
+ import {L1MessageType_batchPostingReport} from "../libraries/MessageTypes.sol";
11
31
  import {GasRefundEnabled, IGasRefunder} from "../libraries/IGasRefunder.sol";
12
32
  import "../libraries/DelegateCallAware.sol";
13
33
  import {MAX_DATA_SIZE} from "../libraries/Constants.sol";
@@ -20,10 +40,9 @@ import {MAX_DATA_SIZE} from "../libraries/Constants.sol";
20
40
  * sequencer within a time limit they can be force included into the rollup inbox by anyone.
21
41
  */
22
42
  contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox {
23
- bytes32[] public override inboxAccs;
24
43
  uint256 public totalDelayedMessagesRead;
25
44
 
26
- IBridge public delayedBridge;
45
+ IBridge public bridge;
27
46
 
28
47
  /// @dev The size of the batch header
29
48
  uint256 public constant HEADER_LENGTH = 40;
@@ -31,19 +50,29 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox
31
50
  /// the sequencer inbox has authenticated the data. Currently not used.
32
51
  bytes1 public constant DATA_AUTHENTICATED_FLAG = 0x40;
33
52
 
34
- address public rollup;
53
+ IOwnable public rollup;
35
54
  mapping(address => bool) public isBatchPoster;
36
55
  ISequencerInbox.MaxTimeVariation public maxTimeVariation;
37
56
 
57
+ struct DasKeySetInfo {
58
+ bool isValidKeyset;
59
+ uint64 creationBlock;
60
+ }
61
+ mapping(bytes32 => DasKeySetInfo) public dasKeySetInfo;
62
+
63
+ modifier onlyRollupOwner() {
64
+ if (msg.sender != rollup.owner()) revert NotOwner(msg.sender, address(rollup));
65
+ _;
66
+ }
67
+
38
68
  function initialize(
39
- IBridge delayedBridge_,
40
- address rollup_,
69
+ IBridge bridge_,
41
70
  ISequencerInbox.MaxTimeVariation calldata maxTimeVariation_
42
71
  ) external onlyDelegated {
43
- if (delayedBridge != IBridge(address(0))) revert AlreadyInit();
44
- if (delayedBridge_ == IBridge(address(0))) revert HadZeroInit();
45
- delayedBridge = delayedBridge_;
46
- rollup = rollup_;
72
+ if (bridge != IBridge(address(0))) revert AlreadyInit();
73
+ if (bridge_ == IBridge(address(0))) revert HadZeroInit();
74
+ bridge = bridge_;
75
+ rollup = bridge_.rollup();
47
76
  maxTimeVariation = maxTimeVariation_;
48
77
  }
49
78
 
@@ -98,22 +127,24 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox
98
127
  // Verify that message hash represents the last message sequence of delayed message to be included
99
128
  bytes32 prevDelayedAcc = 0;
100
129
  if (_totalDelayedMessagesRead > 1) {
101
- prevDelayedAcc = delayedBridge.inboxAccs(_totalDelayedMessagesRead - 2);
130
+ prevDelayedAcc = bridge.delayedInboxAccs(_totalDelayedMessagesRead - 2);
102
131
  }
103
132
  if (
104
- delayedBridge.inboxAccs(_totalDelayedMessagesRead - 1) !=
133
+ bridge.delayedInboxAccs(_totalDelayedMessagesRead - 1) !=
105
134
  Messages.accumulateInboxMessage(prevDelayedAcc, messageHash)
106
135
  ) revert IncorrectMessagePreimage();
107
136
 
108
137
  (bytes32 dataHash, TimeBounds memory timeBounds) = formEmptyDataHash(
109
138
  _totalDelayedMessagesRead
110
139
  );
111
- (bytes32 beforeAcc, bytes32 delayedAcc, bytes32 afterAcc) = addSequencerL2BatchImpl(
112
- dataHash,
113
- _totalDelayedMessagesRead
114
- );
140
+ (
141
+ uint256 seqMessageIndex,
142
+ bytes32 beforeAcc,
143
+ bytes32 delayedAcc,
144
+ bytes32 afterAcc
145
+ ) = addSequencerL2BatchImpl(dataHash, _totalDelayedMessagesRead, 0);
115
146
  emit SequencerBatchDelivered(
116
- inboxAccs.length - 1,
147
+ seqMessageIndex,
117
148
  beforeAcc,
118
149
  afterAcc,
119
150
  delayedAcc,
@@ -128,21 +159,24 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox
128
159
  bytes calldata data,
129
160
  uint256 afterDelayedMessagesRead,
130
161
  IGasRefunder gasRefunder
131
- ) external refundsGasWithCalldata(gasRefunder, payable(msg.sender)) {
162
+ ) external refundsGas(gasRefunder) {
132
163
  // solhint-disable-next-line avoid-tx-origin
133
164
  if (msg.sender != tx.origin) revert NotOrigin();
134
165
  if (!isBatchPoster[msg.sender]) revert NotBatchPoster();
135
- if (inboxAccs.length != sequenceNumber) revert BadSequencerNumber();
136
166
  (bytes32 dataHash, TimeBounds memory timeBounds) = formDataHash(
137
167
  data,
138
168
  afterDelayedMessagesRead
139
169
  );
140
- (bytes32 beforeAcc, bytes32 delayedAcc, bytes32 afterAcc) = addSequencerL2BatchImpl(
141
- dataHash,
142
- afterDelayedMessagesRead
143
- );
170
+ (
171
+ uint256 seqMessageIndex,
172
+ bytes32 beforeAcc,
173
+ bytes32 delayedAcc,
174
+ bytes32 afterAcc
175
+ ) = addSequencerL2BatchImpl(dataHash, afterDelayedMessagesRead, data.length);
176
+ if (seqMessageIndex != sequenceNumber)
177
+ revert BadSequencerNumber(seqMessageIndex, sequenceNumber);
144
178
  emit SequencerBatchDelivered(
145
- inboxAccs.length - 1,
179
+ sequenceNumber,
146
180
  beforeAcc,
147
181
  afterAcc,
148
182
  delayedAcc,
@@ -157,18 +191,23 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox
157
191
  bytes calldata data,
158
192
  uint256 afterDelayedMessagesRead,
159
193
  IGasRefunder gasRefunder
160
- ) external override refundsGasNoCalldata(gasRefunder, payable(msg.sender)) {
161
- if (!isBatchPoster[msg.sender] && msg.sender != rollup) revert NotBatchPoster();
162
- if (inboxAccs.length != sequenceNumber) revert BadSequencerNumber();
194
+ ) external override refundsGas(gasRefunder) {
195
+ if (!isBatchPoster[msg.sender] && msg.sender != address(rollup)) revert NotBatchPoster();
163
196
 
164
197
  (bytes32 dataHash, TimeBounds memory timeBounds) = formDataHash(
165
198
  data,
166
199
  afterDelayedMessagesRead
167
200
  );
168
- (bytes32 beforeAcc, bytes32 delayedAcc, bytes32 afterAcc) = addSequencerL2BatchImpl(
169
- dataHash,
170
- afterDelayedMessagesRead
171
- );
201
+ // we set the calldata length posted to 0 here since the caller isn't the origin
202
+ // of the tx, so they might have not paid tx input cost for the calldata
203
+ (
204
+ uint256 seqMessageIndex,
205
+ bytes32 beforeAcc,
206
+ bytes32 delayedAcc,
207
+ bytes32 afterAcc
208
+ ) = addSequencerL2BatchImpl(dataHash, afterDelayedMessagesRead, 0);
209
+ if (seqMessageIndex != sequenceNumber)
210
+ revert BadSequencerNumber(seqMessageIndex, sequenceNumber);
172
211
  emit SequencerBatchDelivered(
173
212
  sequenceNumber,
174
213
  beforeAcc,
@@ -181,6 +220,22 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox
181
220
  emit SequencerBatchData(sequenceNumber, data);
182
221
  }
183
222
 
223
+ modifier validateBatchData(bytes calldata data) {
224
+ uint256 fullDataLen = HEADER_LENGTH + data.length;
225
+ if (fullDataLen > MAX_DATA_SIZE) revert DataTooLarge(fullDataLen, MAX_DATA_SIZE);
226
+ if (data.length > 0 && (data[0] & DATA_AUTHENTICATED_FLAG) == DATA_AUTHENTICATED_FLAG) {
227
+ revert DataNotAuthenticated();
228
+ }
229
+ // the first byte is used to identify the type of batch data
230
+ // das batches expect to have the type byte set, followed by the keyset (so they should have at least 33 bytes)
231
+ if (data.length >= 33 && data[0] & 0x80 != 0) {
232
+ // we skip the first byte, then read the next 32 bytes for the keyset
233
+ bytes32 dasKeysetHash = bytes32(data[1:33]);
234
+ if (!dasKeySetInfo[dasKeysetHash].isValidKeyset) revert NoSuchKeyset(dasKeysetHash);
235
+ }
236
+ _;
237
+ }
238
+
184
239
  function packHeader(uint256 afterDelayedMessagesRead)
185
240
  internal
186
241
  view
@@ -202,25 +257,12 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox
202
257
  function formDataHash(bytes calldata data, uint256 afterDelayedMessagesRead)
203
258
  internal
204
259
  view
260
+ validateBatchData(data)
205
261
  returns (bytes32, TimeBounds memory)
206
262
  {
207
- uint256 fullDataLen = HEADER_LENGTH + data.length;
208
- if (fullDataLen < HEADER_LENGTH) revert DataLengthOverflow();
209
- if (fullDataLen > MAX_DATA_SIZE) revert DataTooLarge(fullDataLen, MAX_DATA_SIZE);
210
- bytes memory fullData = new bytes(fullDataLen);
211
263
  (bytes memory header, TimeBounds memory timeBounds) = packHeader(afterDelayedMessagesRead);
212
-
213
- for (uint256 i = 0; i < HEADER_LENGTH; i++) {
214
- fullData[i] = header[i];
215
- }
216
- if (data.length > 0 && (data[0] & DATA_AUTHENTICATED_FLAG) == DATA_AUTHENTICATED_FLAG) {
217
- revert DataNotAuthenticated();
218
- }
219
- // copy data into fullData at offset of HEADER_LENGTH (the extra 32 offset is because solidity puts the array len first)
220
- assembly {
221
- calldatacopy(add(fullData, add(HEADER_LENGTH, 32)), data.offset, data.length)
222
- }
223
- return (keccak256(fullData), timeBounds);
264
+ bytes32 dataHash = keccak256(bytes.concat(header, data));
265
+ return (dataHash, timeBounds);
224
266
  }
225
267
 
226
268
  function formEmptyDataHash(uint256 afterDelayedMessagesRead)
@@ -232,43 +274,120 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox
232
274
  return (keccak256(header), timeBounds);
233
275
  }
234
276
 
235
- function addSequencerL2BatchImpl(bytes32 dataHash, uint256 afterDelayedMessagesRead)
277
+ function addSequencerL2BatchImpl(
278
+ bytes32 dataHash,
279
+ uint256 afterDelayedMessagesRead,
280
+ uint256 calldataLengthPosted
281
+ )
236
282
  internal
237
283
  returns (
284
+ uint256 seqMessageIndex,
238
285
  bytes32 beforeAcc,
239
286
  bytes32 delayedAcc,
240
287
  bytes32 acc
241
288
  )
242
289
  {
243
290
  if (afterDelayedMessagesRead < totalDelayedMessagesRead) revert DelayedBackwards();
244
- if (afterDelayedMessagesRead > delayedBridge.messageCount()) revert DelayedTooFar();
291
+ if (afterDelayedMessagesRead > bridge.delayedMessageCount()) revert DelayedTooFar();
245
292
 
246
- if (inboxAccs.length > 0) {
247
- beforeAcc = inboxAccs[inboxAccs.length - 1];
248
- }
249
- if (afterDelayedMessagesRead > 0) {
250
- delayedAcc = delayedBridge.inboxAccs(afterDelayedMessagesRead - 1);
251
- }
293
+ (seqMessageIndex, beforeAcc, delayedAcc, acc) = bridge.enqueueSequencerMessage(
294
+ dataHash,
295
+ afterDelayedMessagesRead
296
+ );
252
297
 
253
- acc = keccak256(abi.encodePacked(beforeAcc, dataHash, delayedAcc));
254
- inboxAccs.push(acc);
255
298
  totalDelayedMessagesRead = afterDelayedMessagesRead;
299
+
300
+ if (calldataLengthPosted > 0) {
301
+ // this msg isn't included in the current sequencer batch, but instead added to
302
+ // the delayed messages queue that is yet to be included
303
+ address batchPoster = msg.sender;
304
+ bytes memory spendingReportMsg = abi.encodePacked(
305
+ block.timestamp,
306
+ batchPoster,
307
+ dataHash,
308
+ seqMessageIndex,
309
+ block.basefee
310
+ );
311
+ uint256 msgNum = bridge.submitBatchSpendingReport(
312
+ batchPoster,
313
+ keccak256(spendingReportMsg)
314
+ );
315
+ // this is the same event used by Inbox.sol after including a message to the delayed message accumulator
316
+ emit InboxMessageDelivered(msgNum, spendingReportMsg);
317
+ }
318
+ }
319
+
320
+ function inboxAccs(uint256 index) external view override returns (bytes32) {
321
+ return bridge.sequencerInboxAccs(index);
256
322
  }
257
323
 
258
324
  function batchCount() external view override returns (uint256) {
259
- return inboxAccs.length;
325
+ return bridge.sequencerMessageCount();
260
326
  }
261
327
 
328
+ /**
329
+ * @notice Set max delay for sequencer inbox
330
+ * @param maxTimeVariation_ the maximum time variation parameters
331
+ */
262
332
  function setMaxTimeVariation(ISequencerInbox.MaxTimeVariation memory maxTimeVariation_)
263
333
  external
264
334
  override
335
+ onlyRollupOwner
265
336
  {
266
- if (msg.sender != rollup) revert NotRollup(msg.sender, rollup);
267
337
  maxTimeVariation = maxTimeVariation_;
338
+ emit OwnerFunctionCalled(0);
268
339
  }
269
340
 
270
- function setIsBatchPoster(address addr, bool isBatchPoster_) external override {
271
- if (msg.sender != rollup) revert NotRollup(msg.sender, rollup);
341
+ /**
342
+ * @notice Updates whether an address is authorized to be a batch poster at the sequencer inbox
343
+ * @param addr the address
344
+ * @param isBatchPoster_ if the specified address should be authorized as a batch poster
345
+ */
346
+ function setIsBatchPoster(address addr, bool isBatchPoster_) external override onlyRollupOwner {
272
347
  isBatchPoster[addr] = isBatchPoster_;
348
+ emit OwnerFunctionCalled(1);
349
+ }
350
+
351
+ /**
352
+ * @notice Makes Data Availability Service keyset valid
353
+ * @param keysetBytes bytes of the serialized keyset
354
+ */
355
+ function setValidKeyset(bytes calldata keysetBytes) external override onlyRollupOwner {
356
+ uint256 ksWord = uint256(keccak256(bytes.concat(hex"fe", keccak256(keysetBytes))));
357
+ bytes32 ksHash = bytes32(ksWord ^ (1 << 255));
358
+ require(keysetBytes.length < 64 * 1024, "keyset is too large");
359
+
360
+ if (dasKeySetInfo[ksHash].isValidKeyset) revert AlreadyValidDASKeyset(ksHash);
361
+ dasKeySetInfo[ksHash] = DasKeySetInfo({
362
+ isValidKeyset: true,
363
+ creationBlock: uint64(block.number)
364
+ });
365
+ emit SetValidKeyset(ksHash, keysetBytes);
366
+ emit OwnerFunctionCalled(2);
367
+ }
368
+
369
+ /**
370
+ * @notice Invalidates a Data Availability Service keyset
371
+ * @param ksHash hash of the keyset
372
+ */
373
+ function invalidateKeysetHash(bytes32 ksHash) external override onlyRollupOwner {
374
+ if (!dasKeySetInfo[ksHash].isValidKeyset) revert NoSuchKeyset(ksHash);
375
+ // we don't delete the block creation value since its used to fetch the SetValidKeyset
376
+ // event efficiently. The event provides the hash preimage of the key.
377
+ // this is still needed when syncing the chain after a keyset is invalidated.
378
+ dasKeySetInfo[ksHash].isValidKeyset = false;
379
+ emit InvalidateKeyset(ksHash);
380
+ emit OwnerFunctionCalled(3);
381
+ }
382
+
383
+ function isValidKeysetHash(bytes32 ksHash) external view returns (bool) {
384
+ return dasKeySetInfo[ksHash].isValidKeyset;
385
+ }
386
+
387
+ /// @notice the creation block is intended to still be available after a keyset is deleted
388
+ function getKeysetCreationBlock(bytes32 ksHash) external view returns (uint256) {
389
+ DasKeySetInfo memory ksInfo = dasKeySetInfo[ksHash];
390
+ if (ksInfo.creationBlock == 0) revert NoSuchKeyset(ksHash);
391
+ return uint256(ksInfo.creationBlock);
273
392
  }
274
393
  }
@@ -61,14 +61,12 @@ library ChallengeLib {
61
61
  ValueArray memory valuesArray = ValueArray({inner: startingValues});
62
62
  ValueStack memory values = ValueStack({proved: valuesArray, remainingHash: 0});
63
63
  ValueStack memory internalStack;
64
- PcStack memory blocks;
65
64
  StackFrameWindow memory frameStack;
66
65
 
67
66
  Machine memory mach = Machine({
68
67
  status: MachineStatus.RUNNING,
69
68
  valueStack: values,
70
69
  internalStack: internalStack,
71
- blockStack: blocks,
72
70
  frameStack: frameStack,
73
71
  globalStateHash: globalStateHash,
74
72
  moduleIdx: 0,
@@ -33,7 +33,7 @@ contract ChallengeManager is DelegateCallAware, IChallengeManager {
33
33
  IChallengeResultReceiver public resultReceiver;
34
34
 
35
35
  ISequencerInbox public sequencerInbox;
36
- IBridge public delayedBridge;
36
+ IBridge public bridge;
37
37
  IOneStepProofEntry public osp;
38
38
 
39
39
  function challengeInfo(uint64 challengeIndex)
@@ -99,14 +99,14 @@ contract ChallengeManager is DelegateCallAware, IChallengeManager {
99
99
  function initialize(
100
100
  IChallengeResultReceiver resultReceiver_,
101
101
  ISequencerInbox sequencerInbox_,
102
- IBridge delayedBridge_,
102
+ IBridge bridge_,
103
103
  IOneStepProofEntry osp_
104
104
  ) external override onlyDelegated {
105
105
  require(address(resultReceiver) == address(0), "ALREADY_INIT");
106
106
  require(address(resultReceiver_) != address(0), "NO_RESULT_RECEIVER");
107
107
  resultReceiver = resultReceiver_;
108
108
  sequencerInbox = sequencerInbox_;
109
- delayedBridge = delayedBridge_;
109
+ bridge = bridge_;
110
110
  osp = osp_;
111
111
  }
112
112
 
@@ -254,11 +254,7 @@ contract ChallengeManager is DelegateCallAware, IChallengeManager {
254
254
  }
255
255
 
256
256
  bytes32 afterHash = osp.proveOneStep(
257
- ExecutionContext({
258
- maxInboxMessagesRead: challenge.maxInboxMessages,
259
- sequencerInbox: sequencerInbox,
260
- delayedBridge: delayedBridge
261
- }),
257
+ ExecutionContext({maxInboxMessagesRead: challenge.maxInboxMessages, bridge: bridge}),
262
258
  challengeStart,
263
259
  selection.oldSegments[selection.challengePosition],
264
260
  proof
@@ -43,7 +43,7 @@ interface IChallengeManager {
43
43
  function initialize(
44
44
  IChallengeResultReceiver resultReceiver_,
45
45
  ISequencerInbox sequencerInbox_,
46
- IBridge delayedBridge_,
46
+ IBridge bridge_,
47
47
  IOneStepProofEntry osp_
48
48
  ) external;
49
49
 
@@ -36,3 +36,116 @@ error NotContract(address addr);
36
36
  /// @param actualLength The length of the merkle proof provided
37
37
  /// @param maxProofLength The max length a merkle proof can have
38
38
  error MerkleProofTooLong(uint256 actualLength, uint256 maxProofLength);
39
+
40
+ /// @dev Thrown when an un-authorized address tries to access an admin function
41
+ /// @param sender The un-authorized sender
42
+ /// @param rollup The rollup, which would be authorized
43
+ /// @param owner The rollup's owner, which would be authorized
44
+ error NotRollupOrOwner(address sender, address rollup, address owner);
45
+
46
+ // Bridge Errors
47
+
48
+ /// @dev Thrown when an un-authorized address tries to access an only-inbox function
49
+ /// @param sender The un-authorized sender
50
+ error NotDelayedInbox(address sender);
51
+
52
+ /// @dev Thrown when an un-authorized address tries to access an only-sequencer-inbox function
53
+ /// @param sender The un-authorized sender
54
+ error NotSequencerInbox(address sender);
55
+
56
+ /// @dev Thrown when an un-authorized address tries to access an only-outbox function
57
+ /// @param sender The un-authorized sender
58
+ error NotOutbox(address sender);
59
+
60
+ /// @dev the provided outbox address isn't valid
61
+ /// @param outbox address of outbox being set
62
+ error InvalidOutboxSet(address outbox);
63
+
64
+ // Inbox Errors
65
+
66
+ /// @dev The contract is paused, so cannot be paused
67
+ error AlreadyPaused();
68
+
69
+ /// @dev The contract is unpaused, so cannot be unpaused
70
+ error AlreadyUnpaused();
71
+
72
+ /// @dev The contract is paused
73
+ error Paused();
74
+
75
+ /// @dev msg.value sent to the inbox isn't high enough
76
+ error InsufficientValue(uint256 expected, uint256 actual);
77
+
78
+ /// @dev submission cost provided isn't enough to create retryable ticket
79
+ error InsufficientSubmissionCost(uint256 expected, uint256 actual);
80
+
81
+ /// @dev address not allowed to interact with the given contract
82
+ error NotAllowedOrigin(address origin);
83
+
84
+ /// @dev used to convey retryable tx data in eth calls without requiring a tx trace
85
+ /// this follows a pattern similar to EIP-3668 where reverts surface call information
86
+ error RetryableData(
87
+ address from,
88
+ address to,
89
+ uint256 l2CallValue,
90
+ uint256 deposit,
91
+ uint256 maxSubmissionCost,
92
+ address excessFeeRefundAddress,
93
+ address callValueRefundAddress,
94
+ uint256 gasLimit,
95
+ uint256 maxFeePerGas,
96
+ bytes data
97
+ );
98
+
99
+ // Outbox Errors
100
+
101
+ /// @dev The provided proof was too long
102
+ /// @param proofLength The length of the too-long proof
103
+ error ProofTooLong(uint256 proofLength);
104
+
105
+ /// @dev The output index was greater than the maximum
106
+ /// @param index The output index
107
+ /// @param maxIndex The max the index could be
108
+ error PathNotMinimal(uint256 index, uint256 maxIndex);
109
+
110
+ /// @dev The calculated root does not exist
111
+ /// @param root The calculated root
112
+ error UnknownRoot(bytes32 root);
113
+
114
+ /// @dev The record has already been spent
115
+ /// @param index The index of the spent record
116
+ error AlreadySpent(uint256 index);
117
+
118
+ /// @dev A call to the bridge failed with no return data
119
+ error BridgeCallFailed();
120
+
121
+ // Sequencer Inbox Errors
122
+
123
+ /// @dev Thrown when someone attempts to read fewer messages than have already been read
124
+ error DelayedBackwards();
125
+
126
+ /// @dev Thrown when someone attempts to read more messages than exist
127
+ error DelayedTooFar();
128
+
129
+ /// @dev Force include can only read messages more blocks old than the delay period
130
+ error ForceIncludeBlockTooSoon();
131
+
132
+ /// @dev Force include can only read messages more seconds old than the delay period
133
+ error ForceIncludeTimeTooSoon();
134
+
135
+ /// @dev The message provided did not match the hash in the delayed inbox
136
+ error IncorrectMessagePreimage();
137
+
138
+ /// @dev This can only be called by the batch poster
139
+ error NotBatchPoster();
140
+
141
+ /// @dev The sequence number provided to this message was inconsistent with the number of batches already included
142
+ error BadSequencerNumber(uint256 stored, uint256 received);
143
+
144
+ /// @dev The batch data has the inbox authenticated bit set, but the batch data was not authenticated by the inbox
145
+ error DataNotAuthenticated();
146
+
147
+ /// @dev Tried to create an already valid Data Availability Service keyset
148
+ error AlreadyValidDASKeyset(bytes32);
149
+
150
+ /// @dev Tried to use or invalidate an already invalid Data Availability Service keyset
151
+ error NoSuchKeyset(bytes32);
@@ -2,7 +2,8 @@
2
2
  // For license information, see https://github.com/nitro/blob/master/LICENSE
3
3
  // SPDX-License-Identifier: BUSL-1.1
4
4
 
5
- pragma solidity >=0.6.11 <0.9.0;
5
+ // solhint-disable-next-line compiler-version
6
+ pragma solidity >=0.6.9 <0.9.0;
6
7
 
7
8
  interface IGasRefunder {
8
9
  function onGasSpent(
@@ -13,23 +14,23 @@ interface IGasRefunder {
13
14
  }
14
15
 
15
16
  abstract contract GasRefundEnabled {
16
- modifier refundsGasWithCalldata(IGasRefunder gasRefunder, address payable spender) {
17
+ /// @dev this refunds the sender for execution costs of the tx
18
+ /// calldata costs are only refunded if `msg.sender == tx.origin` to guarantee the value refunded relates to charging
19
+ /// for the `tx.input`. this avoids a possible attack where you generate large calldata from a contract and get over-refunded
20
+ modifier refundsGas(IGasRefunder gasRefunder) {
17
21
  uint256 startGasLeft = gasleft();
18
22
  _;
19
23
  if (address(gasRefunder) != address(0)) {
20
- uint256 calldataSize;
21
- assembly {
22
- calldataSize := calldatasize()
24
+ uint256 calldataSize = 0;
25
+ // if triggered in a contract call, the spender may be overrefunded by appending dummy data to the call
26
+ // so we check if it is a top level call, which would mean the sender paid calldata as part of tx.input
27
+ // solhint-disable-next-line avoid-tx-origin
28
+ if (msg.sender == tx.origin) {
29
+ assembly {
30
+ calldataSize := calldatasize()
31
+ }
23
32
  }
24
- gasRefunder.onGasSpent(spender, startGasLeft - gasleft(), calldataSize);
25
- }
26
- }
27
-
28
- modifier refundsGasNoCalldata(IGasRefunder gasRefunder, address payable spender) {
29
- uint256 startGasLeft = gasleft();
30
- _;
31
- if (address(gasRefunder) != address(0)) {
32
- gasRefunder.onGasSpent(spender, startGasLeft - gasleft(), 0);
33
+ gasRefunder.onGasSpent(payable(msg.sender), startGasLeft - gasleft(), calldataSize);
33
34
  }
34
35
  }
35
36
  }
@@ -34,10 +34,19 @@ library MerkleLib {
34
34
  if (proofItems > 256) revert MerkleProofTooLong(proofItems, 256);
35
35
  bytes32 h = item;
36
36
  for (uint256 i = 0; i < proofItems; i++) {
37
+ bytes32 node = nodes[i];
37
38
  if (route % 2 == 0) {
38
- h = keccak256(abi.encodePacked(h, nodes[i]));
39
+ assembly {
40
+ mstore(0x00, h)
41
+ mstore(0x20, node)
42
+ h := keccak256(0x00, 0x40)
43
+ }
39
44
  } else {
40
- h = keccak256(abi.encodePacked(nodes[i], h));
45
+ assembly {
46
+ mstore(0x00, node)
47
+ mstore(0x20, h)
48
+ h := keccak256(0x00, 0x40)
49
+ }
41
50
  }
42
51
  route /= 2;
43
52
  }
@@ -8,6 +8,7 @@ uint8 constant L2_MSG = 3;
8
8
  uint8 constant L1MessageType_L2FundedByL1 = 7;
9
9
  uint8 constant L1MessageType_submitRetryableTx = 9;
10
10
  uint8 constant L1MessageType_ethDeposit = 12;
11
+ uint8 constant L1MessageType_batchPostingReport = 13;
11
12
  uint8 constant L2MessageType_unsignedEOATx = 0;
12
13
  uint8 constant L2MessageType_unsignedContractTx = 1;
13
14