@arbitrum/nitro-contracts 1.0.0-beta.7 → 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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arbitrum/nitro-contracts",
3
- "version": "1.0.0-beta.7",
3
+ "version": "1.0.0-beta.8",
4
4
  "description": "Layer 2 precompiles and rollup for Arbitrum Nitro",
5
5
  "author": "Offchain Labs, Inc.",
6
6
  "license": "BUSL-1.1",
@@ -21,7 +21,10 @@
21
21
  "build": "./scripts/build.bash",
22
22
  "solhint": "solhint -f table src/**/*.sol",
23
23
  "prettier:solidity": "prettier --write src/**/*.sol",
24
- "hardhat:prod": "hardhat --config hardhat.prod-config.js"
24
+ "hardhat:prod": "hardhat --config hardhat.prod-config.js",
25
+ "build:0.6": "INTERFACE_TESTER_SOLC_VERSION=0.6.9 yarn run build",
26
+ "build:0.7": "INTERFACE_TESTER_SOLC_VERSION=0.7.0 yarn run build",
27
+ "test:compatibility": "yarn run build:0.6 && yarn run build:0.7"
25
28
  },
26
29
  "dependencies": {
27
30
  "@openzeppelin/contracts": "4.5.0",
@@ -7,6 +7,14 @@ pragma solidity ^0.8.4;
7
7
  import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
8
8
  import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
9
9
 
10
+ import {
11
+ NotContract,
12
+ NotRollupOrOwner,
13
+ NotDelayedInbox,
14
+ NotSequencerInbox,
15
+ NotOutbox,
16
+ InvalidOutboxSet
17
+ } from "../libraries/Error.sol";
10
18
  import "./IBridge.sol";
11
19
  import "./Messages.sol";
12
20
  import "../libraries/DelegateCallAware.sol";
@@ -260,4 +268,7 @@ contract Bridge is Initializable, DelegateCallAware, IBridge {
260
268
  function sequencerMessageCount() external view override returns (uint256) {
261
269
  return sequencerInboxAccs.length;
262
270
  }
271
+
272
+ /// @dev For the classic -> nitro migration. TODO: remove post-migration.
273
+ function acceptFundsFromOldBridge() external payable {}
263
274
  }
@@ -2,27 +2,11 @@
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.8.4;
5
+ // solhint-disable-next-line compiler-version
6
+ pragma solidity >=0.6.9 <0.9.0;
6
7
 
7
- import {NotContract, NotRollupOrOwner} from "../libraries/Error.sol";
8
8
  import "./IOwnable.sol";
9
9
 
10
- /// @dev Thrown when an un-authorized address tries to access an only-inbox function
11
- /// @param sender The un-authorized sender
12
- error NotDelayedInbox(address sender);
13
-
14
- /// @dev Thrown when an un-authorized address tries to access an only-sequencer-inbox function
15
- /// @param sender The un-authorized sender
16
- error NotSequencerInbox(address sender);
17
-
18
- /// @dev Thrown when an un-authorized address tries to access an only-outbox function
19
- /// @param sender The un-authorized sender
20
- error NotOutbox(address sender);
21
-
22
- /// @dev the provided outbox address isn't valid
23
- /// @param outbox address of outbox being set
24
- error InvalidOutboxSet(address outbox);
25
-
26
10
  interface IBridge {
27
11
  event MessageDelivered(
28
12
  uint256 indexed messageIndex,
@@ -99,4 +83,6 @@ interface IBridge {
99
83
  function sequencerMessageCount() external view returns (uint256);
100
84
 
101
85
  function rollup() external view returns (IOwnable);
86
+
87
+ function acceptFundsFromOldBridge() external payable;
102
88
  }
@@ -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.8.0;
5
+ // solhint-disable-next-line compiler-version
6
+ pragma solidity >=0.6.9 <0.9.0;
6
7
 
7
8
  interface IDelayedMessageProvider {
8
9
  /// @dev event emitted when a inbox message is added to the Bridge's delayed accumulator
@@ -2,44 +2,11 @@
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.8.4;
5
+ // solhint-disable-next-line compiler-version
6
+ pragma solidity >=0.6.9 <0.9.0;
6
7
 
7
8
  import "./IBridge.sol";
8
9
  import "./IDelayedMessageProvider.sol";
9
- import {AlreadyInit, NotOrigin, DataTooLarge} from "../libraries/Error.sol";
10
-
11
- /// @dev The contract is paused, so cannot be paused
12
- error AlreadyPaused();
13
-
14
- /// @dev The contract is unpaused, so cannot be unpaused
15
- error AlreadyUnpaused();
16
-
17
- /// @dev The contract is paused
18
- error Paused();
19
-
20
- /// @dev msg.value sent to the inbox isn't high enough
21
- error InsufficientValue(uint256 expected, uint256 actual);
22
-
23
- /// @dev submission cost provided isn't enough to create retryable ticket
24
- error InsufficientSubmissionCost(uint256 expected, uint256 actual);
25
-
26
- /// @dev address not allowed to interact with the given contract
27
- error NotAllowedOrigin(address origin);
28
-
29
- /// @dev used to convey retryable tx data in eth calls without requiring a tx trace
30
- /// this follows a pattern similar to EIP-3668 where reverts surface call information
31
- error RetryableData(
32
- address from,
33
- address to,
34
- uint256 l2CallValue,
35
- uint256 deposit,
36
- uint256 maxSubmissionCost,
37
- address excessFeeRefundAddress,
38
- address callValueRefundAddress,
39
- uint256 gasLimit,
40
- uint256 maxFeePerGas,
41
- bytes data
42
- );
43
10
 
44
11
  interface IInbox is IDelayedMessageProvider {
45
12
  function sendL2Message(bytes calldata messageData) external returns (uint256);
@@ -88,7 +55,6 @@ interface IInbox is IDelayedMessageProvider {
88
55
  bytes calldata data
89
56
  ) external payable returns (uint256);
90
57
 
91
- /// @notice TEMPORARILY DISABLED as exact mechanics are being worked out
92
58
  /// @dev Gas limit and maxFeePerGas should not be set to 1 as that is used to trigger the RetryableData error
93
59
  function unsafeCreateRetryableTicket(
94
60
  address to,
@@ -107,4 +73,6 @@ interface IInbox is IDelayedMessageProvider {
107
73
  function depositEth(uint256 maxSubmissionCost) external payable returns (uint256);
108
74
 
109
75
  function bridge() external view returns (IBridge);
76
+
77
+ function postUpgradeInit(IBridge _bridge) external;
110
78
  }
@@ -2,29 +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.8.4;
6
-
7
- import {AlreadyInit, NotRollup} from "../libraries/Error.sol";
8
-
9
- /// @dev The provided proof was too long
10
- /// @param proofLength The length of the too-long proof
11
- error ProofTooLong(uint256 proofLength);
12
-
13
- /// @dev The output index was greater than the maximum
14
- /// @param index The output index
15
- /// @param maxIndex The max the index could be
16
- error PathNotMinimal(uint256 index, uint256 maxIndex);
17
-
18
- /// @dev The calculated root does not exist
19
- /// @param root The calculated root
20
- error UnknownRoot(bytes32 root);
21
-
22
- /// @dev The record has already been spent
23
- /// @param index The index of the spent record
24
- error AlreadySpent(uint256 index);
25
-
26
- /// @dev A call to the bridge failed with no return data
27
- error BridgeCallFailed();
5
+ // solhint-disable-next-line compiler-version
6
+ pragma solidity >=0.6.9 <0.9.0;
28
7
 
29
8
  interface IOutbox {
30
9
  event SendRootUpdated(bytes32 indexed blockHash, bytes32 indexed outputRoot);
@@ -49,4 +28,45 @@ interface IOutbox {
49
28
  function l2ToL1OutputId() external view returns (bytes32);
50
29
 
51
30
  function updateSendRoot(bytes32 sendRoot, bytes32 l2BlockHash) external;
31
+
32
+ function executeTransaction(
33
+ bytes32[] calldata proof,
34
+ uint256 index,
35
+ address l2Sender,
36
+ address to,
37
+ uint256 l2Block,
38
+ uint256 l1Block,
39
+ uint256 l2Timestamp,
40
+ uint256 value,
41
+ bytes calldata data
42
+ ) external;
43
+
44
+ function executeTransactionSimulation(
45
+ uint256 index,
46
+ address l2Sender,
47
+ address to,
48
+ uint256 l2Block,
49
+ uint256 l1Block,
50
+ uint256 l2Timestamp,
51
+ uint256 value,
52
+ bytes calldata data
53
+ ) external;
54
+
55
+ function isSpent(uint256) external view returns (bool);
56
+
57
+ function calculateItemHash(
58
+ address l2Sender,
59
+ address to,
60
+ uint256 l2Block,
61
+ uint256 l1Block,
62
+ uint256 l2Timestamp,
63
+ uint256 value,
64
+ bytes calldata data
65
+ ) external pure returns (bytes32);
66
+
67
+ function calculateMerkleRoot(
68
+ bytes32[] memory proof,
69
+ uint256 path,
70
+ bytes32 item
71
+ ) external pure returns (bytes32);
52
72
  }
@@ -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.8.4;
5
+ // solhint-disable-next-line compiler-version
6
+ pragma solidity >=0.4.21 <0.9.0;
6
7
 
7
8
  interface IOwnable {
8
9
  function owner() external view returns (address);
@@ -2,10 +2,11 @@
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.8.0;
5
+ // solhint-disable-next-line compiler-version
6
+ pragma solidity >=0.6.9 <0.9.0;
7
+ pragma experimental ABIEncoderV2;
6
8
 
7
9
  import "../libraries/IGasRefunder.sol";
8
- import {AlreadyInit, HadZeroInit, NotOrigin, DataTooLarge, NotRollup} from "../libraries/Error.sol";
9
10
  import "./IDelayedMessageProvider.sol";
10
11
 
11
12
  interface ISequencerInbox is IDelayedMessageProvider {
@@ -50,36 +51,6 @@ interface ISequencerInbox is IDelayedMessageProvider {
50
51
  /// @dev a keyset was invalidated
51
52
  event InvalidateKeyset(bytes32 indexed keysetHash);
52
53
 
53
- /// @dev Thrown when someone attempts to read fewer messages than have already been read
54
- error DelayedBackwards();
55
-
56
- /// @dev Thrown when someone attempts to read more messages than exist
57
- error DelayedTooFar();
58
-
59
- /// @dev Force include can only read messages more blocks old than the delay period
60
- error ForceIncludeBlockTooSoon();
61
-
62
- /// @dev Force include can only read messages more seconds old than the delay period
63
- error ForceIncludeTimeTooSoon();
64
-
65
- /// @dev The message provided did not match the hash in the delayed inbox
66
- error IncorrectMessagePreimage();
67
-
68
- /// @dev This can only be called by the batch poster
69
- error NotBatchPoster();
70
-
71
- /// @dev The sequence number provided to this message was inconsistent with the number of batches already included
72
- error BadSequencerNumber(uint256 stored, uint256 received);
73
-
74
- /// @dev The batch data has the inbox authenticated bit set, but the batch data was not authenticated by the inbox
75
- error DataNotAuthenticated();
76
-
77
- /// @dev Tried to create an already valid Data Availability Service keyset
78
- error AlreadyValidDASKeyset(bytes32);
79
-
80
- /// @dev Tried to use or invalidate an already invalid Data Availability Service keyset
81
- error NoSuchKeyset(bytes32);
82
-
83
54
  function inboxAccs(uint256 index) external view returns (bytes32);
84
55
 
85
56
  function batchCount() external view returns (uint256);
@@ -4,6 +4,19 @@
4
4
 
5
5
  pragma solidity ^0.8.4;
6
6
 
7
+ import {
8
+ AlreadyInit,
9
+ NotOrigin,
10
+ DataTooLarge,
11
+ AlreadyPaused,
12
+ AlreadyUnpaused,
13
+ Paused,
14
+ InsufficientValue,
15
+ InsufficientSubmissionCost,
16
+ NotAllowedOrigin,
17
+ RetryableData,
18
+ NotRollupOrOwner
19
+ } from "../libraries/Error.sol";
7
20
  import "./IInbox.sol";
8
21
  import "./ISequencerInbox.sol";
9
22
  import "./IBridge.sol";
@@ -244,14 +257,15 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
244
257
  * @dev This fee can be paid by funds already in the L2 aliased address or by the current message value
245
258
  * @dev This formula may change in the future, to future proof your code query this method instead of inlining!!
246
259
  * @param dataLength The length of the retryable's calldata, in bytes
247
- * @param baseFee The block basefee when the retryable is included in the chain
260
+ * @param baseFee The block basefee when the retryable is included in the chain, if 0 current block.basefee will be used
248
261
  */
249
262
  function calculateRetryableSubmissionFee(uint256 dataLength, uint256 baseFee)
250
263
  public
251
- pure
264
+ view
252
265
  returns (uint256)
253
266
  {
254
- return (1400 + 6 * dataLength) * baseFee;
267
+ // Use current block basefee if baseFee parameter is 0
268
+ return (1400 + 6 * dataLength) * (baseFee == 0 ? block.basefee : baseFee);
255
269
  }
256
270
 
257
271
  /// @notice deposit eth from L1 to L2
@@ -373,7 +387,7 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
373
387
  }
374
388
 
375
389
  return
376
- unsafeCreateRetryableTicketInternal(
390
+ unsafeCreateRetryableTicket(
377
391
  to,
378
392
  l2CallValue,
379
393
  maxSubmissionCost,
@@ -402,7 +416,7 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
402
416
  * @param data ABI encoded data of L2 message
403
417
  * @return unique id for retryable transaction (keccak256(requestID, uint(0) )
404
418
  */
405
- function unsafeCreateRetryableTicketInternal(
419
+ function unsafeCreateRetryableTicket(
406
420
  address to,
407
421
  uint256 l2CallValue,
408
422
  uint256 maxSubmissionCost,
@@ -411,7 +425,7 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
411
425
  uint256 gasLimit,
412
426
  uint256 maxFeePerGas,
413
427
  bytes calldata data
414
- ) internal virtual whenNotPaused onlyAllowed returns (uint256) {
428
+ ) public payable virtual override whenNotPaused onlyAllowed returns (uint256) {
415
429
  // gas price and limit of 1 should never be a valid input, so instead they are used as
416
430
  // magic values to trigger a revert in eth calls that surface data without requiring a tx trace
417
431
  if (gasLimit == 1 || maxFeePerGas == 1)
@@ -451,19 +465,6 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
451
465
  );
452
466
  }
453
467
 
454
- function unsafeCreateRetryableTicket(
455
- address,
456
- uint256,
457
- uint256,
458
- address,
459
- address,
460
- uint256,
461
- uint256,
462
- bytes calldata
463
- ) public payable override returns (uint256) {
464
- revert("UNSAFE_RETRYABLES_TEMPORARILY_DISABLED");
465
- }
466
-
467
468
  function _deliverMessage(
468
469
  uint8 _kind,
469
470
  address _sender,
@@ -4,6 +4,15 @@
4
4
 
5
5
  pragma solidity ^0.8.4;
6
6
 
7
+ import {
8
+ AlreadyInit,
9
+ NotRollup,
10
+ ProofTooLong,
11
+ PathNotMinimal,
12
+ UnknownRoot,
13
+ AlreadySpent,
14
+ BridgeCallFailed
15
+ } from "../libraries/Error.sol";
7
16
  import "./IBridge.sol";
8
17
  import "./IOutbox.sol";
9
18
  import "../libraries/MerkleLib.sol";
@@ -138,7 +147,7 @@ contract Outbox is DelegateCallAware, IOutbox {
138
147
  uint256 l2Timestamp,
139
148
  uint256 value,
140
149
  bytes calldata data
141
- ) external {
150
+ ) external override {
142
151
  bytes32 userTx = calculateItemHash(
143
152
  l2Sender,
144
153
  to,
@@ -172,7 +181,7 @@ contract Outbox is DelegateCallAware, IOutbox {
172
181
  uint256 l2Timestamp,
173
182
  uint256 value,
174
183
  bytes calldata data
175
- ) external {
184
+ ) external override {
176
185
  if (msg.sender != address(0)) revert SimulationOnlyEntrypoint();
177
186
  executeTransactionImpl(index, l2Sender, to, l2Block, l1Block, l2Timestamp, value, data);
178
187
  }
@@ -226,7 +235,7 @@ contract Outbox is DelegateCallAware, IOutbox {
226
235
  return ((replay >> bitOffset) & bytes32(uint256(1))) != bytes32(0);
227
236
  }
228
237
 
229
- function isSpent(uint256 index) external view returns (bool) {
238
+ function isSpent(uint256 index) external view override returns (bool) {
230
239
  (, uint256 bitOffset, bytes32 replay) = _calcSpentIndexOffset(index);
231
240
  return _isSpent(bitOffset, replay);
232
241
  }
@@ -276,7 +285,7 @@ contract Outbox is DelegateCallAware, IOutbox {
276
285
  uint256 l2Timestamp,
277
286
  uint256 value,
278
287
  bytes calldata data
279
- ) public pure returns (bytes32) {
288
+ ) public pure override returns (bytes32) {
280
289
  return
281
290
  keccak256(abi.encodePacked(l2Sender, to, l2Block, l1Block, l2Timestamp, value, data));
282
291
  }
@@ -285,7 +294,7 @@ contract Outbox is DelegateCallAware, IOutbox {
285
294
  bytes32[] memory proof,
286
295
  uint256 path,
287
296
  bytes32 item
288
- ) public pure returns (bytes32) {
297
+ ) public pure override returns (bytes32) {
289
298
  return MerkleLib.calculateRoot(proof, path, keccak256(abi.encodePacked(item)));
290
299
  }
291
300
  }
@@ -4,6 +4,23 @@
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";
8
25
  import "./IInbox.sol";
9
26
  import "./ISequencerInbox.sol";
@@ -336,7 +353,10 @@ contract SequencerInbox is DelegateCallAware, GasRefundEnabled, ISequencerInbox
336
353
  * @param keysetBytes bytes of the serialized keyset
337
354
  */
338
355
  function setValidKeyset(bytes calldata keysetBytes) external override onlyRollupOwner {
339
- bytes32 ksHash = keccak256(keysetBytes);
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
+
340
360
  if (dasKeySetInfo[ksHash].isValidKeyset) revert AlreadyValidDASKeyset(ksHash);
341
361
  dasKeySetInfo[ksHash] = DasKeySetInfo({
342
362
  isValidKeyset: true,
@@ -42,3 +42,110 @@ error MerkleProofTooLong(uint256 actualLength, uint256 maxProofLength);
42
42
  /// @param rollup The rollup, which would be authorized
43
43
  /// @param owner The rollup's owner, which would be authorized
44
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(
@@ -158,4 +158,6 @@ contract BridgeStub is IBridge {
158
158
  function rollup() external pure override returns (IOwnable) {
159
159
  revert("NOT_IMPLEMENTED");
160
160
  }
161
+
162
+ function acceptFundsFromOldBridge() external payable {}
161
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
  }
@@ -12,7 +12,7 @@ pragma solidity >=0.4.21 <0.9.0;
12
12
  interface NodeInterface {
13
13
  /**
14
14
  * @notice Estimate the cost of putting a message in the L2 inbox that is reexecuted.
15
- * Use eth_estimateGas to call.
15
+ * @dev Use eth_estimateGas to call.
16
16
  * @param sender sender of the L1 and L2 transaction
17
17
  * @param deposit amount to deposit to sender in L2
18
18
  * @param to destination L2 contract address
@@ -33,7 +33,7 @@ interface NodeInterface {
33
33
 
34
34
  /**
35
35
  * @notice Constructs an outbox proof of an l2->l1 send's existence in the outbox accumulator.
36
- * Use eth_call to call.
36
+ * @dev Use eth_call to call.
37
37
  * @param size the number of elements in the accumulator
38
38
  * @param leaf the position of the send in the accumulator
39
39
  * @return send the l2->l1 send's hash
@@ -62,14 +62,16 @@ interface NodeInterface {
62
62
  * @notice Gets the number of L1 confirmations of the sequencer batch producing the requested L2 block
63
63
  * This gets the number of L1 confirmations for the input message producing the L2 block,
64
64
  * which happens well before the L1 rollup contract confirms the L2 block.
65
- * Throws if block doesnt exist in the L2 chain. Use eth_call to call.
65
+ * Throws if block doesnt exist in the L2 chain.
66
+ * @dev Use eth_call to call.
66
67
  * @param blockHash The hash of the L2 block being queried
67
68
  * @return confirmations The number of L1 confirmations the sequencer batch has. Returns 0 if block not yet included in an L1 batch.
68
69
  */
69
70
  function getL1Confirmations(bytes32 blockHash) external view returns (uint64 confirmations);
70
71
 
71
72
  /**
72
- * @notice Same as native gas estimation, but with additional info on the l1 costs. Use eth_call to call.
73
+ * @notice Same as native gas estimation, but with additional info on the l1 costs.
74
+ * @dev Use eth_call to call.
73
75
  * @param data the tx's calldata. Everything else like "From" and "Gas" are copied over
74
76
  * @param to the tx's "To" (ignored when contractCreation is true)
75
77
  * @param contractCreation whether "To" is omitted
@@ -91,4 +93,33 @@ interface NodeInterface {
91
93
  uint256 baseFee,
92
94
  uint256 l1BaseFeeEstimate
93
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
+ );
94
125
  }
@@ -109,4 +109,13 @@ interface ArbGasInfo {
109
109
 
110
110
  /// @notice Get the forgivable amount of backlogged gas ArbOS will ignore when raising the basefee
111
111
  function getGasBacklogTolerance() external view returns (uint64);
112
+
113
+ /// @notice Returns the surplus of funds for L1 batch posting payments (may be negative).
114
+ function getL1PricingSurplus() external view returns (int256);
115
+
116
+ /// @notice Returns the base charge (in L1 gas) attributed to each data batch in the calldata pricer
117
+ function getPerBatchGasCharge() external view returns (int64);
118
+
119
+ /// @notice Returns the cost amortization cap in basis points
120
+ function getAmortizedCostCapBips() external view returns (uint64);
112
121
  }
@@ -66,6 +66,15 @@ interface ArbOwner {
66
66
  /// @notice Sets reward amount for L1 price adjustment algorithm, in wei per unit
67
67
  function setL1PricingRewardRate(uint64 weiPerUnit) external;
68
68
 
69
+ /// @notice Set how much ArbOS charges per L1 gas spent on transaction data.
70
+ function setL1PricePerUnit(uint256 pricePerUnit) external;
71
+
72
+ /// @notice Sets the base charge (in L1 gas) attributed to each data batch in the calldata pricer
73
+ function setPerBatchGasCharge(int64 cost) external;
74
+
75
+ /// @notice Sets the cost amortization cap in basis points
76
+ function setAmortizedCostCapBips(uint64 cap) external;
77
+
69
78
  // Emitted when a successful call is made to this precompile
70
79
  event OwnerActs(bytes4 indexed method, address indexed owner, bytes data);
71
80
  }
@@ -36,13 +36,13 @@ interface ArbSys {
36
36
 
37
37
  /**
38
38
  * @notice Returns 0 since Nitro has no concept of storage gas
39
- * @return int 0
39
+ * @return uint 0
40
40
  */
41
41
  function getStorageGasAvailable() external view returns (uint256);
42
42
 
43
43
  /**
44
- * @notice check if current call is coming from l1
45
- * @return true if the caller of this was called directly from L1
44
+ * @notice check if current call is top level (meaning it was triggered by an EoA or a L1 contract)
45
+ * @return true if current execution frame is not a call by another L2 contract
46
46
  */
47
47
  function isTopLevelCall() external view returns (bool);
48
48
 
@@ -315,4 +315,46 @@ contract RollupAdminLogic is RollupCore, IRollupAdmin, SecondaryLogicUUPSUpgrade
315
315
  bridge.setSequencerInbox(_sequencerInbox);
316
316
  emit OwnerFunctionCalled(27);
317
317
  }
318
+
319
+ /**
320
+ * @notice sets the rollup's inbox reference. Does not update the bridge's view.
321
+ * @param newInbox new address of inbox
322
+ */
323
+ function setInbox(IInbox newInbox) external {
324
+ inbox = newInbox;
325
+ emit OwnerFunctionCalled(28);
326
+ }
327
+
328
+ function createNitroMigrationGenesis(RollupLib.Assertion calldata assertion)
329
+ external
330
+ whenPaused
331
+ {
332
+ bytes32 expectedSendRoot = bytes32(0);
333
+ uint64 expectedInboxCount = 1;
334
+
335
+ require(latestNodeCreated() == 0, "NON_GENESIS_NODES_EXIST");
336
+ require(GlobalStateLib.isEmpty(assertion.beforeState.globalState), "NOT_EMPTY_BEFORE");
337
+ require(
338
+ assertion.beforeState.machineStatus == MachineStatus.FINISHED,
339
+ "BEFORE_MACHINE_NOT_FINISHED"
340
+ );
341
+ // accessors such as state.getSendRoot not available for calldata structs, only memory
342
+ require(
343
+ assertion.afterState.globalState.bytes32Vals[1] == expectedSendRoot,
344
+ "NOT_ZERO_SENDROOT"
345
+ );
346
+ require(
347
+ assertion.afterState.globalState.u64Vals[0] == expectedInboxCount,
348
+ "INBOX_NOT_AT_ONE"
349
+ );
350
+ require(assertion.afterState.globalState.u64Vals[1] == 0, "POSITION_IN_MESSAGE_NOT_ZERO");
351
+ require(
352
+ assertion.afterState.machineStatus == MachineStatus.FINISHED,
353
+ "AFTER_MACHINE_NOT_FINISHED"
354
+ );
355
+ bytes32 genesisBlockHash = assertion.afterState.globalState.bytes32Vals[0];
356
+ createNewNode(assertion, 0, expectedInboxCount, bytes32(0));
357
+ confirmNode(1, genesisBlockHash, expectedSendRoot);
358
+ emit OwnerFunctionCalled(29);
359
+ }
318
360
  }
@@ -552,7 +552,7 @@ abstract contract RollupCore is IRollupCore, PausableUpgradeable {
552
552
  if (afterInboxCount == prevInboxPosition) {
553
553
  require(
554
554
  assertion.afterState.globalState.getPositionInMessage() >=
555
- assertion.afterState.globalState.getPositionInMessage(),
555
+ assertion.beforeState.globalState.getPositionInMessage(),
556
556
  "INBOX_POS_IN_MSG_BACKWARDS"
557
557
  );
558
558
  }
@@ -592,7 +592,10 @@ abstract contract RollupCore is IRollupCore, PausableUpgradeable {
592
592
  memoryFrame.sequencerBatchAcc,
593
593
  wasmModuleRoot
594
594
  );
595
- require(newNodeHash == expectedNodeHash, "UNEXPECTED_NODE_HASH");
595
+ require(
596
+ newNodeHash == expectedNodeHash || expectedNodeHash == bytes32(0),
597
+ "UNEXPECTED_NODE_HASH"
598
+ );
596
599
 
597
600
  memoryFrame.node = NodeLib.createNode(
598
601
  RollupLib.stateHash(assertion.afterState, memoryFrame.currentInboxSize),
@@ -24,6 +24,7 @@ struct Config {
24
24
  address owner;
25
25
  address loserStakeEscrow;
26
26
  uint256 chainId;
27
+ uint64 genesisBlockNum;
27
28
  ISequencerInbox.MaxTimeVariation sequencerInboxMaxTimeVariation;
28
29
  }
29
30
 
@@ -41,4 +41,11 @@ library GlobalStateLib {
41
41
  function getPositionInMessage(GlobalState memory state) internal pure returns (uint64) {
42
42
  return state.u64Vals[1];
43
43
  }
44
+
45
+ function isEmpty(GlobalState calldata state) internal pure returns (bool) {
46
+ return (state.bytes32Vals[0] == bytes32(0) &&
47
+ state.bytes32Vals[1] == bytes32(0) &&
48
+ state.u64Vals[0] == 0 &&
49
+ state.u64Vals[1] == 0);
50
+ }
44
51
  }
@@ -7,6 +7,14 @@ pragma solidity ^0.8.4;
7
7
  import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
8
8
  import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
9
9
 
10
+ import {
11
+ NotContract,
12
+ NotRollupOrOwner,
13
+ NotDelayedInbox,
14
+ NotSequencerInbox,
15
+ NotOutbox,
16
+ InvalidOutboxSet
17
+ } from "../libraries/Error.sol";
10
18
  import "../bridge/IBridge.sol";
11
19
  import "../bridge/Messages.sol";
12
20
  import "../libraries/DelegateCallAware.sol";
@@ -220,4 +228,6 @@ contract BridgeTester is Initializable, DelegateCallAware, IBridge {
220
228
  }
221
229
 
222
230
  receive() external payable {}
231
+
232
+ function acceptFundsFromOldBridge() external payable {}
223
233
  }
@@ -0,0 +1,11 @@
1
+ // Copyright 2021-2022, Offchain Labs, Inc.
2
+ // For license information, see https://github.com/nitro/blob/master/LICENSE
3
+ // SPDX-License-Identifier: BUSL-1.1
4
+
5
+ // solhint-disable-next-line compiler-version
6
+ pragma solidity >=0.6.9 <0.9.0;
7
+
8
+ import "../bridge/IBridge.sol";
9
+ import "../bridge/IOutbox.sol";
10
+ import "../bridge/IInbox.sol";
11
+ import "../bridge/ISequencerInbox.sol";
@@ -4,6 +4,15 @@
4
4
 
5
5
  pragma solidity ^0.8.4;
6
6
 
7
+ import {
8
+ AlreadyInit,
9
+ NotRollup,
10
+ ProofTooLong,
11
+ PathNotMinimal,
12
+ UnknownRoot,
13
+ AlreadySpent,
14
+ BridgeCallFailed
15
+ } from "../libraries/Error.sol";
7
16
  import "../bridge/IBridge.sol";
8
17
  import "../bridge/IOutbox.sol";
9
18
  import "../libraries/MerkleLib.sol";
@@ -93,7 +102,7 @@ contract OutboxWithoutOptTester is DelegateCallAware, IOutbox {
93
102
  uint256 l2Timestamp,
94
103
  uint256 value,
95
104
  bytes calldata data
96
- ) external virtual {
105
+ ) external virtual override {
97
106
  bytes32 outputId;
98
107
  {
99
108
  bytes32 userTx = calculateItemHash(
@@ -128,6 +137,23 @@ contract OutboxWithoutOptTester is DelegateCallAware, IOutbox {
128
137
  context = prevContext;
129
138
  }
130
139
 
140
+ function executeTransactionSimulation(
141
+ uint256,
142
+ address,
143
+ address,
144
+ uint256,
145
+ uint256,
146
+ uint256,
147
+ uint256,
148
+ bytes calldata
149
+ ) external pure override {
150
+ revert("Not implemented");
151
+ }
152
+
153
+ function isSpent(uint256) external pure override returns (bool) {
154
+ revert("Not implemented");
155
+ }
156
+
131
157
  function recordOutputAsSpent(
132
158
  bytes32[] memory proof,
133
159
  uint256 index,
@@ -173,7 +199,7 @@ contract OutboxWithoutOptTester is DelegateCallAware, IOutbox {
173
199
  uint256 l2Timestamp,
174
200
  uint256 value,
175
201
  bytes calldata data
176
- ) public pure returns (bytes32) {
202
+ ) public pure override returns (bytes32) {
177
203
  return
178
204
  keccak256(abi.encodePacked(l2Sender, to, l2Block, l1Block, l2Timestamp, value, data));
179
205
  }
@@ -182,7 +208,7 @@ contract OutboxWithoutOptTester is DelegateCallAware, IOutbox {
182
208
  bytes32[] memory proof,
183
209
  uint256 path,
184
210
  bytes32 item
185
- ) public pure returns (bytes32) {
211
+ ) public pure override returns (bytes32) {
186
212
  return MerkleLib.calculateRoot(proof, path, keccak256(abi.encodePacked(item)));
187
213
  }
188
214
  }