@arbitrum/nitro-contracts 1.0.0-beta.8 → 1.0.0
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 +10 -2
- package/src/bridge/Bridge.sol +39 -30
- package/src/bridge/IBridge.sol +56 -29
- package/src/bridge/IInbox.sol +130 -15
- package/src/bridge/IOutbox.sol +55 -7
- package/src/bridge/ISequencerInbox.sol +84 -7
- package/src/bridge/Inbox.sol +154 -92
- package/src/bridge/Outbox.sol +23 -47
- package/src/bridge/SequencerInbox.sol +132 -62
- package/src/challenge/ChallengeManager.sol +0 -9
- package/src/challenge/IChallengeManager.sol +0 -2
- package/src/libraries/AdminFallbackProxy.sol +4 -4
- package/src/libraries/Constants.sol +3 -0
- package/src/libraries/{SecondaryLogicUUPSUpgradeable.sol → DoubleLogicUUPSUpgradeable.sol} +2 -1
- package/src/libraries/Error.sol +12 -0
- package/src/libraries/IGasRefunder.sol +11 -5
- package/src/libraries/MerkleLib.sol +5 -3
- package/src/mocks/BridgeStub.sol +20 -1
- package/src/mocks/BridgeUnproxied.sol +17 -0
- package/src/mocks/InboxStub.sol +48 -3
- package/src/mocks/SequencerInboxStub.sol +13 -3
- package/src/mocks/Simple.sol +69 -0
- package/src/node-interface/NodeInterface.sol +35 -4
- package/src/precompiles/ArbGasInfo.sol +7 -4
- package/src/precompiles/ArbOwner.sol +9 -0
- package/src/precompiles/ArbOwnerPublic.sol +3 -0
- package/src/precompiles/ArbSys.sol +5 -2
- package/src/rollup/IRollupCore.sol +2 -0
- package/src/rollup/IRollupLogic.sol +10 -0
- package/src/rollup/RollupAdminLogic.sol +27 -3
- package/src/rollup/RollupCore.sol +3 -0
- package/src/rollup/RollupCreator.sol +3 -3
- package/src/rollup/RollupEventInbox.sol +3 -6
- package/src/{libraries/ArbitrumProxy.sol → rollup/RollupProxy.sol} +3 -3
- package/src/rollup/RollupUserLogic.sol +47 -10
- package/src/test-helpers/BridgeTester.sol +7 -1
- 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
|
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
|
}
|
package/src/bridge/Bridge.sol
CHANGED
@@ -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
|
46
|
+
address internal _activeOutbox;
|
46
47
|
|
47
|
-
/// @
|
48
|
-
bytes32[] public
|
48
|
+
/// @inheritdoc IBridge
|
49
|
+
bytes32[] public delayedInboxAccs;
|
49
50
|
|
50
|
-
/// @
|
51
|
-
bytes32[] public
|
51
|
+
/// @inheritdoc IBridge
|
52
|
+
bytes32[] public sequencerInboxAccs;
|
52
53
|
|
53
|
-
IOwnable public
|
54
|
+
IOwnable public rollup;
|
54
55
|
address public sequencerInbox;
|
55
56
|
|
56
|
-
|
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
|
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
|
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(
|
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
|
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
|
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
|
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
|
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
|
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
|
277
|
+
function sequencerMessageCount() external view returns (uint256) {
|
269
278
|
return sequencerInboxAccs.length;
|
270
279
|
}
|
271
280
|
|
package/src/bridge/IBridge.sol
CHANGED
@@ -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
|
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
|
-
|
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
|
-
|
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
|
110
|
+
function setOutbox(address inbox, bool enabled) external;
|
84
111
|
|
85
|
-
|
112
|
+
// ---------- initializer ----------
|
86
113
|
|
87
|
-
function
|
114
|
+
function initialize(IOwnable rollup_) external;
|
88
115
|
}
|
package/src/bridge/IInbox.sol
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
88
|
+
) external returns (uint256);
|
45
89
|
|
46
|
-
|
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
|
139
|
+
uint256 l2CallValue,
|
50
140
|
uint256 maxSubmissionCost,
|
51
|
-
address
|
52
|
-
address
|
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
|
-
|
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
|
167
|
+
uint256 l2CallValue,
|
62
168
|
uint256 maxSubmissionCost,
|
63
|
-
address
|
64
|
-
address
|
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
|
-
|
176
|
+
// ---------- onlyRollupOrOwner functions ----------
|
71
177
|
|
72
|
-
/// @notice
|
73
|
-
function
|
178
|
+
/// @notice pauses all inbox functionality
|
179
|
+
function pause() external;
|
74
180
|
|
75
|
-
|
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
|
}
|
package/src/bridge/IOutbox.sol
CHANGED
@@ -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
|
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
|
-
|
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
|
-
|
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
|
-
|
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,
|