@arbitrum/nitro-contracts 1.0.0 → 1.0.2-beta.0
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 +1 -1
- package/package.json +18 -12
- package/src/bridge/Inbox.sol +79 -1
- package/src/challenge/ChallengeManager.sol +1 -1
- package/src/libraries/Constants.sol +3 -0
- package/src/mocks/InboxStub.sol +2 -2
- package/src/mocks/ProxyAdminForBinding.sol +9 -0
- package/src/mocks/Simple.sol +14 -0
- package/src/mocks/TimedOutChallengeManager.sol +13 -0
- package/src/precompiles/ArbDebug.sol +7 -2
- package/src/precompiles/ArbSys.sol +2 -0
- package/hardhat.prod-config.js +0 -18
- package/scripts/build.bash +0 -5
- /package/src/mocks/{ExecutionManager.sol → SingleExecutionChallenge.sol} +0 -0
package/README.md
CHANGED
@@ -5,8 +5,8 @@ It includes the rollup and fraud proof smart contracts, as well as interfaces fo
|
|
5
5
|
|
6
6
|
For more information see https://developer.arbitrum.io/docs/public_nitro_devnet
|
7
7
|
|
8
|
-
|
9
8
|
Compile the contracts locally by running
|
9
|
+
|
10
10
|
```bash
|
11
11
|
git clone https://github.com/offchainlabs/nitro
|
12
12
|
cd nitro/contracts
|
package/package.json
CHANGED
@@ -1,27 +1,25 @@
|
|
1
1
|
{
|
2
2
|
"name": "@arbitrum/nitro-contracts",
|
3
|
-
"version": "1.0.0",
|
3
|
+
"version": "1.0.2-beta.0",
|
4
4
|
"description": "Layer 2 precompiles and rollup for Arbitrum Nitro",
|
5
5
|
"author": "Offchain Labs, Inc.",
|
6
6
|
"license": "BUSL-1.1",
|
7
7
|
"repository": {
|
8
8
|
"type": "git",
|
9
|
-
"url": "git+https://github.com/offchainlabs/nitro.git"
|
10
|
-
"directory": "contracts"
|
9
|
+
"url": "git+https://github.com/offchainlabs/nitro-contracts.git"
|
11
10
|
},
|
12
11
|
"files": [
|
13
|
-
"src/"
|
14
|
-
"scripts/build.bash",
|
15
|
-
"hardhat.prod-config.js"
|
12
|
+
"src/"
|
16
13
|
],
|
17
14
|
"bugs": {
|
18
|
-
"url": "https://github.com/offchainlabs/nitro/issues"
|
15
|
+
"url": "https://github.com/offchainlabs/nitro-contracts/issues"
|
19
16
|
},
|
20
17
|
"scripts": {
|
21
|
-
"build": "
|
18
|
+
"build": "hardhat compile",
|
19
|
+
"lint:test": "eslint ./test",
|
22
20
|
"solhint": "solhint -f table src/**/*.sol",
|
23
21
|
"prettier:solidity": "prettier --write src/**/*.sol",
|
24
|
-
"
|
22
|
+
"format": "prettier './**/*.{js,json,md,ts,yml,sol}' --write && yarn run lint:test --fix",
|
25
23
|
"build:0.6": "INTERFACE_TESTER_SOLC_VERSION=0.6.9 yarn run build",
|
26
24
|
"build:0.7": "INTERFACE_TESTER_SOLC_VERSION=0.7.0 yarn run build",
|
27
25
|
"test:compatibility": "yarn run build:0.6 && yarn run build:0.7",
|
@@ -31,7 +29,7 @@
|
|
31
29
|
"dependencies": {
|
32
30
|
"@openzeppelin/contracts": "4.5.0",
|
33
31
|
"@openzeppelin/contracts-upgradeable": "4.5.2",
|
34
|
-
"
|
32
|
+
"patch-package": "^6.4.7"
|
35
33
|
},
|
36
34
|
"private": false,
|
37
35
|
"devDependencies": {
|
@@ -43,12 +41,19 @@
|
|
43
41
|
"@types/chai": "^4.3.0",
|
44
42
|
"@types/mocha": "^9.0.0",
|
45
43
|
"@types/node": "^17.0.5",
|
44
|
+
"@typescript-eslint/eslint-plugin": "^5.14.0",
|
45
|
+
"@typescript-eslint/eslint-plugin-tslint": "^5.27.1",
|
46
|
+
"@typescript-eslint/parser": "^5.14.0",
|
46
47
|
"chai": "^4.3.4",
|
48
|
+
"eslint": "^8.23.1",
|
49
|
+
"eslint-config-prettier": "^8.3.0",
|
50
|
+
"eslint-plugin-mocha": "^9.0.0",
|
51
|
+
"eslint-plugin-prettier": "^4.0.0",
|
47
52
|
"ethereum-waffle": "^3.4.0",
|
48
53
|
"ethers": "^5.5.2",
|
54
|
+
"hardhat": "^2.6.6",
|
49
55
|
"hardhat-deploy": "^0.11.4",
|
50
56
|
"hardhat-gas-reporter": "^1.0.8",
|
51
|
-
"patch-package": "^6.4.7",
|
52
57
|
"postinstall-postinstall": "^2.1.0",
|
53
58
|
"prettier": "^2.5.1",
|
54
59
|
"prettier-plugin-solidity": "^1.0.0-beta.19",
|
@@ -56,10 +61,11 @@
|
|
56
61
|
"solhint-plugin-prettier": "^0.0.5",
|
57
62
|
"solidity-coverage": "^0.7.20",
|
58
63
|
"ts-node": "^10.4.0",
|
64
|
+
"tslint": "^6.1.3",
|
59
65
|
"typechain": "^8.0.0",
|
60
66
|
"typescript": "^4.5.4"
|
61
67
|
},
|
62
|
-
"optionalDependencies":{
|
68
|
+
"optionalDependencies": {
|
63
69
|
"sol2uml": "2.2.0"
|
64
70
|
}
|
65
71
|
}
|
package/src/bridge/Inbox.sol
CHANGED
@@ -35,7 +35,7 @@ import {
|
|
35
35
|
L2MessageType_unsignedEOATx,
|
36
36
|
L2MessageType_unsignedContractTx
|
37
37
|
} from "../libraries/MessageTypes.sol";
|
38
|
-
import {MAX_DATA_SIZE} from "../libraries/Constants.sol";
|
38
|
+
import {MAX_DATA_SIZE, UNISWAP_L1_TIMELOCK, UNISWAP_L2_FACTORY} from "../libraries/Constants.sol";
|
39
39
|
import "../precompiles/ArbSys.sol";
|
40
40
|
|
41
41
|
import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
|
@@ -527,6 +527,84 @@ contract Inbox is DelegateCallAware, PausableUpgradeable, IInbox {
|
|
527
527
|
);
|
528
528
|
}
|
529
529
|
|
530
|
+
/// @notice This is an one-time-exception to resolve a misconfiguration of Uniswap Arbitrum deployment
|
531
|
+
/// Only the Uniswap L1 Timelock may call this function and it is allowed to create a crosschain
|
532
|
+
/// retryable ticket without address aliasing. More info here:
|
533
|
+
/// https://gov.uniswap.org/t/consensus-check-fix-the-cross-chain-messaging-bridge-on-arbitrum/18547
|
534
|
+
/// @dev This function will be removed in future releases
|
535
|
+
function uniswapCreateRetryableTicket(
|
536
|
+
address to,
|
537
|
+
uint256 l2CallValue,
|
538
|
+
uint256 maxSubmissionCost,
|
539
|
+
address excessFeeRefundAddress,
|
540
|
+
address callValueRefundAddress,
|
541
|
+
uint256 gasLimit,
|
542
|
+
uint256 maxFeePerGas,
|
543
|
+
bytes calldata data
|
544
|
+
) external payable whenNotPaused onlyAllowed returns (uint256) {
|
545
|
+
// this can only be called by UNISWAP_L1_TIMELOCK
|
546
|
+
require(msg.sender == UNISWAP_L1_TIMELOCK, "NOT_UNISWAP_L1_TIMELOCK");
|
547
|
+
// the retryable can only call UNISWAP_L2_FACTORY
|
548
|
+
require(to == UNISWAP_L2_FACTORY, "NOT_TO_UNISWAP_L2_FACTORY");
|
549
|
+
|
550
|
+
// ensure the user's deposit alone will make submission succeed
|
551
|
+
if (msg.value < (maxSubmissionCost + l2CallValue + gasLimit * maxFeePerGas)) {
|
552
|
+
revert InsufficientValue(
|
553
|
+
maxSubmissionCost + l2CallValue + gasLimit * maxFeePerGas,
|
554
|
+
msg.value
|
555
|
+
);
|
556
|
+
}
|
557
|
+
|
558
|
+
// if a refund address is a contract, we apply the alias to it
|
559
|
+
// so that it can access its funds on the L2
|
560
|
+
// since the beneficiary and other refund addresses don't get rewritten by arb-os
|
561
|
+
if (AddressUpgradeable.isContract(excessFeeRefundAddress)) {
|
562
|
+
excessFeeRefundAddress = AddressAliasHelper.applyL1ToL2Alias(excessFeeRefundAddress);
|
563
|
+
}
|
564
|
+
if (AddressUpgradeable.isContract(callValueRefundAddress)) {
|
565
|
+
// this is the beneficiary. be careful since this is the address that can cancel the retryable in the L2
|
566
|
+
callValueRefundAddress = AddressAliasHelper.applyL1ToL2Alias(callValueRefundAddress);
|
567
|
+
}
|
568
|
+
|
569
|
+
// gas price and limit of 1 should never be a valid input, so instead they are used as
|
570
|
+
// magic values to trigger a revert in eth calls that surface data without requiring a tx trace
|
571
|
+
if (gasLimit == 1 || maxFeePerGas == 1)
|
572
|
+
revert RetryableData(
|
573
|
+
msg.sender,
|
574
|
+
to,
|
575
|
+
l2CallValue,
|
576
|
+
msg.value,
|
577
|
+
maxSubmissionCost,
|
578
|
+
excessFeeRefundAddress,
|
579
|
+
callValueRefundAddress,
|
580
|
+
gasLimit,
|
581
|
+
maxFeePerGas,
|
582
|
+
data
|
583
|
+
);
|
584
|
+
|
585
|
+
uint256 submissionFee = calculateRetryableSubmissionFee(data.length, block.basefee);
|
586
|
+
if (maxSubmissionCost < submissionFee)
|
587
|
+
revert InsufficientSubmissionCost(submissionFee, maxSubmissionCost);
|
588
|
+
|
589
|
+
return
|
590
|
+
_deliverMessage(
|
591
|
+
L1MessageType_submitRetryableTx,
|
592
|
+
AddressAliasHelper.undoL1ToL2Alias(msg.sender),
|
593
|
+
abi.encodePacked(
|
594
|
+
uint256(uint160(to)),
|
595
|
+
l2CallValue,
|
596
|
+
msg.value,
|
597
|
+
maxSubmissionCost,
|
598
|
+
uint256(uint160(excessFeeRefundAddress)),
|
599
|
+
uint256(uint160(callValueRefundAddress)),
|
600
|
+
gasLimit,
|
601
|
+
maxFeePerGas,
|
602
|
+
data.length,
|
603
|
+
data
|
604
|
+
)
|
605
|
+
);
|
606
|
+
}
|
607
|
+
|
530
608
|
function _deliverMessage(
|
531
609
|
uint8 _kind,
|
532
610
|
address _sender,
|
@@ -285,7 +285,7 @@ contract ChallengeManager is DelegateCallAware, IChallengeManager {
|
|
285
285
|
return challenges[challengeIndex].current.addr;
|
286
286
|
}
|
287
287
|
|
288
|
-
function isTimedOut(uint64 challengeIndex) public view override returns (bool) {
|
288
|
+
function isTimedOut(uint64 challengeIndex) public view virtual override returns (bool) {
|
289
289
|
return challenges[challengeIndex].isTimedOut();
|
290
290
|
}
|
291
291
|
|
@@ -11,3 +11,6 @@ uint64 constant NO_CHAL_INDEX = 0;
|
|
11
11
|
|
12
12
|
// Expected seconds per block in Ethereum PoS
|
13
13
|
uint256 constant ETH_POS_BLOCK_TIME = 12;
|
14
|
+
|
15
|
+
address constant UNISWAP_L1_TIMELOCK = 0x1a9C8182C09F50C8318d769245beA52c32BE35BC;
|
16
|
+
address constant UNISWAP_L2_FACTORY = 0x1F98431c8aD98523631AE4a59f267346ea31F984;
|
package/src/mocks/InboxStub.sol
CHANGED
@@ -151,7 +151,7 @@ contract InboxStub is IInbox {
|
|
151
151
|
address,
|
152
152
|
uint256,
|
153
153
|
bytes calldata
|
154
|
-
) external returns (uint256) {
|
154
|
+
) external pure returns (uint256) {
|
155
155
|
revert("NOT_IMPLEMENTED");
|
156
156
|
}
|
157
157
|
|
@@ -161,7 +161,7 @@ contract InboxStub is IInbox {
|
|
161
161
|
uint256,
|
162
162
|
uint256,
|
163
163
|
address
|
164
|
-
) external returns (uint256) {
|
164
|
+
) external pure returns (uint256) {
|
165
165
|
revert("NOT_IMPLEMENTED");
|
166
166
|
}
|
167
167
|
|
@@ -0,0 +1,9 @@
|
|
1
|
+
// Copyright 2021-2022, Offchain Labs, Inc.
|
2
|
+
// For license information, see https://github.com/nitro/blob/master/LICENSE
|
3
|
+
// SPDX-License-Identifier: BUSL-1.1
|
4
|
+
|
5
|
+
pragma solidity ^0.8.0;
|
6
|
+
|
7
|
+
import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
|
8
|
+
|
9
|
+
contract ProxyAdminForBinding is ProxyAdmin {}
|
package/src/mocks/Simple.sol
CHANGED
@@ -13,11 +13,17 @@ contract Simple {
|
|
13
13
|
event CounterEvent(uint64 count);
|
14
14
|
event RedeemedEvent(address caller, address redeemer);
|
15
15
|
event NullEvent();
|
16
|
+
event LogAndIncrementCalled(uint256 expected, uint256 have);
|
16
17
|
|
17
18
|
function increment() external {
|
18
19
|
counter++;
|
19
20
|
}
|
20
21
|
|
22
|
+
function logAndIncrement(uint256 expected) external {
|
23
|
+
emit LogAndIncrementCalled(expected, counter);
|
24
|
+
counter++;
|
25
|
+
}
|
26
|
+
|
21
27
|
function incrementEmit() external {
|
22
28
|
counter++;
|
23
29
|
emit CounterEvent(counter);
|
@@ -104,4 +110,12 @@ contract Simple {
|
|
104
110
|
(success, ) = address(this).call(data);
|
105
111
|
require(success, "CALL_FAILED");
|
106
112
|
}
|
113
|
+
|
114
|
+
function checkGasUsed(address to, bytes calldata input) external view returns (uint256) {
|
115
|
+
uint256 before = gasleft();
|
116
|
+
// The inner call may revert, but we still want to return the amount of gas used,
|
117
|
+
// so we ignore the result of this call.
|
118
|
+
(to.staticcall{gas: before - 10000}(input));
|
119
|
+
return before - gasleft();
|
120
|
+
}
|
107
121
|
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// Copyright 2021-2022, Offchain Labs, Inc.
|
2
|
+
// For license information, see https://github.com/nitro/blob/master/LICENSE
|
3
|
+
// SPDX-License-Identifier: BUSL-1.1
|
4
|
+
|
5
|
+
pragma solidity ^0.8.0;
|
6
|
+
|
7
|
+
import "../challenge/ChallengeManager.sol";
|
8
|
+
|
9
|
+
contract TimedOutChallengeManager is ChallengeManager {
|
10
|
+
function isTimedOut(uint64) public pure override returns (bool) {
|
11
|
+
return true;
|
12
|
+
}
|
13
|
+
}
|
@@ -1,5 +1,5 @@
|
|
1
|
-
// Copyright 2021-
|
2
|
-
// For license information, see https://github.com/nitro/blob/master/LICENSE
|
1
|
+
// Copyright 2021-2023, Offchain Labs, Inc.
|
2
|
+
// For license information, see https://github.com/OffchainLabs/nitro/blob/master/LICENSE
|
3
3
|
// SPDX-License-Identifier: BUSL-1.1
|
4
4
|
|
5
5
|
pragma solidity >=0.4.21 <0.9.0;
|
@@ -15,6 +15,9 @@ interface ArbDebug {
|
|
15
15
|
/// @notice Emit events with values based on the args provided
|
16
16
|
function events(bool flag, bytes32 value) external payable returns (address, uint256);
|
17
17
|
|
18
|
+
/// @notice Tries (and fails) to emit logs in a view context
|
19
|
+
function eventsView() external view;
|
20
|
+
|
18
21
|
// Events that exist for testing log creation and pricing
|
19
22
|
event Basic(bool flag, bytes32 indexed value);
|
20
23
|
event Mixed(
|
@@ -34,6 +37,8 @@ interface ArbDebug {
|
|
34
37
|
|
35
38
|
function customRevert(uint64 number) external pure;
|
36
39
|
|
40
|
+
function legacyError() external pure;
|
41
|
+
|
37
42
|
error Custom(uint64, string, bool);
|
38
43
|
error Unused();
|
39
44
|
}
|
package/hardhat.prod-config.js
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* @type import('hardhat/config').HardhatUserConfig
|
3
|
-
*/
|
4
|
-
module.exports = {
|
5
|
-
solidity: {
|
6
|
-
version: "0.8.9",
|
7
|
-
settings: {
|
8
|
-
optimizer: {
|
9
|
-
enabled: true,
|
10
|
-
runs: 100,
|
11
|
-
},
|
12
|
-
},
|
13
|
-
},
|
14
|
-
paths: {
|
15
|
-
sources: "./src",
|
16
|
-
artifacts: "build/contracts",
|
17
|
-
},
|
18
|
-
};
|
package/scripts/build.bash
DELETED
File without changes
|