@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,357 @@
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/Value.sol";
8
+ import "../state/Machine.sol";
9
+ import "../state/Deserialize.sol";
10
+ import "./IOneStepProver.sol";
11
+ import "../bridge/Messages.sol";
12
+ import "../bridge/IBridge.sol";
13
+ import "../bridge/ISequencerInbox.sol";
14
+
15
+ contract OneStepProverHostIo is IOneStepProver {
16
+ using GlobalStateLib for GlobalState;
17
+ using MerkleProofLib for MerkleProof;
18
+ using ModuleMemoryLib for ModuleMemory;
19
+ using ValueLib for Value;
20
+ using ValueStackLib for ValueStack;
21
+
22
+ uint256 private constant LEAF_SIZE = 32;
23
+ uint256 private constant INBOX_NUM = 2;
24
+ uint64 private constant INBOX_HEADER_LEN = 40;
25
+ uint64 private constant DELAYED_HEADER_LEN = 112 + 1;
26
+
27
+ function setLeafByte(
28
+ bytes32 oldLeaf,
29
+ uint256 idx,
30
+ uint8 val
31
+ ) internal pure returns (bytes32) {
32
+ require(idx < LEAF_SIZE, "BAD_SET_LEAF_BYTE_IDX");
33
+ // Take into account that we are casting the leaf to a big-endian integer
34
+ uint256 leafShift = (LEAF_SIZE - 1 - idx) * 8;
35
+ uint256 newLeaf = uint256(oldLeaf);
36
+ newLeaf &= ~(0xFF << leafShift);
37
+ newLeaf |= uint256(val) << leafShift;
38
+ return bytes32(newLeaf);
39
+ }
40
+
41
+ function executeGetOrSetBytes32(
42
+ Machine memory mach,
43
+ Module memory mod,
44
+ GlobalState memory state,
45
+ Instruction calldata inst,
46
+ bytes calldata proof
47
+ ) internal pure {
48
+ uint256 ptr = mach.valueStack.pop().assumeI32();
49
+ uint32 idx = mach.valueStack.pop().assumeI32();
50
+
51
+ if (idx >= GlobalStateLib.BYTES32_VALS_NUM) {
52
+ mach.status = MachineStatus.ERRORED;
53
+ return;
54
+ }
55
+ if (ptr + 32 > mod.moduleMemory.size || ptr % LEAF_SIZE != 0) {
56
+ mach.status = MachineStatus.ERRORED;
57
+ return;
58
+ }
59
+
60
+ uint256 leafIdx = ptr / LEAF_SIZE;
61
+ uint256 proofOffset = 0;
62
+ bytes32 startLeafContents;
63
+ MerkleProof memory merkleProof;
64
+ (startLeafContents, proofOffset, merkleProof) = mod.moduleMemory.proveLeaf(
65
+ leafIdx,
66
+ proof,
67
+ proofOffset
68
+ );
69
+
70
+ if (inst.opcode == Instructions.GET_GLOBAL_STATE_BYTES32) {
71
+ mod.moduleMemory.merkleRoot = merkleProof.computeRootFromMemory(
72
+ leafIdx,
73
+ state.bytes32Vals[idx]
74
+ );
75
+ } else if (inst.opcode == Instructions.SET_GLOBAL_STATE_BYTES32) {
76
+ state.bytes32Vals[idx] = startLeafContents;
77
+ } else {
78
+ revert("BAD_GLOBAL_STATE_OPCODE");
79
+ }
80
+ }
81
+
82
+ function executeGetU64(Machine memory mach, GlobalState memory state) internal pure {
83
+ uint32 idx = mach.valueStack.pop().assumeI32();
84
+
85
+ if (idx >= GlobalStateLib.U64_VALS_NUM) {
86
+ mach.status = MachineStatus.ERRORED;
87
+ return;
88
+ }
89
+
90
+ mach.valueStack.push(ValueLib.newI64(state.u64Vals[idx]));
91
+ }
92
+
93
+ function executeSetU64(Machine memory mach, GlobalState memory state) internal pure {
94
+ uint64 val = mach.valueStack.pop().assumeI64();
95
+ uint32 idx = mach.valueStack.pop().assumeI32();
96
+
97
+ if (idx >= GlobalStateLib.U64_VALS_NUM) {
98
+ mach.status = MachineStatus.ERRORED;
99
+ return;
100
+ }
101
+ state.u64Vals[idx] = val;
102
+ }
103
+
104
+ function executeReadPreImage(
105
+ ExecutionContext calldata,
106
+ Machine memory mach,
107
+ Module memory mod,
108
+ Instruction calldata,
109
+ bytes calldata proof
110
+ ) internal pure {
111
+ uint256 preimageOffset = mach.valueStack.pop().assumeI32();
112
+ uint256 ptr = mach.valueStack.pop().assumeI32();
113
+ if (ptr + 32 > mod.moduleMemory.size || ptr % LEAF_SIZE != 0) {
114
+ mach.status = MachineStatus.ERRORED;
115
+ return;
116
+ }
117
+
118
+ uint256 leafIdx = ptr / LEAF_SIZE;
119
+ uint256 proofOffset = 0;
120
+ bytes32 leafContents;
121
+ MerkleProof memory merkleProof;
122
+ (leafContents, proofOffset, merkleProof) = mod.moduleMemory.proveLeaf(
123
+ leafIdx,
124
+ proof,
125
+ proofOffset
126
+ );
127
+
128
+ bytes memory extracted;
129
+ uint8 proofType = uint8(proof[proofOffset]);
130
+ proofOffset++;
131
+ if (proofType == 0) {
132
+ bytes calldata preimage = proof[proofOffset:];
133
+ require(keccak256(preimage) == leafContents, "BAD_PREIMAGE");
134
+
135
+ uint256 preimageEnd = preimageOffset + 32;
136
+ if (preimageEnd > preimage.length) {
137
+ preimageEnd = preimage.length;
138
+ }
139
+ extracted = preimage[preimageOffset:preimageEnd];
140
+ } else {
141
+ // TODO: support proving via an authenticated contract
142
+ revert("UNKNOWN_PREIMAGE_PROOF");
143
+ }
144
+
145
+ for (uint256 i = 0; i < extracted.length; i++) {
146
+ leafContents = setLeafByte(leafContents, i, uint8(extracted[i]));
147
+ }
148
+
149
+ mod.moduleMemory.merkleRoot = merkleProof.computeRootFromMemory(leafIdx, leafContents);
150
+
151
+ mach.valueStack.push(ValueLib.newI32(uint32(extracted.length)));
152
+ }
153
+
154
+ function validateSequencerInbox(
155
+ ExecutionContext calldata execCtx,
156
+ uint64 msgIndex,
157
+ bytes calldata message
158
+ ) internal view returns (bool) {
159
+ require(message.length >= INBOX_HEADER_LEN, "BAD_SEQINBOX_PROOF");
160
+
161
+ uint64 afterDelayedMsg;
162
+ (afterDelayedMsg, ) = Deserialize.u64(message, 32);
163
+ bytes32 messageHash = keccak256(message);
164
+ bytes32 beforeAcc;
165
+ bytes32 delayedAcc;
166
+
167
+ if (msgIndex > 0) {
168
+ beforeAcc = execCtx.sequencerInbox.inboxAccs(msgIndex - 1);
169
+ }
170
+ if (afterDelayedMsg > 0) {
171
+ delayedAcc = execCtx.delayedBridge.inboxAccs(afterDelayedMsg - 1);
172
+ }
173
+ bytes32 acc = keccak256(abi.encodePacked(beforeAcc, messageHash, delayedAcc));
174
+ require(acc == execCtx.sequencerInbox.inboxAccs(msgIndex), "BAD_SEQINBOX_MESSAGE");
175
+ return true;
176
+ }
177
+
178
+ function validateDelayedInbox(
179
+ ExecutionContext calldata execCtx,
180
+ uint64 msgIndex,
181
+ bytes calldata message
182
+ ) internal view returns (bool) {
183
+ require(message.length >= DELAYED_HEADER_LEN, "BAD_DELAYED_PROOF");
184
+
185
+ bytes32 beforeAcc;
186
+
187
+ if (msgIndex > 0) {
188
+ beforeAcc = execCtx.delayedBridge.inboxAccs(msgIndex - 1);
189
+ }
190
+
191
+ bytes32 messageDataHash = keccak256(message[DELAYED_HEADER_LEN:]);
192
+ bytes1 kind = message[0];
193
+ uint256 sender;
194
+ (sender, ) = Deserialize.u256(message, 1);
195
+
196
+ bytes32 messageHash = keccak256(
197
+ abi.encodePacked(kind, uint160(sender), message[33:DELAYED_HEADER_LEN], messageDataHash)
198
+ );
199
+ bytes32 acc = Messages.accumulateInboxMessage(beforeAcc, messageHash);
200
+
201
+ require(acc == execCtx.delayedBridge.inboxAccs(msgIndex), "BAD_DELAYED_MESSAGE");
202
+ return true;
203
+ }
204
+
205
+ function executeReadInboxMessage(
206
+ ExecutionContext calldata execCtx,
207
+ Machine memory mach,
208
+ Module memory mod,
209
+ Instruction calldata inst,
210
+ bytes calldata proof
211
+ ) internal view {
212
+ uint256 messageOffset = mach.valueStack.pop().assumeI32();
213
+ uint256 ptr = mach.valueStack.pop().assumeI32();
214
+ uint256 msgIndex = mach.valueStack.pop().assumeI64();
215
+ if (
216
+ inst.argumentData == Instructions.INBOX_INDEX_SEQUENCER &&
217
+ msgIndex >= execCtx.maxInboxMessagesRead
218
+ ) {
219
+ mach.status = MachineStatus.TOO_FAR;
220
+ return;
221
+ }
222
+
223
+ if (ptr + 32 > mod.moduleMemory.size || ptr % LEAF_SIZE != 0) {
224
+ mach.status = MachineStatus.ERRORED;
225
+ return;
226
+ }
227
+
228
+ uint256 leafIdx = ptr / LEAF_SIZE;
229
+ uint256 proofOffset = 0;
230
+ bytes32 leafContents;
231
+ MerkleProof memory merkleProof;
232
+ (leafContents, proofOffset, merkleProof) = mod.moduleMemory.proveLeaf(
233
+ leafIdx,
234
+ proof,
235
+ proofOffset
236
+ );
237
+
238
+ {
239
+ // TODO: support proving via an authenticated contract
240
+ require(proof[proofOffset] == 0, "UNKNOWN_INBOX_PROOF");
241
+ proofOffset++;
242
+
243
+ function(ExecutionContext calldata, uint64, bytes calldata)
244
+ internal
245
+ view
246
+ returns (bool) inboxValidate;
247
+
248
+ bool success;
249
+ if (inst.argumentData == Instructions.INBOX_INDEX_SEQUENCER) {
250
+ inboxValidate = validateSequencerInbox;
251
+ } else if (inst.argumentData == Instructions.INBOX_INDEX_DELAYED) {
252
+ inboxValidate = validateDelayedInbox;
253
+ } else {
254
+ mach.status = MachineStatus.ERRORED;
255
+ return;
256
+ }
257
+ success = inboxValidate(execCtx, uint64(msgIndex), proof[proofOffset:]);
258
+ if (!success) {
259
+ mach.status = MachineStatus.ERRORED;
260
+ return;
261
+ }
262
+ }
263
+
264
+ require(proof.length >= proofOffset, "BAD_MESSAGE_PROOF");
265
+ uint256 messageLength = proof.length - proofOffset;
266
+
267
+ uint32 i = 0;
268
+ for (; i < 32 && messageOffset + i < messageLength; i++) {
269
+ leafContents = setLeafByte(
270
+ leafContents,
271
+ i,
272
+ uint8(proof[proofOffset + messageOffset + i])
273
+ );
274
+ }
275
+
276
+ mod.moduleMemory.merkleRoot = merkleProof.computeRootFromMemory(leafIdx, leafContents);
277
+ mach.valueStack.push(ValueLib.newI32(i));
278
+ }
279
+
280
+ function executeHaltAndSetFinished(
281
+ ExecutionContext calldata,
282
+ Machine memory mach,
283
+ Module memory,
284
+ Instruction calldata,
285
+ bytes calldata
286
+ ) internal pure {
287
+ mach.status = MachineStatus.FINISHED;
288
+ }
289
+
290
+ function executeGlobalStateAccess(
291
+ ExecutionContext calldata,
292
+ Machine memory mach,
293
+ Module memory mod,
294
+ Instruction calldata inst,
295
+ bytes calldata proof
296
+ ) internal pure {
297
+ uint16 opcode = inst.opcode;
298
+
299
+ GlobalState memory state;
300
+ uint256 proofOffset = 0;
301
+ (state, proofOffset) = Deserialize.globalState(proof, proofOffset);
302
+ require(state.hash() == mach.globalStateHash, "BAD_GLOBAL_STATE");
303
+
304
+ if (
305
+ opcode == Instructions.GET_GLOBAL_STATE_BYTES32 ||
306
+ opcode == Instructions.SET_GLOBAL_STATE_BYTES32
307
+ ) {
308
+ executeGetOrSetBytes32(mach, mod, state, inst, proof[proofOffset:]);
309
+ } else if (opcode == Instructions.GET_GLOBAL_STATE_U64) {
310
+ executeGetU64(mach, state);
311
+ } else if (opcode == Instructions.SET_GLOBAL_STATE_U64) {
312
+ executeSetU64(mach, state);
313
+ } else {
314
+ revert("INVALID_GLOBALSTATE_OPCODE");
315
+ }
316
+
317
+ mach.globalStateHash = state.hash();
318
+ }
319
+
320
+ function executeOneStep(
321
+ ExecutionContext calldata execCtx,
322
+ Machine calldata startMach,
323
+ Module calldata startMod,
324
+ Instruction calldata inst,
325
+ bytes calldata proof
326
+ ) external view override returns (Machine memory mach, Module memory mod) {
327
+ mach = startMach;
328
+ mod = startMod;
329
+
330
+ uint16 opcode = inst.opcode;
331
+
332
+ function(
333
+ ExecutionContext calldata,
334
+ Machine memory,
335
+ Module memory,
336
+ Instruction calldata,
337
+ bytes calldata
338
+ ) internal view impl;
339
+
340
+ if (
341
+ opcode >= Instructions.GET_GLOBAL_STATE_BYTES32 &&
342
+ opcode <= Instructions.SET_GLOBAL_STATE_U64
343
+ ) {
344
+ impl = executeGlobalStateAccess;
345
+ } else if (opcode == Instructions.READ_PRE_IMAGE) {
346
+ impl = executeReadPreImage;
347
+ } else if (opcode == Instructions.READ_INBOX_MESSAGE) {
348
+ impl = executeReadInboxMessage;
349
+ } else if (opcode == Instructions.HALT_AND_SET_FINISHED) {
350
+ impl = executeHaltAndSetFinished;
351
+ } else {
352
+ revert("INVALID_MEMORY_OPCODE");
353
+ }
354
+
355
+ impl(execCtx, mach, mod, inst, proof);
356
+ }
357
+ }