@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
@@ -14,19 +14,28 @@ contract BridgeStub is IBridge {
14
14
  bool allowed;
15
15
  }
16
16
 
17
- mapping(address => InOutInfo) private allowedInboxesMap;
17
+ mapping(address => InOutInfo) private allowedDelayedInboxesMap;
18
18
  //mapping(address => InOutInfo) private allowedOutboxesMap;
19
19
 
20
- address[] public allowedInboxList;
20
+ address[] public allowedDelayedInboxList;
21
21
  address[] public allowedOutboxList;
22
22
 
23
23
  address public override activeOutbox;
24
24
 
25
25
  // Accumulator for delayed inbox; tail represents hash of the current state; each element represents the inclusion of a new message.
26
- bytes32[] public override inboxAccs;
26
+ bytes32[] public override delayedInboxAccs;
27
27
 
28
- function allowedInboxes(address inbox) external view override returns (bool) {
29
- return allowedInboxesMap[inbox].allowed;
28
+ bytes32[] public override sequencerInboxAccs;
29
+
30
+ address public sequencerInbox;
31
+
32
+ function setSequencerInbox(address _sequencerInbox) external override {
33
+ sequencerInbox = _sequencerInbox;
34
+ emit SequencerInboxUpdated(_sequencerInbox);
35
+ }
36
+
37
+ function allowedDelayedInboxes(address inbox) external view override returns (bool) {
38
+ return allowedDelayedInboxesMap[inbox].allowed;
30
39
  }
31
40
 
32
41
  function allowedOutboxes(address) external pure override returns (bool) {
@@ -38,9 +47,9 @@ contract BridgeStub is IBridge {
38
47
  address sender,
39
48
  bytes32 messageDataHash
40
49
  ) external payable override returns (uint256) {
41
- require(allowedInboxesMap[msg.sender].allowed, "NOT_FROM_INBOX");
50
+ require(allowedDelayedInboxesMap[msg.sender].allowed, "NOT_FROM_INBOX");
42
51
  return
43
- addMessageToAccumulator(
52
+ addMessageToDelayedAccumulator(
44
53
  kind,
45
54
  sender,
46
55
  block.number,
@@ -50,7 +59,34 @@ contract BridgeStub is IBridge {
50
59
  );
51
60
  }
52
61
 
53
- function addMessageToAccumulator(
62
+ function enqueueSequencerMessage(bytes32 dataHash, uint256 afterDelayedMessagesRead)
63
+ external
64
+ returns (
65
+ uint256 seqMessageIndex,
66
+ bytes32 beforeAcc,
67
+ bytes32 delayedAcc,
68
+ bytes32 acc
69
+ )
70
+ {
71
+ seqMessageIndex = sequencerInboxAccs.length;
72
+ if (sequencerInboxAccs.length > 0) {
73
+ beforeAcc = sequencerInboxAccs[sequencerInboxAccs.length - 1];
74
+ }
75
+ if (afterDelayedMessagesRead > 0) {
76
+ delayedAcc = delayedInboxAccs[afterDelayedMessagesRead - 1];
77
+ }
78
+ acc = keccak256(abi.encodePacked(beforeAcc, dataHash, delayedAcc));
79
+ sequencerInboxAccs.push(acc);
80
+ }
81
+
82
+ function submitBatchSpendingReport(address batchPoster, bytes32 dataHash)
83
+ external
84
+ returns (uint256)
85
+ {
86
+ // TODO: implement stub
87
+ }
88
+
89
+ function addMessageToDelayedAccumulator(
54
90
  uint8,
55
91
  address,
56
92
  uint256,
@@ -58,7 +94,7 @@ contract BridgeStub is IBridge {
58
94
  uint256,
59
95
  bytes32 messageDataHash
60
96
  ) internal returns (uint256) {
61
- uint256 count = inboxAccs.length;
97
+ uint256 count = delayedInboxAccs.length;
62
98
  bytes32 messageHash = Messages.messageHash(
63
99
  0,
64
100
  address(uint160(0)),
@@ -70,9 +106,9 @@ contract BridgeStub is IBridge {
70
106
  );
71
107
  bytes32 prevAcc = 0;
72
108
  if (count > 0) {
73
- prevAcc = inboxAccs[count - 1];
109
+ prevAcc = delayedInboxAccs[count - 1];
74
110
  }
75
- inboxAccs.push(Messages.accumulateInboxMessage(prevAcc, messageHash));
111
+ delayedInboxAccs.push(Messages.accumulateInboxMessage(prevAcc, messageHash));
76
112
  return count;
77
113
  }
78
114
 
@@ -84,21 +120,23 @@ contract BridgeStub is IBridge {
84
120
  revert("NOT_IMPLEMENTED");
85
121
  }
86
122
 
87
- function setInbox(address inbox, bool enabled) external override {
88
- InOutInfo storage info = allowedInboxesMap[inbox];
123
+ function setDelayedInbox(address inbox, bool enabled) external override {
124
+ InOutInfo storage info = allowedDelayedInboxesMap[inbox];
89
125
  bool alreadyEnabled = info.allowed;
90
126
  emit InboxToggle(inbox, enabled);
91
127
  if ((alreadyEnabled && enabled) || (!alreadyEnabled && !enabled)) {
92
128
  return;
93
129
  }
94
130
  if (enabled) {
95
- allowedInboxesMap[inbox] = InOutInfo(allowedInboxList.length, true);
96
- allowedInboxList.push(inbox);
131
+ allowedDelayedInboxesMap[inbox] = InOutInfo(allowedDelayedInboxList.length, true);
132
+ allowedDelayedInboxList.push(inbox);
97
133
  } else {
98
- allowedInboxList[info.index] = allowedInboxList[allowedInboxList.length - 1];
99
- allowedInboxesMap[allowedInboxList[info.index]].index = info.index;
100
- allowedInboxList.pop();
101
- delete allowedInboxesMap[inbox];
134
+ allowedDelayedInboxList[info.index] = allowedDelayedInboxList[
135
+ allowedDelayedInboxList.length - 1
136
+ ];
137
+ allowedDelayedInboxesMap[allowedDelayedInboxList[info.index]].index = info.index;
138
+ allowedDelayedInboxList.pop();
139
+ delete allowedDelayedInboxesMap[inbox];
102
140
  }
103
141
  }
104
142
 
@@ -109,7 +147,17 @@ contract BridgeStub is IBridge {
109
147
  revert("NOT_IMPLEMENTED");
110
148
  }
111
149
 
112
- function messageCount() external view override returns (uint256) {
113
- return inboxAccs.length;
150
+ function delayedMessageCount() external view override returns (uint256) {
151
+ return delayedInboxAccs.length;
152
+ }
153
+
154
+ function sequencerMessageCount() external view override returns (uint256) {
155
+ return sequencerInboxAccs.length;
114
156
  }
157
+
158
+ function rollup() external pure override returns (IOwnable) {
159
+ revert("NOT_IMPLEMENTED");
160
+ }
161
+
162
+ function acceptFundsFromOldBridge() external payable {}
115
163
  }
@@ -132,4 +132,6 @@ contract InboxStub is IInbox {
132
132
  function depositEth(uint256) external payable override returns (uint256) {
133
133
  revert("NOT_IMPLEMENTED");
134
134
  }
135
+
136
+ function postUpgradeInit(IBridge _bridge) external {}
135
137
  }
@@ -8,24 +8,26 @@ import "../bridge/SequencerInbox.sol";
8
8
 
9
9
  contract SequencerInboxStub is SequencerInbox {
10
10
  constructor(
11
- IBridge delayedBridge_,
11
+ IBridge bridge_,
12
12
  address sequencer_,
13
13
  ISequencerInbox.MaxTimeVariation memory maxTimeVariation_
14
14
  ) {
15
- delayedBridge = delayedBridge_;
16
- rollup = msg.sender;
15
+ bridge = bridge_;
16
+ rollup = IOwnable(msg.sender);
17
17
  maxTimeVariation = maxTimeVariation_;
18
18
  isBatchPoster[sequencer_] = true;
19
19
  }
20
20
 
21
21
  function addInitMessage() external {
22
22
  (bytes32 dataHash, TimeBounds memory timeBounds) = formEmptyDataHash(0);
23
- (bytes32 beforeAcc, bytes32 delayedAcc, bytes32 afterAcc) = addSequencerL2BatchImpl(
24
- dataHash,
25
- 0
26
- );
23
+ (
24
+ uint256 sequencerMessageCount,
25
+ bytes32 beforeAcc,
26
+ bytes32 delayedAcc,
27
+ bytes32 afterAcc
28
+ ) = addSequencerL2BatchImpl(dataHash, 0, 0);
27
29
  emit SequencerBatchDelivered(
28
- inboxAccs.length - 1,
30
+ sequencerMessageCount,
29
31
  beforeAcc,
30
32
  afterAcc,
31
33
  delayedAcc,
@@ -4,10 +4,13 @@
4
4
 
5
5
  pragma solidity ^0.8.0;
6
6
 
7
+ import "../precompiles/ArbRetryableTx.sol";
8
+
7
9
  contract Simple {
8
10
  uint64 public counter;
9
11
 
10
12
  event CounterEvent(uint64 count);
13
+ event RedeemedEvent(address caller, address redeemer);
11
14
  event NullEvent();
12
15
 
13
16
  function increment() external {
@@ -19,6 +22,11 @@ contract Simple {
19
22
  emit CounterEvent(counter);
20
23
  }
21
24
 
25
+ function incrementRedeem() external {
26
+ counter++;
27
+ emit RedeemedEvent(msg.sender, ArbRetryableTx(address(110)).getCurrentRedeemer());
28
+ }
29
+
22
30
  function emitNullEvent() external {
23
31
  emit NullEvent();
24
32
  }
@@ -11,7 +11,8 @@ pragma solidity >=0.4.21 <0.9.0;
11
11
  */
12
12
  interface NodeInterface {
13
13
  /**
14
- * @notice Estimate the cost of putting a message in the L2 inbox that is reexecuted
14
+ * @notice Estimate the cost of putting a message in the L2 inbox that is reexecuted.
15
+ * @dev Use eth_estimateGas to call.
15
16
  * @param sender sender of the L1 and L2 transaction
16
17
  * @param deposit amount to deposit to sender in L2
17
18
  * @param to destination L2 contract address
@@ -31,7 +32,8 @@ interface NodeInterface {
31
32
  ) external;
32
33
 
33
34
  /**
34
- * @notice Constructs an outbox proof of an l2->l1 send's existence in the outbox accumulator
35
+ * @notice Constructs an outbox proof of an l2->l1 send's existence in the outbox accumulator.
36
+ * @dev Use eth_call to call.
35
37
  * @param size the number of elements in the accumulator
36
38
  * @param leaf the position of the send in the accumulator
37
39
  * @return send the l2->l1 send's hash
@@ -48,8 +50,9 @@ interface NodeInterface {
48
50
  );
49
51
 
50
52
  /**
51
- * @notice Finds the L1 batch containing a requested L2 block, reverting if none does
52
- * Throws if block doesn't exist, or if block number is 0
53
+ * @notice Finds the L1 batch containing a requested L2 block, reverting if none does.
54
+ * Use eth_call to call.
55
+ * Throws if block doesn't exist, or if block number is 0. Use eth_call
53
56
  * @param blockNum The L2 block being queried
54
57
  * @return batch The L1 block containing the requested L2 block
55
58
  */
@@ -60,8 +63,63 @@ interface NodeInterface {
60
63
  * This gets the number of L1 confirmations for the input message producing the L2 block,
61
64
  * which happens well before the L1 rollup contract confirms the L2 block.
62
65
  * Throws if block doesnt exist in the L2 chain.
66
+ * @dev Use eth_call to call.
63
67
  * @param blockHash The hash of the L2 block being queried
64
68
  * @return confirmations The number of L1 confirmations the sequencer batch has. Returns 0 if block not yet included in an L1 batch.
65
69
  */
66
70
  function getL1Confirmations(bytes32 blockHash) external view returns (uint64 confirmations);
71
+
72
+ /**
73
+ * @notice Same as native gas estimation, but with additional info on the l1 costs.
74
+ * @dev Use eth_call to call.
75
+ * @param data the tx's calldata. Everything else like "From" and "Gas" are copied over
76
+ * @param to the tx's "To" (ignored when contractCreation is true)
77
+ * @param contractCreation whether "To" is omitted
78
+ * @return gasEstimate an estimate of the total amount of gas needed for this tx
79
+ * @return gasEstimateForL1 an estimate of the amount of gas needed for the l1 component of this tx
80
+ * @return baseFee the l2 base fee
81
+ * @return l1BaseFeeEstimate ArbOS's l1 estimate of the l1 base fee
82
+ */
83
+ function gasEstimateComponents(
84
+ address to,
85
+ bool contractCreation,
86
+ bytes calldata data
87
+ )
88
+ external
89
+ payable
90
+ returns (
91
+ uint64 gasEstimate,
92
+ uint64 gasEstimateForL1,
93
+ uint256 baseFee,
94
+ uint256 l1BaseFeeEstimate
95
+ );
96
+
97
+ /**
98
+ * @notice Returns the proof necessary to redeem a message
99
+ * @param batchNum index of outbox entry (i.e., outgoing messages Merkle root) in array of outbox entries
100
+ * @param index index of outgoing message in outbox entry
101
+ * @return proof Merkle proof of message inclusion in outbox entry
102
+ * @return path Merkle path to message
103
+ * @return l2Sender sender if original message (i.e., caller of ArbSys.sendTxToL1)
104
+ * @return l1Dest destination address for L1 contract call
105
+ * @return l2Block l2 block number at which sendTxToL1 call was made
106
+ * @return l1Block l1 block number at which sendTxToL1 call was made
107
+ * @return timestamp l2 Timestamp at which sendTxToL1 call was made
108
+ * @return amount value in L1 message in wei
109
+ * @return calldataForL1 abi-encoded L1 message data
110
+ */
111
+ function legacyLookupMessageBatchProof(uint256 batchNum, uint64 index)
112
+ external
113
+ view
114
+ returns (
115
+ bytes32[] memory proof,
116
+ uint256 path,
117
+ address l2Sender,
118
+ address l1Dest,
119
+ uint256 l2Block,
120
+ uint256 l1Block,
121
+ uint256 timestamp,
122
+ uint256 amount,
123
+ bytes memory calldataForL1
124
+ );
67
125
  }
@@ -12,8 +12,7 @@ import "../bridge/IBridge.sol";
12
12
 
13
13
  struct ExecutionContext {
14
14
  uint256 maxInboxMessagesRead;
15
- ISequencerInbox sequencerInbox;
16
- IBridge delayedBridge;
15
+ IBridge bridge;
17
16
  }
18
17
 
19
18
  abstract contract IOneStepProver {
@@ -12,7 +12,6 @@ import "./IOneStepProver.sol";
12
12
 
13
13
  contract OneStepProver0 is IOneStepProver {
14
14
  using MerkleProofLib for MerkleProof;
15
- using PcStackLib for PcStack;
16
15
  using StackFrameLib for StackFrameWindow;
17
16
  using ValueLib for Value;
18
17
  using ValueStackLib for ValueStack;
@@ -51,8 +50,6 @@ contract OneStepProver0 is IOneStepProver {
51
50
  ty = ValueType.F32;
52
51
  } else if (opcode == Instructions.F64_CONST) {
53
52
  ty = ValueType.F64;
54
- } else if (opcode == Instructions.PUSH_STACK_BOUNDARY) {
55
- ty = ValueType.STACK_BOUNDARY;
56
53
  } else {
57
54
  revert("CONST_PUSH_INVALID_OPCODE");
58
55
  }
@@ -86,39 +83,6 @@ contract OneStepProver0 is IOneStepProver {
86
83
  }
87
84
  }
88
85
 
89
- function executeBlock(
90
- Machine memory mach,
91
- Module memory,
92
- Instruction calldata inst,
93
- bytes calldata
94
- ) internal pure {
95
- uint32 targetPc = uint32(inst.argumentData);
96
- require(targetPc == inst.argumentData, "BAD_BLOCK_PC");
97
- mach.blockStack.push(targetPc);
98
- }
99
-
100
- function executeBranch(
101
- Machine memory mach,
102
- Module memory,
103
- Instruction calldata,
104
- bytes calldata
105
- ) internal pure {
106
- mach.functionPc = mach.blockStack.pop();
107
- }
108
-
109
- function executeBranchIf(
110
- Machine memory mach,
111
- Module memory,
112
- Instruction calldata,
113
- bytes calldata
114
- ) internal pure {
115
- uint32 cond = mach.valueStack.pop().assumeI32();
116
- if (cond != 0) {
117
- // Jump to target
118
- mach.functionPc = mach.blockStack.pop();
119
- }
120
- }
121
-
122
86
  function executeReturn(
123
87
  Machine memory mach,
124
88
  Module memory,
@@ -419,27 +383,6 @@ contract OneStepProver0 is IOneStepProver {
419
383
  );
420
384
  }
421
385
 
422
- function executeEndBlock(
423
- Machine memory mach,
424
- Module memory,
425
- Instruction calldata,
426
- bytes calldata
427
- ) internal pure {
428
- mach.blockStack.pop();
429
- }
430
-
431
- function executeEndBlockIf(
432
- Machine memory mach,
433
- Module memory,
434
- Instruction calldata,
435
- bytes calldata
436
- ) internal pure {
437
- uint32 cond = mach.valueStack.peek().assumeI32();
438
- if (cond != 0) {
439
- mach.blockStack.pop();
440
- }
441
- }
442
-
443
386
  function executeInitFrame(
444
387
  Machine memory mach,
445
388
  Module memory,
@@ -476,20 +419,6 @@ contract OneStepProver0 is IOneStepProver {
476
419
  }
477
420
  }
478
421
 
479
- function executeIsStackBoundary(
480
- Machine memory mach,
481
- Module memory,
482
- Instruction calldata,
483
- bytes calldata
484
- ) internal pure {
485
- Value memory val = mach.valueStack.pop();
486
- uint32 newContents = 0;
487
- if (val.valueType == ValueType.STACK_BOUNDARY) {
488
- newContents = 1;
489
- }
490
- mach.valueStack.push(ValueLib.newI32(newContents));
491
- }
492
-
493
422
  function executeDup(
494
423
  Machine memory mach,
495
424
  Module memory,
@@ -519,12 +448,6 @@ contract OneStepProver0 is IOneStepProver {
519
448
  impl = executeUnreachable;
520
449
  } else if (opcode == Instructions.NOP) {
521
450
  impl = executeNop;
522
- } else if (opcode == Instructions.BLOCK) {
523
- impl = executeBlock;
524
- } else if (opcode == Instructions.BRANCH) {
525
- impl = executeBranch;
526
- } else if (opcode == Instructions.BRANCH_IF) {
527
- impl = executeBranchIf;
528
451
  } else if (opcode == Instructions.RETURN) {
529
452
  impl = executeReturn;
530
453
  } else if (opcode == Instructions.CALL) {
@@ -535,10 +458,6 @@ contract OneStepProver0 is IOneStepProver {
535
458
  impl = executeCallerModuleInternalCall;
536
459
  } else if (opcode == Instructions.CALL_INDIRECT) {
537
460
  impl = executeCallIndirect;
538
- } else if (opcode == Instructions.END_BLOCK) {
539
- impl = executeEndBlock;
540
- } else if (opcode == Instructions.END_BLOCK_IF) {
541
- impl = executeEndBlockIf;
542
461
  } else if (opcode == Instructions.ARBITRARY_JUMP) {
543
462
  impl = executeArbitraryJump;
544
463
  } else if (opcode == Instructions.ARBITRARY_JUMP_IF) {
@@ -557,18 +476,13 @@ contract OneStepProver0 is IOneStepProver {
557
476
  impl = executeDrop;
558
477
  } else if (opcode == Instructions.SELECT) {
559
478
  impl = executeSelect;
560
- } else if (
561
- (opcode >= Instructions.I32_CONST && opcode <= Instructions.F64_CONST) ||
562
- opcode == Instructions.PUSH_STACK_BOUNDARY
563
- ) {
479
+ } else if (opcode >= Instructions.I32_CONST && opcode <= Instructions.F64_CONST) {
564
480
  impl = executeConstPush;
565
481
  } else if (
566
482
  opcode == Instructions.MOVE_FROM_STACK_TO_INTERNAL ||
567
483
  opcode == Instructions.MOVE_FROM_INTERNAL_TO_STACK
568
484
  ) {
569
485
  impl = executeMoveInternal;
570
- } else if (opcode == Instructions.IS_STACK_BOUNDARY) {
571
- impl = executeIsStackBoundary;
572
486
  } else if (opcode == Instructions.DUP) {
573
487
  impl = executeDup;
574
488
  } else {
@@ -10,7 +10,6 @@ import "../state/Deserialize.sol";
10
10
  import "./IOneStepProver.sol";
11
11
  import "../bridge/Messages.sol";
12
12
  import "../bridge/IBridge.sol";
13
- import "../bridge/ISequencerInbox.sol";
14
13
 
15
14
  contract OneStepProverHostIo is IOneStepProver {
16
15
  using GlobalStateLib for GlobalState;
@@ -165,13 +164,13 @@ contract OneStepProverHostIo is IOneStepProver {
165
164
  bytes32 delayedAcc;
166
165
 
167
166
  if (msgIndex > 0) {
168
- beforeAcc = execCtx.sequencerInbox.inboxAccs(msgIndex - 1);
167
+ beforeAcc = execCtx.bridge.sequencerInboxAccs(msgIndex - 1);
169
168
  }
170
169
  if (afterDelayedMsg > 0) {
171
- delayedAcc = execCtx.delayedBridge.inboxAccs(afterDelayedMsg - 1);
170
+ delayedAcc = execCtx.bridge.delayedInboxAccs(afterDelayedMsg - 1);
172
171
  }
173
172
  bytes32 acc = keccak256(abi.encodePacked(beforeAcc, messageHash, delayedAcc));
174
- require(acc == execCtx.sequencerInbox.inboxAccs(msgIndex), "BAD_SEQINBOX_MESSAGE");
173
+ require(acc == execCtx.bridge.sequencerInboxAccs(msgIndex), "BAD_SEQINBOX_MESSAGE");
175
174
  return true;
176
175
  }
177
176
 
@@ -185,7 +184,7 @@ contract OneStepProverHostIo is IOneStepProver {
185
184
  bytes32 beforeAcc;
186
185
 
187
186
  if (msgIndex > 0) {
188
- beforeAcc = execCtx.delayedBridge.inboxAccs(msgIndex - 1);
187
+ beforeAcc = execCtx.bridge.delayedInboxAccs(msgIndex - 1);
189
188
  }
190
189
 
191
190
  bytes32 messageDataHash = keccak256(message[DELAYED_HEADER_LEN:]);
@@ -198,7 +197,7 @@ contract OneStepProverHostIo is IOneStepProver {
198
197
  );
199
198
  bytes32 acc = Messages.accumulateInboxMessage(beforeAcc, messageHash);
200
199
 
201
- require(acc == execCtx.delayedBridge.inboxAccs(msgIndex), "BAD_DELAYED_MESSAGE");
200
+ require(acc == execCtx.bridge.delayedInboxAccs(msgIndex), "BAD_DELAYED_MESSAGE");
202
201
  return true;
203
202
  }
204
203
 
@@ -210,38 +210,38 @@ contract OneStepProverMath is IOneStepProver {
210
210
  uint64 a,
211
211
  uint64 b,
212
212
  uint16 opcodeOffset
213
- ) internal pure returns (uint64) {
213
+ ) internal pure returns (uint64, bool) {
214
214
  unchecked {
215
215
  if (opcodeOffset == 0) {
216
216
  // add
217
- return a + b;
217
+ return (a + b, false);
218
218
  } else if (opcodeOffset == 1) {
219
219
  // sub
220
- return a - b;
220
+ return (a - b, false);
221
221
  } else if (opcodeOffset == 2) {
222
222
  // mul
223
- return a * b;
223
+ return (a * b, false);
224
224
  } else if (opcodeOffset == 4) {
225
225
  // div_u
226
226
  if (b == 0) {
227
- return 0;
227
+ return (0, true);
228
228
  }
229
- return a / b;
229
+ return (a / b, false);
230
230
  } else if (opcodeOffset == 6) {
231
231
  // rem_u
232
232
  if (b == 0) {
233
- return 0;
233
+ return (0, true);
234
234
  }
235
- return a % b;
235
+ return (a % b, false);
236
236
  } else if (opcodeOffset == 7) {
237
237
  // and
238
- return a & b;
238
+ return (a & b, false);
239
239
  } else if (opcodeOffset == 8) {
240
240
  // or
241
- return a | b;
241
+ return (a | b, false);
242
242
  } else if (opcodeOffset == 9) {
243
243
  // xor
244
- return a ^ b;
244
+ return (a ^ b, false);
245
245
  } else {
246
246
  revert("INVALID_GENERIC_BIN_OP");
247
247
  }
@@ -263,18 +263,18 @@ contract OneStepProverMath is IOneStepProver {
263
263
  unchecked {
264
264
  if (opcodeOffset == 3) {
265
265
  // div_s
266
- if (b == 0) {
267
- res = 0;
268
- } else {
269
- res = uint32(int32(a) / int32(b));
266
+ if (b == 0 || (int32(a) == -2147483648 && int32(b) == -1)) {
267
+ mach.status = MachineStatus.ERRORED;
268
+ return;
270
269
  }
270
+ res = uint32(int32(a) / int32(b));
271
271
  } else if (opcodeOffset == 5) {
272
272
  // rem_s
273
273
  if (b == 0) {
274
- res = 0;
275
- } else {
276
- res = uint32(int32(a) % int32(b));
274
+ mach.status = MachineStatus.ERRORED;
275
+ return;
277
276
  }
277
+ res = uint32(int32(a) % int32(b));
278
278
  } else if (opcodeOffset == 10) {
279
279
  // shl
280
280
  res = a << (b % 32);
@@ -291,7 +291,12 @@ contract OneStepProverMath is IOneStepProver {
291
291
  // rotr
292
292
  res = rotr32(a, b);
293
293
  } else {
294
- res = uint32(genericBinOp(a, b, opcodeOffset));
294
+ (uint64 computed, bool err) = genericBinOp(a, b, opcodeOffset);
295
+ if (err) {
296
+ mach.status = MachineStatus.ERRORED;
297
+ return;
298
+ }
299
+ res = uint32(computed);
295
300
  }
296
301
  }
297
302
 
@@ -313,18 +318,18 @@ contract OneStepProverMath is IOneStepProver {
313
318
  unchecked {
314
319
  if (opcodeOffset == 3) {
315
320
  // div_s
316
- if (b == 0) {
317
- res = 0;
318
- } else {
319
- res = uint64(int64(a) / int64(b));
321
+ if (b == 0 || (int64(a) == -9223372036854775808 && int64(b) == -1)) {
322
+ mach.status = MachineStatus.ERRORED;
323
+ return;
320
324
  }
325
+ res = uint64(int64(a) / int64(b));
321
326
  } else if (opcodeOffset == 5) {
322
327
  // rem_s
323
328
  if (b == 0) {
324
- res = 0;
325
- } else {
326
- res = uint64(int64(a) % int64(b));
329
+ mach.status = MachineStatus.ERRORED;
330
+ return;
327
331
  }
332
+ res = uint64(int64(a) % int64(b));
328
333
  } else if (opcodeOffset == 10) {
329
334
  // shl
330
335
  res = a << (b % 64);
@@ -341,7 +346,12 @@ contract OneStepProverMath is IOneStepProver {
341
346
  // rotr
342
347
  res = rotr64(a, b);
343
348
  } else {
344
- res = genericBinOp(a, b, opcodeOffset);
349
+ bool err;
350
+ (res, err) = genericBinOp(a, b, opcodeOffset);
351
+ if (err) {
352
+ mach.status = MachineStatus.ERRORED;
353
+ return;
354
+ }
345
355
  }
346
356
  }
347
357
 
@@ -271,10 +271,9 @@ contract OneStepProverMemory is IOneStepProver {
271
271
  uint32 oldPages = uint32(mod.moduleMemory.size / PAGE_SIZE);
272
272
  uint32 growingPages = mach.valueStack.pop().assumeI32();
273
273
  // Safe as the input integers are too small to overflow a uint256
274
- uint256 newSize = (uint256(oldPages) + uint256(growingPages)) * PAGE_SIZE;
275
- // Note: we require the size remain *below* 2^32, meaning the actual limit is 2^32-PAGE_SIZE
276
- if (newSize < (1 << 32)) {
277
- mod.moduleMemory.size = uint64(newSize);
274
+ uint256 newSize = uint256(oldPages) + uint256(growingPages);
275
+ if (newSize <= mod.moduleMemory.maxSize) {
276
+ mod.moduleMemory.size = uint64(newSize * PAGE_SIZE);
278
277
  mach.valueStack.push(ValueLib.newI32(oldPages));
279
278
  } else {
280
279
  mach.valueStack.push(ValueLib.newI32(~uint32(0)));