@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
@@ -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 proposedTimes Times that the two nodes were proposed
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 proposedTimes,
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
- proposedTimes[0],
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
- proposedTimes[1],
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 commonEndTime = getNodeStorage(node1.prevNum).firstChildBlock +
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 - proposedTimes[0]) +
330
+ (node1.deadlineBlock - proposedBlocks[0]) +
297
331
  extraChallengeTimeBlocks; // add dispute window to dispute start time
298
- if (commonEndTime < proposedTimes[1]) {
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
- commonEndTime - proposedTimes[0],
311
- commonEndTime - proposedTimes[1]
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(bytes32 dataHash, uint256 afterDelayedMessagesRead)
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
- mapping(uint256 => bool) public spent; // maps leaf number => if spent
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 override returns (uint256) {
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 (spent[index]) revert AlreadySpent(index);
170
- spent[index] = true;
169
+ if (isSpent[index]) revert AlreadySpent(index);
170
+ isSpent[index] = true;
171
171
 
172
172
  return bytes32(index);
173
173
  }