@arbitrum/nitro-contracts 1.0.0-beta.8 → 1.0.1
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/README.md +1 -1
- package/hardhat.prod-config.js +4 -4
- package/package.json +21 -3
- 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 +233 -93
- 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 +6 -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
|
}
|