@arbitrum/nitro-contracts 1.0.0-beta.1 → 1.0.0-beta.4

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.
Files changed (50) hide show
  1. package/README.md +15 -0
  2. package/package.json +12 -8
  3. package/src/bridge/IInbox.sol +9 -0
  4. package/src/bridge/Inbox.sol +19 -39
  5. package/src/libraries/AdminFallbackProxy.sol +5 -5
  6. package/src/libraries/MessageTypes.sol +1 -0
  7. package/src/mocks/InboxStub.sol +4 -0
  8. package/src/mocks/Simple.sol +30 -0
  9. package/src/node-interface/NodeInterface.sol +18 -1
  10. package/src/node-interface/NodeInterfaceDebug.sol +30 -0
  11. package/src/osp/OneStepProver0.sol +14 -0
  12. package/src/osp/OneStepProverMath.sol +2 -2
  13. package/src/precompiles/ArbOwner.sol +3 -0
  14. package/src/rollup/IRollupCore.sol +26 -2
  15. package/src/rollup/IRollupEventBridge.sol +17 -0
  16. package/src/rollup/IRollupLogic.sol +34 -2
  17. package/src/rollup/RollupCore.sol +2 -2
  18. package/src/rollup/RollupCreator.sol +5 -15
  19. package/src/rollup/RollupEventBridge.sol +2 -3
  20. package/src/rollup/RollupLib.sol +2 -2
  21. package/src/rollup/RollupUserLogic.sol +7 -3
  22. package/src/rollup/ValidatorUtils.sol +0 -1
  23. package/src/rollup/ValidatorWallet.sol +0 -1
  24. package/src/state/Instructions.sol +2 -0
  25. package/.prettierrc +0 -5
  26. package/.solhint.json +0 -18
  27. package/deploy/BridgeStubCreator.js +0 -10
  28. package/deploy/HashProofHelper.js +0 -13
  29. package/deploy/InboxStubCreator.js +0 -17
  30. package/deploy/OneStepProofEntryCreator.js +0 -19
  31. package/deploy/OneStepProver0Creator.js +0 -14
  32. package/deploy/OneStepProverHostIoCreator.js +0 -14
  33. package/deploy/OneStepProverMathCreator.js +0 -14
  34. package/deploy/OneStepProverMemoryCreator.js +0 -14
  35. package/deploy/SequencerInboxStubCreator.js +0 -13
  36. package/deploy/ValueArrayTesterCreator.js +0 -13
  37. package/hardhat.config.ts +0 -47
  38. package/src/mocks/Counter.sol +0 -13
  39. package/test/contract/arbRollup.spec.ts +0 -869
  40. package/test/contract/common/challengeLib.ts +0 -43
  41. package/test/contract/common/globalStateLib.ts +0 -17
  42. package/test/contract/common/rolluplib.ts +0 -259
  43. package/test/contract/cryptographyPrimitives.spec.ts +0 -82
  44. package/test/contract/sequencerInboxForceInclude.spec.ts +0 -516
  45. package/test/contract/utils.ts +0 -40
  46. package/test/prover/hash-proofs.ts +0 -75
  47. package/test/prover/one-step-proof.ts +0 -93
  48. package/test/prover/proofs/.gitkeep +0 -0
  49. package/test/prover/value-arrays.ts +0 -11
  50. package/tsconfig.json +0 -13
package/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # Arbitrum Nitro Contracts
2
+
3
+ This is the package with the smart contract code that powers Arbitrum Nitro.
4
+ It includes the rollup and fraud proof smart contracts, as well as interfaces for interacting with precompiles.
5
+
6
+ For more information see https://developer.arbitrum.io/docs/public_nitro_devnet
7
+
8
+
9
+ Compile the contracts locally by running
10
+ ```bash
11
+ git clone https://github.com/offchainlabs/nitro
12
+ cd nitro/contracts
13
+ yarn install
14
+ yarn build
15
+ ```
package/package.json CHANGED
@@ -1,15 +1,19 @@
1
1
  {
2
2
  "name": "@arbitrum/nitro-contracts",
3
- "version": "1.0.0-beta.1",
3
+ "version": "1.0.0-beta.4",
4
4
  "description": "Layer 2 precompiles and rollup for Arbitrum Nitro",
5
- "main": "index.js",
6
5
  "author": "Offchain Labs, Inc.",
7
- "license": "UNLICENSED",
6
+ "license": "BUSL-1.1",
8
7
  "repository": {
9
8
  "type": "git",
10
9
  "url": "git+https://github.com/offchainlabs/nitro.git",
11
10
  "directory": "contracts"
12
11
  },
12
+ "files": [
13
+ "src/",
14
+ "scripts/build.bash",
15
+ "hardhat.prod-config.js"
16
+ ],
13
17
  "bugs": {
14
18
  "url": "https://github.com/offchainlabs/nitro/issues"
15
19
  },
@@ -21,29 +25,29 @@
21
25
  },
