@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.
- package/.prettierrc +5 -0
- package/.solhint.json +18 -0
- package/deploy/BridgeStubCreator.js +10 -0
- package/deploy/HashProofHelper.js +13 -0
- package/deploy/InboxStubCreator.js +17 -0
- package/deploy/OneStepProofEntryCreator.js +19 -0
- package/deploy/OneStepProver0Creator.js +14 -0
- package/deploy/OneStepProverHostIoCreator.js +14 -0
- package/deploy/OneStepProverMathCreator.js +14 -0
- package/deploy/OneStepProverMemoryCreator.js +14 -0
- package/deploy/SequencerInboxStubCreator.js +13 -0
- package/deploy/ValueArrayTesterCreator.js +13 -0
- package/hardhat.config.ts +47 -0
- package/hardhat.prod-config.js +18 -0
- package/package.json +49 -0
- package/scripts/build.bash +5 -0
- package/src/bridge/Bridge.sol +168 -0
- package/src/bridge/IBridge.sol +68 -0
- package/src/bridge/IInbox.sol +80 -0
- package/src/bridge/IMessageProvider.sol +11 -0
- package/src/bridge/IOutbox.sol +52 -0
- package/src/bridge/ISequencerInbox.sol +85 -0
- package/src/bridge/Inbox.sol +414 -0
- package/src/bridge/Messages.sol +38 -0
- package/src/bridge/Outbox.sol +188 -0
- package/src/bridge/SequencerInbox.sol +274 -0
- package/src/challenge/ChallengeLib.sol +135 -0
- package/src/challenge/ChallengeManager.sol +367 -0
- package/src/challenge/IChallengeManager.sol +75 -0
- package/src/challenge/IChallengeResultReceiver.sol +13 -0
- package/src/libraries/AddressAliasHelper.sol +29 -0
- package/src/libraries/AdminFallbackProxy.sol +153 -0
- package/src/libraries/ArbitrumProxy.sol +20 -0
- package/src/libraries/Constants.sol +10 -0
- package/src/libraries/CryptographyPrimitives.sol +323 -0
- package/src/libraries/DelegateCallAware.sol +44 -0
- package/src/libraries/Error.sol +38 -0
- package/src/libraries/IGasRefunder.sol +35 -0
- package/src/libraries/MerkleLib.sol +46 -0
- package/src/libraries/MessageTypes.sol +14 -0
- package/src/libraries/SecondaryLogicUUPSUpgradeable.sol +58 -0
- package/src/libraries/UUPSNotUpgradeable.sol +56 -0
- package/src/mocks/BridgeStub.sol +115 -0
- package/src/mocks/Counter.sol +13 -0
- package/src/mocks/ExecutionManager.sol +41 -0
- package/src/mocks/InboxStub.sol +131 -0
- package/src/mocks/MockResultReceiver.sol +59 -0
- package/src/mocks/SequencerInboxStub.sol +42 -0
- package/src/mocks/SimpleProxy.sol +19 -0
- package/src/node-interface/NodeInterface.sol +50 -0
- package/src/osp/HashProofHelper.sol +154 -0
- package/src/osp/IOneStepProofEntry.sol +20 -0
- package/src/osp/IOneStepProver.sol +27 -0
- package/src/osp/OneStepProofEntry.sol +129 -0
- package/src/osp/OneStepProver0.sol +566 -0
- package/src/osp/OneStepProverHostIo.sol +357 -0
- package/src/osp/OneStepProverMath.sol +514 -0
- package/src/osp/OneStepProverMemory.sol +313 -0
- package/src/precompiles/ArbAddressTable.sol +60 -0
- package/src/precompiles/ArbAggregator.sol +62 -0
- package/src/precompiles/ArbBLS.sol +53 -0
- package/src/precompiles/ArbDebug.sol +39 -0
- package/src/precompiles/ArbFunctionTable.sol +29 -0
- package/src/precompiles/ArbGasInfo.sol +121 -0
- package/src/precompiles/ArbInfo.sol +15 -0
- package/src/precompiles/ArbOwner.sol +65 -0
- package/src/precompiles/ArbOwnerPublic.sol +18 -0
- package/src/precompiles/ArbRetryableTx.sol +89 -0
- package/src/precompiles/ArbStatistics.sol +29 -0
- package/src/precompiles/ArbSys.sol +134 -0
- package/src/precompiles/ArbosActs.sol +41 -0
- package/src/precompiles/ArbosTest.sol +14 -0
- package/src/rollup/BridgeCreator.sol +120 -0
- package/src/rollup/IRollupCore.sol +152 -0
- package/src/rollup/IRollupLogic.sol +183 -0
- package/src/rollup/Node.sol +99 -0
- package/src/rollup/RollupAdminLogic.sol +322 -0
- package/src/rollup/RollupCore.sol +627 -0
- package/src/rollup/RollupCreator.sol +133 -0
- package/src/rollup/RollupEventBridge.sol +46 -0
- package/src/rollup/RollupLib.sol +135 -0
- package/src/rollup/RollupUserLogic.sol +712 -0
- package/src/rollup/ValidatorUtils.sol +243 -0
- package/src/rollup/ValidatorWallet.sol +76 -0
- package/src/rollup/ValidatorWalletCreator.sol +43 -0
- package/src/state/Deserialize.sol +321 -0
- package/src/state/GlobalState.sol +44 -0
- package/src/state/Instructions.sol +159 -0
- package/src/state/Machine.sol +65 -0
- package/src/state/MerkleProof.sol +99 -0
- package/src/state/Module.sol +33 -0
- package/src/state/ModuleMemory.sol +42 -0
- package/src/state/PcArray.sol +45 -0
- package/src/state/PcStack.sol +32 -0
- package/src/state/StackFrame.sol +63 -0
- package/src/state/Value.sol +65 -0
- package/src/state/ValueArray.sol +47 -0
- package/src/state/ValueStack.sol +39 -0
- package/src/test-helpers/CryptographyPrimitivesTester.sol +27 -0
- package/src/test-helpers/MessageTester.sol +34 -0
- package/src/test-helpers/ValueArrayTester.sol +34 -0
- package/test/contract/arbRollup.spec.ts +869 -0
- package/test/contract/common/challengeLib.ts +43 -0
- package/test/contract/common/globalStateLib.ts +17 -0
- package/test/contract/common/rolluplib.ts +259 -0
- package/test/contract/cryptographyPrimitives.spec.ts +82 -0
- package/test/contract/sequencerInboxForceInclude.spec.ts +516 -0
- package/test/contract/utils.ts +40 -0
- package/test/prover/hash-proofs.ts +75 -0
- package/test/prover/one-step-proof.ts +93 -0
- package/test/prover/proofs/.gitkeep +0 -0
- package/test/prover/value-arrays.ts +11 -0
- package/tsconfig.json +13 -0
|
@@ -0,0 +1,133 @@
|
|
|
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/Bridge.sol";
|
|
8
|
+
import "../bridge/SequencerInbox.sol";
|
|
9
|
+
import "../bridge/Inbox.sol";
|
|
10
|
+
import "../bridge/Outbox.sol";
|
|
11
|
+
import "./RollupEventBridge.sol";
|
|
12
|
+
import "./BridgeCreator.sol";
|
|
13
|
+
|
|
14
|
+
import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
|
|
15
|
+
import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
|
|
16
|
+
import "@openzeppelin/contracts/access/Ownable.sol";
|
|
17
|
+
|
|
18
|
+
import "../libraries/ArbitrumProxy.sol";
|
|
19
|
+
import "./RollupUserLogic.sol";
|
|
20
|
+
import "./RollupAdminLogic.sol";
|
|
21
|
+
import "../bridge/IBridge.sol";
|
|
22
|
+
|
|
23
|
+
import "./RollupLib.sol";
|
|
24
|
+
|
|
25
|
+
contract RollupCreator is Ownable {
|
|
26
|
+
event RollupCreated(
|
|
27
|
+
address indexed rollupAddress,
|
|
28
|
+
address inboxAddress,
|
|
29
|
+
address adminProxy,
|
|
30
|
+
address sequencerInbox,
|
|
31
|
+
address delayedBridge
|
|
32
|
+
);
|
|
33
|
+
event TemplatesUpdated();
|
|
34
|
+
|
|
35
|
+
BridgeCreator public bridgeCreator;
|
|
36
|
+
IOneStepProofEntry public osp;
|
|
37
|
+
IChallengeManager public challengeManagerTemplate;
|
|
38
|
+
IRollupAdmin public rollupAdminLogic;
|
|
39
|
+
IRollupUser public rollupUserLogic;
|
|
40
|
+
|
|
41
|
+
constructor() Ownable() {}
|
|
42
|
+
|
|
43
|
+
function setTemplates(
|
|
44
|
+
BridgeCreator _bridgeCreator,
|
|
45
|
+
IOneStepProofEntry _osp,
|
|
46
|
+
IChallengeManager _challengeManagerLogic,
|
|
47
|
+
IRollupAdmin _rollupAdminLogic,
|
|
48
|
+
IRollupUser _rollupUserLogic
|
|
49
|
+
) external onlyOwner {
|
|
50
|
+
bridgeCreator = _bridgeCreator;
|
|
51
|
+
osp = _osp;
|
|
52
|
+
challengeManagerTemplate = _challengeManagerLogic;
|
|
53
|
+
rollupAdminLogic = _rollupAdminLogic;
|
|
54
|
+
rollupUserLogic = _rollupUserLogic;
|
|
55
|
+
emit TemplatesUpdated();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
struct CreateRollupFrame {
|
|
59
|
+
ProxyAdmin admin;
|
|
60
|
+
Bridge delayedBridge;
|
|
61
|
+
SequencerInbox sequencerInbox;
|
|
62
|
+
Inbox inbox;
|
|
63
|
+
RollupEventBridge rollupEventBridge;
|
|
64
|
+
Outbox outbox;
|
|
65
|
+
ArbitrumProxy rollup;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// After this setup:
|
|
69
|
+
// Rollup should be the owner of bridge
|
|
70
|
+
// RollupOwner should be the owner of Rollup's ProxyAdmin
|
|
71
|
+
// RollupOwner should be the owner of Rollup
|
|
72
|
+
// Bridge should have a single inbox and outbox
|
|
73
|
+
function createRollup(Config memory config, address expectedRollupAddr)
|
|
74
|
+
external
|
|
75
|
+
returns (address)
|
|
76
|
+
{
|
|
77
|
+
CreateRollupFrame memory frame;
|
|
78
|
+
frame.admin = new ProxyAdmin();
|
|
79
|
+
|
|
80
|
+
(
|
|
81
|
+
frame.delayedBridge,
|
|
82
|
+
frame.sequencerInbox,
|
|
83
|
+
frame.inbox,
|
|
84
|
+
frame.rollupEventBridge,
|
|
85
|
+
frame.outbox
|
|
86
|
+
) = bridgeCreator.createBridge(
|
|
87
|
+
address(frame.admin),
|
|
88
|
+
expectedRollupAddr,
|
|
89
|
+
config.sequencerInboxMaxTimeVariation
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
frame.admin.transferOwnership(config.owner);
|
|
93
|
+
|
|
94
|
+
IChallengeManager challengeManager = IChallengeManager(
|
|
95
|
+
address(
|
|
96
|
+
new TransparentUpgradeableProxy(
|
|
97
|
+
address(challengeManagerTemplate),
|
|
98
|
+
address(frame.admin),
|
|
99
|
+
""
|
|
100
|
+
)
|
|
101
|
+
)
|
|
102
|
+
);
|
|
103
|
+
challengeManager.initialize(
|
|
104
|
+
IChallengeResultReceiver(expectedRollupAddr),
|
|
105
|
+
frame.sequencerInbox,
|
|
106
|
+
frame.delayedBridge,
|
|
107
|
+
osp
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
frame.rollup = new ArbitrumProxy(
|
|
111
|
+
config,
|
|
112
|
+
ContractDependencies({
|
|
113
|
+
delayedBridge: frame.delayedBridge,
|
|
114
|
+
sequencerInbox: frame.sequencerInbox,
|
|
115
|
+
outbox: frame.outbox,
|
|
116
|
+
rollupEventBridge: frame.rollupEventBridge,
|
|
117
|
+
challengeManager: challengeManager,
|
|
118
|
+
rollupAdminLogic: rollupAdminLogic,
|
|
119
|
+
rollupUserLogic: rollupUserLogic
|
|
120
|
+
})
|
|
121
|
+
);
|
|
122
|
+
require(address(frame.rollup) == expectedRollupAddr, "WRONG_ROLLUP_ADDR");
|
|
123
|
+
|
|
124
|
+
emit RollupCreated(
|
|
125
|
+
address(frame.rollup),
|
|
126
|
+
address(frame.inbox),
|
|
127
|
+
address(frame.admin),
|
|
128
|
+
address(frame.sequencerInbox),
|
|
129
|
+
address(frame.delayedBridge)
|
|
130
|
+
);
|
|
131
|
+
return address(frame.rollup);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
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 "./IRollupLogic.sol";
|
|
8
|
+
|
|
9
|
+
import "../bridge/IBridge.sol";
|
|
10
|
+
import "../bridge/IMessageProvider.sol";
|
|
11
|
+
import "../libraries/DelegateCallAware.sol";
|
|
12
|
+
import {INITIALIZATION_MSG_TYPE} from "../libraries/MessageTypes.sol";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @title The inbox for rollup protocol events
|
|
16
|
+
*/
|
|
17
|
+
contract RollupEventBridge is IMessageProvider, DelegateCallAware {
|
|
18
|
+
uint8 internal constant CREATE_NODE_EVENT = 0;
|
|
19
|
+
uint8 internal constant CONFIRM_NODE_EVENT = 1;
|
|
20
|
+
uint8 internal constant REJECT_NODE_EVENT = 2;
|
|
21
|
+
uint8 internal constant STAKE_CREATED_EVENT = 3;
|
|
22
|
+
|
|
23
|
+
IBridge public bridge;
|
|
24
|
+
address public rollup;
|
|
25
|
+
|
|
26
|
+
modifier onlyRollup() {
|
|
27
|
+
require(msg.sender == rollup, "ONLY_ROLLUP");
|
|
28
|
+
_;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function initialize(address _bridge, address _rollup) external onlyDelegated {
|
|
32
|
+
require(rollup == address(0), "ALREADY_INIT");
|
|
33
|
+
bridge = IBridge(_bridge);
|
|
34
|
+
rollup = _rollup;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function rollupInitialized(uint256 chainId) external onlyRollup {
|
|
38
|
+
bytes memory initMsg = abi.encodePacked(chainId);
|
|
39
|
+
uint256 num = bridge.enqueueDelayedMessage(
|
|
40
|
+
INITIALIZATION_MSG_TYPE,
|
|
41
|
+
address(0),
|
|
42
|
+
keccak256(initMsg)
|
|
43
|
+
);
|
|
44
|
+
emit InboxMessageDelivered(num, initMsg);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
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/IChallengeManager.sol";
|
|
8
|
+
import "../challenge/ChallengeLib.sol";
|
|
9
|
+
import "../state/GlobalState.sol";
|
|
10
|
+
import "../bridge/ISequencerInbox.sol";
|
|
11
|
+
|
|
12
|
+
import "../bridge/IBridge.sol";
|
|
13
|
+
import "../bridge/IOutbox.sol";
|
|
14
|
+
import "./RollupEventBridge.sol";
|
|
15
|
+
import "./IRollupLogic.sol";
|
|
16
|
+
|
|
17
|
+
struct Config {
|
|
18
|
+
uint64 confirmPeriodBlocks;
|
|
19
|
+
uint64 extraChallengeTimeBlocks;
|
|
20
|
+
address stakeToken;
|
|
21
|
+
uint256 baseStake;
|
|
22
|
+
bytes32 wasmModuleRoot;
|
|
23
|
+
address owner;
|
|
24
|
+
address loserStakeEscrow;
|
|
25
|
+
uint256 chainId;
|
|
26
|
+
ISequencerInbox.MaxTimeVariation sequencerInboxMaxTimeVariation;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
struct ContractDependencies {
|
|
30
|
+
IBridge delayedBridge;
|
|
31
|
+
ISequencerInbox sequencerInbox;
|
|
32
|
+
IOutbox outbox;
|
|
33
|
+
RollupEventBridge rollupEventBridge;
|
|
34
|
+
IChallengeManager challengeManager;
|
|
35
|
+
IRollupAdmin rollupAdminLogic;
|
|
36
|
+
IRollupUser rollupUserLogic;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
library RollupLib {
|
|
40
|
+
using GlobalStateLib for GlobalState;
|
|
41
|
+
|
|
42
|
+
struct ExecutionState {
|
|
43
|
+
GlobalState globalState;
|
|
44
|
+
MachineStatus machineStatus;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function stateHash(ExecutionState calldata execState, uint256 inboxMaxCount)
|
|
48
|
+
internal
|
|
49
|
+
pure
|
|
50
|
+
returns (bytes32)
|
|
51
|
+
{
|
|
52
|
+
return
|
|
53
|
+
keccak256(
|
|
54
|
+
abi.encodePacked(
|
|
55
|
+
execState.globalState.hash(),
|
|
56
|
+
inboxMaxCount,
|
|
57
|
+
execState.machineStatus
|
|
58
|
+
)
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/// @dev same as stateHash but expects execState in memory instead of calldata
|
|
63
|
+
function stateHashMem(ExecutionState memory execState, uint256 inboxMaxCount)
|
|
64
|
+
internal
|
|
65
|
+
pure
|
|
66
|
+
returns (bytes32)
|
|
67
|
+
{
|
|
68
|
+
return
|
|
69
|
+
keccak256(
|
|
70
|
+
abi.encodePacked(
|
|
71
|
+
execState.globalState.hash(),
|
|
72
|
+
inboxMaxCount,
|
|
73
|
+
execState.machineStatus
|
|
74
|
+
)
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
struct Assertion {
|
|
79
|
+
ExecutionState beforeState;
|
|
80
|
+
ExecutionState afterState;
|
|
81
|
+
uint64 numBlocks;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function executionHash(Assertion memory assertion) internal pure returns (bytes32) {
|
|
85
|
+
MachineStatus[2] memory statuses;
|
|
86
|
+
statuses[0] = assertion.beforeState.machineStatus;
|
|
87
|
+
statuses[1] = assertion.afterState.machineStatus;
|
|
88
|
+
GlobalState[2] memory globalStates;
|
|
89
|
+
globalStates[0] = assertion.beforeState.globalState;
|
|
90
|
+
globalStates[1] = assertion.afterState.globalState;
|
|
91
|
+
// TODO: benchmark how much this abstraction adds of gas overhead
|
|
92
|
+
return executionHash(statuses, globalStates, assertion.numBlocks);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function executionHash(
|
|
96
|
+
MachineStatus[2] memory statuses,
|
|
97
|
+
GlobalState[2] memory globalStates,
|
|
98
|
+
uint64 numBlocks
|
|
99
|
+
) internal pure returns (bytes32) {
|
|
100
|
+
bytes32[] memory segments = new bytes32[](2);
|
|
101
|
+
segments[0] = ChallengeLib.blockStateHash(statuses[0], globalStates[0].hash());
|
|
102
|
+
segments[1] = ChallengeLib.blockStateHash(statuses[1], globalStates[1].hash());
|
|
103
|
+
return ChallengeLib.hashChallengeState(0, numBlocks, segments);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function challengeRootHash(
|
|
107
|
+
bytes32 execution,
|
|
108
|
+
uint256 proposedTime,
|
|
109
|
+
bytes32 wasmModuleRoot
|
|
110
|
+
) internal pure returns (bytes32) {
|
|
111
|
+
return keccak256(abi.encodePacked(execution, proposedTime, wasmModuleRoot));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function confirmHash(Assertion memory assertion) internal pure returns (bytes32) {
|
|
115
|
+
return
|
|
116
|
+
confirmHash(
|
|
117
|
+
assertion.afterState.globalState.getBlockHash(),
|
|
118
|
+
assertion.afterState.globalState.getSendRoot()
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function confirmHash(bytes32 blockHash, bytes32 sendRoot) internal pure returns (bytes32) {
|
|
123
|
+
return keccak256(abi.encodePacked(blockHash, sendRoot));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function nodeHash(
|
|
127
|
+
bool hasSibling,
|
|
128
|
+
bytes32 lastHash,
|
|
129
|
+
bytes32 assertionExecHash,
|
|
130
|
+
bytes32 inboxAcc
|
|
131
|
+
) internal pure returns (bytes32) {
|
|
132
|
+
uint8 hasSiblingInt = hasSibling ? 1 : 0;
|
|
133
|
+
return keccak256(abi.encodePacked(hasSiblingInt, lastHash, assertionExecHash, inboxAcc));
|
|
134
|
+
}
|
|
135
|
+
}
|