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

Sign up to get free protection for your applications and to get access to all the features.
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