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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. package/package.json +10 -2
  2. package/src/bridge/Bridge.sol +39 -30
  3. package/src/bridge/IBridge.sol +56 -29
  4. package/src/bridge/IInbox.sol +130 -15
  5. package/src/bridge/IOutbox.sol +55 -7
  6. package/src/bridge/ISequencerInbox.sol +84 -7
  7. package/src/bridge/Inbox.sol +154 -92
  8. package/src/bridge/Outbox.sol +23 -47
  9. package/src/bridge/SequencerInbox.sol +132 -62
  10. package/src/challenge/ChallengeManager.sol +0 -9
  11. package/src/challenge/IChallengeManager.sol +0 -2
  12. package/src/libraries/AdminFallbackProxy.sol +4 -4
  13. package/src/libraries/Constants.sol +3 -0
  14. package/src/libraries/{SecondaryLogicUUPSUpgradeable.sol → DoubleLogicUUPSUpgradeable.sol} +2 -1
  15. package/src/libraries/Error.sol +12 -0
  16. package/src/libraries/IGasRefunder.sol +11 -5
  17. package/src/libraries/MerkleLib.sol +5 -3
  18. package/src/mocks/BridgeStub.sol +20 -1
  19. package/src/mocks/BridgeUnproxied.sol +17 -0
  20. package/src/mocks/InboxStub.sol +48 -3
  21. package/src/mocks/SequencerInboxStub.sol +13 -3
  22. package/src/mocks/Simple.sol +69 -0
  23. package/src/node-interface/NodeInterface.sol +35 -4
  24. package/src/precompiles/ArbGasInfo.sol +7 -4
  25. package/src/precompiles/ArbOwner.sol +9 -0
  26. package/src/precompiles/ArbOwnerPublic.sol +3 -0
  27. package/src/precompiles/ArbSys.sol +5 -2
  28. package/src/rollup/IRollupCore.sol +2 -0
  29. package/src/rollup/IRollupLogic.sol +10 -0
  30. package/src/rollup/RollupAdminLogic.sol +27 -3
  31. package/src/rollup/RollupCore.sol +3 -0
  32. package/src/rollup/RollupCreator.sol +3 -3
  33. package/src/rollup/RollupEventInbox.sol +3 -6
  34. package/src/{libraries/ArbitrumProxy.sol → rollup/RollupProxy.sol} +3 -3
  35. package/src/rollup/RollupUserLogic.sol +47 -10
  36. package/src/test-helpers/BridgeTester.sol +7 -1
  37. package/src/test-helpers/OutboxWithoutOptTester.sol +8 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arbitrum/nitro-contracts",
3
- "version": "1.0.0-beta.8",
3
+ "version": "1.0.0",
4
4
  "description": "Layer 2 precompiles and rollup for Arbitrum Nitro",
5
5
  "author": "Offchain Labs, Inc.",
6
6
  "license": "BUSL-1.1",
@@ -24,7 +24,9 @@
24
24
  "hardhat:prod": "hardhat --config hardhat.prod-config.js",
25
25
  "build:0.6": "INTERFACE_TESTER_SOLC_VERSION=0.6.9 yarn run build",
26
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"
27
+ "test:compatibility": "yarn run build:0.6 && yarn run build:0.7",
28
+ "test:storage": "./test/storage/test.bash",
29
+ "postinstall": "patch-package"
28
30
  },
29
31
  "dependencies": {
30
32
  "@openzeppelin/contracts": "4.5.0",
@@ -34,6 +36,7 @@
34
36
  "private": false,
35
37
  "devDependencies": {
36
38
  "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.13",
39
+ "@nomiclabs/hardhat-etherscan": "^3.1.0",
37
40
  "@nomiclabs/hardhat-waffle": "^2.0.1",
38
41
  "@typechain/ethers-v5": "^10.0.0",
39
42
  "@typechain/hardhat": "^6.0.0",
@@ -45,6 +48,8 @@
45
48
  "ethers": "^5.5.2",
46
49
  "hardhat-deploy": "^0.11.4",
47
50
  "hardhat-gas-reporter": "^1.0.8",
51
+ "patch-package": "^6.4.7",
52
+ "postinstall-postinstall": "^2.1.0",
48
53
  "prettier": "^2.5.1",
49
54
  "prettier-plugin-solidity": "^1.0.0-beta.19",
50
55
  "solhint": "^3.3.7",
@@ -53,5 +58,8 @@
53
58
  "ts-node": "^10.4.0",
54
59
  "typechain": "^8.0.0",
55
60
  "typescript": "^4.5.4"
61
+ },
62
+ "optionalDependencies":{
63
+ "sol2uml": "2.2.0"
56
64
  }
57
65
  }
