@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.
- 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
|
|