diff --git a/contracts b/contracts index c863a6592293..63e360600715 160000 --- a/contracts +++ b/contracts @@ -1 +1 @@ -Subproject commit c863a659229319966c55cf7e66cd6542c6da9899 +Subproject commit 63e3606007158701f47c2532dd585c7d13741271 diff --git a/zk_toolbox/crates/config/src/contracts.rs b/zk_toolbox/crates/config/src/contracts.rs index 0a0b3c22ab5b..6042c4bea088 100644 --- a/zk_toolbox/crates/config/src/contracts.rs +++ b/zk_toolbox/crates/config/src/contracts.rs @@ -5,7 +5,7 @@ use crate::{ consts::CONTRACTS_FILE, forge_interface::{ deploy_ecosystem::output::DeployL1Output, - initialize_bridges::output::InitializeBridgeOutput, + deploy_l2_contracts::output::{DefaultL2UpgradeOutput, InitializeBridgeOutput}, register_chain::output::RegisterChainOutput, }, traits::{FileConfigWithDefaultName, ZkToolboxConfig}, @@ -83,6 +83,14 @@ impl ContractsConfig { self.bridges.erc20.l2_address = Some(initialize_bridges_output.l2_shared_bridge_proxy); Ok(()) } + + pub fn set_default_l2_upgrade( + &mut self, + default_upgrade_output: &DefaultL2UpgradeOutput, + ) -> anyhow::Result<()> { + self.l2.default_l2_upgrader = default_upgrade_output.l2_default_upgrader; + Ok(()) + } } impl FileConfigWithDefaultName for ContractsConfig { @@ -131,4 +139,5 @@ pub struct L1Contracts { #[derive(Debug, Serialize, Deserialize, Clone, Default)] pub struct L2Contracts { pub testnet_paymaster_addr: Address, + pub default_l2_upgrader: Address, } diff --git a/zk_toolbox/crates/config/src/forge_interface/initialize_bridges/input.rs b/zk_toolbox/crates/config/src/forge_interface/deploy_l2_contracts/input.rs similarity index 89% rename from zk_toolbox/crates/config/src/forge_interface/initialize_bridges/input.rs rename to zk_toolbox/crates/config/src/forge_interface/deploy_l2_contracts/input.rs index d06e36185607..f48fd0ba2b5e 100644 --- a/zk_toolbox/crates/config/src/forge_interface/initialize_bridges/input.rs +++ b/zk_toolbox/crates/config/src/forge_interface/deploy_l2_contracts/input.rs @@ -4,10 +4,10 @@ use zksync_basic_types::L2ChainId; use crate::{traits::ZkToolboxConfig, ChainConfig}; -impl ZkToolboxConfig for InitializeBridgeInput {} +impl ZkToolboxConfig for DeployL2ContractsInput {} #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct InitializeBridgeInput { +pub struct DeployL2ContractsInput { pub era_chain_id: L2ChainId, pub chain_id: L2ChainId, pub l1_shared_bridge: Address, @@ -16,7 +16,7 @@ pub struct InitializeBridgeInput { pub erc20_bridge: Address, } -impl InitializeBridgeInput { +impl DeployL2ContractsInput { pub fn new(chain_config: &ChainConfig, era_chain_id: L2ChainId) -> anyhow::Result { let contracts = chain_config.get_contracts_config()?; let wallets = chain_config.get_wallets_config()?; diff --git a/zk_toolbox/crates/config/src/forge_interface/initialize_bridges/mod.rs b/zk_toolbox/crates/config/src/forge_interface/deploy_l2_contracts/mod.rs similarity index 100% rename from zk_toolbox/crates/config/src/forge_interface/initialize_bridges/mod.rs rename to zk_toolbox/crates/config/src/forge_interface/deploy_l2_contracts/mod.rs diff --git a/zk_toolbox/crates/config/src/forge_interface/initialize_bridges/output.rs b/zk_toolbox/crates/config/src/forge_interface/deploy_l2_contracts/output.rs similarity index 65% rename from zk_toolbox/crates/config/src/forge_interface/initialize_bridges/output.rs rename to zk_toolbox/crates/config/src/forge_interface/deploy_l2_contracts/output.rs index 8da3707ed706..22f3dc9381b3 100644 --- a/zk_toolbox/crates/config/src/forge_interface/initialize_bridges/output.rs +++ b/zk_toolbox/crates/config/src/forge_interface/deploy_l2_contracts/output.rs @@ -5,8 +5,15 @@ use crate::traits::ZkToolboxConfig; impl ZkToolboxConfig for InitializeBridgeOutput {} +impl ZkToolboxConfig for DefaultL2UpgradeOutput {} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct InitializeBridgeOutput { pub l2_shared_bridge_implementation: Address, pub l2_shared_bridge_proxy: Address, } + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct DefaultL2UpgradeOutput { + pub l2_default_upgrader: Address, +} diff --git a/zk_toolbox/crates/config/src/forge_interface/mod.rs b/zk_toolbox/crates/config/src/forge_interface/mod.rs index bcf21b7fb087..ea3d49c67ecb 100644 --- a/zk_toolbox/crates/config/src/forge_interface/mod.rs +++ b/zk_toolbox/crates/config/src/forge_interface/mod.rs @@ -1,6 +1,6 @@ pub mod accept_ownership; pub mod deploy_ecosystem; -pub mod initialize_bridges; +pub mod deploy_l2_contracts; pub mod paymaster; pub mod register_chain; pub mod script_params; diff --git a/zk_toolbox/crates/config/src/forge_interface/script_params.rs b/zk_toolbox/crates/config/src/forge_interface/script_params.rs index 70ed08ec5651..fb16aa97e6a8 100644 --- a/zk_toolbox/crates/config/src/forge_interface/script_params.rs +++ b/zk_toolbox/crates/config/src/forge_interface/script_params.rs @@ -32,10 +32,10 @@ pub const DEPLOY_ECOSYSTEM_SCRIPT_PARAMS: ForgeScriptParams = ForgeScriptParams script_path: "deploy-scripts/DeployL1.s.sol", }; -pub const INITIALIZE_BRIDGES_SCRIPT_PARAMS: ForgeScriptParams = ForgeScriptParams { - input: "script-config/config-initialize-shared-bridges.toml", - output: "script-out/output-initialize-shared-bridges.toml", - script_path: "deploy-scripts/InitializeSharedBridgeOnL2.sol", +pub const DEPLOY_L2_CONTRACTS_SCRIPT_PARAMS: ForgeScriptParams = ForgeScriptParams { + input: "script-config/config-deploy-l2-contracts.toml", + output: "script-out/output-deploy-l2-contracts.toml", + script_path: "deploy-scripts/DeployL2Contracts.sol", }; pub const REGISTER_CHAIN_SCRIPT_PARAMS: ForgeScriptParams = ForgeScriptParams { diff --git a/zk_toolbox/crates/zk_inception/src/commands/chain/deploy_l2_contracts.rs b/zk_toolbox/crates/zk_inception/src/commands/chain/deploy_l2_contracts.rs new file mode 100644 index 000000000000..30f361e44af2 --- /dev/null +++ b/zk_toolbox/crates/zk_inception/src/commands/chain/deploy_l2_contracts.rs @@ -0,0 +1,215 @@ +use std::path::Path; + +use anyhow::Context; +use common::{ + cmd::Cmd, + config::global_config, + forge::{Forge, ForgeScriptArgs}, + spinner::Spinner, +}; +use config::{ + forge_interface::{ + deploy_l2_contracts::{ + input::DeployL2ContractsInput, + output::{DefaultL2UpgradeOutput, InitializeBridgeOutput}, + }, + script_params::DEPLOY_L2_CONTRACTS_SCRIPT_PARAMS, + }, + traits::{ReadConfig, SaveConfig, SaveConfigWithBasePath}, + ChainConfig, ContractsConfig, EcosystemConfig, +}; +use xshell::{cmd, Shell}; + +use crate::{ + messages::{ + MSG_CHAIN_NOT_INITIALIZED, MSG_DEPLOYING_L2_CONTRACT_SPINNER, + MSG_L1_SECRETS_MUST_BE_PRESENTED, + }, + utils::forge::{check_the_balance, fill_forge_private_key}, +}; + +pub enum Deploy2ContractsOption { + All, + Upgrader, + IntiailizeBridges, +} + +pub async fn run( + args: ForgeScriptArgs, + shell: &Shell, + deploy_option: Deploy2ContractsOption, +) -> anyhow::Result<()> { + let chain_name = global_config().chain_name.clone(); + let ecosystem_config = EcosystemConfig::from_file(shell)?; + let chain_config = ecosystem_config + .load_chain(chain_name) + .context(MSG_CHAIN_NOT_INITIALIZED)?; + + let mut contracts = chain_config.get_contracts_config()?; + + let spinner = Spinner::new(MSG_DEPLOYING_L2_CONTRACT_SPINNER); + + match deploy_option { + Deploy2ContractsOption::All => { + deploy_l2_contracts( + shell, + &chain_config, + &ecosystem_config, + &mut contracts, + args, + ) + .await?; + } + Deploy2ContractsOption::Upgrader => { + deploy_upgrader( + shell, + &chain_config, + &ecosystem_config, + &mut contracts, + args, + ) + .await?; + } + Deploy2ContractsOption::IntiailizeBridges => { + initialize_bridges( + shell, + &chain_config, + &ecosystem_config, + &mut contracts, + args, + ) + .await? + } + } + + contracts.save_with_base_path(shell, &chain_config.configs)?; + spinner.finish(); + + Ok(()) +} + +pub async fn initialize_bridges( + shell: &Shell, + chain_config: &ChainConfig, + ecosystem_config: &EcosystemConfig, + contracts_config: &mut ContractsConfig, + forge_args: ForgeScriptArgs, +) -> anyhow::Result<()> { + build_l2_contracts(shell, &ecosystem_config.link_to_code)?; + call_forge( + shell, + chain_config, + ecosystem_config, + forge_args, + Some("runDeploySharedBridge"), + ) + .await?; + let output = InitializeBridgeOutput::read( + shell, + DEPLOY_L2_CONTRACTS_SCRIPT_PARAMS.output(&chain_config.link_to_code), + )?; + + contracts_config.set_l2_shared_bridge(&output)?; + Ok(()) +} + +pub async fn deploy_upgrader( + shell: &Shell, + chain_config: &ChainConfig, + ecosystem_config: &EcosystemConfig, + contracts_config: &mut ContractsConfig, + forge_args: ForgeScriptArgs, +) -> anyhow::Result<()> { + build_l2_contracts(shell, &ecosystem_config.link_to_code)?; + call_forge( + shell, + chain_config, + ecosystem_config, + forge_args, + Some("runDefaultUpgrader"), + ) + .await?; + let output = DefaultL2UpgradeOutput::read( + shell, + DEPLOY_L2_CONTRACTS_SCRIPT_PARAMS.output(&chain_config.link_to_code), + )?; + + contracts_config.set_default_l2_upgrade(&output)?; + Ok(()) +} + +pub async fn deploy_l2_contracts( + shell: &Shell, + chain_config: &ChainConfig, + ecosystem_config: &EcosystemConfig, + contracts_config: &mut ContractsConfig, + forge_args: ForgeScriptArgs, +) -> anyhow::Result<()> { + build_l2_contracts(shell, &ecosystem_config.link_to_code)?; + call_forge(shell, chain_config, ecosystem_config, forge_args, None).await?; + let output = InitializeBridgeOutput::read( + shell, + DEPLOY_L2_CONTRACTS_SCRIPT_PARAMS.output(&chain_config.link_to_code), + )?; + + contracts_config.set_l2_shared_bridge(&output)?; + + let output = DefaultL2UpgradeOutput::read( + shell, + DEPLOY_L2_CONTRACTS_SCRIPT_PARAMS.output(&chain_config.link_to_code), + )?; + + contracts_config.set_default_l2_upgrade(&output)?; + + Ok(()) +} + +async fn call_forge( + shell: &Shell, + chain_config: &ChainConfig, + ecosystem_config: &EcosystemConfig, + forge_args: ForgeScriptArgs, + signature: Option<&str>, +) -> anyhow::Result<()> { + let input = DeployL2ContractsInput::new(chain_config, ecosystem_config.era_chain_id)?; + let foundry_contracts_path = chain_config.path_to_foundry(); + let secrets = chain_config.get_secrets_config()?; + input.save( + shell, + DEPLOY_L2_CONTRACTS_SCRIPT_PARAMS.input(&chain_config.link_to_code), + )?; + + let mut forge = Forge::new(&foundry_contracts_path) + .script( + &DEPLOY_L2_CONTRACTS_SCRIPT_PARAMS.script(), + forge_args.clone(), + ) + .with_ffi() + .with_rpc_url( + secrets + .l1 + .context(MSG_L1_SECRETS_MUST_BE_PRESENTED)? + .l1_rpc_url + .expose_str() + .to_string(), + ) + .with_broadcast(); + + if let Some(signature) = signature { + forge = forge.with_signature(signature); + } + + forge = fill_forge_private_key( + forge, + ecosystem_config.get_wallets()?.governor_private_key(), + )?; + + check_the_balance(&forge).await?; + forge.run(shell)?; + Ok(()) +} + +fn build_l2_contracts(shell: &Shell, link_to_code: &Path) -> anyhow::Result<()> { + let _dir_guard = shell.push_dir(link_to_code.join("contracts")); + Ok(Cmd::new(cmd!(shell, "yarn l2 build")).run()?) +} diff --git a/zk_toolbox/crates/zk_inception/src/commands/chain/init.rs b/zk_toolbox/crates/zk_inception/src/commands/chain/init.rs index bf44b5d5c999..17a993a86ace 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/chain/init.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/chain/init.rs @@ -21,9 +21,8 @@ use crate::{ accept_ownership::accept_admin, commands::chain::{ args::init::{InitArgs, InitArgsFinal}, - deploy_paymaster, + deploy_l2_contracts, deploy_paymaster, genesis::genesis, - initialize_bridges, }, messages::{ msg_initializing_chain, MSG_ACCEPTING_ADMIN_SPINNER, MSG_CHAIN_INITIALIZED, @@ -103,7 +102,7 @@ pub async fn init( .await?; spinner.finish(); - initialize_bridges::initialize_bridges( + deploy_l2_contracts::deploy_l2_contracts( shell, chain_config, ecosystem_config, diff --git a/zk_toolbox/crates/zk_inception/src/commands/chain/initialize_bridges.rs b/zk_toolbox/crates/zk_inception/src/commands/chain/initialize_bridges.rs deleted file mode 100644 index b60daa9dbd61..000000000000 --- a/zk_toolbox/crates/zk_inception/src/commands/chain/initialize_bridges.rs +++ /dev/null @@ -1,103 +0,0 @@ -use std::path::Path; - -use anyhow::Context; -use common::{ - cmd::Cmd, - config::global_config, - forge::{Forge, ForgeScriptArgs}, - spinner::Spinner, -}; -use config::{ - forge_interface::{ - initialize_bridges::{input::InitializeBridgeInput, output::InitializeBridgeOutput}, - script_params::INITIALIZE_BRIDGES_SCRIPT_PARAMS, - }, - traits::{ReadConfig, SaveConfig, SaveConfigWithBasePath}, - ChainConfig, ContractsConfig, EcosystemConfig, -}; -use xshell::{cmd, Shell}; - -use crate::{ - messages::{ - MSG_CHAIN_NOT_INITIALIZED, MSG_INITIALIZING_BRIDGES_SPINNER, - MSG_L1_SECRETS_MUST_BE_PRESENTED, - }, - utils::forge::{check_the_balance, fill_forge_private_key}, -}; - -pub async fn run(args: ForgeScriptArgs, shell: &Shell) -> anyhow::Result<()> { - let chain_name = global_config().chain_name.clone(); - let ecosystem_config = EcosystemConfig::from_file(shell)?; - let chain_config = ecosystem_config - .load_chain(chain_name) - .context(MSG_CHAIN_NOT_INITIALIZED)?; - - let mut contracts = chain_config.get_contracts_config()?; - let spinner = Spinner::new(MSG_INITIALIZING_BRIDGES_SPINNER); - initialize_bridges( - shell, - &chain_config, - &ecosystem_config, - &mut contracts, - args, - ) - .await?; - contracts.save_with_base_path(shell, &chain_config.configs)?; - spinner.finish(); - - Ok(()) -} - -pub async fn initialize_bridges( - shell: &Shell, - chain_config: &ChainConfig, - ecosystem_config: &EcosystemConfig, - contracts_config: &mut ContractsConfig, - forge_args: ForgeScriptArgs, -) -> anyhow::Result<()> { - build_l2_contracts(shell, &ecosystem_config.link_to_code)?; - let input = InitializeBridgeInput::new(chain_config, ecosystem_config.era_chain_id)?; - let foundry_contracts_path = chain_config.path_to_foundry(); - let secrets = chain_config.get_secrets_config()?; - input.save( - shell, - INITIALIZE_BRIDGES_SCRIPT_PARAMS.input(&chain_config.link_to_code), - )?; - - let mut forge = Forge::new(&foundry_contracts_path) - .script( - &INITIALIZE_BRIDGES_SCRIPT_PARAMS.script(), - forge_args.clone(), - ) - .with_ffi() - .with_rpc_url( - secrets - .l1 - .context(MSG_L1_SECRETS_MUST_BE_PRESENTED)? - .l1_rpc_url - .expose_str() - .to_string(), - ) - .with_broadcast(); - - forge = fill_forge_private_key( - forge, - ecosystem_config.get_wallets()?.governor_private_key(), - )?; - - check_the_balance(&forge).await?; - forge.run(shell)?; - - let output = InitializeBridgeOutput::read( - shell, - INITIALIZE_BRIDGES_SCRIPT_PARAMS.output(&chain_config.link_to_code), - )?; - - contracts_config.set_l2_shared_bridge(&output)?; - Ok(()) -} - -fn build_l2_contracts(shell: &Shell, link_to_code: &Path) -> anyhow::Result<()> { - let _dir_guard = shell.push_dir(link_to_code.join("contracts")); - Ok(Cmd::new(cmd!(shell, "yarn l2 build")).run()?) -} diff --git a/zk_toolbox/crates/zk_inception/src/commands/chain/mod.rs b/zk_toolbox/crates/zk_inception/src/commands/chain/mod.rs index fa4f81d76312..5333ead30662 100644 --- a/zk_toolbox/crates/zk_inception/src/commands/chain/mod.rs +++ b/zk_toolbox/crates/zk_inception/src/commands/chain/mod.rs @@ -4,14 +4,17 @@ use common::forge::ForgeScriptArgs; pub(crate) use create::create_chain_inner; use xshell::Shell; -use crate::commands::chain::args::{create::ChainCreateArgs, genesis::GenesisArgs, init::InitArgs}; +use crate::commands::chain::{ + args::{create::ChainCreateArgs, genesis::GenesisArgs, init::InitArgs}, + deploy_l2_contracts::Deploy2ContractsOption, +}; pub(crate) mod args; mod create; +pub mod deploy_l2_contracts; pub mod deploy_paymaster; pub mod genesis; pub(crate) mod init; -mod initialize_bridges; #[derive(Subcommand, Debug)] pub enum ChainCommands { @@ -24,6 +27,11 @@ pub enum ChainCommands { /// Initialize bridges on l2 #[command(alias = "bridge")] InitializeBridges(ForgeScriptArgs), + /// Deploy all l2 contracts + #[command(alias = "l2")] + DeployL2Contracts(ForgeScriptArgs), + /// Deploy Default Upgrader + Upgrader(ForgeScriptArgs), /// Initialize bridges on l2 #[command(alias = "paymaster")] DeployPaymaster(ForgeScriptArgs), @@ -34,7 +42,15 @@ pub(crate) async fn run(shell: &Shell, args: ChainCommands) -> anyhow::Result<() ChainCommands::Create(args) => create::run(args, shell), ChainCommands::Init(args) => init::run(args, shell).await, ChainCommands::Genesis(args) => genesis::run(args, shell).await, - ChainCommands::InitializeBridges(args) => initialize_bridges::run(args, shell).await, + ChainCommands::DeployL2Contracts(args) => { + deploy_l2_contracts::run(args, shell, Deploy2ContractsOption::All).await + } + ChainCommands::Upgrader(args) => { + deploy_l2_contracts::run(args, shell, Deploy2ContractsOption::Upgrader).await + } + ChainCommands::InitializeBridges(args) => { + deploy_l2_contracts::run(args, shell, Deploy2ContractsOption::IntiailizeBridges).await + } ChainCommands::DeployPaymaster(args) => deploy_paymaster::run(args, shell).await, } } diff --git a/zk_toolbox/crates/zk_inception/src/messages.rs b/zk_toolbox/crates/zk_inception/src/messages.rs index 428b06516921..4e1ad9074389 100644 --- a/zk_toolbox/crates/zk_inception/src/messages.rs +++ b/zk_toolbox/crates/zk_inception/src/messages.rs @@ -171,7 +171,7 @@ pub(super) fn msg_server_db_name_prompt(chain_name: &str) -> String { } /// Chain initialize bridges related messages -pub(super) const MSG_INITIALIZING_BRIDGES_SPINNER: &str = "Initializing bridges"; +pub(super) const MSG_DEPLOYING_L2_CONTRACT_SPINNER: &str = "Deploying l2 contracts"; /// Chain deploy paymaster related messages pub(super) const MSG_DEPLOYING_PAYMASTER: &str = "Deploying paymaster";