use vm::TxExecutionMode;
use zksync_contracts::{
read_playground_batch_bootloader_bytecode, read_proved_batch_bootloader_bytecode,
read_sys_contract_bytecode, read_zbin_bytecode, BaseSystemContracts, ContractLanguage,
SystemContractCode,
};
use zksync_types::system_contracts::get_system_smart_contracts;
use zksync_utils::{bytecode::hash_bytecode, bytes_to_be_words};
use crate::deps::system_contracts::{bytecode_from_slice, COMPILED_IN_SYSTEM_CONTRACTS};
pub enum Options {
BuiltIn,
Local,
BuiltInWithoutSecurity,
}
#[derive(Debug, Clone)]
pub struct SystemContracts {
pub baseline_contracts: BaseSystemContracts,
pub playground_contracts: BaseSystemContracts,
pub fee_estimate_contracts: BaseSystemContracts,
}
pub fn get_deployed_contracts(options: &Options) -> Vec<zksync_types::block::DeployedContract> {
match options {
Options::BuiltIn | Options::BuiltInWithoutSecurity => COMPILED_IN_SYSTEM_CONTRACTS.clone(),
Options::Local => get_system_smart_contracts(),
}
}
impl Default for SystemContracts {
fn default() -> Self {
SystemContracts::from_options(&Options::BuiltIn)
}
}
impl SystemContracts {
pub fn from_options(options: &Options) -> Self {
Self {
baseline_contracts: baseline_contracts(options),
playground_contracts: playground(options),
fee_estimate_contracts: fee_estimate_contracts(options),
}
}
pub fn contracts_for_l2_call(&self) -> &BaseSystemContracts {
self.contracts(TxExecutionMode::EthCall)
}
pub fn contracts_for_fee_estimate(&self) -> &BaseSystemContracts {
self.contracts(TxExecutionMode::EstimateFee)
}
pub fn contracts(&self, execution_mode: TxExecutionMode) -> &BaseSystemContracts {
match execution_mode {
TxExecutionMode::VerifyExecute => &self.baseline_contracts,
TxExecutionMode::EstimateFee => &self.fee_estimate_contracts,
TxExecutionMode::EthCall => &self.playground_contracts,
}
}
}
fn bsc_load_with_bootloader(
bootloader_bytecode: Vec<u8>,
options: &Options,
) -> BaseSystemContracts {
let hash = hash_bytecode(&bootloader_bytecode);
let bootloader = SystemContractCode {
code: bytes_to_be_words(bootloader_bytecode),
hash,
};
let bytecode = match options {
Options::BuiltIn => bytecode_from_slice(
"DefaultAccount",
include_bytes!("deps/contracts/DefaultAccount.json"),
),
Options::Local => read_sys_contract_bytecode("", "DefaultAccount", ContractLanguage::Sol),
Options::BuiltInWithoutSecurity => bytecode_from_slice(
"DefaultAccountNoSecurity",
include_bytes!("deps/contracts/DefaultAccountNoSecurity.json"),
),
};
let hash = hash_bytecode(&bytecode);
let default_aa = SystemContractCode {
code: bytes_to_be_words(bytecode),
hash,
};
BaseSystemContracts {
bootloader,
default_aa,
}
}
pub fn playground(options: &Options) -> BaseSystemContracts {
let bootloader_bytecode = match options {
Options::BuiltIn | Options::BuiltInWithoutSecurity => {
include_bytes!("deps/contracts/playground_batch.yul.zbin").to_vec()
}
Options::Local => read_playground_batch_bootloader_bytecode(),
};
bsc_load_with_bootloader(bootloader_bytecode, options)
}
pub fn fee_estimate_contracts(options: &Options) -> BaseSystemContracts {
let bootloader_bytecode = match options {
Options::BuiltIn |
Options::BuiltInWithoutSecurity => {
include_bytes!("deps/contracts/fee_estimate.yul.zbin").to_vec()
}
Options::Local =>
read_zbin_bytecode("etc/system-contracts/bootloader/build/artifacts/fee_estimate.yul/fee_estimate.yul.zbin")
};
bsc_load_with_bootloader(bootloader_bytecode, options)
}
pub fn baseline_contracts(options: &Options) -> BaseSystemContracts {
let bootloader_bytecode = match options {
Options::BuiltIn | Options::BuiltInWithoutSecurity => {
include_bytes!("deps/contracts/proved_batch.yul.zbin").to_vec()
}
Options::Local => read_proved_batch_bootloader_bytecode(),
};
bsc_load_with_bootloader(bootloader_bytecode, options)
}