@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
package/.prettierrc
ADDED
package/.solhint.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": ["solhint:recommended"],
|
|
3
|
+
"rules": {
|
|
4
|
+
"prettier/prettier": "error",
|
|
5
|
+
"avoid-throw": "off",
|
|
6
|
+
"avoid-suicide": "error",
|
|
7
|
+
"avoid-sha3": "warn",
|
|
8
|
+
"max-line-length": "off",
|
|
9
|
+
"compiler-version": "off",
|
|
10
|
+
"func-visibility": ["warn",{"ignoreConstructors":true}],
|
|
11
|
+
"no-empty-blocks": "off",
|
|
12
|
+
"reason-string": ["warn",{"maxLength":128}],
|
|
13
|
+
"not-rely-on-time": "off",
|
|
14
|
+
"max-states-count": ["warn",30],
|
|
15
|
+
"no-inline-assembly": "off"
|
|
16
|
+
},
|
|
17
|
+
"plugins": ["prettier"]
|
|
18
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module.exports = async (hre) => {
|
|
2
|
+
const { deployments, getNamedAccounts, ethers } = hre;
|
|
3
|
+
const { deploy } = deployments;
|
|
4
|
+
const { deployer } = await getNamedAccounts();
|
|
5
|
+
|
|
6
|
+
await deploy("BridgeStub", {from: deployer, args: []});
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
module.exports.tags = ["BridgeStub", "test"];
|
|
10
|
+
module.exports.dependencies = [];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module.exports = async (hre) => {
|
|
2
|
+
const { deployments, getNamedAccounts } = hre;
|
|
3
|
+
const { deploy } = deployments;
|
|
4
|
+
const { deployer } = await getNamedAccounts();
|
|
5
|
+
|
|
6
|
+
await deploy("HashProofHelper", {
|
|
7
|
+
from: deployer,
|
|
8
|
+
args: [],
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
module.exports.tags = ["HashProofHelper", "test", "live"];
|
|
13
|
+
module.exports.dependencies = [];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module.exports = async (hre) => {
|
|
2
|
+
const { deployments, getNamedAccounts, ethers } = hre;
|
|
3
|
+
const { deploy } = deployments;
|
|
4
|
+
const { deployer } = await getNamedAccounts();
|
|
5
|
+
|
|
6
|
+
await deploy("InboxStub", {from: deployer, args: []});
|
|
7
|
+
|
|
8
|
+
const bridge = await ethers.getContract("BridgeStub");
|
|
9
|
+
const inbox = await ethers.getContract("InboxStub");
|
|
10
|
+
|
|
11
|
+
await bridge.setInbox(inbox.address, true);
|
|
12
|
+
await inbox.initialize(bridge.address);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
module.exports.tags = ["InboxStub", "test"];
|
|
16
|
+
module.exports.dependencies = ["BridgeStub"];
|
|
17
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module.exports = async (hre) => {
|
|
2
|
+
const { deployments, getNamedAccounts } = hre;
|
|
3
|
+
const { deploy } = deployments;
|
|
4
|
+
const { deployer } = await getNamedAccounts();
|
|
5
|
+
|
|
6
|
+
await deploy("OneStepProofEntry", {
|
|
7
|
+
from: deployer,
|
|
8
|
+
args: [
|
|
9
|
+
(await deployments.get("OneStepProver0")).address,
|
|
10
|
+
(await deployments.get("OneStepProverMemory")).address,
|
|
11
|
+
(await deployments.get("OneStepProverMath")).address,
|
|
12
|
+
(await deployments.get("OneStepProverHostIo")).address,
|
|
13
|
+
],
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
module.exports.tags = ["OneStepProofEntry"];
|
|
18
|
+
module.exports.dependencies = ["OneStepProver0", "OneStepProverMemory", "OneStepProverMath", "OneStepProverHostIo"];
|
|
19
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module.exports = async (hre) => {
|
|
2
|
+
const { deployments, getNamedAccounts } = hre;
|
|
3
|
+
const { deploy } = deployments;
|
|
4
|
+
const { deployer } = await getNamedAccounts();
|
|
5
|
+
|
|
6
|
+
await deploy("OneStepProver0", {
|
|
7
|
+
from: deployer,
|
|
8
|
+
args: [],
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
module.exports.tags = ["OneStepProver0", "live", "test"];
|
|
13
|
+
module.exports.dependencies = [];
|
|
14
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module.exports = async (hre) => {
|
|
2
|
+
const { deployments, getNamedAccounts, ethers } = hre;
|
|
3
|
+
const { deploy } = deployments;
|
|
4
|
+
const { deployer } = await getNamedAccounts();
|
|
5
|
+
|
|
6
|
+
await deploy("OneStepProverHostIo", {
|
|
7
|
+
from: deployer,
|
|
8
|
+
args: [],
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
module.exports.tags = ["OneStepProverHostIo"];
|
|
13
|
+
module.exports.dependencies = [];
|
|
14
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module.exports = async (hre) => {
|
|
2
|
+
const { deployments, getNamedAccounts } = hre;
|
|
3
|
+
const { deploy } = deployments;
|
|
4
|
+
const { deployer } = await getNamedAccounts();
|
|
5
|
+
|
|
6
|
+
await deploy("OneStepProverMath", {
|
|
7
|
+
from: deployer,
|
|
8
|
+
args: [],
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
module.exports.tags = ["OneStepProverMath", "live", "test"];
|
|
13
|
+
module.exports.dependencies = [];
|
|
14
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module.exports = async (hre) => {
|
|
2
|
+
const { deployments, getNamedAccounts } = hre;
|
|
3
|
+
const { deploy } = deployments;
|
|
4
|
+
const { deployer } = await getNamedAccounts();
|
|
5
|
+
|
|
6
|
+
await deploy("OneStepProverMemory", {
|
|
7
|
+
from: deployer,
|
|
8
|
+
args: [],
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
module.exports.tags = ["OneStepProverMemory", "live", "test"];
|
|
13
|
+
module.exports.dependencies = [];
|
|
14
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module.exports = async (hre) => {
|
|
2
|
+
const { deployments, getNamedAccounts, ethers } = hre;
|
|
3
|
+
const { deploy } = deployments;
|
|
4
|
+
const { deployer } = await getNamedAccounts();
|
|
5
|
+
|
|
6
|
+
const bridge = await ethers.getContract("BridgeStub");
|
|
7
|
+
const maxTime = {delayBlocks: 10000, futureBlocks: 10000, delaySeconds: 10000, futureSeconds: 10000}
|
|
8
|
+
await deploy("SequencerInboxStub", {from: deployer, args: [bridge.address, deployer, maxTime]})
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
module.exports.tags = ["SequencerInboxStub", "test"];
|
|
12
|
+
module.exports.dependencies = ["BridgeStub"];
|
|
13
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module.exports = async (hre) => {
|
|
2
|
+
const { deployments, getNamedAccounts } = hre;
|
|
3
|
+
const { deploy } = deployments;
|
|
4
|
+
const { deployer } = await getNamedAccounts();
|
|
5
|
+
|
|
6
|
+
await deploy("ValueArrayTester", {
|
|
7
|
+
from: deployer,
|
|
8
|
+
args: [],
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
module.exports.tags = ["ValueArrayTester", "test"];
|
|
13
|
+
module.exports.dependencies = [];
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import '@nomiclabs/hardhat-waffle'
|
|
2
|
+
import 'hardhat-deploy'
|
|
3
|
+
import '@nomiclabs/hardhat-ethers'
|
|
4
|
+
import '@typechain/hardhat'
|
|
5
|
+
import 'solidity-coverage'
|
|
6
|
+
import prodConfig from "./hardhat.prod-config"
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @type import('hardhat/config').HardhatUserConfig
|
|
10
|
+
*/
|
|
11
|
+
module.exports = {
|
|
12
|
+
...prodConfig,
|
|
13
|
+
namedAccounts: {
|
|
14
|
+
deployer: {
|
|
15
|
+
default: 0,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
networks: {
|
|
19
|
+
hardhat: {
|
|
20
|
+
chainId: 1338,
|
|
21
|
+
throwOnTransactionFailures: true,
|
|
22
|
+
allowUnlimitedContractSize: true,
|
|
23
|
+
accounts: {
|
|
24
|
+
accountsBalance: '1000000000000000000000000000',
|
|
25
|
+
},
|
|
26
|
+
blockGasLimit: 200000000,
|
|
27
|
+
// mining: {
|
|
28
|
+
// auto: false,
|
|
29
|
+
// interval: 1000,
|
|
30
|
+
// },
|
|
31
|
+
forking: {
|
|
32
|
+
url: 'https://mainnet.infura.io/v3/' + process.env['INFURA_KEY'],
|
|
33
|
+
enabled: process.env['SHOULD_FORK'] === '1',
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
geth: {
|
|
37
|
+
url: 'http://localhost:8545',
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
mocha: {
|
|
41
|
+
timeout: 0,
|
|
42
|
+
},
|
|
43
|
+
typechain: {
|
|
44
|
+
outDir: 'build/types',
|
|
45
|
+
target: 'ethers-v5',
|
|
46
|
+
},
|
|
47
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
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/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@arbitrum/nitro-contracts",
|
|
3
|
+
"version": "1.0.0-beta.1",
|
|
4
|
+
"description": "Layer 2 precompiles and rollup for Arbitrum Nitro",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"author": "Offchain Labs, Inc.",
|
|
7
|
+
"license": "UNLICENSED",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/offchainlabs/nitro.git",
|
|
11
|
+
"directory": "contracts"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/offchainlabs/nitro/issues"
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "./scripts/build.bash",
|
|
18
|
+
"solhint": "solhint -f table src/**/*.sol",
|
|
19
|
+
"prettier:solidity": "prettier --write src/**/*.sol",
|
|
20
|
+
"hardhat:prod": "hardhat --config hardhat.prod-config.js"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@openzeppelin/contracts": "4.5.0",
|
|
24
|
+
"@openzeppelin/contracts-upgradeable": "4.5.1",
|
|
25
|
+
"hardhat": "^2.6.6"
|
|
26
|
+
},
|
|
27
|
+
"private": false,
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers@^0.3.0-beta.13",
|
|
30
|
+
"@nomiclabs/hardhat-waffle": "^2.0.1",
|
|
31
|
+
"@typechain/ethers-v5": "^9.0.0",
|
|
32
|
+
"@typechain/hardhat": "^4.0.0",
|
|
33
|
+
"@types/chai": "^4.3.0",
|
|
34
|
+
"@types/mocha": "^9.0.0",
|
|
35
|
+
"@types/node": "^17.0.5",
|
|
36
|
+
"chai": "^4.3.4",
|
|
37
|
+
"ethereum-waffle": "^3.4.0",
|
|
38
|
+
"ethers": "^5.5.2",
|
|
39
|
+
"hardhat-deploy": "^0.10.5",
|
|
40
|
+
"prettier": "^2.5.1",
|
|
41
|
+
"prettier-plugin-solidity": "^1.0.0-beta.19",
|
|
42
|
+
"solhint": "^3.3.7",
|
|
43
|
+
"solhint-plugin-prettier": "^0.0.5",
|
|
44
|
+
"solidity-coverage": "^0.7.20",
|
|
45
|
+
"ts-node": "^10.4.0",
|
|
46
|
+
"typechain": "^7.0.0",
|
|
47
|
+
"typescript": "^4.5.4"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
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.4;
|
|
6
|
+
|
|
7
|
+
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
|
|
8
|
+
import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
|
|
9
|
+
|
|
10
|
+
import "./IBridge.sol";
|
|
11
|
+
import "./Messages.sol";
|
|
12
|
+
import "../libraries/DelegateCallAware.sol";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @title Staging ground for incoming and outgoing messages
|
|
16
|
+
* @notice Holds the inbox accumulator for delayed messages, and is the ETH escrow
|
|
17
|
+
* for value sent with these messages.
|
|
18
|
+
* Since the escrow is held here, this contract also contains a list of allowed
|
|
19
|
+
* outboxes that can make calls from here and withdraw this escrow.
|
|
20
|
+
*/
|
|
21
|
+
contract Bridge is OwnableUpgradeable, DelegateCallAware, IBridge {
|
|
22
|
+
using AddressUpgradeable for address;
|
|
23
|
+
|
|
24
|
+
struct InOutInfo {
|
|
25
|
+
uint256 index;
|
|
26
|
+
bool allowed;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
mapping(address => InOutInfo) private allowedInboxesMap;
|
|
30
|
+
mapping(address => InOutInfo) private allowedOutboxesMap;
|
|
31
|
+
|
|
32
|
+
address[] public allowedInboxList;
|
|
33
|
+
address[] public allowedOutboxList;
|
|
34
|
+
|
|
35
|
+
address public override activeOutbox;
|
|
36
|
+
|
|
37
|
+
/// @dev Accumulator for delayed inbox messages; tail represents hash of the current state; each element represents the inclusion of a new message.
|
|
38
|
+
bytes32[] public override inboxAccs;
|
|
39
|
+
|
|
40
|
+
function initialize() external initializer onlyDelegated {
|
|
41
|
+
__Ownable_init();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function allowedInboxes(address inbox) external view override returns (bool) {
|
|
45
|
+
return allowedInboxesMap[inbox].allowed;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function allowedOutboxes(address outbox) external view override returns (bool) {
|
|
49
|
+
return allowedOutboxesMap[outbox].allowed;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @dev Enqueue a message in the delayed inbox accumulator.
|
|
54
|
+
* These messages are later sequenced in the SequencerInbox, either by the sequencer as
|
|
55
|
+
* part of a normal batch, or by force inclusion.
|
|
56
|
+
*/
|
|
57
|
+
function enqueueDelayedMessage(
|
|
58
|
+
uint8 kind,
|
|
59
|
+
address sender,
|
|
60
|
+
bytes32 messageDataHash
|
|
61
|
+
) external payable override returns (uint256) {
|
|
62
|
+
if (!allowedInboxesMap[msg.sender].allowed) revert NotInbox(msg.sender);
|
|
63
|
+
return
|
|
64
|
+
addMessageToAccumulator(
|
|
65
|
+
kind,
|
|
66
|
+
sender,
|
|
67
|
+
uint64(block.number),
|
|
68
|
+
uint64(block.timestamp), // solhint-disable-line not-rely-on-time
|
|
69
|
+
block.basefee,
|
|
70
|
+
messageDataHash
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function addMessageToAccumulator(
|
|
75
|
+
uint8 kind,
|
|
76
|
+
address sender,
|
|
77
|
+
uint64 blockNumber,
|
|
78
|
+
uint64 blockTimestamp,
|
|
79
|
+
uint256 baseFeeL1,
|
|
80
|
+
bytes32 messageDataHash
|
|
81
|
+
) internal returns (uint256) {
|
|
82
|
+
uint256 count = inboxAccs.length;
|
|
83
|
+
bytes32 messageHash = Messages.messageHash(
|
|
84
|
+
kind,
|
|
85
|
+
sender,
|
|
86
|
+
blockNumber,
|
|
87
|
+
blockTimestamp,
|
|
88
|
+
count,
|
|
89
|
+
baseFeeL1,
|
|
90
|
+
messageDataHash
|
|
91
|
+
);
|
|
92
|
+
bytes32 prevAcc = 0;
|
|
93
|
+
if (count > 0) {
|
|
94
|
+
prevAcc = inboxAccs[count - 1];
|
|
95
|
+
}
|
|
96
|
+
inboxAccs.push(Messages.accumulateInboxMessage(prevAcc, messageHash));
|
|
97
|
+
emit MessageDelivered(
|
|
98
|
+
count,
|
|
99
|
+
prevAcc,
|
|
100
|
+
msg.sender,
|
|
101
|
+
kind,
|
|
102
|
+
sender,
|
|
103
|
+
messageDataHash,
|
|
104
|
+
baseFeeL1,
|
|
105
|
+
blockTimestamp
|
|
106
|
+
);
|
|
107
|
+
return count;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function executeCall(
|
|
111
|
+
address to,
|
|
112
|
+
uint256 value,
|
|
113
|
+
bytes calldata data
|
|
114
|
+
) external override returns (bool success, bytes memory returnData) {
|
|
115
|
+
if (!allowedOutboxesMap[msg.sender].allowed) revert NotOutbox(msg.sender);
|
|
116
|
+
if (data.length > 0 && !to.isContract()) revert NotContract(to);
|
|
117
|
+
address prevOutbox = activeOutbox;
|
|
118
|
+
activeOutbox = msg.sender;
|
|
119
|
+
// We set and reset active outbox around external call so activeOutbox remains valid during call
|
|
120
|
+
|
|
121
|
+
// We use a low level call here since we want to bubble up whether it succeeded or failed to the caller
|
|
122
|
+
// rather than reverting on failure as well as allow contract and non-contract calls
|
|
123
|
+
// solhint-disable-next-line avoid-low-level-calls
|
|
124
|
+
(success, returnData) = to.call{value: value}(data);
|
|
125
|
+
activeOutbox = prevOutbox;
|
|
126
|
+
emit BridgeCallTriggered(msg.sender, to, value, data);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function setInbox(address inbox, bool enabled) external override onlyOwner {
|
|
130
|
+
InOutInfo storage info = allowedInboxesMap[inbox];
|
|
131
|
+
bool alreadyEnabled = info.allowed;
|
|
132
|
+
emit InboxToggle(inbox, enabled);
|
|
133
|
+
if ((alreadyEnabled && enabled) || (!alreadyEnabled && !enabled)) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (enabled) {
|
|
137
|
+
allowedInboxesMap[inbox] = InOutInfo(allowedInboxList.length, true);
|
|
138
|
+
allowedInboxList.push(inbox);
|
|
139
|
+
} else {
|
|
140
|
+
allowedInboxList[info.index] = allowedInboxList[allowedInboxList.length - 1];
|
|
141
|
+
allowedInboxesMap[allowedInboxList[info.index]].index = info.index;
|
|
142
|
+
allowedInboxList.pop();
|
|
143
|
+
delete allowedInboxesMap[inbox];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function setOutbox(address outbox, bool enabled) external override onlyOwner {
|
|
148
|
+
InOutInfo storage info = allowedOutboxesMap[outbox];
|
|
149
|
+
bool alreadyEnabled = info.allowed;
|
|
150
|
+
emit OutboxToggle(outbox, enabled);
|
|
151
|
+
if ((alreadyEnabled && enabled) || (!alreadyEnabled && !enabled)) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (enabled) {
|
|
155
|
+
allowedOutboxesMap[outbox] = InOutInfo(allowedOutboxList.length, true);
|
|
156
|
+
allowedOutboxList.push(outbox);
|
|
157
|
+
} else {
|
|
158
|
+
allowedOutboxList[info.index] = allowedOutboxList[allowedOutboxList.length - 1];
|
|
159
|
+
allowedOutboxesMap[allowedOutboxList[info.index]].index = info.index;
|
|
160
|
+
allowedOutboxList.pop();
|
|
161
|
+
delete allowedOutboxesMap[outbox];
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function messageCount() external view override returns (uint256) {
|
|
166
|
+
return inboxAccs.length;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
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.4;
|
|
6
|
+
|
|
7
|
+
import {NotContract} from "../libraries/Error.sol";
|
|
8
|
+
|
|
9
|
+
/// @dev Thrown when an un-authorized address tries to access an only-inbox function
|
|
10
|
+
/// @param sender The un-authorized sender
|
|
11
|
+
error NotInbox(address sender);
|
|
12
|
+
|
|
13
|
+
/// @dev Thrown when an un-authorized address tries to access an only-outbox function
|
|
14
|
+
/// @param sender The un-authorized sender
|
|
15
|
+
error NotOutbox(address sender);
|
|
16
|
+
|
|
17
|
+
interface IBridge {
|
|
18
|
+
event MessageDelivered(
|
|
19
|
+
uint256 indexed messageIndex,
|
|
20
|
+
bytes32 indexed beforeInboxAcc,
|
|
21
|
+
address inbox,
|
|
22
|
+
uint8 kind,
|
|
23
|
+
address sender,
|
|
24
|
+
bytes32 messageDataHash,
|
|
25
|
+
uint256 baseFeeL1,
|
|
26
|
+
uint64 timestamp
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
event BridgeCallTriggered(
|
|
30
|
+
address indexed outbox,
|
|
31
|
+
address indexed to,
|
|
32
|
+
uint256 value,
|
|
33
|
+
bytes data
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
event InboxToggle(address indexed inbox, bool enabled);
|
|
37
|
+
|
|
38
|
+
event OutboxToggle(address indexed outbox, bool enabled);
|
|
39
|
+
|
|
40
|
+
function enqueueDelayedMessage(
|
|
41
|
+
uint8 kind,
|
|
42
|
+
address sender,
|
|
43
|
+
bytes32 messageDataHash
|
|
44
|
+
) external payable returns (uint256);
|
|
45
|
+
|
|
46
|
+
function executeCall(
|
|
47
|
+
address to,
|
|
48
|
+
uint256 value,
|
|
49
|
+
bytes calldata data
|
|
50
|
+
) external returns (bool success, bytes memory returnData);
|
|
51
|
+
|
|
52
|
+
// These are only callable by the admin
|
|
53
|
+
function setInbox(address inbox, bool enabled) external;
|
|
54
|
+
|
|
55
|
+
function setOutbox(address inbox, bool enabled) external;
|
|
56
|
+
|
|
57
|
+
// View functions
|
|
58
|
+
|
|
59
|
+
function activeOutbox() external view returns (address);
|
|
60
|
+
|
|
61
|
+
function allowedInboxes(address inbox) external view returns (bool);
|
|
62
|
+
|
|
63
|
+
function allowedOutboxes(address outbox) external view returns (bool);
|
|
64
|
+
|
|
65
|
+
function inboxAccs(uint256 index) external view returns (bytes32);
|
|
66
|
+
|
|
67
|
+
function messageCount() external view returns (uint256);
|
|
68
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
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.4;
|
|
6
|
+
|
|
7
|
+
import "./IBridge.sol";
|
|
8
|
+
import "./IMessageProvider.sol";
|
|
9
|
+
import {AlreadyInit, NotOrigin, DataTooLarge} from "../libraries/Error.sol";
|
|
10
|
+
|
|
11
|
+
/// @dev The contract is paused, so cannot be paused
|
|
12
|
+
error AlreadyPaused();
|
|
13
|
+
|
|
14
|
+
/// @dev The contract is unpaused, so cannot be unpaused
|
|
15
|
+
error AlreadyUnpaused();
|
|
16
|
+
|
|
17
|
+
/// @dev The contract is paused
|
|
18
|
+
error Paused();
|
|
19
|
+
|
|
20
|
+
interface IInbox is IMessageProvider {
|
|
21
|
+
function sendL2Message(bytes calldata messageData) external returns (uint256);
|
|
22
|
+
|
|
23
|
+
function sendUnsignedTransaction(
|
|
24
|
+
uint256 gasLimit,
|
|
25
|
+
uint256 maxFeePerGas,
|
|
26
|
+
uint256 nonce,
|
|
27
|
+
address to,
|
|
28
|
+
uint256 value,
|
|
29
|
+
bytes calldata data
|
|
30
|
+
) external returns (uint256);
|
|
31
|
+
|
|
32
|
+
function sendContractTransaction(
|
|
33
|
+
uint256 gasLimit,
|
|
34
|
+
uint256 maxFeePerGas,
|
|
35
|
+
address to,
|
|
36
|
+
uint256 value,
|
|
37
|
+
bytes calldata data
|
|
38
|
+
) external returns (uint256);
|
|
39
|
+
|
|
40
|
+
function sendL1FundedUnsignedTransaction(
|
|
41
|
+
uint256 gasLimit,
|
|
42
|
+
uint256 maxFeePerGas,
|
|
43
|
+
uint256 nonce,
|
|
44
|
+
address to,
|
|
45
|
+
bytes calldata data
|
|
46
|
+
) external payable returns (uint256);
|
|
47
|
+
|
|
48
|
+
function sendL1FundedContractTransaction(
|
|
49
|
+
uint256 gasLimit,
|
|
50
|
+
uint256 maxFeePerGas,
|
|
51
|
+
address to,
|
|
52
|
+
bytes calldata data
|
|
53
|
+
) external payable returns (uint256);
|
|
54
|
+
|
|
55
|
+
function createRetryableTicket(
|
|
56
|
+
address to,
|
|
57
|
+
uint256 arbTxCallValue,
|
|
58
|
+
uint256 maxSubmissionCost,
|
|
59
|
+
address submissionRefundAddress,
|
|
60
|
+
address valueRefundAddress,
|
|
61
|
+
uint256 gasLimit,
|
|
62
|
+
uint256 maxFeePerGas,
|
|
63
|
+
bytes calldata data
|
|
64
|
+
) external payable returns (uint256);
|
|
65
|
+
|
|
66
|
+
function unsafeCreateRetryableTicket(
|
|
67
|
+
address to,
|
|
68
|
+
uint256 arbTxCallValue,
|
|
69
|
+
uint256 maxSubmissionCost,
|
|
70
|
+
address submissionRefundAddress,
|
|
71
|
+
address valueRefundAddress,
|
|
72
|
+
uint256 gasLimit,
|
|
73
|
+
uint256 maxFeePerGas,
|
|
74
|
+
bytes calldata data
|
|
75
|
+
) external payable returns (uint256);
|
|
76
|
+
|
|
77
|
+
function depositEth(uint256 maxSubmissionCost) external payable returns (uint256);
|
|
78
|
+
|
|
79
|
+
function bridge() external view returns (IBridge);
|
|
80
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
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
|
+
interface IMessageProvider {
|
|
8
|
+
event InboxMessageDelivered(uint256 indexed messageNum, bytes data);
|
|
9
|
+
|
|
10
|
+
event InboxMessageDeliveredFromOrigin(uint256 indexed messageNum);
|
|
11
|
+
}
|