@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
@@ -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)));