Skip to content

Commit 04f228b

Browse files
authored
feat: deterministic deployment configuration management (#141)
1 parent f3f416c commit 04f228b

13 files changed

+264
-231
lines changed

foundry.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,6 @@ bytecode_hash = 'none'
3535
ffi = true
3636

3737
fs_permissions = [
38-
{ access='read-write', path='./scripts/deterministic/config' },
38+
{ access='read-write', path='./scripts/deterministic/scroll/config' },
3939
{ access='read-write', path='../../config' },
4040
]

scripts/deterministic/Configuration.sol

Lines changed: 17 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@ import {Script} from "forge-std/Script.sol";
55
import {VmSafe} from "forge-std/Vm.sol";
66
import {stdToml} from "forge-std/StdToml.sol";
77

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.
118
abstract contract Configuration is Script {
129
using stdToml for string;
1310

@@ -18,135 +15,32 @@ abstract contract Configuration is Script {
1815
string internal cfg;
1916
string internal contractsCfg;
2017

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-
9218
/**********************
9319
* Internal interface *
9420
**********************/
9521

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");
22+
function initialize(string memory workdir) internal {
23+
string memory cfgPath = string(abi.encodePacked(workdir, "/config.toml"));
24+
cfg = vm.readFile(cfgPath);
13525

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;
26+
string memory contractsCfgPath = string(abi.encodePacked(workdir, "/config-contracts.toml"));
27+
contractsCfg = vm.readFile(contractsCfgPath);
28+
}
13929

140-
DEPLOYMENT_SALT = cfg.readString(".contracts.DEPLOYMENT_SALT");
30+
function readUint(string memory key) internal view returns (uint256) {
31+
return cfg.readUint(key);
32+
}
14133

142-
L1_FEE_VAULT_ADDR = cfg.readAddress(".contracts.L1_FEE_VAULT_ADDR");
34+
function readAddress(string memory key) internal view returns (address) {
35+
return cfg.readAddress(key);
36+
}
14337

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");
38+
function readString(string memory key) internal view returns (string memory) {
39+
return cfg.readString(key);
40+
}
14841

149-
runSanityCheck();
42+
function writeToml(address addr, string memory tomlPath) internal {
43+
vm.writeToml(vm.toString(addr), cfg, tomlPath);
15044
}
15145

15246
/// @dev Ensure that `addr` is not the zero address.
@@ -193,38 +87,4 @@ abstract contract Configuration is Script {
19387

19488
return addr;
19589
}
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-
}
23090
}

scripts/deterministic/DeterministicDeployment.sol

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@ import {ProxyAdmin} from "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.s
88
import {ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
99
import {ERC1967Upgrade} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol";
1010

11-
import {CONFIG_CONTRACTS_PATH, DEFAULT_DEPLOYMENT_SALT, DETERMINISTIC_DEPLOYMENT_PROXY_ADDR} from "./Constants.sol";
1211
import {Configuration} from "./Configuration.sol";
1312

13+
/// @dev The address of DeterministicDeploymentProxy.
14+
/// See https://github.com/Arachnid/deterministic-deployment-proxy.
15+
address constant DETERMINISTIC_DEPLOYMENT_PROXY_ADDR = 0x4e59b44847b379578588920cA78FbF26c0B4956C;
16+
1417
/// @notice DeterministicDeployment provides utilities for deterministic contract deployments.
1518
abstract contract DeterministicDeployment is Configuration {
1619
using stdToml for string;
@@ -39,19 +42,20 @@ abstract contract DeterministicDeployment is Configuration {
3942
* Internal interface *
4043
**********************/
4144

42-
function initialize(ScriptMode _mode) internal {
45+
function initialize(ScriptMode _mode, string memory workdir) internal {
4346
mode = _mode;
4447
skipDeploy = false;
4548

4649
if (mode != ScriptMode.EmptyConfig) {
47-
readConfig();
50+
super.initialize(workdir);
4851
}
4952

5053
// salt prefix used for deterministic deployments
54+
string memory DEPLOYMENT_SALT = readString(".contracts.DEPLOYMENT_SALT");
5155
if (bytes(DEPLOYMENT_SALT).length != 0) {
5256
saltPrefix = DEPLOYMENT_SALT;
5357
} else {
54-
saltPrefix = DEFAULT_DEPLOYMENT_SALT;
58+
revert("Missing deployment salt");
5559
}
5660

5761
// sanity check: make sure DeterministicDeploymentProxy exists
@@ -203,7 +207,7 @@ abstract contract DeterministicDeployment is Configuration {
203207
string memory tomlPath = string(abi.encodePacked(".", name, "_ADDR"));
204208

205209
if (mode == ScriptMode.WriteConfig) {
206-
vm.writeToml(vm.toString(addr), CONFIG_CONTRACTS_PATH, tomlPath);
210+
writeToml(addr, tomlPath);
207211
return;
208212
}
209213

scripts/deterministic/Constants.sol renamed to scripts/deterministic/scroll/Constants.sol

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
11
// SPDX-License-Identifier: UNLICENSED
22
pragma solidity =0.8.24;
33

4-
/// @dev The default deterministic deployment salt prefix.
5-
string constant DEFAULT_DEPLOYMENT_SALT = "ScrollStack";
6-
7-
/// @dev The address of DeterministicDeploymentProxy.
8-
/// See https://github.com/Arachnid/deterministic-deployment-proxy.
9-
address constant DETERMINISTIC_DEPLOYMENT_PROXY_ADDR = 0x4e59b44847b379578588920cA78FbF26c0B4956C;
10-
114
/// @dev The default minimum withdraw amount configured on L2TxFeeVault.
125
uint256 constant FEE_VAULT_MIN_WITHDRAW_AMOUNT = 1 ether;
136

scripts/deterministic/DeployScroll.s.sol renamed to scripts/deterministic/scroll/DeployScroll.s.sol

Lines changed: 46 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,54 +2,55 @@
22
pragma solidity =0.8.24;
33

44
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
5-
import {ProxyAdminSetOwner} from "./contracts/ProxyAdminSetOwner.sol";
5+
import {ProxyAdminSetOwner} from "../contracts/ProxyAdminSetOwner.sol";
66
import {TransparentUpgradeableProxy, ITransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
77
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
88

9-
import {EmptyContract} from "../../src/misc/EmptyContract.sol";
10-
11-
import {EnforcedTxGateway} from "../../src/L1/gateways/EnforcedTxGateway.sol";
12-
import {L1CustomERC20Gateway} from "../../src/L1/gateways/L1CustomERC20Gateway.sol";
13-
import {L1ERC1155Gateway} from "../../src/L1/gateways/L1ERC1155Gateway.sol";
14-
import {L1ERC721Gateway} from "../../src/L1/gateways/L1ERC721Gateway.sol";
15-
import {L1ETHGateway} from "../../src/L1/gateways/L1ETHGateway.sol";
16-
import {L1GatewayRouter} from "../../src/L1/gateways/L1GatewayRouter.sol";
17-
import {L1MessageQueueV1WithGasPriceOracle} from "../../src/L1/rollup/L1MessageQueueV1WithGasPriceOracle.sol";
18-
import {L1MessageQueueV2} from "../../src/L1/rollup/L1MessageQueueV2.sol";
19-
import {SystemConfig} from "../../src/L1/system-contract/SystemConfig.sol";
20-
import {L1ScrollMessenger} from "../../src/L1/L1ScrollMessenger.sol";
21-
import {L1StandardERC20Gateway} from "../../src/L1/gateways/L1StandardERC20Gateway.sol";
22-
import {L1WETHGateway} from "../../src/L1/gateways/L1WETHGateway.sol";
23-
import {L2GasPriceOracle} from "../../src/L1/rollup/L2GasPriceOracle.sol";
24-
import {MultipleVersionRollupVerifierSetOwner} from "./contracts/MultipleVersionRollupVerifierSetOwner.sol";
25-
import {ScrollChain} from "../../src/L1/rollup/ScrollChain.sol";
26-
import {ZkEvmVerifierV2} from "../../src/libraries/verifier/ZkEvmVerifierV2.sol";
27-
import {L2CustomERC20Gateway} from "../../src/L2/gateways/L2CustomERC20Gateway.sol";
28-
import {L2ERC1155Gateway} from "../../src/L2/gateways/L2ERC1155Gateway.sol";
29-
import {L2ERC721Gateway} from "../../src/L2/gateways/L2ERC721Gateway.sol";
30-
import {L2ETHGateway} from "../../src/L2/gateways/L2ETHGateway.sol";
31-
import {L2GatewayRouter} from "../../src/L2/gateways/L2GatewayRouter.sol";
32-
import {L2ScrollMessenger} from "../../src/L2/L2ScrollMessenger.sol";
33-
import {L2StandardERC20Gateway} from "../../src/L2/gateways/L2StandardERC20Gateway.sol";
34-
import {L2WETHGateway} from "../../src/L2/gateways/L2WETHGateway.sol";
35-
import {L1GasPriceOracle} from "../../src/L2/predeploys/L1GasPriceOracle.sol";
36-
import {L2MessageQueue} from "../../src/L2/predeploys/L2MessageQueue.sol";
37-
import {L2TxFeeVault} from "../../src/L2/predeploys/L2TxFeeVault.sol";
38-
import {Whitelist} from "../../src/L2/predeploys/Whitelist.sol";
39-
import {WrappedEther} from "../../src/L2/predeploys/WrappedEther.sol";
40-
import {ScrollStandardERC20} from "../../src/libraries/token/ScrollStandardERC20.sol";
41-
import {ScrollStandardERC20FactorySetOwner} from "./contracts/ScrollStandardERC20FactorySetOwner.sol";
42-
43-
import {ScrollChainMockFinalize} from "../../src/mocks/ScrollChainMockFinalize.sol";
9+
import {EmptyContract} from "../../../src/misc/EmptyContract.sol";
10+
11+
import {EnforcedTxGateway} from "../../../src/L1/gateways/EnforcedTxGateway.sol";
12+
import {L1CustomERC20Gateway} from "../../../src/L1/gateways/L1CustomERC20Gateway.sol";
13+
import {L1ERC1155Gateway} from "../../../src/L1/gateways/L1ERC1155Gateway.sol";
14+
import {L1ERC721Gateway} from "../../../src/L1/gateways/L1ERC721Gateway.sol";
15+
import {L1ETHGateway} from "../../../src/L1/gateways/L1ETHGateway.sol";
16+
import {L1GatewayRouter} from "../../../src/L1/gateways/L1GatewayRouter.sol";
17+
import {L1MessageQueueV1WithGasPriceOracle} from "../../../src/L1/rollup/L1MessageQueueV1WithGasPriceOracle.sol";
18+
import {L1MessageQueueV2} from "../../../src/L1/rollup/L1MessageQueueV2.sol";
19+
import {SystemConfig} from "../../../src/L1/system-contract/SystemConfig.sol";
20+
import {L1ScrollMessenger} from "../../../src/L1/L1ScrollMessenger.sol";
21+
import {L1StandardERC20Gateway} from "../../../src/L1/gateways/L1StandardERC20Gateway.sol";
22+
import {L1WETHGateway} from "../../../src/L1/gateways/L1WETHGateway.sol";
23+
import {L2GasPriceOracle} from "../../../src/L1/rollup/L2GasPriceOracle.sol";
24+
import {ScrollChain} from "../../../src/L1/rollup/ScrollChain.sol";
25+
import {ZkEvmVerifierV2} from "../../../src/libraries/verifier/ZkEvmVerifierV2.sol";
26+
import {L2CustomERC20Gateway} from "../../../src/L2/gateways/L2CustomERC20Gateway.sol";
27+
import {L2ERC1155Gateway} from "../../../src/L2/gateways/L2ERC1155Gateway.sol";
28+
import {L2ERC721Gateway} from "../../../src/L2/gateways/L2ERC721Gateway.sol";
29+
import {L2ETHGateway} from "../../../src/L2/gateways/L2ETHGateway.sol";
30+
import {L2GatewayRouter} from "../../../src/L2/gateways/L2GatewayRouter.sol";
31+
import {L2ScrollMessenger} from "../../../src/L2/L2ScrollMessenger.sol";
32+
import {L2StandardERC20Gateway} from "../../../src/L2/gateways/L2StandardERC20Gateway.sol";
33+
import {L2WETHGateway} from "../../../src/L2/gateways/L2WETHGateway.sol";
34+
import {L1GasPriceOracle} from "../../../src/L2/predeploys/L1GasPriceOracle.sol";
35+
import {L2MessageQueue} from "../../../src/L2/predeploys/L2MessageQueue.sol";
36+
import {L2TxFeeVault} from "../../../src/L2/predeploys/L2TxFeeVault.sol";
37+
import {Whitelist} from "../../../src/L2/predeploys/Whitelist.sol";
38+
import {WrappedEther} from "../../../src/L2/predeploys/WrappedEther.sol";
39+
import {ScrollStandardERC20} from "../../../src/libraries/token/ScrollStandardERC20.sol";
40+
41+
import {MultipleVersionRollupVerifierSetOwner} from "../contracts/MultipleVersionRollupVerifierSetOwner.sol";
42+
import {ScrollStandardERC20FactorySetOwner} from "../contracts/ScrollStandardERC20FactorySetOwner.sol";
43+
44+
import {ScrollChainMockFinalize} from "../../../src/mocks/ScrollChainMockFinalize.sol";
4445

4546
import "./Constants.sol";
46-
import "./Configuration.sol";
47-
import "./DeterministicDeployment.sol";
47+
import {ScrollConfiguration} from "./ScrollConfiguration.sol";
48+
import "../DeterministicDeployment.sol";
4849

4950
/// @dev The minimum deployer account balance.
5051
uint256 constant MINIMUM_DEPLOYER_BALANCE = 0.1 ether;
5152

52-
contract DeployScroll is DeterministicDeployment {
53+
contract DeployScroll is DeterministicDeployment, ScrollConfiguration {
5354
using stdToml for string;
5455

5556
/*********
@@ -178,11 +179,15 @@ contract DeployScroll is DeterministicDeployment {
178179
* Entry point *
179180
***************/
180181

181-
function run(string memory layer, string memory scriptMode) public {
182+
function run(
183+
string memory workdir,
184+
string memory layer,
185+
string memory scriptMode
186+
) public {
182187
broadcastLayer = parseLayer(layer);
183188
ScriptMode mode = parseScriptMode(scriptMode);
184189

185-
DeterministicDeployment.initialize(mode);
190+
DeterministicDeployment.initialize(mode, workdir);
186191

187192
checkDeployerBalance();
188193
deployAllContracts();

0 commit comments

Comments
 (0)