@@ -13,7 +13,8 @@ import {
13
13
  NotDelayedInbox,
14
14
  NotSequencerInbox,
15
15
  NotOutbox,
16
- InvalidOutboxSet
16
+ InvalidOutboxSet,
17
+ BadSequencerMessageNumber
17
18
  } from "../libraries/Error.sol";
18
19
  import "./IBridge.sol";
19
20
  import "./Messages.sol";
@@ -42,18 +43,20 @@ contract Bridge is Initializable, DelegateCallAware, IBridge {
42
43
  address[] public allowedDelayedInboxList;
43
44
  address[] public allowedOutboxList;
44
45
 
45
- address private _activeOutbox;
46
+ address internal _activeOutbox;
46
47
 
47
- /// @dev Accumulator for delayed inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message.
48
- bytes32[] public override delayedInboxAccs;
48
+ /// @inheritdoc IBridge
49
+ bytes32[] public delayedInboxAccs;
49
50
 
50
- /// @dev Accumulator for sequencer inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message.
51
- bytes32[] public override sequencerInboxAccs;
51
+ /// @inheritdoc IBridge
52
+ bytes32[] public sequencerInboxAccs;
52
53
 
53
- IOwnable public override rollup;
54
+ IOwnable public rollup;
54
55
  address public sequencerInbox;
55
56
 
56
- address private constant EMPTY_ACTIVEOUTBOX = address(type(uint160).max);
57
+ uint256 public override sequencerReportedSubMessageCount;
58
+
59
+ address internal constant EMPTY_ACTIVEOUTBOX = address(type(uint160).max);
57
60
 
58
61
  function initialize(IOwnable rollup_) external initializer onlyDelegated {
59
62
  _activeOutbox = EMPTY_ACTIVEOUTBOX;
@@ -81,11 +84,11 @@ contract Bridge is Initializable, DelegateCallAware, IBridge {
81
84
  return outbox;
82
85
  }
83
86
 
84
- function allowedDelayedInboxes(address inbox) external view override returns (bool) {
87
+ function allowedDelayedInboxes(address inbox) external view returns (bool) {
85
88
  return allowedDelayedInboxesMap[inbox].allowed;
86
89
  }
87
90
 
88
- function allowedOutboxes(address outbox) external view override returns (bool) {
91
+ function allowedOutboxes(address outbox) external view returns (bool) {
89
92
  return allowedOutboxesMap[outbox].allowed;
90
93
  }
91
94
 
@@ -94,9 +97,13 @@ contract Bridge is Initializable, DelegateCallAware, IBridge {
94
97
  _;
95
98
  }
96
99
 
97
- function enqueueSequencerMessage(bytes32 dataHash, uint256 afterDelayedMessagesRead)
100
+ function enqueueSequencerMessage(
101
+ bytes32 dataHash,
102
+ uint256 afterDelayedMessagesRead,
103
+ uint256 prevMessageCount,
104
+ uint256 newMessageCount
105
+ )
98
106
  external
99
- override
100
107
  onlySequencerInbox
101
108
  returns (
102
109
  uint256 seqMessageIndex,
@@ -105,6 +112,14 @@ contract Bridge is Initializable, DelegateCallAware, IBridge {
105
112
  bytes32 acc
106
113
  )
107
114
  {
115
+ if (
116
+ sequencerReportedSubMessageCount != prevMessageCount &&
117
+ prevMessageCount != 0 &&
118
+ sequencerReportedSubMessageCount != 0
119
+ ) {
120
+ revert BadSequencerMessageNumber(sequencerReportedSubMessageCount, prevMessageCount);
121
+ }
122
+ sequencerReportedSubMessageCount = newMessageCount;
108
123
  seqMessageIndex = sequencerInboxAccs.length;
109
124
  if (sequencerInboxAccs.length > 0) {
110
125
  beforeAcc = sequencerInboxAccs[sequencerInboxAccs.length - 1];
@@ -116,15 +131,9 @@ contract Bridge is Initializable, DelegateCallAware, IBridge {
116
131
  sequencerInboxAccs.push(acc);
117
132
  }
118
133
 
119
- /**
120
- * @dev allows the sequencer inbox to submit a delayed message of the batchPostingReport type
121
- * This is done through a separate function entrypoint instead of allowing the sequencer inbox
122
- * to call `enqueueDelayedMessage` to avoid the gas overhead of an extra SLOAD in either
123
- * every delayed inbox or every sequencer inbox call.
124
- */
134
+ /// @inheritdoc IBridge
125
135
  function submitBatchSpendingReport(address sender, bytes32 messageDataHash)
126
136
  external
127
- override
128
137
  onlySequencerInbox
129
138
  returns (uint256)
130
139
  {
@@ -139,16 +148,12 @@ contract Bridge is Initializable, DelegateCallAware, IBridge {
139
148
  );
140
149
  }
141
150
 
142
- /**
143
- * @dev Enqueue a message in the delayed inbox accumulator.
144
- * These messages are later sequenced in the SequencerInbox, either by the sequencer as
145
- * part of a normal batch, or by force inclusion.
146
- */
151
+ /// @inheritdoc IBridge
147
152
  function enqueueDelayedMessage(
148
153
  uint8 kind,
149
154
  address sender,
150
155
  bytes32 messageDataHash
151
- ) external payable override returns (uint256) {
156
+ ) external payable returns (uint256) {
152
157
  if (!allowedDelayedInboxesMap[msg.sender].allowed) revert NotDelayedInbox(msg.sender);
153
158
  return
154
159
  addMessageToDelayedAccumulator(
@@ -201,7 +206,7 @@ contract Bridge is Initializable, DelegateCallAware, IBridge {
201
206
  address to,
202
207
  uint256 value,
203
208
  bytes calldata data
204
- ) external override returns (bool success, bytes memory returnData) {
209
+ ) external returns (bool success, bytes memory returnData) {
205
210
  if (!allowedOutboxesMap[msg.sender].allowed) revert NotOutbox(msg.sender);
206
211
  if (data.length > 0 && !to.isContract()) revert NotContract(to);
207
212
  address prevOutbox = _activeOutbox;
@@ -216,12 +221,12 @@ contract Bridge is Initializable, DelegateCallAware, IBridge {
216
221
  emit BridgeCallTriggered(msg.sender, to, value, data);
217
222
  }
218
223
 
219
- function setSequencerInbox(address _sequencerInbox) external override onlyRollupOrOwner {
224
+ function setSequencerInbox(address _sequencerInbox) external onlyRollupOrOwner {
220
225
  sequencerInbox = _sequencerInbox;
221
226
  emit SequencerInboxUpdated(_sequencerInbox);
222
227
  }
223
228
 
224
- function setDelayedInbox(address inbox, bool enabled) external override onlyRollupOrOwner {
229
+ function setDelayedInbox(address inbox, bool enabled) external onlyRollupOrOwner {
225
230
  InOutInfo storage info = allowedDelayedInboxesMap[inbox];
226
231
  bool alreadyEnabled = info.allowed;
227
232
  emit InboxToggle(inbox, enabled);
@@ -241,7 +246,7 @@ contract Bridge is Initializable, DelegateCallAware, IBridge {
241
246
  }
242
247
  }
243
248
 
244
- function setOutbox(address outbox, bool enabled) external override onlyRollupOrOwner {
249
+ function setOutbox(address outbox, bool enabled) external onlyRollupOrOwner {
245
250
  if (outbox == EMPTY_ACTIVEOUTBOX) revert InvalidOutboxSet(outbox);
246
251
 
247
252
  InOutInfo storage info = allowedOutboxesMap[outbox];
@@ -261,11 +266,15 @@ contract Bridge is Initializable, DelegateCallAware, IBridge {
261
266
  }
262
267
  }
263
268
 
269
+ function setSequencerReportedSubMessageCount(uint256 newMsgCount) external onlyRollupOrOwner {
270
+ sequencerReportedSubMessageCount = newMsgCount;
271
+ }
272
+
264
273
  function delayedMessageCount() external view override returns (uint256) {
265
274
  return delayedInboxAccs.length;
266
275
  }
267
276
 
268
- function sequencerMessageCount() external view override returns (uint256) {
277
+ function sequencerMessageCount() external view returns (uint256) {
269
278
  return sequencerInboxAccs.length;
270
279
  }
271
280
 
@@ -32,13 +32,57 @@ interface IBridge {
32
32
 
33
33
  event SequencerInboxUpdated(address newSequencerInbox);
34
34
 
35
+ function allowedDelayedInboxList(uint256) external returns (address);
36
+
37
+ function allowedOutboxList(uint256) external returns (address);
38
+
39
+ /// @dev Accumulator for delayed inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message.
40
+ function delayedInboxAccs(uint256) external view returns (bytes32);
41
+
42
+ /// @dev Accumulator for sequencer inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message.
43
+ function sequencerInboxAccs(uint256) external view returns (bytes32);
44
+
45
+ function rollup() external view returns (IOwnable);
46
+
47
+ function sequencerInbox() external view returns (address);
48
+
49
+ function activeOutbox() external view returns (address);
50
+
51
+ function allowedDelayedInboxes(address inbox) external view returns (bool);
52
+
53
+ function allowedOutboxes(address outbox) external view returns (bool);
54
+
55
+ function sequencerReportedSubMessageCount() external view returns (uint256);
56
+
57
+ /**
58
+ * @dev Enqueue a message in the delayed inbox accumulator.
59
+ * These messages are later sequenced in the SequencerInbox, either
60
+ * by the sequencer as part of a normal batch, or by force inclusion.
61
+ */
35
62
  function enqueueDelayedMessage(
36
63
  uint8 kind,
37
64
  address sender,
38
65
  bytes32 messageDataHash
39
66
  ) external payable returns (uint256);
40
67
 
41
- function enqueueSequencerMessage(bytes32 dataHash, uint256 afterDelayedMessagesRead)
68
+ function executeCall(
69
+ address to,
70
+ uint256 value,
71
+ bytes calldata data
72
+ ) external returns (bool success, bytes memory returnData);
73
+
74
+ function delayedMessageCount() external view returns (uint256);
75
+
76
+ function sequencerMessageCount() external view returns (uint256);
77
+
78
+ // ---------- onlySequencerInbox functions ----------
79
+
80
+ function enqueueSequencerMessage(
81
+ bytes32 dataHash,
82
+ uint256 afterDelayedMessagesRead,
83
+ uint256 prevMessageCount,
84
+ uint256 newMessageCount
85
+ )
42
86
  external
43
87
  returns (
44
88
  uint256 seqMessageIndex,
@@ -47,42 +91,25 @@ interface IBridge {
47
91
  bytes32 acc
48
92
  );
49
93
 
94
+ /**
95
+ * @dev Allows the sequencer inbox to submit a delayed message of the batchPostingReport type
96
+ * This is done through a separate function entrypoint instead of allowing the sequencer inbox
97
+ * to call `enqueueDelayedMessage` to avoid the gas overhead of an extra SLOAD in either
98
+ * every delayed inbox or every sequencer inbox call.
99
+ */
50
100
  function submitBatchSpendingReport(address batchPoster, bytes32 dataHash)
51
101
  external
52
102
  returns (uint256 msgNum);
53
103
 
54
- function executeCall(
55
- address to,
56
- uint256 value,
57
- bytes calldata data
58
- ) external returns (bool success, bytes memory returnData);
59
-
60
- // These are only callable by the admin
61
- function setDelayedInbox(address inbox, bool enabled) external;
62
-
63
- function setOutbox(address inbox, bool enabled) external;
104
+ // ---------- onlyRollupOrOwner functions ----------
64
105
 
65
106
  function setSequencerInbox(address _sequencerInbox) external;
66
107
 
67
- // View functions
68
-
69
- function sequencerInbox() external view returns (address);
70
-
71
- function activeOutbox() external view returns (address);
72
-
73
- function allowedDelayedInboxes(address inbox) external view returns (bool);
74
-
75
- function allowedOutboxes(address outbox) external view returns (bool);
76
-
77
- function delayedInboxAccs(uint256 index) external view returns (bytes32);
78
-
79
- function sequencerInboxAccs(uint256 index) external view returns (bytes32);
80
-
81
- function delayedMessageCount() external view returns (uint256);
108
+ function setDelayedInbox(address inbox, bool enabled) external;
82
109
 
83
- function sequencerMessageCount() external view returns (uint256);
110
+ function setOutbox(address inbox, bool enabled) external;
84
111
 
85
- function rollup() external view returns (IOwnable);
112
+ // ---------- initializer ----------
86
113
 
87
- function acceptFundsFromOldBridge() external payable;
114
+ function initialize(IOwnable rollup_) external;
88
115
  }
@@ -7,10 +7,44 @@ pragma solidity >=0.6.9 <0.9.0;
7
7
 
8
8
  import "./IBridge.sol";
9
9
  import "./IDelayedMessageProvider.sol";
10
+ import "./ISequencerInbox.sol";
10
11
 
11
12
  interface IInbox is IDelayedMessageProvider {
13
+ function bridge() external view returns (IBridge);
14
+
15
+ function sequencerInbox() external view returns (ISequencerInbox);
16
+
17
+ /**
18
+ * @notice Send a generic L2 message to the chain
19
+ * @dev This method is an optimization to avoid having to emit the entirety of the messageData in a log. Instead validators are expected to be able to parse the data from the transaction's input
20
+ * This method will be disabled upon L1 fork to prevent replay attacks on L2
21
+ * @param messageData Data of the message being sent
22
+ */
23
+ function sendL2MessageFromOrigin(bytes calldata messageData) external returns (uint256);
24
+
25
+ /**
26
+ * @notice Send a generic L2 message to the chain
27
+ * @dev This method can be used to send any type of message that doesn't require L1 validation
28
+ * This method will be disabled upon L1 fork to prevent replay attacks on L2
29
+ * @param messageData Data of the message being sent
30
+ */
12
31
  function sendL2Message(bytes calldata messageData) external returns (uint256);
13
32
 
33
+ function sendL1FundedUnsignedTransaction(
34
+ uint256 gasLimit,
35
+ uint256 maxFeePerGas,
36
+ uint256 nonce,
37
+ address to,
38
+ bytes calldata data
39
+ ) external payable returns (uint256);
40
+
41
+ function sendL1FundedContractTransaction(
42
+ uint256 gasLimit,
43
+ uint256 maxFeePerGas,
44
+ address to,
45
+ bytes calldata data
46
+ ) external payable returns (uint256);
47
+
14
48
  function sendUnsignedTransaction(
15
49
  uint256 gasLimit,
16
50
  uint256 maxFeePerGas,
@@ -28,7 +62,11 @@ interface IInbox is IDelayedMessageProvider {
28
62
  bytes calldata data
29
63
  ) external returns (uint256);
30
64
 
31
- function sendL1FundedUnsignedTransaction(
65
+ /**
66
+ * @dev This method can only be called upon L1 fork and will not alias the caller
67
+ * This method will revert if not called from origin
68
+ */
69
+ function sendL1FundedUnsignedTransactionToFork(
32
70
  uint256 gasLimit,
33
71
  uint256 maxFeePerGas,
34
72
  uint256 nonce,
@@ -36,43 +74,120 @@ interface IInbox is IDelayedMessageProvider {
36
74
  bytes calldata data
37
75
  ) external payable returns (uint256);
38
76
 
39
- function sendL1FundedContractTransaction(
77
+ /**
78
+ * @dev This method can only be called upon L1 fork and will not alias the caller
79
+ * This method will revert if not called from origin
80
+ */
81
+ function sendUnsignedTransactionToFork(
40
82
  uint256 gasLimit,
41
83
  uint256 maxFeePerGas,
84
+ uint256 nonce,
42
85
  address to,
86
+ uint256 value,
43
87
  bytes calldata data
44
- ) external payable returns (uint256);
88
+ ) external returns (uint256);
45
89
 
46
- /// @dev Gas limit and maxFeePerGas should not be set to 1 as that is used to trigger the RetryableData error
90
+ /**
91
+ * @notice Send a message to initiate L2 withdrawal
92
+ * @dev This method can only be called upon L1 fork and will not alias the caller
93
+ * This method will revert if not called from origin
94
+ */
95
+ function sendWithdrawEthToFork(
96
+ uint256 gasLimit,
97
+ uint256 maxFeePerGas,
98
+ uint256 nonce,
99
+ uint256 value,
100
+ address withdrawTo
101
+ ) external returns (uint256);
102
+
103
+ /**
104
+ * @notice Get the L1 fee for submitting a retryable
105
+ * @dev This fee can be paid by funds already in the L2 aliased address or by the current message value
106
+ * @dev This formula may change in the future, to future proof your code query this method instead of inlining!!
107
+ * @param dataLength The length of the retryable's calldata, in bytes
108
+ * @param baseFee The block basefee when the retryable is included in the chain, if 0 current block.basefee will be used
109
+ */
110
+ function calculateRetryableSubmissionFee(uint256 dataLength, uint256 baseFee)
111
+ external
112
+ view
113
+ returns (uint256);
114
+
115
+ /**
116
+ * @notice Deposit eth from L1 to L2 to address of the sender if sender is an EOA, and to its aliased address if the sender is a contract
117
+ * @dev This does not trigger the fallback function when receiving in the L2 side.
118
+ * Look into retryable tickets if you are interested in this functionality.
119
+ * @dev This function should not be called inside contract constructors
120
+ */
121
+ function depositEth() external payable returns (uint256);
122
+
123
+ /**
124
+ * @notice Put a message in the L2 inbox that can be reexecuted for some fixed amount of time if it reverts
125
+ * @dev all msg.value will deposited to callValueRefundAddress on L2
126
+ * @dev Gas limit and maxFeePerGas should not be set to 1 as that is used to trigger the RetryableData error
127
+ * @param to destination L2 contract address
128
+ * @param l2CallValue call value for retryable L2 message
129
+ * @param maxSubmissionCost Max gas deducted from user's L2 balance to cover base submission fee
130
+ * @param excessFeeRefundAddress gasLimit x maxFeePerGas - execution cost gets credited here on L2 balance
131
+ * @param callValueRefundAddress l2Callvalue gets credited here on L2 if retryable txn times out or gets cancelled
132
+ * @param gasLimit Max gas deducted from user's L2 balance to cover L2 execution. Should not be set to 1 (magic value used to trigger the RetryableData error)
133
+ * @param maxFeePerGas price bid for L2 execution. Should not be set to 1 (magic value used to trigger the RetryableData error)
134
+ * @param data ABI encoded data of L2 message
135
+ * @return unique message number of the retryable transaction
136
+ */
47
137
  function createRetryableTicket(
48
138
  address to,
49
- uint256 arbTxCallValue,
139
+ uint256 l2CallValue,
50
140
  uint256 maxSubmissionCost,
51
- address submissionRefundAddress,
52
- address valueRefundAddress,
141
+ address excessFeeRefundAddress,
142
+ address callValueRefundAddress,
53
143
  uint256 gasLimit,
54
144
  uint256 maxFeePerGas,
55
145
  bytes calldata data
56
146
  ) external payable returns (uint256);
57
147
 
58
- /// @dev Gas limit and maxFeePerGas should not be set to 1 as that is used to trigger the RetryableData error
148
+ /**
149
+ * @notice Put a message in the L2 inbox that can be reexecuted for some fixed amount of time if it reverts
150
+ * @dev Same as createRetryableTicket, but does not guarantee that submission will succeed by requiring the needed funds
151
+ * come from the deposit alone, rather than falling back on the user's L2 balance
152
+ * @dev Advanced usage only (does not rewrite aliases for excessFeeRefundAddress and callValueRefundAddress).
153
+ * createRetryableTicket method is the recommended standard.
154
+ * @dev Gas limit and maxFeePerGas should not be set to 1 as that is used to trigger the RetryableData error
155
+ * @param to destination L2 contract address
156
+ * @param l2CallValue call value for retryable L2 message
157
+ * @param maxSubmissionCost Max gas deducted from user's L2 balance to cover base submission fee
158
+ * @param excessFeeRefundAddress gasLimit x maxFeePerGas - execution cost gets credited here on L2 balance
159
+ * @param callValueRefundAddress l2Callvalue gets credited here on L2 if retryable txn times out or gets cancelled
160
+ * @param gasLimit Max gas deducted from user's L2 balance to cover L2 execution. Should not be set to 1 (magic value used to trigger the RetryableData error)
161
+ * @param maxFeePerGas price bid for L2 execution. Should not be set to 1 (magic value used to trigger the RetryableData error)
162
+ * @param data ABI encoded data of L2 message
163
+ * @return unique message number of the retryable transaction
164
+ */
59
165
  function unsafeCreateRetryableTicket(
60
166
  address to,
61
- uint256 arbTxCallValue,
167
+ uint256 l2CallValue,
62
168
  uint256 maxSubmissionCost,
63
- address submissionRefundAddress,
64
- address valueRefundAddress,
169
+ address excessFeeRefundAddress,
170
+ address callValueRefundAddress,
65
171
  uint256 gasLimit,
66
172
  uint256 maxFeePerGas,
67
173
  bytes calldata data
68
174
  ) external payable returns (uint256);
69
175
 
70
- function depositEth() external payable returns (uint256);
176
+ // ---------- onlyRollupOrOwner functions ----------
71
177
 
72
- /// @notice deprecated in favour of depositEth with no parameters
73
- function depositEth(uint256 maxSubmissionCost) external payable returns (uint256);
178
+ /// @notice pauses all inbox functionality
179
+ function pause() external;
74
180
 
75
- function bridge() external view returns (IBridge);
181
+ /// @notice unpauses all inbox functionality
182
+ function unpause() external;
76
183
 
184
+ // ---------- initializer ----------
185
+
186
+ /**
187
+ * @dev function to be called one time during the inbox upgrade process
188
+ * this is used to fix the storage slots
189
+ */
77
190
  function postUpgradeInit(IBridge _bridge) external;
191
+
192
+ function initialize(IBridge _bridge, ISequencerInbox _sequencerInbox) external;
78
193
  }
@@ -5,8 +5,10 @@
5
5
  // solhint-disable-next-line compiler-version
6
6
  pragma solidity >=0.6.9 <0.9.0;
7
7
 
8
+ import "./IBridge.sol";
9
+
8
10
  interface IOutbox {
9
- event SendRootUpdated(bytes32 indexed blockHash, bytes32 indexed outputRoot);
11
+ event SendRootUpdated(bytes32 indexed outputRoot, bytes32 indexed l2BlockHash);
10
12
  event OutBoxTransactionExecuted(
11
13
  address indexed to,
12
14
  address indexed l2Sender,
@@ -14,21 +16,52 @@ interface IOutbox {
14
16
  uint256 transactionIndex
15
17
  );
16
18
 
19
+ function rollup() external view returns (address); // the rollup contract
20
+
21
+ function bridge() external view returns (IBridge); // the bridge contract
22
+
23
+ function spent(uint256) external view returns (bytes32); // packed spent bitmap
24
+
25
+ function roots(bytes32) external view returns (bytes32); // maps root hashes => L2 block hash
26
+
27
+ // solhint-disable-next-line func-name-mixedcase
28
+ function OUTBOX_VERSION() external view returns (uint128); // the outbox version
29
+
30
+ function updateSendRoot(bytes32 sendRoot, bytes32 l2BlockHash) external;
31
+
32
+ /// @notice When l2ToL1Sender returns a nonzero address, the message was originated by an L2 account
33
+ /// When the return value is zero, that means this is a system message
34
+ /// @dev the l2ToL1Sender behaves as the tx.origin, the msg.sender should be validated to protect against reentrancies
17
35
  function l2ToL1Sender() external view returns (address);
18
36
 
37
+ /// @return l2Block return L2 block when the L2 tx was initiated or 0 if no L2 to L1 transaction is active
19
38
  function l2ToL1Block() external view returns (uint256);
20
39
 
40
+ /// @return l1Block return L1 block when the L2 tx was initiated or 0 if no L2 to L1 transaction is active
21
41
  function l2ToL1EthBlock() external view returns (uint256);
22
42
 
43
+ /// @return timestamp return L2 timestamp when the L2 tx was initiated or 0 if no L2 to L1 transaction is active
23
44
  function l2ToL1Timestamp() external view returns (uint256);
24
45
 
25
- // @deprecated batch number is now always 0
26
- function l2ToL1BatchNum() external view returns (uint256);
27
-
46
+ /// @return outputId returns the unique output identifier of the L2 to L1 tx or 0 if no L2 to L1 transaction is active
28
47
  function l2ToL1OutputId() external view returns (bytes32);
29
48
 
30
- function updateSendRoot(bytes32 sendRoot, bytes32 l2BlockHash) external;
31
-
49
+ /**
50
+ * @notice Executes a messages in an Outbox entry.
51
+ * @dev Reverts if dispute period hasn't expired, since the outbox entry
52
+ * is only created once the rollup confirms the respective assertion.
53
+ * @dev it is not possible to execute any L2-to-L1 transaction which contains data
54
+ * to a contract address without any code (as enforced by the Bridge contract).
55
+ * @param proof Merkle proof of message inclusion in send root
56
+ * @param index Merkle path to message
57
+ * @param l2Sender sender if original message (i.e., caller of ArbSys.sendTxToL1)
58
+ * @param to destination address for L1 contract call
59
+ * @param l2Block l2 block number at which sendTxToL1 call was made
60
+ * @param l1Block l1 block number at which sendTxToL1 call was made
61
+ * @param l2Timestamp l2 Timestamp at which sendTxToL1 call was made
62
+ * @param value wei in L1 message
63
+ * @param data abi-encoded L1 message data
64
+ */
32
65
  function executeTransaction(
33
66
  bytes32[] calldata proof,
34
67
  uint256 index,
@@ -41,6 +74,17 @@ interface IOutbox {
41
74
  bytes calldata data
42
75
  ) external;
43
76
 
77
+ /**
78
+ * @dev function used to simulate the result of a particular function call from the outbox
79
+ * it is useful for things such as gas estimates. This function includes all costs except for
80
+ * proof validation (which can be considered offchain as a somewhat of a fixed cost - it's
81
+ * not really a fixed cost, but can be treated as so with a fixed overhead for gas estimation).
82
+ * We can't include the cost of proof validation since this is intended to be used to simulate txs
83
+ * that are included in yet-to-be confirmed merkle roots. The simulation entrypoint could instead pretend
84
+ * to confirm a pending merkle root, but that would be less practical for integrating with tooling.
85
+ * It is only possible to trigger it when the msg sender is address zero, which should be impossible
86
+ * unless under simulation in an eth_call or eth_estimateGas
87
+ */
44
88
  function executeTransactionSimulation(
45
89
  uint256 index,
46
90
  address l2Sender,
@@ -52,7 +96,11 @@ interface IOutbox {
52
96
  bytes calldata data
53
97
  ) external;
54
98
 
55
- function isSpent(uint256) external view returns (bool);
99
+ /**
100
+ * @param index Merkle path to message
101
+ * @return true if the message has been spent
102
+ */
103
+ function isSpent(uint256 index) external view returns (bool);
56
104
 
57
105
  function calculateItemHash(
58
106
  address l2Sender,