22
26
  "dependencies": {
23
27
  "@openzeppelin/contracts": "4.5.0",
24
- "@openzeppelin/contracts-upgradeable": "4.5.1",
28
+ "@openzeppelin/contracts-upgradeable": "4.5.2",
25
29
  "hardhat": "^2.6.6"
26
30
  },
27
31
  "private": false,
28
32
  "devDependencies": {
29
33
  "@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.13",
30
34
  "@nomiclabs/hardhat-waffle": "^2.0.1",
31
- "@typechain/ethers-v5": "^9.0.0",
32
- "@typechain/hardhat": "^4.0.0",
35
+ "@typechain/ethers-v5": "^10.0.0",
36
+ "@typechain/hardhat": "^6.0.0",
33
37
  "@types/chai": "^4.3.0",
34
38
  "@types/mocha": "^9.0.0",
35
39
  "@types/node": "^17.0.5",
36
40
  "chai": "^4.3.4",
37
41
  "ethereum-waffle": "^3.4.0",
38
42
  "ethers": "^5.5.2",
39
- "hardhat-deploy": "^0.10.5",
43
+ "hardhat-deploy": "^0.11.4",
40
44
  "prettier": "^2.5.1",
41
45
  "prettier-plugin-solidity": "^1.0.0-beta.19",
42
46
  "solhint": "^3.3.7",
43
47
  "solhint-plugin-prettier": "^0.0.5",
44
48
  "solidity-coverage": "^0.7.20",
45
49
  "ts-node": "^10.4.0",
46
- "typechain": "^7.0.0",
50
+ "typechain": "^8.0.0",
47
51
  "typescript": "^4.5.4"
48
52
  }
49
53
  }
@@ -17,6 +17,12 @@ error AlreadyUnpaused();
17
17
  /// @dev The contract is paused
18
18
  error Paused();
19
19
 
