Skip to content

Commit 6c715b1

Browse files
authored
feat: add e2e devnet deployment scripts (#97)
1 parent bb96529 commit 6c715b1

16 files changed

+2755
-2
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,9 @@ broadcast
1919

2020
# Visual Studio Code
2121
.vscode
22+
23+
# OS
24+
.DS_Store
25+
26+
# config
27+
scripts/deterministic/config/config-contracts.toml

foundry.toml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ optimizer = true # enable or disabl
1414
optimizer_runs = 200 # the number of optimizer runs
1515
verbosity = 2 # the verbosity of tests
1616
ignored_error_codes = [] # a list of ignored solc error codes
17-
fuzz_runs = 256 # the number of fuzz runs for tests
18-
ffi = false # whether to enable ffi or not
17+
fuzz_runs = 256 # the number of fuzz runs for test
1918
sender = '0x00a329c0648769a73afac7f9381e08fb43dbea72' # the address of `msg.sender` in tests
2019
tx_origin = '0x00a329c0648769a73afac7f9381e08fb43dbea72' # the address of `tx.origin` in tests
2120
initial_balance = '0xffffffffffffffffffffffff' # the initial balance of the test contract
@@ -28,3 +27,14 @@ block_timestamp = 0 # the value of `bl
2827
block_difficulty = 0 # the value of `block.difficulty` in tests
2928

3029
gas_reports = ["L2GasPriceOracle"]
30+
31+
# remove bytecode hash for reliable deterministic addresses
32+
bytecode_hash = 'none'
33+
34+
# file system permissions
35+
ffi = true
36+
37+
fs_permissions = [
38+
{ access='read-write', path='./scripts/deterministic/config' },
39+
{ access='read-write', path='../../config' },
40+
]
Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
// SPDX-License-Identifier: UNLICENSED
2+
pragma solidity =0.8.24;
3+
4+
import {Script} from "forge-std/Script.sol";
5+
import {VmSafe} from "forge-std/Vm.sol";
6+
import {stdToml} from "forge-std/StdToml.sol";
7+
8+
import {CONFIG_PATH, CONFIG_CONTRACTS_PATH, CONFIG_CONTRACTS_TEMPLATE_PATH} from "./Constants.sol";
9+
10+
/// @notice Configuration allows inheriting contracts to read the TOML configuration file.
11+
abstract contract Configuration is Script {
12+
using stdToml for string;
13+
14+
/*******************
15+
* State variables *
16+
*******************/
17+
18+
string internal cfg;
19+
string internal contractsCfg;
20+
21+
/****************************
22+
* Configuration parameters *
23+
****************************/
24+
25+
// general
26+
string internal L1_RPC_ENDPOINT;
27+
string internal L2_RPC_ENDPOINT;
28+
29+
string internal CHAIN_NAME_L1;
30+
string internal CHAIN_NAME_L2;
31+
uint64 internal CHAIN_ID_L1;
32+
uint64 internal CHAIN_ID_L2;
33+
34+
uint256 internal MAX_TX_IN_CHUNK;
35+
uint256 internal MAX_BLOCK_IN_CHUNK;
36+
uint256 internal MAX_BATCH_IN_BUNDLE;
37+
uint256 internal MAX_L1_MESSAGE_GAS_LIMIT;
38+
uint256 internal FINALIZE_BATCH_DEADLINE_SEC;
39+
uint256 internal RELAY_MESSAGE_DEADLINE_SEC;
40+
41+
uint256 internal L1_CONTRACT_DEPLOYMENT_BLOCK;
42+
43+
bool internal TEST_ENV_MOCK_FINALIZE_ENABLED;
44+
uint256 internal TEST_ENV_MOCK_FINALIZE_TIMEOUT_SEC;
45+
46+
// accounts
47+
uint256 internal DEPLOYER_PRIVATE_KEY;
48+
uint256 internal L1_COMMIT_SENDER_PRIVATE_KEY;
49+
uint256 internal L1_FINALIZE_SENDER_PRIVATE_KEY;
50+
uint256 internal L1_GAS_ORACLE_SENDER_PRIVATE_KEY;
51+
uint256 internal L2_GAS_ORACLE_SENDER_PRIVATE_KEY;
52+
53+
address internal DEPLOYER_ADDR;
54+
address internal L1_COMMIT_SENDER_ADDR;
55+
address internal L1_FINALIZE_SENDER_ADDR;
56+
address internal L1_GAS_ORACLE_SENDER_ADDR;
57+
address internal L2_GAS_ORACLE_SENDER_ADDR;
58+
59+
address internal OWNER_ADDR;
60+
61+
address internal L2GETH_SIGNER_ADDRESS;
62+
63+
// db
64+
string internal ROLLUP_EXPLORER_BACKEND_DB_CONNECTION_STRING;
65+
66+
// genesis
67+
uint256 internal L2_MAX_ETH_SUPPLY;
68+
uint256 internal L2_DEPLOYER_INITIAL_BALANCE;
69+
uint256 internal L2_SCROLL_MESSENGER_INITIAL_BALANCE;
70+
71+
// contracts
72+
string internal DEPLOYMENT_SALT;
73+
74+
address internal L1_FEE_VAULT_ADDR;
75+
76+
// coordinator
77+
string internal CHUNK_COLLECTION_TIME_SEC;
78+
string internal BATCH_COLLECTION_TIME_SEC;
79+
string internal BUNDLE_COLLECTION_TIME_SEC;
80+
string internal COORDINATOR_JWT_SECRET_KEY;
81+
82+
// frontend
83+
string internal EXTERNAL_RPC_URI_L1;
84+
string internal EXTERNAL_RPC_URI_L2;
85+
string internal BRIDGE_API_URI;
86+
string internal ROLLUPSCAN_API_URI;
87+
string internal EXTERNAL_EXPLORER_URI_L1;
88+
string internal EXTERNAL_EXPLORER_URI_L2;
89+
string internal ADMIN_SYSTEM_DASHBOARD_URI;
90+
string internal GRAFANA_URI;
91+
92+
/**********************
93+
* Internal interface *
94+
**********************/
95+
96+
function readConfig() internal {
97+
if (!vm.exists(CONFIG_CONTRACTS_PATH)) {
98+
string memory template = vm.readFile(CONFIG_CONTRACTS_TEMPLATE_PATH);
99+
vm.writeFile(CONFIG_CONTRACTS_PATH, template);
100+
}
101+
102+
cfg = vm.readFile(CONFIG_PATH);
103+
contractsCfg = vm.readFile(CONFIG_CONTRACTS_PATH);
104+
105+
CHAIN_ID_L1 = uint64(cfg.readUint(".general.CHAIN_ID_L1"));
106+
CHAIN_ID_L2 = uint64(cfg.readUint(".general.CHAIN_ID_L2"));
107+
108+
MAX_TX_IN_CHUNK = cfg.readUint(".rollup.MAX_TX_IN_CHUNK");
109+
MAX_BLOCK_IN_CHUNK = cfg.readUint(".rollup.MAX_BLOCK_IN_CHUNK");
110+
MAX_BATCH_IN_BUNDLE = cfg.readUint(".rollup.MAX_BATCH_IN_BUNDLE");
111+
MAX_L1_MESSAGE_GAS_LIMIT = cfg.readUint(".rollup.MAX_L1_MESSAGE_GAS_LIMIT");
112+
FINALIZE_BATCH_DEADLINE_SEC = cfg.readUint(".rollup.FINALIZE_BATCH_DEADLINE_SEC");
113+
RELAY_MESSAGE_DEADLINE_SEC = cfg.readUint(".rollup.RELAY_MESSAGE_DEADLINE_SEC");
114+
115+
L1_CONTRACT_DEPLOYMENT_BLOCK = cfg.readUint(".general.L1_CONTRACT_DEPLOYMENT_BLOCK");
116+
117+
TEST_ENV_MOCK_FINALIZE_ENABLED = cfg.readBool(".rollup.TEST_ENV_MOCK_FINALIZE_ENABLED");
118+
TEST_ENV_MOCK_FINALIZE_TIMEOUT_SEC = cfg.readUint(".rollup.TEST_ENV_MOCK_FINALIZE_TIMEOUT_SEC");
119+
120+
DEPLOYER_PRIVATE_KEY = cfg.readUint(".accounts.DEPLOYER_PRIVATE_KEY");
121+
L1_COMMIT_SENDER_PRIVATE_KEY = cfg.readUint(".accounts.L1_COMMIT_SENDER_PRIVATE_KEY");
122+
L1_FINALIZE_SENDER_PRIVATE_KEY = cfg.readUint(".accounts.L1_FINALIZE_SENDER_PRIVATE_KEY");
123+
L1_GAS_ORACLE_SENDER_PRIVATE_KEY = cfg.readUint(".accounts.L1_GAS_ORACLE_SENDER_PRIVATE_KEY");
124+
L2_GAS_ORACLE_SENDER_PRIVATE_KEY = cfg.readUint(".accounts.L2_GAS_ORACLE_SENDER_PRIVATE_KEY");
125+
126+
DEPLOYER_ADDR = cfg.readAddress(".accounts.DEPLOYER_ADDR");
127+
L1_COMMIT_SENDER_ADDR = cfg.readAddress(".accounts.L1_COMMIT_SENDER_ADDR");
128+
L1_FINALIZE_SENDER_ADDR = cfg.readAddress(".accounts.L1_FINALIZE_SENDER_ADDR");
129+
L1_GAS_ORACLE_SENDER_ADDR = cfg.readAddress(".accounts.L1_GAS_ORACLE_SENDER_ADDR");
130+
L2_GAS_ORACLE_SENDER_ADDR = cfg.readAddress(".accounts.L2_GAS_ORACLE_SENDER_ADDR");
131+
132+
OWNER_ADDR = cfg.readAddress(".accounts.OWNER_ADDR");
133+
134+
L2GETH_SIGNER_ADDRESS = cfg.readAddress(".sequencer.L2GETH_SIGNER_ADDRESS");
135+
136+
L2_MAX_ETH_SUPPLY = cfg.readUint(".genesis.L2_MAX_ETH_SUPPLY");
137+
L2_DEPLOYER_INITIAL_BALANCE = cfg.readUint(".genesis.L2_DEPLOYER_INITIAL_BALANCE");
138+
L2_SCROLL_MESSENGER_INITIAL_BALANCE = L2_MAX_ETH_SUPPLY - L2_DEPLOYER_INITIAL_BALANCE;
139+
140+
DEPLOYMENT_SALT = cfg.readString(".contracts.DEPLOYMENT_SALT");
141+
142+
L1_FEE_VAULT_ADDR = cfg.readAddress(".contracts.L1_FEE_VAULT_ADDR");
143+
144+
CHUNK_COLLECTION_TIME_SEC = cfg.readString(".coordinator.CHUNK_COLLECTION_TIME_SEC");
145+
BATCH_COLLECTION_TIME_SEC = cfg.readString(".coordinator.BATCH_COLLECTION_TIME_SEC");
146+
BUNDLE_COLLECTION_TIME_SEC = cfg.readString(".coordinator.BUNDLE_COLLECTION_TIME_SEC");
147+
COORDINATOR_JWT_SECRET_KEY = cfg.readString(".coordinator.COORDINATOR_JWT_SECRET_KEY");
148+
149+
runSanityCheck();
150+
}
151+
152+
/// @dev Ensure that `addr` is not the zero address.
153+
/// This helps catch bugs arising from incorrect deployment order.
154+
function notnull(address addr) internal pure returns (address) {
155+
require(addr != address(0), "null address");
156+
return addr;
157+
}
158+
159+
function tryGetOverride(string memory name) internal returns (address) {
160+
address addr;
161+
string memory key;
162+
if (keccak256(abi.encodePacked(name)) == keccak256(abi.encodePacked("L1_GAS_TOKEN"))) {
163+
key = string(abi.encodePacked(".gas-token.", name));
164+
} else {
165+
key = string(abi.encodePacked(".contracts.overrides.", name));
166+
}
167+
168+
if (!vm.keyExistsToml(cfg, key)) {
169+
return address(0);
170+
}
171+
172+
addr = cfg.readAddress(key);
173+
174+
if (addr.code.length == 0) {
175+
(VmSafe.CallerMode callerMode, , ) = vm.readCallers();
176+
177+
// if we're ready to start broadcasting transactions, then we
178+
// must ensure that the override contract has been deployed.
179+
if (callerMode == VmSafe.CallerMode.Broadcast || callerMode == VmSafe.CallerMode.RecurrentBroadcast) {
180+
revert(
181+
string(
182+
abi.encodePacked(
183+
"[ERROR] override ",
184+
name,
185+
" = ",
186+
vm.toString(addr),
187+
" not deployed in broadcast mode"
188+
)
189+
)
190+
);
191+
}
192+
}
193+
194+
return addr;
195+
}
196+
197+
/*********************
198+
* Private functions *
199+
*********************/
200+
201+
function runSanityCheck() private view {
202+
verifyAccount("DEPLOYER", DEPLOYER_PRIVATE_KEY, DEPLOYER_ADDR);
203+
verifyAccount("L1_COMMIT_SENDER", L1_COMMIT_SENDER_PRIVATE_KEY, L1_COMMIT_SENDER_ADDR);
204+
verifyAccount("L1_FINALIZE_SENDER", L1_FINALIZE_SENDER_PRIVATE_KEY, L1_FINALIZE_SENDER_ADDR);
205+
verifyAccount("L1_GAS_ORACLE_SENDER", L1_GAS_ORACLE_SENDER_PRIVATE_KEY, L1_GAS_ORACLE_SENDER_ADDR);
206+
verifyAccount("L2_GAS_ORACLE_SENDER", L2_GAS_ORACLE_SENDER_PRIVATE_KEY, L2_GAS_ORACLE_SENDER_ADDR);
207+
}
208+
209+
function verifyAccount(
210+
string memory name,
211+
uint256 privateKey,
212+
address addr
213+
) private pure {
214+
if (vm.addr(privateKey) != addr) {
215+
revert(
216+
string(
217+
abi.encodePacked(
218+
"[ERROR] ",
219+
name,
220+
"_ADDR (",
221+
vm.toString(addr),
222+
") does not match ",
223+
name,
224+
"_PRIVATE_KEY"
225+
)
226+
)
227+
);
228+
}
229+
}
230+
}

scripts/deterministic/Constants.sol

Lines changed: 50 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)