@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.
- 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
@@ -9,6 +9,7 @@ import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
|
|
9
9
|
import {IRollupUser} from "./IRollupLogic.sol";
|
10
10
|
import "../libraries/UUPSNotUpgradeable.sol";
|
11
11
|
import "./RollupCore.sol";
|
12
|
+
import {ETH_POS_BLOCK_TIME} from "../libraries/Constants.sol";
|
12
13
|
|
13
14
|
abstract contract AbsRollupUserLogic is
|
14
15
|
RollupCore,
|
@@ -20,10 +21,43 @@ abstract contract AbsRollupUserLogic is
|
|
20
21
|
using GlobalStateLib for GlobalState;
|
21
22
|
|
22
23
|
modifier onlyValidator() {
|
23
|
-
require(isValidator[msg.sender], "NOT_VALIDATOR");
|
24
|
+
require(isValidator[msg.sender] || validatorWhitelistDisabled, "NOT_VALIDATOR");
|
24
25
|
_;
|
25
26
|
}
|
26
27
|
|
28
|
+
uint256 internal immutable deployTimeChainId = block.chainid;
|
29
|
+
|
30
|
+
function _chainIdChanged() internal view returns (bool) {
|
31
|
+
return deployTimeChainId != block.chainid;
|
32
|
+
}
|
33
|
+
|
34
|
+
/**
|
35
|
+
* @notice Extra number of blocks the validator can remain inactive before considered inactive
|
36
|
+
* This is 7 days assuming a 13.2 seconds block time
|
37
|
+
*/
|
38
|
+
uint256 public constant VALIDATOR_AFK_BLOCKS = 45818;
|
39
|
+
|
40
|
+
function _validatorIsAfk() internal view returns (bool) {
|
41
|
+
Node memory latestNode = getNodeStorage(latestNodeCreated());
|
42
|
+
if (latestNode.createdAtBlock == 0) return false;
|
43
|
+
if (latestNode.createdAtBlock + confirmPeriodBlocks + VALIDATOR_AFK_BLOCKS < block.number) {
|
44
|
+
return true;
|
45
|
+
}
|
46
|
+
return false;
|
47
|
+
}
|
48
|
+
|
49
|
+
function removeWhitelistAfterFork() external {
|
50
|
+
require(!validatorWhitelistDisabled, "WHITELIST_DISABLED");
|
51
|
+
require(_chainIdChanged(), "CHAIN_ID_NOT_CHANGED");
|
52
|
+
validatorWhitelistDisabled = true;
|
53
|
+
}
|
54
|
+
|
55
|
+
function removeWhitelistAfterValidatorAfk() external {
|
56
|
+
require(!validatorWhitelistDisabled, "WHITELIST_DISABLED");
|
57
|
+
require(_validatorIsAfk(), "VALIDATOR_NOT_AFK");
|
58
|
+
validatorWhitelistDisabled = true;
|
59
|
+
}
|
60
|
+
|
27
61
|
function isERC20Enabled() public view override returns (bool) {
|
28
62
|
return stakeToken != address(0);
|
29
63
|
}
|
@@ -239,7 +273,7 @@ abstract contract AbsRollupUserLogic is
|
|
239
273
|
* @param globalStates The before and after global state for the first assertion
|
240
274
|
* @param numBlocks The number of L2 blocks contained in the first assertion
|
241
275
|
* @param secondExecutionHash The execution hash of the second assertion
|
242
|
-
* @param
|
276
|
+
* @param proposedBlocks L1 block numbers that the two nodes were proposed at
|
243
277
|
* @param wasmModuleRoots The wasm module roots at the time of the creation of each assertion
|
244
278
|
*/
|
245
279
|
function createChallenge(
|
@@ -249,7 +283,7 @@ abstract contract AbsRollupUserLogic is
|
|
249
283
|
GlobalState[2] calldata globalStates,
|
250
284
|
uint64 numBlocks,
|
251
285
|
bytes32 secondExecutionHash,
|
252
|
-
uint256[2] calldata
|
286
|
+
uint256[2] calldata proposedBlocks,
|
253
287
|
bytes32[2] calldata wasmModuleRoots
|
254
288
|
) external onlyValidator whenNotPaused {
|
255
289
|
require(nodeNums[0] < nodeNums[1], "WRONG_ORDER");
|
@@ -274,7 +308,7 @@ abstract contract AbsRollupUserLogic is
|
|
274
308
|
node1.challengeHash ==
|
275
309
|
RollupLib.challengeRootHash(
|
276
310
|
RollupLib.executionHash(machineStatuses, globalStates, numBlocks),
|
277
|
-
|
311
|
+
proposedBlocks[0],
|
278
312
|
wasmModuleRoots[0]
|
279
313
|
),
|
280
314
|
"CHAL_HASH1"
|
@@ -284,18 +318,18 @@ abstract contract AbsRollupUserLogic is
|
|
284
318
|
node2.challengeHash ==
|
285
319
|
RollupLib.challengeRootHash(
|
286
320
|
secondExecutionHash,
|
287
|
-
|
321
|
+
proposedBlocks[1],
|
288
322
|
wasmModuleRoots[1]
|
289
323
|
),
|
290
324
|
"CHAL_HASH2"
|
291
325
|
);
|
292
326
|
|
293
327
|
// Calculate upper limit for allowed node proposal time:
|
294
|
-
uint256
|
328
|
+
uint256 commonEndBlock = getNodeStorage(node1.prevNum).firstChildBlock +
|
295
329
|
// Dispute start: dispute timer for a node starts when its first child is created
|
296
|
-
(node1.deadlineBlock -
|
330
|
+
(node1.deadlineBlock - proposedBlocks[0]) +
|
297
331
|
extraChallengeTimeBlocks; // add dispute window to dispute start time
|
298
|
-
if (
|
332
|
+
if (commonEndBlock < proposedBlocks[1]) {
|
299
333
|
// The 2nd node was created too late; loses challenge automatically.
|
300
334
|
completeChallengeImpl(stakers[0], stakers[1]);
|
301
335
|
return;
|
@@ -307,8 +341,9 @@ abstract contract AbsRollupUserLogic is
|
|
307
341
|
globalStates,
|
308
342
|
numBlocks,
|
309
343
|
wasmModuleRoots,
|
310
|
-
|
311
|
-
|
344
|
+
// convert from block counts to real second based timestamps
|
345
|
+
(commonEndBlock - proposedBlocks[0]) * ETH_POS_BLOCK_TIME,
|
346
|
+
(commonEndBlock - proposedBlocks[1]) * ETH_POS_BLOCK_TIME
|
312
347
|
); // trusted external call
|
313
348
|
|
314
349
|
challengeStarted(stakers[0], stakers[1], challengeIndex);
|
@@ -366,6 +401,8 @@ abstract contract AbsRollupUserLogic is
|
|
366
401
|
uint256 amountWon = remainingLoserStake / 2;
|
367
402
|
increaseStakeBy(winningStaker, amountWon);
|
368
403
|
remainingLoserStake -= amountWon;
|
404
|
+
// We deliberately leave loser in challenge state to prevent them from
|
405
|
+
// doing certain thing that are allowed only to parties not in a challenge
|
369
406
|
clearChallenge(winningStaker);
|
370
407
|
// Credit the other half to the loserStakeEscrow address
|
371
408
|
increaseWithdrawableFunds(loserStakeEscrow, remainingLoserStake);
|
@@ -64,6 +64,7 @@ contract BridgeTester is Initializable, DelegateCallAware, IBridge {
|
|
64
64
|
bytes32[] public override delayedInboxAccs;
|
65
65
|
|
66
66
|
bytes32[] public override sequencerInboxAccs;
|
67
|
+
uint256 public override sequencerReportedSubMessageCount;
|
67
68
|
|
68
69
|
address private constant EMPTY_ACTIVEOUTBOX = address(type(uint160).max);
|
69
70
|
|
@@ -85,7 +86,12 @@ contract BridgeTester is Initializable, DelegateCallAware, IBridge {
|
|
85
86
|
return allowedOutboxesMap[outbox].allowed;
|
86
87
|
}
|
87
88
|
|
88
|
-
function enqueueSequencerMessage(
|
89
|
+
function enqueueSequencerMessage(
|
90
|
+
bytes32 dataHash,
|
91
|
+
uint256 afterDelayedMessagesRead,
|
92
|
+
uint256 prevMessageCount,
|
93
|
+
uint256 newMessageCount
|
94
|
+
)
|
89
95
|
external
|
90
96
|
returns (
|
91
97
|
uint256 seqMessageIndex,
|
@@ -22,7 +22,11 @@ contract OutboxWithoutOptTester is DelegateCallAware, IOutbox {
|
|
22
22
|
address public rollup; // the rollup contract
|
23
23
|
IBridge public bridge; // the bridge contract
|
24
24
|
|
25
|
-
|
25
|
+
function spent(uint256) external pure override returns (bytes32) {
|
26
|
+
revert("NOT_IMPLEMETED");
|
27
|
+
}
|
28
|
+
|
29
|
+
mapping(uint256 => bool) public isSpent; // maps leaf number => if spent
|
26
30
|
mapping(bytes32 => bytes32) public roots; // maps root hashes => L2 block hash
|
27
31
|
|
28
32
|
struct L2ToL1Context {
|
@@ -70,7 +74,7 @@ contract OutboxWithoutOptTester is DelegateCallAware, IOutbox {
|
|
70
74
|
}
|
71
75
|
|
72
76
|
// @deprecated batch number is now always 0
|
73
|
-
function l2ToL1BatchNum() external pure
|
77
|
+
function l2ToL1BatchNum() external pure returns (uint256) {
|
74
78
|
return 0;
|
75
79
|
}
|
76
80
|
|
@@ -150,10 +154,6 @@ contract OutboxWithoutOptTester is DelegateCallAware, IOutbox {
|
|
150
154
|
revert("Not implemented");
|
151
155
|
}
|
152
156
|
|
153
|
-
function isSpent(uint256) external pure override returns (bool) {
|
154
|
-
revert("Not implemented");
|
155
|
-
}
|
156
|
-
|
157
157
|
function recordOutputAsSpent(
|
158
158
|
bytes32[] memory proof,
|
159
159
|
uint256 index,
|
@@ -166,8 +166,8 @@ contract OutboxWithoutOptTester is DelegateCallAware, IOutbox {
|
|
166
166
|
bytes32 calcRoot = calculateMerkleRoot(proof, index, item);
|
167
167
|
if (roots[calcRoot] == bytes32(0)) revert UnknownRoot(calcRoot);
|
168
168
|
|
169
|
-
if (
|
170
|
-
|
169
|
+
if (isSpent[index]) revert AlreadySpent(index);
|
170
|
+
isSpent[index] = true;
|
171
171
|
|
172
172
|
return bytes32(index);
|
173
173
|
}
|