20
+ /// @dev msg.value sent to the inbox isn't high enough
21
+ error InsufficientValue(uint256 expected, uint256 actual);
22
+
23
+ /// @dev submission cost provided isn't enough to create retryable ticket
24
+ error InsufficientSubmissionCost(uint256 expected, uint256 actual);
25
+
20
26
  interface IInbox is IMessageProvider {
21
27
  function sendL2Message(bytes calldata messageData) external returns (uint256);
22
28
 
@@ -74,6 +80,9 @@ interface IInbox is IMessageProvider {
74
80
  bytes calldata data
75
81
  ) external payable returns (uint256);
76
82
 
83
+ function depositEth() external payable returns (uint256);
84
+
85
+ /// @notice deprecated in favour of depositEth with no parameters
77
86
  function depositEth(uint256 maxSubmissionCost) external payable returns (uint256);
78
87
 
79
88
  function bridge() external view returns (IBridge);
@@ -14,14 +14,15 @@ import {
14
14
  L2_MSG,
15
15
  L1MessageType_L2FundedByL1,
16
16
  L1MessageType_submitRetryableTx,
17
+ L1MessageType_ethDeposit,
17
18
  L2MessageType_unsignedEOATx,
18
19
  L2MessageType_unsignedContractTx
19
20
  } from "../libraries/MessageTypes.sol";
20
21
  import {MAX_DATA_SIZE} from "../libraries/Constants.sol";
21
22
 
23
+ import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
22
24
  import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
23
25
  import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
24
- import "./Bridge.sol";
25
26
 
26
27
  /**
27
28
  * @title Inbox for user and contract originated messages
@@ -33,7 +34,7 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
33
34
 
34
35
  modifier onlyOwner() {
35
36
  // whoevever owns the Bridge, also owns the Inbox. this is usually the rollup contract
36
- address bridgeOwner = Bridge(address(bridge)).owner();
37
+ address bridgeOwner = OwnableUpgradeable(address(bridge)).owner();
37
38
  if (msg.sender != bridgeOwner) revert NotOwner(msg.sender, bridgeOwner);
38
39
  _;
39
40
  }
@@ -96,11 +97,7 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
96
97
  whenNotPaused
97
98
  returns (uint256)
98
99
  {
99
- if (messageData.length > MAX_DATA_SIZE)
100
- revert DataTooLarge(messageData.length, MAX_DATA_SIZE);
101
- uint256 msgNum = deliverToBridge(L2_MSG, msg.sender, keccak256(messageData));
102
- emit InboxMessageDelivered(msgNum, messageData);
103
- return msgNum;
100
+ return _deliverMessage(L2_MSG, msg.sender, messageData);
104
101
  }
105
102
 
106
103
  function sendL1FundedUnsignedTransaction(
@@ -209,20 +206,11 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
209
206
  }
210
207
 
211
208
  /// @notice deposit eth from L1 to L2
209
+ /// @dev this does not trigger the fallback function when receiving in the L2 side.
210
+ /// Look into retryable tickets if you are interested in this functionality.
212
211
  /// @dev this function should not be called inside contract constructors
213
- function depositEth(uint256 maxSubmissionCost)
214
- external
215
- payable
216
- virtual
217
- override
218
- whenNotPaused
219
- returns (uint256)
220
- {
212
+ function depositEth() public payable override whenNotPaused returns (uint256) {
221
213
  address sender = msg.sender;
222
- address destinationAddress = msg.sender;
223
-
224
- uint256 submissionFee = calculateRetryableSubmissionFee(0, block.basefee);
225
- require(maxSubmissionCost >= submissionFee, "insufficient submission fee");
226
214
 
227
215
  // solhint-disable-next-line avoid-tx-origin
228
216
  if (!AddressUpgradeable.isContract(sender) && tx.origin == msg.sender) {
@@ -233,31 +221,21 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
233
221
  // have the L1 sender address mapped.
234
222
  // Here we preemptively reverse the mapping for EOAs so deposits work as expected
235
223
  sender = AddressAliasHelper.undoL1ToL2Alias(sender);
236
- } else {
237
- destinationAddress = AddressAliasHelper.applyL1ToL2Alias(destinationAddress);
238
224
  }
239
225
 
240
226
  return
241
227
  _deliverMessage(
242
- L1MessageType_submitRetryableTx,
243
- sender,
244
- abi.encodePacked(
245
- // the beneficiary and other refund addresses don't get rewritten by arb-os
246
- // so we use the original msg.sender value
247
- uint256(uint160(bytes20(destinationAddress))),
248
- uint256(0),
249
- msg.value,
250
- maxSubmissionCost,
251
- uint256(uint160(bytes20(destinationAddress))),
252
- uint256(uint160(bytes20(destinationAddress))),
253
- uint256(0),
254
- uint256(0),
255
- uint256(0),
256
- ""
257
- )
228
+ L1MessageType_ethDeposit,
229
+ sender, // arb-os will add the alias to this value
230
+ abi.encodePacked(msg.value)
258
231
  );
259
232
  }
260
233
 
234
+ /// @notice deprecated in favour of depositEth with no parameters
235
+ function depositEth(uint256) external payable virtual override whenNotPaused returns (uint256) {
236
+ return depositEth();
237
+ }
238
+
261
239
  /**
262
240
  * @notice deprecated in favour of unsafeCreateRetryableTicket
263
241
  * @dev deprecated in favour of unsafeCreateRetryableTicket
@@ -318,7 +296,8 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
318
296
  bytes calldata data
319
297
  ) external payable virtual override whenNotPaused returns (uint256) {
320
298
  // ensure the user's deposit alone will make submission succeed
321
- require(msg.value >= maxSubmissionCost + l2CallValue, "insufficient value");
299
+ if (msg.value < maxSubmissionCost + l2CallValue)
300
+ revert InsufficientValue(maxSubmissionCost + l2CallValue, msg.value);
322
301
 
323
302
  // if a refund address is a contract, we apply the alias to it
324
303
  // so that it can access its funds on the L2
@@ -371,7 +350,8 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
371
350
  bytes calldata data
372
351
  ) public payable virtual override whenNotPaused returns (uint256) {
373
352
  uint256 submissionFee = calculateRetryableSubmissionFee(data.length, block.basefee);
374
- require(maxSubmissionCost >= submissionFee, "insufficient submission fee");
353
+ if (maxSubmissionCost < submissionFee)
354
+ revert InsufficientSubmissionCost(submissionFee, maxSubmissionCost);
375
355
 
376
356
  return
377
357
  _deliverMessage(
@@ -11,8 +11,6 @@ import "@openzeppelin/contracts/utils/StorageSlot.sol";
11
11
 
12
12
  /// @notice An extension to OZ's ERC1967Upgrade implementation to support two logic contracts
13
13
  abstract contract DoubleLogicERC1967Upgrade is ERC1967Upgrade {
14
- using Address for address;
15
-
16
14
  // This is the keccak-256 hash of "eip1967.proxy.implementation.secondary" subtracted by 1
17
15
  bytes32 internal constant _IMPLEMENTATION_SECONDARY_SLOT =
18
16
  0x2b1dbce74324248c222f0ec2d5ed7bd323cfc425b336f0253c5ccfda7265546d;
@@ -133,12 +131,14 @@ contract AdminFallbackProxy is Proxy, DoubleLogicERC1967Upgrade {
133
131
  function _implementation() internal view override returns (address) {
134
132
  require(msg.data.length >= 4, "NO_FUNC_SIG");
135
133
  // if the sender is the proxy's admin, delegate to admin logic
136
- // if the admin is disabled (set to addr zero), all calls will be forwarded to user logic
134
+ // if the admin is disabled, all calls will be forwarded to user logic
135
+ // admin affordances can be disabled by setting to address(1) since
136
+ // `ERC1697._setAdmin()` doesn't allow address(0) to be set
137
137
  address target = _getAdmin() != msg.sender
138
138
  ? DoubleLogicERC1967Upgrade._getSecondaryImplementation()
139
139
  : ERC1967Upgrade._getImplementation();
140
- // implementation setters already do an existence check
141
- // require(target.isContract(), "TARGET_NOT_CONTRACT");
140
+ // implementation setters do an existence check, but we protect against selfdestructs this way
141
+ require(Address.isContract(target), "TARGET_NOT_CONTRACT");
142
142
  return target;
143
143
  }
144
144
 
@@ -7,6 +7,7 @@ pragma solidity ^0.8.4;
7
7
  uint8 constant L2_MSG = 3;
8
8
  uint8 constant L1MessageType_L2FundedByL1 = 7;
9
9
  uint8 constant L1MessageType_submitRetryableTx = 9;
10
+ uint8 constant L1MessageType_ethDeposit = 12;
10
11
  uint8 constant L2MessageType_unsignedEOATx = 0;
11
12
  uint8 constant L2MessageType_unsignedContractTx = 1;
12
13
 
@@ -125,6 +125,10 @@ contract InboxStub is IInbox {
125
125
  revert("NOT_IMPLEMENTED");
126
126
  }
127
127
 
128
+ function depositEth() external payable override returns (uint256) {
129
+ revert("NOT_IMPLEMENTED");
130
+ }
131
+
128
132
  function depositEth(uint256) external payable override returns (uint256) {
129
133
  revert("NOT_IMPLEMENTED");
130
134
  }
@@ -0,0 +1,30 @@
1
+ // Copyright 2021-2022, Offchain Labs, Inc.
2
+ // For license information, see https://github.com/nitro/blob/master/LICENSE
3
+ // SPDX-License-Identifier: BUSL-1.1
4
+
5
+ pragma solidity ^0.8.0;
6
+
7
+ contract Simple {
8
+ uint64 public counter;
9
+
10
+ event CounterEvent(uint64 count);
11
+ event NullEvent();
12
+
13
+ function increment() external {
14
+ counter++;
15
+ }
16
+
17
+ function incrementEmit() external {
18
+ counter++;
19
+ emit CounterEvent(counter);
20
+ }
21
+
22
+ function emitNullEvent() external {
23
+ emit NullEvent();
24
+ }
25
+
26
+ function checkBlockHashes() external view returns (uint256) {
27
+ require(blockhash(block.number - 1) != blockhash(block.number - 2), "SAME_BLOCK_HASH");
28
+ return block.number;
29
+ }
30
+ }
@@ -9,7 +9,6 @@ pragma solidity >=0.4.21 <0.9.0;
9
9
  * 0x00000000000000000000000000000000000000C8
10
10
  * This is a cute trick to allow an Arbitrum node to provide data without us having to implement additional RPCs
11
11
  */
12
-
13
12
  interface NodeInterface {
14
13
  /**
15
14
  * @notice Estimate the cost of putting a message in the L2 inbox that is reexecuted
@@ -47,4 +46,22 @@ interface NodeInterface {
47
46
  bytes32 root,
48
47
  bytes32[] memory proof
49
48
  );
49
+
50
+ /**
51
+ * @notice Finds the L1 batch containing a requested L2 block, reverting if none does
52
+ * Throws if block doesn't exist, or if block number is 0
53
+ * @param blockNum The L2 block being queried
54
+ * @return batch The L1 block containing the requested L2 block
55
+ */
56
+ function findBatchContainingBlock(uint64 blockNum) external view returns (uint64 batch);
57
+
58
+ /**
59
+ * @notice Gets the number of L1 confirmations of the sequencer batch producing the requested L2 block
60
+ * This gets the number of L1 confirmations for the input message producing the L2 block,
61
+ * which happens well before the L1 rollup contract confirms the L2 block.
62
+ * Throws if block doesnt exist in the L2 chain.
63
+ * @param blockHash The hash of the L2 block being queried
64
+ * @return confirmations The number of L1 confirmations the sequencer batch has. Returns 0 if block not yet included in an L1 batch.
65
+ */
66
+ function getL1Confirmations(bytes32 blockHash) external view returns (uint64 confirmations);
50
67
  }
@@ -0,0 +1,30 @@
1
+ // Copyright 2021-2022, Offchain Labs, Inc.
2
+ // For license information, see https://github.com/nitro/blob/master/LICENSE
3
+ // SPDX-License-Identifier: BUSL-1.1
4
+
5
+ pragma solidity >=0.4.21 <0.9.0;
6
+
7
+ /** @title An extension to NodeInterface not meant for public consumption. Do not call.
8
+ * @notice This contract doesn't exist on-chain. Instead it is a virtual interface accessible at 0xc9.
9
+ * These methods add additional debugging and network monitoring instruments not intended for end users and
10
+ * as such may change without notice.
11
+ */
12
+
13
+ interface NodeInterfaceDebug {
14
+ struct RetryableInfo {
15
+ uint64 timeout;
16
+ address from;
17
+ address to;
18
+ uint256 value;
19
+ address beneficiary;
20
+ uint64 tries;
21
+ bytes data;
22
+ }
23
+
24
+ /**
25
+ * @notice gets a retryable
26
+ * @param ticket the retryable's id
27
+ * @return retryable the serialized retryable
28
+ */
29
+ function getRetryable(bytes32 ticket) external view returns (RetryableInfo memory retryable);
30
+ }
@@ -309,6 +309,18 @@ contract OneStepProver0 is IOneStepProver {
309
309
  mach.functionPc = 0;
310
310
  }
311
311
 
312
+ function executeArbitraryJump(
313
+ Machine memory mach,
314
+ Module memory,
315
+ Instruction calldata inst,
316
+ bytes calldata
317
+ ) internal pure {
318
+ // Jump to target
319
+ uint32 pc = uint32(inst.argumentData);
320
+ require(pc == inst.argumentData, "BAD_CALL_DATA");
321
+ mach.functionPc = pc;
322
+ }
323
+
312
324
  function executeArbitraryJumpIf(
313
325
  Machine memory mach,
314
326
  Module memory,
@@ -527,6 +539,8 @@ contract OneStepProver0 is IOneStepProver {
527
539
  impl = executeEndBlock;
528
540
  } else if (opcode == Instructions.END_BLOCK_IF) {
529
541
  impl = executeEndBlockIf;
542
+ } else if (opcode == Instructions.ARBITRARY_JUMP) {
543
+ impl = executeArbitraryJump;
530
544
  } else if (opcode == Instructions.ARBITRARY_JUMP_IF) {
531
545
  impl = executeArbitraryJumpIf;
532
546
  } else if (opcode == Instructions.LOCAL_GET) {
@@ -283,7 +283,7 @@ contract OneStepProverMath is IOneStepProver {
283
283
  res = a >> (b % 32);
284
284
  } else if (opcodeOffset == 11) {
285
285
  // shr_s
286
- res = uint32(int32(a) >> b);
286
+ res = uint32(int32(a) >> (b % 32));
287
287
  } else if (opcodeOffset == 13) {
288
288
  // rotl
289
289
  res = rotl32(a, b);
@@ -333,7 +333,7 @@ contract OneStepProverMath is IOneStepProver {
333
333
  res = a >> (b % 64);
334
334
  } else if (opcodeOffset == 11) {
335
335
  // shr_s
336
- res = uint64(int64(a) >> b);
336
+ res = uint64(int64(a) >> (b % 64));
337
337
  } else if (opcodeOffset == 13) {
338
338
  // rotl
339
339
  res = rotl64(a, b);
@@ -60,6 +60,9 @@ interface ArbOwner {
60
60
  /// @notice Set the network fee collector
61
61
  function setNetworkFeeAccount(address newNetworkFeeAccount) external;
62
62
 
63
+ /// @notice Upgrades ArbOS to the requested version at the requested timestamp
64
+ function scheduleArbOSUpgrade(uint64 newVersion, uint64 timestamp) external;
65
+
63
66
  // Emitted when a successful call is made to this precompile
64
67
  event OwnerActs(bytes4 indexed method, address indexed owner, bytes data);
65
68
  }
@@ -7,8 +7,6 @@ pragma solidity ^0.8.0;
7
7
  import "./Node.sol";
8
8
  import "./RollupLib.sol";
9
9
 
10
- import "../osp/IOneStepProofEntry.sol";
11
-
12
10
  interface IRollupCore {
13
11
  struct Staker {
14
12
  uint256 amountStaked;
@@ -51,8 +49,34 @@ interface IRollupCore {
51
49
  uint256 finalBalance
52
50
  );
53
51
 
52
+ function confirmPeriodBlocks() external view returns (uint64);
53
+
54
+ function extraChallengeTimeBlocks() external view returns (uint64);
55
+
56
+ function chainId() external view returns (uint256);
57
+
58
+ function baseStake() external view returns (uint256);
59
+
60
+ function wasmModuleRoot() external view returns (bytes32);
61
+
62
+ function delayedBridge() external view returns (IBridge);
63
+
64
+ function sequencerBridge() external view returns (ISequencerInbox);
65
+
66
+ function outbox() external view returns (IOutbox);
67
+
68
+ function rollupEventBridge() external view returns (IRollupEventBridge);
69
+
54
70
  function challengeManager() external view returns (IChallengeManager);
55
71
 
72
+ function loserStakeEscrow() external view returns (address);
73
+
74
+ function stakeToken() external view returns (address);
75
+
76
+ function minimumAssertionPeriod() external view returns (uint256);
77
+
78
+ function isValidator(address) external view returns (bool);
79
+
56
80
  /**
57
81
  * @notice Get the Node for the given index.
58
82
  */
@@ -0,0 +1,17 @@
1
+ // Copyright 2021-2022, Offchain Labs, Inc.
2
+ // For license information, see https://github.com/nitro/blob/master/LICENSE
3
+ // SPDX-License-Identifier: BUSL-1.1
4
+
5
+ pragma solidity ^0.8.0;
6
+
7
+ import "../bridge/IBridge.sol";
8
+
9
+ interface IRollupEventBridge {
10
+ function bridge() external view returns (IBridge);
11
+
12
+ function initialize(address _bridge, address _rollup) external;
13
+
14
+ function rollup() external view returns (address);
15
+
16
+ function rollupInitialized(uint256 chainId) external;
17
+ }
@@ -16,15 +16,43 @@ interface IRollupUserAbs is IRollupCore {
16
16
 
17
17
  function isERC20Enabled() external view returns (bool);
18
18
 
19
+ function rejectNextNode(address stakerAddress) external;
20
+
21
+ function confirmNextNode(bytes32 blockHash, bytes32 sendRoot) external;
22
+
23
+ function stakeOnExistingNode(uint64 nodeNum, bytes32 nodeHash) external;
24
+
25
+ function stakeOnNewNode(
26
+ RollupLib.Assertion memory assertion,
27
+ bytes32 expectedNodeHash,
28
+ uint256 prevNodeInboxMaxCount
29
+ ) external;
30
+
19
31
  function returnOldDeposit(address stakerAddress) external;
20
32
 
21
- function requireUnresolved(uint256 nodeNum) external view;
33
+ function reduceDeposit(uint256 target) external;
22
34
 
23
- function requireUnresolvedExists() external view;
35
+ function removeZombie(uint256 zombieNum, uint256 maxNodes) external;
36
+
37
+ function removeOldZombies(uint256 startIndex) external;
38
+
39
+ function requiredStake(
40
+ uint256 blockNumber,
41
+ uint64 firstUnresolvedNodeNum,
42
+ uint64 latestCreatedNode
43
+ ) external view returns (uint256);
44
+
45
+ function currentRequiredStake() external view returns (uint256);
24
46
 
25
47
  function countStakedZombies(uint64 nodeNum) external view returns (uint256);
26
48
 
27
49
  function countZombiesStakedOnChildren(uint64 nodeNum) external view returns (uint256);
50
+
51
+ function requireUnresolvedExists() external view;
52
+
53
+ function requireUnresolved(uint256 nodeNum) external view;
54
+
55
+ function withdrawStakerFunds(address payable destination) external returns (uint256);
28
56
  }
29
57
 
30
58
  interface IRollupUser is IRollupUserAbs {
@@ -35,6 +63,8 @@ interface IRollupUser is IRollupUserAbs {
35
63
  bytes32 expectedNodeHash,
36
64
  uint256 prevNodeInboxMaxCount
37
65
  ) external payable;
66
+
67
+ function addToDeposit(address stakerAddress) external payable;
38
68
  }
39
69
 
40
70
  interface IRollupUserERC20 is IRollupUserAbs {
@@ -50,6 +80,8 @@ interface IRollupUserERC20 is IRollupUserAbs {
50
80
  bytes32 expectedNodeHash,
51
81
  uint256 prevNodeInboxMaxCount
52
82
  ) external;
83
+
84
+ function addToDeposit(address stakerAddress, uint256 tokenAmount) external;
53
85
  }
54
86
 
55
87
  interface IRollupAdmin {
@@ -9,7 +9,7 @@ import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol";
9
9
  import "./Node.sol";
10
10
  import "./IRollupCore.sol";
11
11
  import "./RollupLib.sol";
12
- import "./RollupEventBridge.sol";
12
+ import "./IRollupEventBridge.sol";
13
13
  import "./IRollupCore.sol";
14
14
 
15
15
  import "../challenge/IChallengeManager.sol";
@@ -34,7 +34,7 @@ abstract contract RollupCore is IRollupCore, PausableUpgradeable {
34
34
  IBridge public delayedBridge;
35
35
  ISequencerInbox public sequencerBridge;
36
36
  IOutbox public outbox;
37
- RollupEventBridge public rollupEventBridge;
37
+ IRollupEventBridge public rollupEventBridge;
38
38
  IChallengeManager public override challengeManager;
39
39
  // when a staker loses a challenge, half of their funds get escrowed in this address
40
40
  address public loserStakeEscrow;
@@ -4,11 +4,6 @@
4
4
 
5
5
  pragma solidity ^0.8.0;
6
6
 
7
- import "../bridge/Bridge.sol";
8
- import "../bridge/SequencerInbox.sol";
9
- import "../bridge/Inbox.sol";
10
- import "../bridge/Outbox.sol";
11
- import "./RollupEventBridge.sol";
12
7
  import "./BridgeCreator.sol";
13
8
 
14
9
  import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
@@ -16,11 +11,6 @@ import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.so
16
11
  import "@openzeppelin/contracts/access/Ownable.sol";
17
12
 
18
13
  import "../libraries/ArbitrumProxy.sol";
19
- import "./RollupUserLogic.sol";
20
- import "./RollupAdminLogic.sol";
21
- import "../bridge/IBridge.sol";
22
-
23
- import "./RollupLib.sol";
24
14
 
25
15
  contract RollupCreator is Ownable {
26
16
  event RollupCreated(
@@ -57,11 +47,11 @@ contract RollupCreator is Ownable {
57
47
 
58
48
  struct CreateRollupFrame {
59
49
  ProxyAdmin admin;
60
- Bridge delayedBridge;
61
- SequencerInbox sequencerInbox;
62
- Inbox inbox;
63
- RollupEventBridge rollupEventBridge;
64
- Outbox outbox;
50
+ IBridge delayedBridge;
51
+ ISequencerInbox sequencerInbox;
52
+ IInbox inbox;
53
+ IRollupEventBridge rollupEventBridge;
54
+ IOutbox outbox;
65
55
  ArbitrumProxy rollup;
66
56
  }
67
57
 
@@ -4,8 +4,7 @@
4
4
 
5
5
  pragma solidity ^0.8.0;
6
6
 
7
- import "./IRollupLogic.sol";
8
-
7
+ import "./IRollupEventBridge.sol";
9
8
  import "../bridge/IBridge.sol";
10
9
  import "../bridge/IMessageProvider.sol";
11
10
  import "../libraries/DelegateCallAware.sol";
@@ -14,7 +13,7 @@ import {INITIALIZATION_MSG_TYPE} from "../libraries/MessageTypes.sol";
14
13
  /**
15
14
  * @title The inbox for rollup protocol events
16
15
  */
17
- contract RollupEventBridge is IMessageProvider, DelegateCallAware {
16
+ contract RollupEventBridge is IRollupEventBridge, IMessageProvider, DelegateCallAware {
18
17
  uint8 internal constant CREATE_NODE_EVENT = 0;
19
18
  uint8 internal constant CONFIRM_NODE_EVENT = 1;
20
19
  uint8 internal constant REJECT_NODE_EVENT = 2;
@@ -11,7 +11,7 @@ import "../bridge/ISequencerInbox.sol";
11
11
 
12
12
  import "../bridge/IBridge.sol";
13
13
  import "../bridge/IOutbox.sol";
14
- import "./RollupEventBridge.sol";
14
+ import "./IRollupEventBridge.sol";
15
15
  import "./IRollupLogic.sol";
16
16
 
17
17
  struct Config {
@@ -30,7 +30,7 @@ struct ContractDependencies {
30
30
  IBridge delayedBridge;
31
31
  ISequencerInbox sequencerInbox;
32
32
  IOutbox outbox;
33
- RollupEventBridge rollupEventBridge;
33
+ IRollupEventBridge rollupEventBridge;
34
34
  IChallengeManager challengeManager;
35
35
  IRollupAdmin rollupAdminLogic;
36
36
  IRollupUser rollupUserLogic;
@@ -564,8 +564,6 @@ abstract contract AbsRollupUserLogic is
564
564
  require(isStaked(stakerAddress), "NOT_STAKED");
565
565
  require(currentChallenge(stakerAddress) == NO_CHAL_INDEX, "IN_CHAL");
566
566
  }
567
-
568
- function withdrawStakerFunds(address payable destination) external virtual returns (uint256);
569
567
  }
570
568
 
571
569
  contract RollupUserLogic is AbsRollupUserLogic, IRollupUser {
@@ -605,7 +603,13 @@ contract RollupUserLogic is AbsRollupUserLogic, IRollupUser {
605
603
  * @notice Increase the amount staked eth for the given staker
606
604
  * @param stakerAddress Address of the staker whose stake is increased
607
605
  */
608
- function addToDeposit(address stakerAddress) external payable onlyValidator whenNotPaused {
606
+ function addToDeposit(address stakerAddress)
607
+ external
608
+ payable
609
+ override
610
+ onlyValidator
611
+ whenNotPaused
612
+ {
609
613
  _addToDeposit(stakerAddress, msg.value);
610
614
  }
611
615