diff --git a/core/bin/external_node/src/config/mod.rs b/core/bin/external_node/src/config/mod.rs
index d0249f7be5eb..ab780837ae06 100644
--- a/core/bin/external_node/src/config/mod.rs
+++ b/core/bin/external_node/src/config/mod.rs
@@ -13,14 +13,13 @@ use zksync_core::{
consensus,
temp_config_store::decode_yaml,
};
-use zksync_types::{api::BridgeAddresses, fee_model::FeeParams};
+use zksync_types::{api::BridgeAddresses, fee_model::FeeParams, ETHEREUM_ADDRESS};
use zksync_web3_decl::{
client::L2Client,
- error::ClientRpcContext,
+ error::{ClientRpcContext, Web3Error},
jsonrpsee::http_client::HttpClientBuilder,
namespaces::{EnNamespaceClient, EthNamespaceClient, ZksNamespaceClient},
};
-
pub(crate) mod observability;
#[cfg(test)]
mod tests;
@@ -43,6 +42,7 @@ pub(crate) struct RemoteENConfig {
pub l2_testnet_paymaster_addr: Option
,
pub l2_chain_id: L2ChainId,
pub l1_chain_id: L1ChainId,
+ pub base_token_addr: Address,
pub max_pubdata_per_batch: u64,
pub l1_batch_commit_data_generator_mode: L1BatchCommitDataGeneratorMode,
pub dummy_verifier: bool,
@@ -64,6 +64,22 @@ impl RemoteENConfig {
.get_main_contract()
.rpc_context("get_main_contract")
.await?;
+ let base_token_addr = match client.get_base_token_l1_address().await {
+ Err(ClientError::Call(err))
+ if [
+ ErrorCode::MethodNotFound.code(),
+ // This what Web3Error::NotImplemented gets
+ // casted into in the api server.
+ ErrorCode::InternalError.code(),
+ ]
+ .contains(&(err.code())) =>
+ {
+ // This is the fallback case for when the EN tries to interact
+ // with a node that does not implement the zks_baseTokenL1Address endpoint.
+ ETHEREUM_ADDRESS
+ }
+ response => response.context("Failed to fetch base token address")?,
+ };
let l2_chain_id = client.chain_id().rpc_context("chain_id").await?;
let l2_chain_id = L2ChainId::try_from(l2_chain_id.as_u64())
.map_err(|err| anyhow::anyhow!("invalid chain ID supplied by main node: {err}"))?;
@@ -101,6 +117,7 @@ impl RemoteENConfig {
l2_weth_bridge_addr: bridges.l2_weth_bridge,
l2_chain_id,
l1_chain_id,
+ base_token_addr,
max_pubdata_per_batch,
l1_batch_commit_data_generator_mode: genesis
.as_ref()
@@ -714,6 +731,7 @@ impl From for InternalApiConfig {
l2_testnet_paymaster_addr: config.remote.l2_testnet_paymaster_addr,
req_entities_limit: config.optional.req_entities_limit,
fee_history_limit: config.optional.fee_history_limit,
+ base_token_address: Some(config.remote.base_token_addr),
filters_disabled: config.optional.filters_disabled,
mempool_cache_update_interval: config.optional.mempool_cache_update_interval(),
mempool_cache_size: config.optional.mempool_cache_size,
diff --git a/core/lib/config/src/configs/contracts.rs b/core/lib/config/src/configs/contracts.rs
index 82ec4b1678b9..c3c4fce63b72 100644
--- a/core/lib/config/src/configs/contracts.rs
+++ b/core/lib/config/src/configs/contracts.rs
@@ -1,7 +1,7 @@
// External uses
use serde::Deserialize;
// Workspace uses
-use zksync_basic_types::Address;
+use zksync_basic_types::{Address, H256};
/// Data about deployed contracts.
#[derive(Debug, Deserialize, Clone, PartialEq)]
@@ -19,6 +19,7 @@ pub struct ContractsConfig {
pub l2_weth_bridge_addr: Option,
pub l2_testnet_paymaster_addr: Option,
pub l1_multicall3_addr: Address,
+ pub base_token_addr: Option
}
impl ContractsConfig {
@@ -37,6 +38,7 @@ impl ContractsConfig {
l2_testnet_paymaster_addr: Some(Address::repeat_byte(0x11)),
l1_multicall3_addr: Address::repeat_byte(0x12),
governance_addr: Address::repeat_byte(0x13),
+ base_token_addr: Some(Address::repeat_byte(0x14)),
}
}
}
diff --git a/core/lib/config/src/testonly.rs b/core/lib/config/src/testonly.rs
index b058fed9ae20..95a7f3982ae8 100644
--- a/core/lib/config/src/testonly.rs
+++ b/core/lib/config/src/testonly.rs
@@ -243,6 +243,7 @@ impl Distribution for EncodeDist {
l2_weth_bridge_addr: g.gen(),
l2_testnet_paymaster_addr: g.gen(),
l1_multicall3_addr: g.gen(),
+ base_token_addr: g.gen(),
}
}
}
diff --git a/core/lib/constants/src/contracts.rs b/core/lib/constants/src/contracts.rs
index 29072d906fdd..1fc43d65884a 100644
--- a/core/lib/constants/src/contracts.rs
+++ b/core/lib/constants/src/contracts.rs
@@ -121,6 +121,10 @@ pub const MINT_AND_BURN_ADDRESS: H160 = H160::zero();
// The `storage_log.value` database value for a contract that was deployed in a failed transaction.
pub const FAILED_CONTRACT_DEPLOYMENT_BYTECODE_HASH: H256 = H256::zero();
+pub const ETHEREUM_SHARED_BRIDGE_ADDRESS: Address = H160([
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x01,
+]);
// Default ERA_CHAIN_ID. All hyeprchains starts with this chain id and later on
// it will be changed to proper one
pub const DEFAULT_ERA_CHAIN_ID: u32 = 270;
diff --git a/core/lib/env_config/Cargo.toml b/core/lib/env_config/Cargo.toml
index 0de13c90b5a4..e63b33ecae2d 100644
--- a/core/lib/env_config/Cargo.toml
+++ b/core/lib/env_config/Cargo.toml
@@ -10,6 +10,7 @@ keywords.workspace = true
categories.workspace = true
[dependencies]
+zksync_system_constants.workspace = true
zksync_basic_types.workspace = true
zksync_config.workspace = true
diff --git a/core/lib/env_config/src/contracts.rs b/core/lib/env_config/src/contracts.rs
index edad9981f138..a90f84da5d45 100644
--- a/core/lib/env_config/src/contracts.rs
+++ b/core/lib/env_config/src/contracts.rs
@@ -10,6 +10,7 @@ impl FromEnv for ContractsConfig {
#[cfg(test)]
mod tests {
+ use zksync_system_constants::ETHEREUM_SHARED_BRIDGE_ADDRESS;
use super::*;
use crate::test_utils::{addr, EnvMutex};
@@ -30,6 +31,7 @@ mod tests {
l2_shared_bridge_addr: addr("8656770FA78c830456B00B4fFCeE6b1De0e1b888"),
l2_testnet_paymaster_addr: Some(addr("FC073319977e314F251EAE6ae6bE76B0B3BAeeCF")),
l1_multicall3_addr: addr("0xcA11bde05977b3631167028862bE2a173976CA11"),
+ base_token_addr: Some(ETHEREUM_SHARED_BRIDGE_ADDRESS)
}
}
@@ -66,6 +68,7 @@ CONTRACTS_FRI_RECURSION_NODE_LEVEL_VK_HASH="0x5a3ef282b21e12fe1f4438e5bb158fc506
CONTRACTS_FRI_RECURSION_LEAF_LEVEL_VK_HASH="0x72167c43a46cf38875b267d67716edc4563861364a3c03ab7aee73498421e828"
CONTRACTS_PROVER_AT_GENESIS="fri"
CONTRACTS_SNARK_WRAPPER_VK_HASH="0x4be443afd605a782b6e56d199df2460a025c81b3dea144e135bece83612563f2"
+CONTRACTS_BASE_TOKEN_ADDR=0x0000000000000000000000000000000000000001
CONTRACTS_BRIDGEHUB_PROXY_ADDR="0x35ea7f92f4c5f433efe15284e99c040110cf6297"
CONTRACTS_BRIDGEHUB_IMPL_ADDR="0x87d456da9ed212eb49d80d96afb44afddf36adf8"
CONTRACTS_STATE_TRANSITION_PROXY_ADDR="0xd90f1c081c6117241624e97cb6147257c3cb2097"
diff --git a/core/lib/protobuf_config/src/contracts.rs b/core/lib/protobuf_config/src/contracts.rs
index 67febfcc0803..418d28610d85 100644
--- a/core/lib/protobuf_config/src/contracts.rs
+++ b/core/lib/protobuf_config/src/contracts.rs
@@ -14,6 +14,7 @@ impl ProtoRepr for proto::Contracts {
let shared = required(&bridges.shared).context("shared")?;
let erc20 = required(&bridges.erc20).context("erc20")?;
let weth_bridge = required(&bridges.weth).context("weth_bridge")?;
+ // let base_token_address = &self.l2.
Ok(Self::Type {
governance_addr: required(&l1.governance_addr)
.and_then(|x| parse_h160(x))
@@ -69,6 +70,12 @@ impl ProtoRepr for proto::Contracts {
l1_multicall3_addr: required(&l1.multicall3_addr)
.and_then(|x| parse_h160(x))
.context("l1_multicall3_addr")?,
+ base_token_addr: self
+ .base_token_address
+ .as_ref()
+ .map(|x| parse_h160(x))
+ .transpose()
+ .context("base_token_addr")?,
})
}
diff --git a/core/lib/web3_decl/src/namespaces/zks.rs b/core/lib/web3_decl/src/namespaces/zks.rs
index 3086d2ba1420..b896b11430ca 100644
--- a/core/lib/web3_decl/src/namespaces/zks.rs
+++ b/core/lib/web3_decl/src/namespaces/zks.rs
@@ -118,4 +118,7 @@ pub trait ZksNamespace {
keys: Vec,
l1_batch_number: L1BatchNumber,
) -> RpcResult