@arbitrum/nitro-contracts 1.0.0-beta.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.
Files changed (113) hide show
  1. package/.prettierrc +5 -0
  2. package/.solhint.json +18 -0
  3. package/deploy/BridgeStubCreator.js +10 -0
  4. package/deploy/HashProofHelper.js +13 -0
  5. package/deploy/InboxStubCreator.js +17 -0
  6. package/deploy/OneStepProofEntryCreator.js +19 -0
  7. package/deploy/OneStepProver0Creator.js +14 -0
  8. package/deploy/OneStepProverHostIoCreator.js +14 -0
  9. package/deploy/OneStepProverMathCreator.js +14 -0
  10. package/deploy/OneStepProverMemoryCreator.js +14 -0
  11. package/deploy/SequencerInboxStubCreator.js +13 -0
  12. package/deploy/ValueArrayTesterCreator.js +13 -0
  13. package/hardhat.config.ts +47 -0
  14. package/hardhat.prod-config.js +18 -0
  15. package/package.json +49 -0
  16. package/scripts/build.bash +5 -0
  17. package/src/bridge/Bridge.sol +168 -0
  18. package/src/bridge/IBridge.sol +68 -0
  19. package/src/bridge/IInbox.sol +80 -0
  20. package/src/bridge/IMessageProvider.sol +11 -0
  21. package/src/bridge/IOutbox.sol +52 -0
  22. package/src/bridge/ISequencerInbox.sol +85 -0
  23. package/src/bridge/Inbox.sol +414 -0
  24. package/src/bridge/Messages.sol +38 -0
  25. package/src/bridge/Outbox.sol +188 -0
  26. package/src/bridge/SequencerInbox.sol +274 -0
  27. package/src/challenge/ChallengeLib.sol +135 -0
  28. package/src/challenge/ChallengeManager.sol +367 -0
  29. package/src/challenge/IChallengeManager.sol +75 -0
  30. package/src/challenge/IChallengeResultReceiver.sol +13 -0
  31. package/src/libraries/AddressAliasHelper.sol +29 -0
  32. package/src/libraries/AdminFallbackProxy.sol +153 -0
  33. package/src/libraries/ArbitrumProxy.sol +20 -0
  34. package/src/libraries/Constants.sol +10 -0
  35. package/src/libraries/CryptographyPrimitives.sol +323 -0
  36. package/src/libraries/DelegateCallAware.sol +44 -0
  37. package/src/libraries/Error.sol +38 -0
  38. package/src/libraries/IGasRefunder.sol +35 -0
  39. package/src/libraries/MerkleLib.sol +46 -0
  40. package/src/libraries/MessageTypes.sol +14 -0
  41. package/src/libraries/SecondaryLogicUUPSUpgradeable.sol +58 -0
  42. package/src/libraries/UUPSNotUpgradeable.sol +56 -0
  43. package/src/mocks/BridgeStub.sol +115 -0
  44. package/src/mocks/Counter.sol +13 -0
  45. package/src/mocks/ExecutionManager.sol +41 -0
  46. package/src/mocks/InboxStub.sol +131 -0
  47. package/src/mocks/MockResultReceiver.sol +59 -0
  48. package/src/mocks/SequencerInboxStub.sol +42 -0
  49. package/src/mocks/SimpleProxy.sol +19 -0
  50. package/src/node-interface/NodeInterface.sol +50 -0
  51. package/src/osp/HashProofHelper.sol +154 -0
  52. package/src/osp/IOneStepProofEntry.sol +20 -0
  53. package/src/osp/IOneStepProver.sol +27 -0
  54. package/src/osp/OneStepProofEntry.sol +129 -0
  55. package/src/osp/OneStepProver0.sol +566 -0
  56. package/src/osp/OneStepProverHostIo.sol +357 -0
  57. package/src/osp/OneStepProverMath.sol +514 -0
  58. package/src/osp/OneStepProverMemory.sol +313 -0
  59. package/src/precompiles/ArbAddressTable.sol +60 -0
  60. package/src/precompiles/ArbAggregator.sol +62 -0
  61. package/src/precompiles/ArbBLS.sol +53 -0
  62. package/src/precompiles/ArbDebug.sol +39 -0
  63. package/src/precompiles/ArbFunctionTable.sol +29 -0
  64. package/src/precompiles/ArbGasInfo.sol +121 -0
  65. package/src/precompiles/ArbInfo.sol +15 -0
  66. package/src/precompiles/ArbOwner.sol +65 -0
  67. package/src/precompiles/ArbOwnerPublic.sol +18 -0
  68. package/src/precompiles/ArbRetryableTx.sol +89 -0
  69. package/src/precompiles/ArbStatistics.sol +29 -0
  70. package/src/precompiles/ArbSys.sol +134 -0
  71. package/src/precompiles/ArbosActs.sol +41 -0
  72. package/src/precompiles/ArbosTest.sol +14 -0
  73. package/src/rollup/BridgeCreator.sol +120 -0
  74. package/src/rollup/IRollupCore.sol +152 -0
  75. package/src/rollup/IRollupLogic.sol +183 -0
  76. package/src/rollup/Node.sol +99 -0
  77. package/src/rollup/RollupAdminLogic.sol +322 -0
  78. package/src/rollup/RollupCore.sol +627 -0
  79. package/src/rollup/RollupCreator.sol +133 -0
  80. package/src/rollup/RollupEventBridge.sol +46 -0
  81. package/src/rollup/RollupLib.sol +135 -0
  82. package/src/rollup/RollupUserLogic.sol +712 -0
  83. package/src/rollup/ValidatorUtils.sol +243 -0
  84. package/src/rollup/ValidatorWallet.sol +76 -0
  85. package/src/rollup/ValidatorWalletCreator.sol +43 -0
  86. package/src/state/Deserialize.sol +321 -0
  87. package/src/state/GlobalState.sol +44 -0
  88. package/src/state/Instructions.sol +159 -0
  89. package/src/state/Machine.sol +65 -0
  90. package/src/state/MerkleProof.sol +99 -0
  91. package/src/state/Module.sol +33 -0
  92. package/src/state/ModuleMemory.sol +42 -0
  93. package/src/state/PcArray.sol +45 -0
  94. package/src/state/PcStack.sol +32 -0
  95. package/src/state/StackFrame.sol +63 -0
  96. package/src/state/Value.sol +65 -0
  97. package/src/state/ValueArray.sol +47 -0
  98. package/src/state/ValueStack.sol +39 -0
  99. package/src/test-helpers/CryptographyPrimitivesTester.sol +27 -0
  100. package/src/test-helpers/MessageTester.sol +34 -0
  101. package/src/test-helpers/ValueArrayTester.sol +34 -0
  102. package/test/contract/arbRollup.spec.ts +869 -0
  103. package/test/contract/common/challengeLib.ts +43 -0
  104. package/test/contract/common/globalStateLib.ts +17 -0
  105. package/test/contract/common/rolluplib.ts +259 -0
  106. package/test/contract/cryptographyPrimitives.spec.ts +82 -0
  107. package/test/contract/sequencerInboxForceInclude.spec.ts +516 -0
  108. package/test/contract/utils.ts +40 -0
  109. package/test/prover/hash-proofs.ts +75 -0
  110. package/test/prover/one-step-proof.ts +93 -0
  111. package/test/prover/proofs/.gitkeep +0 -0
  112. package/test/prover/value-arrays.ts +11 -0
  113. package/tsconfig.json +13 -0
