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

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.
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