@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.
- package/README.md +15 -0
- package/package.json +12 -8
- package/src/bridge/IInbox.sol +9 -0
- package/src/bridge/Inbox.sol +19 -39
- package/src/libraries/AdminFallbackProxy.sol +5 -5
- package/src/libraries/MessageTypes.sol +1 -0
- package/src/mocks/InboxStub.sol +4 -0
- package/src/mocks/Simple.sol +30 -0
- package/src/node-interface/NodeInterface.sol +18 -1
- package/src/node-interface/NodeInterfaceDebug.sol +30 -0
- package/src/osp/OneStepProver0.sol +14 -0
- package/src/osp/OneStepProverMath.sol +2 -2
- package/src/precompiles/ArbOwner.sol +3 -0
- package/src/rollup/IRollupCore.sol +26 -2
- package/src/rollup/IRollupEventBridge.sol +17 -0
- package/src/rollup/IRollupLogic.sol +34 -2
- package/src/rollup/RollupCore.sol +2 -2
- package/src/rollup/RollupCreator.sol +5 -15
- package/src/rollup/RollupEventBridge.sol +2 -3
- package/src/rollup/RollupLib.sol +2 -2
- package/src/rollup/RollupUserLogic.sol +7 -3
- package/src/rollup/ValidatorUtils.sol +0 -1
- package/src/rollup/ValidatorWallet.sol +0 -1
- package/src/state/Instructions.sol +2 -0
- package/.prettierrc +0 -5
- package/.solhint.json +0 -18
- package/deploy/BridgeStubCreator.js +0 -10
- package/deploy/HashProofHelper.js +0 -13
- package/deploy/InboxStubCreator.js +0 -17
- package/deploy/OneStepProofEntryCreator.js +0 -19
- package/deploy/OneStepProver0Creator.js +0 -14
- package/deploy/OneStepProverHostIoCreator.js +0 -14
- package/deploy/OneStepProverMathCreator.js +0 -14
- package/deploy/OneStepProverMemoryCreator.js +0 -14
- package/deploy/SequencerInboxStubCreator.js +0 -13
- package/deploy/ValueArrayTesterCreator.js +0 -13
- package/hardhat.config.ts +0 -47
- package/src/mocks/Counter.sol +0 -13
- package/test/contract/arbRollup.spec.ts +0 -869
- package/test/contract/common/challengeLib.ts +0 -43
- package/test/contract/common/globalStateLib.ts +0 -17
- package/test/contract/common/rolluplib.ts +0 -259
- package/test/contract/cryptographyPrimitives.spec.ts +0 -82
- package/test/contract/sequencerInboxForceInclude.spec.ts +0 -516
- package/test/contract/utils.ts +0 -40
- package/test/prover/hash-proofs.ts +0 -75
- package/test/prover/one-step-proof.ts +0 -93
- package/test/prover/proofs/.gitkeep +0 -0
- package/test/prover/value-arrays.ts +0 -11
- 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.
|
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": "
|
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.
|
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": "^
|
32
|
-
"@typechain/hardhat": "^
|
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.
|
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": "^
|
50
|
+
"typechain": "^8.0.0",
|
47
51
|
"typescript": "^4.5.4"
|
48
52
|
}
|
49
53
|
}
|
package/src/bridge/IInbox.sol
CHANGED
@@ -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);
|
package/src/bridge/Inbox.sol
CHANGED
@@ -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 =
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
141
|
-
|
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
|
|
package/src/mocks/InboxStub.sol
CHANGED
@@ -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
|
33
|
+
function reduceDeposit(uint256 target) external;
|
22
34
|
|
23
|
-
function
|
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 "./
|
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
|
-
|
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
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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 "./
|
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;
|
package/src/rollup/RollupLib.sol
CHANGED
@@ -11,7 +11,7 @@ import "../bridge/ISequencerInbox.sol";
|
|
11
11
|
|
12
12
|
import "../bridge/IBridge.sol";
|
13
13
|
import "../bridge/IOutbox.sol";
|
14
|
-
import "./
|
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
|
-
|
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)
|
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
|
|