diff --git a/.gitmodules b/.gitmodules
index 445344c3f20..dd5b3b3bc82 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,3 @@
[submodule "contracts"]
path = contracts
-url = https://github.com/matter-labs/era-contracts.git
+url = https://github.com/matter-labs/era-contracts-private.git
diff --git a/Cargo.lock b/Cargo.lock
index 30368383981..d718a2b221b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -10235,6 +10235,7 @@ dependencies = [
"tracing",
"vise",
"zksync_concurrency",
+ "zksync_config",
"zksync_contracts",
"zksync_dal",
"zksync_eth_client",
@@ -11276,6 +11277,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"assert_matches",
+ "async-trait",
"bigdecimal",
"bincode",
"blake2 0.10.6",
diff --git a/contracts b/contracts
index 53b0283f82f..9771f8e73fb 160000
--- a/contracts
+++ b/contracts
@@ -1 +1 @@
-Subproject commit 53b0283f82f4262c973eb3faed56ee8f6cda47b9
+Subproject commit 9771f8e73fb58e0e6cea003b7e85e1bf1eac7962
diff --git a/core/bin/external_node/src/config/mod.rs b/core/bin/external_node/src/config/mod.rs
index 420a6941c81..42bc9f0c091 100644
--- a/core/bin/external_node/src/config/mod.rs
+++ b/core/bin/external_node/src/config/mod.rs
@@ -104,6 +104,7 @@ pub(crate) struct RemoteENConfig {
pub bridgehub_proxy_addr: Option
,
pub state_transition_proxy_addr: Option,
pub transparent_proxy_admin_addr: Option,
+ pub l1_bytecodes_supplier_addr: Option,
/// Should not be accessed directly. Use [`ExternalNodeConfig::diamond_proxy_address`] instead.
pub user_facing_diamond_proxy: Address,
// While on L1 shared bridge and legacy bridge are different contracts with different addresses,
@@ -196,6 +197,9 @@ impl RemoteENConfig {
transparent_proxy_admin_addr: ecosystem_contracts
.as_ref()
.map(|a| a.transparent_proxy_admin_addr),
+ l1_bytecodes_supplier_addr: ecosystem_contracts
+ .as_ref()
+ .and_then(|a| a.l1_bytecodes_supplier_addr),
user_facing_diamond_proxy,
user_facing_bridgehub,
l2_testnet_paymaster_addr,
@@ -224,6 +228,7 @@ impl RemoteENConfig {
bridgehub_proxy_addr: None,
state_transition_proxy_addr: None,
transparent_proxy_admin_addr: None,
+ l1_bytecodes_supplier_addr: None,
user_facing_diamond_proxy: Address::repeat_byte(1),
user_facing_bridgehub: None,
l1_erc20_bridge_proxy_addr: Some(Address::repeat_byte(2)),
@@ -1428,6 +1433,7 @@ impl From<&ExternalNodeConfig> for InternalApiConfig {
l1_weth_bridge: config.remote.l1_weth_bridge_addr,
l2_weth_bridge: config.remote.l2_weth_bridge_addr,
},
+ l1_bytecodes_supplier_addr: config.remote.l1_bytecodes_supplier_addr,
bridgehub_proxy_addr: config.remote.bridgehub_proxy_addr,
state_transition_proxy_addr: config.remote.state_transition_proxy_addr,
transparent_proxy_admin_addr: config.remote.transparent_proxy_admin_addr,
diff --git a/core/bin/system-constants-generator/src/main.rs b/core/bin/system-constants-generator/src/main.rs
index cc2e031106b..cd795f9f532 100644
--- a/core/bin/system-constants-generator/src/main.rs
+++ b/core/bin/system-constants-generator/src/main.rs
@@ -3,7 +3,9 @@ use std::fs;
use codegen::{Block, Scope};
use serde::{Deserialize, Serialize};
use zksync_multivm::{
- utils::{get_bootloader_encoding_space, get_bootloader_max_txs_in_batch},
+ utils::{
+ get_bootloader_encoding_space, get_bootloader_max_txs_in_batch, get_max_new_factory_deps,
+ },
vm_latest::constants::MAX_VM_PUBDATA_PER_BATCH,
zk_evm_latest::zkevm_opcode_defs::{
circuit_prices::{
@@ -15,7 +17,7 @@ use zksync_multivm::{
};
use zksync_types::{
IntrinsicSystemGasConstants, ProtocolVersionId, GUARANTEED_PUBDATA_IN_TX,
- L1_GAS_PER_PUBDATA_BYTE, MAX_NEW_FACTORY_DEPS, REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_BYTE,
+ L1_GAS_PER_PUBDATA_BYTE, REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_BYTE,
};
use zksync_utils::env::Workspace;
@@ -73,7 +75,7 @@ pub fn generate_l1_contracts_system_config(gas_constants: &IntrinsicSystemGasCon
l1_tx_delta_544_encoding_bytes: gas_constants.l1_tx_delta_544_encoding_bytes,
l1_tx_delta_factory_deps_l2_gas: gas_constants.l1_tx_delta_factory_dep_gas,
l1_tx_delta_factory_deps_pubdata: gas_constants.l1_tx_delta_factory_dep_pubdata,
- max_new_factory_deps: MAX_NEW_FACTORY_DEPS as u32,
+ max_new_factory_deps: get_max_new_factory_deps(ProtocolVersionId::latest().into()) as u32,
required_l2_gas_price_per_pubdata: REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_BYTE,
};
diff --git a/core/lib/basic_types/src/protocol_version.rs b/core/lib/basic_types/src/protocol_version.rs
index 88513360916..2cf941510d9 100644
--- a/core/lib/basic_types/src/protocol_version.rs
+++ b/core/lib/basic_types/src/protocol_version.rs
@@ -144,7 +144,11 @@ impl ProtocolVersionId {
}
pub fn is_pre_gateway(&self) -> bool {
- self <= &Self::Version26
+ self < &Self::gateway_upgrade()
+ }
+
+ pub fn is_post_gateway(&self) -> bool {
+ self >= &Self::gateway_upgrade()
}
pub fn is_1_4_0(&self) -> bool {
@@ -182,6 +186,10 @@ impl ProtocolVersionId {
pub fn is_post_1_5_0(&self) -> bool {
self >= &ProtocolVersionId::Version23
}
+
+ pub const fn gateway_upgrade() -> Self {
+ ProtocolVersionId::Version26
+ }
}
impl Default for ProtocolVersionId {
diff --git a/core/lib/config/src/configs/contracts.rs b/core/lib/config/src/configs/contracts.rs
index 1d49a09d213..5cb738f118e 100644
--- a/core/lib/config/src/configs/contracts.rs
+++ b/core/lib/config/src/configs/contracts.rs
@@ -1,13 +1,14 @@
// External uses
use serde::{Deserialize, Serialize};
// Workspace uses
-use zksync_basic_types::Address;
+use zksync_basic_types::{Address, H256};
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct EcosystemContracts {
pub bridgehub_proxy_addr: Address,
pub state_transition_proxy_addr: Address,
pub transparent_proxy_admin_addr: Address,
+ pub l1_bytecodes_supplier_addr: Option,
}
impl EcosystemContracts {
@@ -16,6 +17,7 @@ impl EcosystemContracts {
bridgehub_proxy_addr: Address::repeat_byte(0x14),
state_transition_proxy_addr: Address::repeat_byte(0x15),
transparent_proxy_admin_addr: Address::repeat_byte(0x15),
+ l1_bytecodes_supplier_addr: Some(Address::repeat_byte(0x16)),
}
}
}
@@ -45,6 +47,10 @@ pub struct ContractsConfig {
pub ecosystem_contracts: Option,
// Used by the RPC API and by the node builder in wiring the BaseTokenRatioProvider layer.
pub base_token_addr: Option,
+ pub base_token_asset_id: Option,
+
+ pub predeployed_l2_wrapped_base_token_address: Option,
+
// FIXME: maybe refactor
pub user_facing_bridgehub_proxy_addr: Option,
pub user_facing_diamond_proxy_addr: Option,
@@ -71,6 +77,8 @@ impl ContractsConfig {
l1_multicall3_addr: Address::repeat_byte(0x12),
governance_addr: Address::repeat_byte(0x13),
base_token_addr: Some(Address::repeat_byte(0x14)),
+ base_token_asset_id: Some(H256::repeat_byte(0x15)),
+ predeployed_l2_wrapped_base_token_address: Some(Address::repeat_byte(0x1b)),
ecosystem_contracts: Some(EcosystemContracts::for_tests()),
user_facing_bridgehub_proxy_addr: Some(Address::repeat_byte(0x15)),
user_facing_diamond_proxy_addr: Some(Address::repeat_byte(0x16)),
diff --git a/core/lib/config/src/testonly.rs b/core/lib/config/src/testonly.rs
index 4e6930a3384..eb648902ac5 100644
--- a/core/lib/config/src/testonly.rs
+++ b/core/lib/config/src/testonly.rs
@@ -272,6 +272,8 @@ impl Distribution for EncodeDist {
user_facing_bridgehub_proxy_addr: rng.gen(),
user_facing_diamond_proxy_addr: rng.gen(),
base_token_addr: self.sample_opt(|| rng.gen()),
+ base_token_asset_id: self.sample_opt(|| rng.gen()),
+ predeployed_l2_wrapped_base_token_address: self.sample_opt(|| rng.gen()),
chain_admin_addr: self.sample_opt(|| rng.gen()),
settlement_layer: self.sample_opt(|| rng.gen()),
l2_da_validator_addr: self.sample_opt(|| rng.gen()),
@@ -763,6 +765,7 @@ impl Distribution for EncodeDist {
bridgehub_proxy_addr: rng.gen(),
state_transition_proxy_addr: rng.gen(),
transparent_proxy_admin_addr: rng.gen(),
+ l1_bytecodes_supplier_addr: rng.gen(),
}
}
}
diff --git a/core/lib/constants/src/contracts.rs b/core/lib/constants/src/contracts.rs
index f9138b2bbf1..faee06e6fc1 100644
--- a/core/lib/constants/src/contracts.rs
+++ b/core/lib/constants/src/contracts.rs
@@ -165,6 +165,14 @@ pub const L2_MESSAGE_ROOT_ADDRESS: Address = H160([
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x05,
]);
+pub const SLOAD_CONTRACT_ADDRESS: Address = H160([
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x06,
+]);
+pub const L2_WRAPPED_BASE_TOKEN_IMPL: Address = H160([
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0x00, 0x07,
+]);
pub const ERC20_TRANSFER_TOPIC: H256 = H256([
221, 242, 82, 173, 27, 226, 200, 155, 105, 194, 176, 104, 252, 55, 141, 170, 149, 43, 167, 241,
diff --git a/core/lib/constants/src/crypto.rs b/core/lib/constants/src/crypto.rs
index ead2cc31837..0260ee578c8 100644
--- a/core/lib/constants/src/crypto.rs
+++ b/core/lib/constants/src/crypto.rs
@@ -3,8 +3,6 @@ pub const ZKPORTER_IS_AVAILABLE: bool = false;
/// Depth of the account tree.
pub const ROOT_TREE_DEPTH: usize = 256;
-pub const MAX_NEW_FACTORY_DEPS: usize = 32;
-
/// To avoid DDoS we limit the size of the transactions size.
/// TODO(X): remove this as a constant and introduce a config.
pub const MAX_ENCODED_TX_SIZE: usize = 1 << 24;
diff --git a/core/lib/contracts/src/lib.rs b/core/lib/contracts/src/lib.rs
index af9b5fe99f2..ce0c6231da2 100644
--- a/core/lib/contracts/src/lib.rs
+++ b/core/lib/contracts/src/lib.rs
@@ -38,6 +38,8 @@ const STATE_TRANSITION_CONTRACT_FILE: (&str, &str) = (
"state-transition",
"IChainTypeManager.sol/IChainTypeManager.json",
);
+const BYTECODE_SUPPLIER_CONTRACT_FILE: (&str, &str) =
+ ("upgrades", "BytecodesSupplier.sol/BytecodesSupplier.json");
const ZKSYNC_HYPERCHAIN_CONTRACT_FILE: (&str, &str) = (
"state-transition/chain-interfaces",
"IZKChain.sol/IZKChain.json",
@@ -157,6 +159,10 @@ pub fn state_transition_manager_contract() -> Contract {
load_contract_for_both_compilers(STATE_TRANSITION_CONTRACT_FILE)
}
+pub fn bytecode_supplier_contract() -> Contract {
+ load_contract_for_both_compilers(BYTECODE_SUPPLIER_CONTRACT_FILE)
+}
+
pub fn hyperchain_contract() -> Contract {
load_contract_for_both_compilers(ZKSYNC_HYPERCHAIN_CONTRACT_FILE)
}
@@ -209,13 +215,11 @@ pub fn l1_messenger_contract() -> Contract {
}
pub fn l2_message_root() -> Contract {
- load_contract(
- "contracts/l1-contracts/artifacts-zk/contracts/bridgehub/MessageRoot.sol/MessageRoot.json",
- )
+ load_contract("contracts/l1-contracts/zkout/MessageRoot.sol/MessageRoot.json")
}
pub fn l2_rollup_da_validator_bytecode() -> Vec {
- read_bytecode("contracts/l2-contracts/artifacts-zk/contracts/data-availability/RollupL2DAValidator.sol/RollupL2DAValidator.json")
+ read_bytecode("contracts/l2-contracts/zkout/RollupL2DAValidator.sol/RollupL2DAValidator.json")
}
/// Reads bytecode from the path RELATIVE to the Cargo workspace location.
@@ -326,21 +330,10 @@ pub fn read_bootloader_code(bootloader_type: &str) -> Vec {
{
return contract;
};
-
- let artifacts_path =
- Path::new(&home_path()).join("contracts/system-contracts/bootloader/build/artifacts");
- let bytecode_path = artifacts_path.join(format!("{bootloader_type}.yul.zbin"));
- if fs::exists(bytecode_path).unwrap_or_default() {
- read_yul_bytecode(
- "contracts/system-contracts/bootloader/build/artifacts",
- bootloader_type,
- )
- } else {
- read_yul_bytecode(
- "contracts/system-contracts/bootloader/tests/artifacts",
- bootloader_type,
- )
- }
+ read_yul_bytecode(
+ "contracts/system-contracts/bootloader/build/artifacts",
+ bootloader_type,
+ )
}
fn read_proved_batch_bootloader_bytecode() -> Vec {
@@ -540,10 +533,8 @@ impl BaseSystemContracts {
}
pub fn playground_gateway() -> Self {
- let bootloader_bytecode = read_zbin_bytecode(
- "contracts/system-contracts/bootloader/build/artifacts/playground_batch.yul.zbin",
- // "etc/multivm_bootloaders/vm_gateway/playground_batch.yul/playground_batch.yul.zbin",
- );
+ // TODO: the value should be taken from the `multivm_bootloaders` folder
+ let bootloader_bytecode = read_bootloader_code("playground_batch");
BaseSystemContracts::load_with_bootloader(bootloader_bytecode)
}
@@ -618,10 +609,8 @@ impl BaseSystemContracts {
}
pub fn estimate_gas_gateway() -> Self {
- let bootloader_bytecode = read_zbin_bytecode(
- "contracts/system-contracts/bootloader/build/artifacts/fee_estimate.yul.zbin",
- // "etc/multivm_bootloaders/vm_gateway/fee_estimate.yul/fee_estimate.yul.zbin",
- );
+ // TODO: the value should be taken from the `multivm_bootloaders` folder
+ let bootloader_bytecode = read_bootloader_code("fee_estimate");
BaseSystemContracts::load_with_bootloader(bootloader_bytecode)
}
diff --git a/core/lib/dal/src/factory_deps_dal.rs b/core/lib/dal/src/factory_deps_dal.rs
index 857e2973ae3..0ad5b9a7eab 100644
--- a/core/lib/dal/src/factory_deps_dal.rs
+++ b/core/lib/dal/src/factory_deps_dal.rs
@@ -3,10 +3,10 @@ use std::collections::{HashMap, HashSet};
use anyhow::Context as _;
use zksync_contracts::{BaseSystemContracts, SystemContractCode};
use zksync_db_connection::{connection::Connection, error::DalResult, instrument::InstrumentExt};
-use zksync_types::{L2BlockNumber, H256, U256};
-use zksync_utils::{bytes_to_be_words, bytes_to_chunks};
+use zksync_types::{L2BlockNumber, ProtocolVersionId, H256, U256};
+use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words, bytes_to_chunks};
-use crate::Core;
+use crate::{Core, CoreDal};
/// DAL methods related to factory dependencies.
#[derive(Debug)]
@@ -90,31 +90,26 @@ impl FactoryDepsDal<'_, '_> {
.map(|row| row.bytecode))
}
- pub async fn get_base_system_contracts(
+ pub async fn get_base_system_contracts_from_factory_deps(
&mut self,
bootloader_hash: H256,
default_aa_hash: H256,
evm_emulator_hash: Option,
- ) -> anyhow::Result {
+ ) -> anyhow::Result