Skip to content

Commit 43dffec

Browse files
fix(zkstack_cli): regenerate CREATE2 salt on ecosystem init (#4892)
## What ❔ Regenerate the ecosystem CREATE2 salt (`create2_factory_salt`) on every `zkstack init` instead of reusing the persisted one. ## Why ❔ The salt is generated once at `ecosystem create` time via `InitialDeploymentConfig::default()` (`H256::random()`) and persisted to `initial_deployments.yaml`. Every subsequent `zkstack init` simply read that same salt back: ```rust let initial_deployment_config = match ecosystem_config.get_initial_deployment_config() { Ok(config) => config, // reuses the SAME salt Err(_) => create_initial_deployments_config(shell, &ecosystem_config.config)?, }; ``` Because the salt never changed, running `zkstack init` twice (e.g. `zkstack init --dev`) redeployed the ecosystem contracts to the **same CREATE2 addresses**, colliding with the previous deployment and causing ownership problems. `--dev` had no effect on the salt. ## How ❔ `init.rs` now loads the existing config (preserving customizations like `create2_factory_addr`, WETH address, governance delays) but overwrites `create2_factory_salt` with a fresh `H256::random()` and persists it back, so each init deploys fresh contracts to new addresses. The change is scoped to the `ecosystem init` path only. `build-transactions` and `init-core-contracts` intentionally keep the persisted salt so a deployment can be reproduced deterministically. The per-chain `RegisterChainL1Config` already generates a fresh salt per call, so chain registration was not the collision source. ## Checklist - [x] PR title follows the [contribution guidelines](https://github.com/matter-labs/zksync-era/blob/main/docs/src/guides/contributing.md). - [x] Code has been formatted via `zkstack dev fmt`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 70f8271 commit 43dffec

1 file changed

Lines changed: 10 additions & 2 deletions

File tree

  • zkstack_cli/crates/zkstack/src/commands/ecosystem

zkstack_cli/crates/zkstack/src/commands/ecosystem/init.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use zkstack_cli_config::{
1010
ContractsConfig, CoreContractsConfig, EcosystemConfig, ZkStackConfig,
1111
};
1212
use zkstack_cli_types::{L1Network, VMOption};
13-
use zksync_basic_types::Address;
13+
use zksync_basic_types::{Address, H256};
1414

1515
use super::{
1616
args::init::{EcosystemInitArgs, EcosystemInitArgsFinal},
@@ -38,11 +38,19 @@ use crate::{
3838
pub async fn run(args: EcosystemInitArgs, shell: &Shell) -> anyhow::Result<()> {
3939
let ecosystem_config = ZkStackConfig::ecosystem(shell)?;
4040

41-
let initial_deployment_config = match ecosystem_config.get_initial_deployment_config() {
41+
let mut initial_deployment_config = match ecosystem_config.get_initial_deployment_config() {
4242
Ok(config) => config,
4343
Err(_) => create_initial_deployments_config(shell, &ecosystem_config.config)?,
4444
};
4545

46+
// The CREATE2 salt is persisted in `initial_deployments.yaml` and is otherwise reused across
47+
// runs. Reusing it means a repeated `zkstack init` (e.g. `--dev`) redeploys the ecosystem
48+
// contracts to the *same* CREATE2 addresses, colliding with the previous deployment and
49+
// breaking ownership. Regenerate it on every init so that each init deploys fresh contracts,
50+
// preserving any other customizations already present in the file.
51+
initial_deployment_config.create2_factory_salt = H256::random();
52+
initial_deployment_config.save_with_base_path(shell, &ecosystem_config.config)?;
53+
4654
let final_ecosystem_args = args
4755
.fill_values_with_prompt(ecosystem_config.l1_network)
4856
.await?;

0 commit comments

Comments
 (0)