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

Sign up to get free protection for your applications and to get access to all the features.
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
  }