@@ -0,0 +1,115 @@
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 "./InboxStub.sol";
8
+
9
+ import "../bridge/IBridge.sol";
10
+
11
+ contract BridgeStub is IBridge {
12
+ struct InOutInfo {
13
+ uint256 index;
14
+ bool allowed;
15
+ }
16
+
17
+ mapping(address => InOutInfo) private allowedInboxesMap;
18
+ //mapping(address => InOutInfo) private allowedOutboxesMap;
19
+
20
+ address[] public allowedInboxList;
21
+ address[] public allowedOutboxList;
22
+
23
+ address public override activeOutbox;
24
+
25
+ // Accumulator for delayed inbox; tail represents hash of the current state; each element represents the inclusion of a new message.
26
+ bytes32[] public override inboxAccs;
27
+
28
+ function allowedInboxes(address inbox) external view override returns (bool) {
29
+ return allowedInboxesMap[inbox].allowed;
30
+ }
31
+
32
+ function allowedOutboxes(address) external pure override returns (bool) {
33
+ revert("NOT_IMPLEMENTED");
34
+ }
35
+
36
+ function enqueueDelayedMessage(
37
+ uint8 kind,
38
+ address sender,
39
+ bytes32 messageDataHash
40
+ ) external payable override returns (uint256) {
41
+ require(allowedInboxesMap[msg.sender].allowed, "NOT_FROM_INBOX");
42
+ return
43
+ addMessageToAccumulator(
44
+ kind,
45
+ sender,
46
+ block.number,
47
+ block.timestamp, // solhint-disable-line not-rely-on-time
48
+ block.basefee,
49
+ messageDataHash
50
+ );
51
+ }
52
+
53
+ function addMessageToAccumulator(
54
+ uint8,
55
+ address,
56
+ uint256,
57
+ uint256,
58
+ uint256,
59
+ bytes32 messageDataHash
60
+ ) internal returns (uint256) {
61
+ uint256 count = inboxAccs.length;
62
+ bytes32 messageHash = Messages.messageHash(
63
+ 0,
64
+ address(uint160(0)),
65
+ 0,
66
+ 0,
67
+ 0,
68
+ 0,
69
+ messageDataHash
70
+ );
71
+ bytes32 prevAcc = 0;
72
+ if (count > 0) {
73
+ prevAcc = inboxAccs[count - 1];
74
+ }
75
+ inboxAccs.push(Messages.accumulateInboxMessage(prevAcc, messageHash));
76
+ return count;
77
+ }
78
+
79
+ function executeCall(
80
+ address,
81
+ uint256,
82
+ bytes calldata
83
+ ) external pure override returns (bool, bytes memory) {
84
+ revert("NOT_IMPLEMENTED");
85
+ }
86
+
87
+ function setInbox(address inbox, bool enabled) external override {
88
+ InOutInfo storage info = allowedInboxesMap[inbox];
89
+ bool alreadyEnabled = info.allowed;
90
+ emit InboxToggle(inbox, enabled);
91
+ if ((alreadyEnabled && enabled) || (!alreadyEnabled && !enabled)) {
92
+ return;
93
+ }
94
+ if (enabled) {
95
+ allowedInboxesMap[inbox] = InOutInfo(allowedInboxList.length, true);
96
+ allowedInboxList.push(inbox);
97
+ } else {
98
+ allowedInboxList[info.index] = allowedInboxList[allowedInboxList.length - 1];
99
+ allowedInboxesMap[allowedInboxList[info.index]].index = info.index;
100
+ allowedInboxList.pop();
101
+ delete allowedInboxesMap[inbox];
102
+ }
103
+ }
104
+
105
+ function setOutbox(
106
+ address, /* outbox */
107
+ bool /* enabled*/
108
+ ) external pure override {
109
+ revert("NOT_IMPLEMENTED");
110
+ }
111
+
112
+ function messageCount() external view override returns (uint256) {
113
+ return inboxAccs.length;
114
+ }
115
+ }
@@ -0,0 +1,13 @@
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
+ function increment() external {
11
+ counter++;
12
+ }
13
+ }
@@ -0,0 +1,41 @@
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 "../challenge/ChallengeManager.sol";
8
+
9
+ contract SingleExecutionChallenge is ChallengeManager {
10
+ constructor(
11
+ IOneStepProofEntry osp_,
12
+ IChallengeResultReceiver resultReceiver_,
13
+ uint64 maxInboxMessagesRead_,
14
+ bytes32[2] memory startAndEndHashes,
15
+ uint256 numSteps_,
16
+ address asserter_,
17
+ address challenger_,
18
+ uint256 asserterTimeLeft_,
19
+ uint256 challengerTimeLeft_
20
+ ) {
21
+ osp = osp_;
22
+ resultReceiver = resultReceiver_;
23
+ uint64 challengeIndex = ++totalChallengesCreated;
24
+ ChallengeLib.Challenge storage challenge = challenges[challengeIndex];
25
+ challenge.maxInboxMessages = maxInboxMessagesRead_;
26
+ bytes32[] memory segments = new bytes32[](2);
27
+ segments[0] = startAndEndHashes[0];
28
+ segments[1] = startAndEndHashes[1];
29
+ bytes32 challengeStateHash = ChallengeLib.hashChallengeState(0, numSteps_, segments);
30
+ challenge.challengeStateHash = challengeStateHash;
31
+ challenge.next = ChallengeLib.Participant({addr: asserter_, timeLeft: asserterTimeLeft_});
32
+ challenge.current = ChallengeLib.Participant({
33
+ addr: challenger_,
34
+ timeLeft: challengerTimeLeft_
35
+ });
36
+ challenge.lastMoveTimestamp = block.timestamp;
37
+ challenge.mode = ChallengeLib.ChallengeMode.EXECUTION;
38
+
39
+ emit Bisected(challengeIndex, challengeStateHash, 0, numSteps_, segments);
40
+ }
41
+ }
@@ -0,0 +1,131 @@
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/IInbox.sol";
8
+ import "../bridge/IBridge.sol";
9
+
10
+ import "../bridge/Messages.sol";
11
+ import "./BridgeStub.sol";
12
+ import {
13
+ L2_MSG,
14
+ L1MessageType_L2FundedByL1,
15
+ L1MessageType_submitRetryableTx,
16
+ L2MessageType_unsignedEOATx,
17
+ L2MessageType_unsignedContractTx
18
+ } from "../libraries/MessageTypes.sol";
19
+
20
+ contract InboxStub is IInbox {
21
+ IBridge public override bridge;
22
+
23
+ bool public paused;
24
+
25
+ function initialize(IBridge _bridge) external {
26
+ require(address(bridge) == address(0), "ALREADY_INIT");
27
+ bridge = _bridge;
28
+ }
29
+
30
+ /**
31
+ * @notice Send a generic L2 message to the chain
32
+ * @dev This method is an optimization to avoid having to emit the entirety of the messageData in a log. Instead validators are expected to be able to parse the data from the transaction's input
33
+ * @param messageData Data of the message being sent
34
+ */
35
+ function sendL2MessageFromOrigin(bytes calldata messageData) external returns (uint256) {
36
+ // solhint-disable-next-line avoid-tx-origin
37
+ require(msg.sender == tx.origin, "origin only");
38
+ uint256 msgNum = deliverToBridge(L2_MSG, msg.sender, keccak256(messageData));
39
+ emit InboxMessageDeliveredFromOrigin(msgNum);
40
+ return msgNum;
41
+ }
42
+
43
+ /**
44
+ * @notice Send a generic L2 message to the chain
45
+ * @dev This method can be used to send any type of message that doesn't require L1 validation
46
+ * @param messageData Data of the message being sent
47
+ */
48
+ function sendL2Message(bytes calldata messageData) external override returns (uint256) {
49
+ uint256 msgNum = deliverToBridge(L2_MSG, msg.sender, keccak256(messageData));
50
+ emit InboxMessageDelivered(msgNum, messageData);
51
+ return msgNum;
52
+ }
53
+
54
+ function deliverToBridge(
55
+ uint8 kind,
56
+ address sender,
57
+ bytes32 messageDataHash
58
+ ) internal returns (uint256) {
59
+ return bridge.enqueueDelayedMessage{value: msg.value}(kind, sender, messageDataHash);
60
+ }
61
+
62
+ function sendUnsignedTransaction(
63
+ uint256,
64
+ uint256,
65
+ uint256,
66
+ address,
67
+ uint256,
68
+ bytes calldata
69
+ ) external pure override returns (uint256) {
70
+ revert("NOT_IMPLEMENTED");
71
+ }
72
+
73
+ function sendContractTransaction(
74
+ uint256,
75
+ uint256,
76
+ address,
77
+ uint256,
78
+ bytes calldata
79
+ ) external pure override returns (uint256) {
80
+ revert("NOT_IMPLEMENTED");
81
+ }
82
+
83
+ function sendL1FundedUnsignedTransaction(
84
+ uint256,
85
+ uint256,
86
+ uint256,
87
+ address,
88
+ bytes calldata
89
+ ) external payable override returns (uint256) {
90
+ revert("NOT_IMPLEMENTED");
91
+ }
92
+
93
+ function sendL1FundedContractTransaction(
94
+ uint256,
95
+ uint256,
96
+ address,
97
+ bytes calldata
98
+ ) external payable override returns (uint256) {
99
+ revert("NOT_IMPLEMENTED");
100
+ }
101
+
102
+ function createRetryableTicket(
103
+ address,
104
+ uint256,
105
+ uint256,
106
+ address,
107
+ address,
108
+ uint256,
109
+ uint256,
110
+ bytes calldata
111
+ ) external payable override returns (uint256) {
112
+ revert("NOT_IMPLEMENTED");
113
+ }
114
+
115
+ function unsafeCreateRetryableTicket(
116
+ address,
117
+ uint256,
118
+ uint256,
119
+ address,
120
+ address,
121
+ uint256,
122
+ uint256,
123
+ bytes calldata
124
+ ) external payable override returns (uint256) {
125
+ revert("NOT_IMPLEMENTED");
126
+ }
127
+
128
+ function depositEth(uint256) external payable override returns (uint256) {
129
+ revert("NOT_IMPLEMENTED");
130
+ }
131
+ }
@@ -0,0 +1,59 @@
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 "../challenge/IChallengeResultReceiver.sol";
8
+ import "../challenge/IChallengeManager.sol";
9
+
10
+ contract MockResultReceiver is IChallengeResultReceiver {
11
+ IChallengeManager public manager;
12
+ address public winner;
13
+ address public loser;
14
+ uint256 public challengeIndex;
15
+
16
+ event ChallengeCompleted(
17
+ uint256 indexed challengeIndex,
18
+ address indexed winner,
19
+ address indexed loser
20
+ );
21
+
22
+ constructor(IChallengeManager manager_) {
23
+ manager = manager_;
24
+ }
25
+
26
+ function createChallenge(
27
+ bytes32 wasmModuleRoot_,
28
+ MachineStatus[2] calldata startAndEndMachineStatuses_,
29
+ GlobalState[2] calldata startAndEndGlobalStates_,
30
+ uint64 numBlocks,
31
+ address asserter_,
32
+ address challenger_,
33
+ uint256 asserterTimeLeft_,
34
+ uint256 challengerTimeLeft_
35
+ ) external returns (uint64) {
36
+ return
37
+ manager.createChallenge(
38
+ wasmModuleRoot_,
39
+ startAndEndMachineStatuses_,
40
+ startAndEndGlobalStates_,
41
+ numBlocks,
42
+ asserter_,
43
+ challenger_,
44
+ asserterTimeLeft_,
45
+ challengerTimeLeft_
46
+ );
47
+ }
48
+
49
+ function completeChallenge(
50
+ uint256 challengeIndex_,
51
+ address winner_,
52
+ address loser_
53
+ ) external override {
54
+ winner = winner_;
55
+ loser = loser_;
56
+ challengeIndex = challengeIndex_;
57
+ emit ChallengeCompleted(challengeIndex, winner_, loser_);
58
+ }
59
+ }
@@ -0,0 +1,42 @@
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/SequencerInbox.sol";
8
+
9
+ contract SequencerInboxStub is SequencerInbox {
10
+ constructor(
11
+ IBridge delayedBridge_,
12
+ address sequencer_,
13
+ ISequencerInbox.MaxTimeVariation memory maxTimeVariation_
14
+ ) {
15
+ delayedBridge = delayedBridge_;
16
+ rollup = msg.sender;
17
+ maxTimeVariation = maxTimeVariation_;
18
+ isBatchPoster[sequencer_] = true;
19
+ }
20
+
21
+ function addInitMessage() external {
22
+ (bytes32 dataHash, TimeBounds memory timeBounds) = formEmptyDataHash(0);
23
+ (bytes32 beforeAcc, bytes32 delayedAcc, bytes32 afterAcc) = addSequencerL2BatchImpl(
24
+ dataHash,
25
+ 0
26
+ );
27
+ emit SequencerBatchDelivered(
28
+ inboxAccs.length - 1,
29
+ beforeAcc,
30
+ afterAcc,
31
+ delayedAcc,
32
+ totalDelayedMessagesRead,
33
+ timeBounds,
34
+ BatchDataLocation.NoData
35
+ );
36
+ }
37
+
38
+ function getTimeBounds() internal view override returns (TimeBounds memory bounds) {
39
+ this; // silence warning about function not being view
40
+ return bounds;
41
+ }
42
+ }
@@ -0,0 +1,19 @@
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 "@openzeppelin/contracts/proxy/Proxy.sol";
8
+
9
+ contract SimpleProxy is Proxy {
10
+ address private immutable impl;
11
+
12
+ constructor(address impl_) {
13
+ impl = impl_;
14
+ }
15
+
16
+ function _implementation() internal view override returns (address) {
17
+ return impl;
18
+ }
19
+ }
@@ -0,0 +1,50 @@
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 Interface for providing gas estimation for retryable auto-redeems and constructing outbox proofs
8
+ * @notice This contract doesn't exist on-chain. Instead it is a virtual interface accessible at
9
+ * 0x00000000000000000000000000000000000000C8
10
+ * This is a cute trick to allow an Arbitrum node to provide data without us having to implement additional RPCs
11
+ */
12
+
13
+ interface NodeInterface {
14
+ /**
15
+ * @notice Estimate the cost of putting a message in the L2 inbox that is reexecuted
16
+ * @param sender sender of the L1 and L2 transaction
17
+ * @param deposit amount to deposit to sender in L2
18
+ * @param to destination L2 contract address
19
+ * @param l2CallValue call value for retryable L2 message
20
+ * @param excessFeeRefundAddress gasLimit x maxFeePerGas - execution cost gets credited here on L2 balance
21
+ * @param callValueRefundAddress l2Callvalue gets credited here on L2 if retryable txn times out or gets cancelled
22
+ * @param data ABI encoded data of L2 message
23
+ */
24
+ function estimateRetryableTicket(
25
+ address sender,
26
+ uint256 deposit,
27
+ address to,
28
+ uint256 l2CallValue,
29
+ address excessFeeRefundAddress,
30
+ address callValueRefundAddress,
31
+ bytes calldata data
32
+ ) external;
33
+
34
+ /**
35
+ * @notice Constructs an outbox proof of an l2->l1 send's existence in the outbox accumulator
36
+ * @param size the number of elements in the accumulator
37
+ * @param leaf the position of the send in the accumulator
38
+ * @return send the l2->l1 send's hash
39
+ * @return root the root of the outbox accumulator
40
+ * @return proof level-by-level branch hashes constituting a proof of the send's membership at the given size
41
+ */
42
+ function constructOutboxProof(uint64 size, uint64 leaf)
43
+ external
44
+ view
45
+ returns (
46
+ bytes32 send,
47
+ bytes32 root,
48
+ bytes32[] memory proof
49
+ );
50
+ }
@@ -0,0 +1,154 @@
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 "../libraries/CryptographyPrimitives.sol";
8
+
9
+ /// @dev The requested hash preimage at the given offset has not been proven yet
10
+ error NotProven(bytes32 fullHash, uint64 offset);
11
+
12
+ contract HashProofHelper {
13
+ struct KeccakState {
14
+ uint64 offset;
15
+ bytes part;
16
+ uint64[25] state;
17
+ uint256 length;
18
+ }
19
+
20
+ struct PreimagePart {
21
+ bool proven;
22
+ bytes part;
23
+ }
24
+
25
+ mapping(bytes32 => mapping(uint64 => PreimagePart)) private preimageParts;
26
+ mapping(address => KeccakState) public keccakStates;
27
+
28
+ event PreimagePartProven(bytes32 indexed fullHash, uint64 indexed offset, bytes part);
29
+
30
+ uint256 private constant MAX_PART_LENGTH = 32;
31
+ uint256 private constant KECCAK_ROUND_INPUT = 136;
32
+
33
+ function proveWithFullPreimage(bytes calldata data, uint64 offset)
34
+ external
35
+ returns (bytes32 fullHash)
36
+ {
37
+ fullHash = keccak256(data);
38
+ bytes memory part;
39
+ if (data.length > offset) {
40
+ uint256 partLength = data.length - offset;
41
+ if (partLength > 32) {
42
+ partLength = 32;
43
+ }
44
+ part = data[offset:(offset + partLength)];
45
+ }
46
+ preimageParts[fullHash][offset] = PreimagePart({proven: true, part: part});
47
+ emit PreimagePartProven(fullHash, offset, part);
48
+ }
49
+
50
+ // Flags: a bitset signaling various things about the proof, ordered from least to most significant bits.
51
+ // 0th bit: indicates that this data is the final chunk of preimage data.
52
+ // 1st bit: indicates that the preimage part currently being built should be cleared before this.
53
+ function proveWithSplitPreimage(
54
+ bytes calldata data,
55
+ uint64 offset,
56
+ uint256 flags
57
+ ) external returns (bytes32 fullHash) {
58
+ bool isFinal = (flags & (1 << 0)) != 0;
59
+ if ((flags & (1 << 1)) != 0) {
60
+ delete keccakStates[msg.sender];
61
+ }
62
+ require(isFinal || data.length % KECCAK_ROUND_INPUT == 0, "NOT_BLOCK_ALIGNED");
63
+ KeccakState storage state = keccakStates[msg.sender];
64
+ uint256 startLength = state.length;
65
+ if (startLength == 0) {
66
+ state.offset = offset;
67
+ } else {
68
+ require(state.offset == offset, "DIFF_OFFSET");
69
+ }
70
+ keccakUpdate(state, data, isFinal);
71
+ if (uint256(offset) + MAX_PART_LENGTH > startLength && offset < state.length) {
72
+ uint256 startIdx = 0;
73
+ if (offset > startLength) {
74
+ startIdx = offset - startLength;
75
+ }
76
+ uint256 endIdx = uint256(offset) + MAX_PART_LENGTH - startLength;
77
+ if (endIdx > data.length) {
78
+ endIdx = data.length;
79
+ }
80
+ for (uint256 i = startIdx; i < endIdx; i++) {
81
+ state.part.push(data[i]);
82
+ }
83
+ }
84
+ if (!isFinal) {
85
+ return bytes32(0);
86
+ }
87
+ for (uint256 i = 0; i < 32; i++) {
88
+ uint256 stateIdx = i / 8;
89
+ // work around our weird keccakF function state ordering
90
+ stateIdx = 5 * (stateIdx % 5) + stateIdx / 5;
91
+ uint8 b = uint8(state.state[stateIdx] >> ((i % 8) * 8));
92
+ fullHash |= bytes32(uint256(b) << (248 - (i * 8)));
93
+ }
94
+ preimageParts[fullHash][state.offset] = PreimagePart({proven: true, part: state.part});
95
+ emit PreimagePartProven(fullHash, state.offset, state.part);
96
+ delete keccakStates[msg.sender];
97
+ }
98
+
99
+ function keccakUpdate(
100
+ KeccakState storage state,
101
+ bytes calldata data,
102
+ bool isFinal
103
+ ) internal {
104
+ state.length += data.length;
105
+ while (true) {
106
+ if (data.length == 0 && !isFinal) {
107
+ break;
108
+ }
109
+ for (uint256 i = 0; i < KECCAK_ROUND_INPUT; i++) {
110
+ uint8 b = 0;
111
+ if (i < data.length) {
112
+ b = uint8(data[i]);
113
+ } else {
114
+ // Padding
115
+ if (i == data.length) {
116
+ b |= uint8(0x01);
117
+ }
118
+ if (i == KECCAK_ROUND_INPUT - 1) {
119
+ b |= uint8(0x80);
120
+ }
121
+ }
122
+ uint256 stateIdx = i / 8;
123
+ // work around our weird keccakF function state ordering
124
+ stateIdx = 5 * (stateIdx % 5) + stateIdx / 5;
125
+ state.state[stateIdx] ^= uint64(b) << uint64((i % 8) * 8);
126
+ }
127
+ uint256[25] memory state256;
128
+ for (uint256 i = 0; i < 25; i++) {
129
+ state256[i] = state.state[i];
130
+ }
131
+ state256 = CryptographyPrimitives.keccakF(state256);
132
+ for (uint256 i = 0; i < 25; i++) {
133
+ state.state[i] = uint64(state256[i]);
134
+ }
135
+ if (data.length < KECCAK_ROUND_INPUT) {
136
+ break;
137
+ }
138
+ data = data[KECCAK_ROUND_INPUT:];
139
+ }
140
+ }
141
+
142
+ function clearSplitProof() external {
143
+ delete keccakStates[msg.sender];
144
+ }
145
+
146
+ /// Retrieves up to 32 bytes of the preimage of fullHash at the given offset, reverting if it hasn't been proven yet.
147
+ function getPreimagePart(bytes32 fullHash, uint64 offset) external view returns (bytes memory) {
148
+ PreimagePart storage part = preimageParts[fullHash][offset];
149
+ if (!part.proven) {
150
+ revert NotProven(fullHash, offset);
151
+ }
152
+ return part.part;
153
+ }
154
+ }
@@ -0,0 +1,20 @@
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 "./IOneStepProver.sol";
8
+
9
+ library OneStepProofEntryLib {
10
+ uint256 internal constant MAX_STEPS = 1 << 43;
11
+ }
12
+
13
+ interface IOneStepProofEntry {
14
+ function proveOneStep(
15
+ ExecutionContext calldata execCtx,
16
+ uint256 machineStep,
17
+ bytes32 beforeHash,
18
+ bytes calldata proof
19
+ ) external view returns (bytes32 afterHash);
20
+ }
@@ -0,0 +1,27 @@
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 "../state/Machine.sol";
8
+ import "../state/Module.sol";
9
+ import "../state/Instructions.sol";
10
+ import "../bridge/ISequencerInbox.sol";
11
+ import "../bridge/IBridge.sol";
12
+
13
+ struct ExecutionContext {
14
+ uint256 maxInboxMessagesRead;
15
+ ISequencerInbox sequencerInbox;
16
+ IBridge delayedBridge;
17
+ }
18
+
19
+ abstract contract IOneStepProver {
20
+ function executeOneStep(
21
+ ExecutionContext memory execCtx,
22
+ Machine calldata mach,
23
+ Module calldata mod,
24
+ Instruction calldata instruction,
25
+ bytes calldata proof
26
+ ) external view virtual returns (Machine memory result, Module memory resultMod);
27
+ }