zksync_contracts/
lib.rs

1//! Set of utility functions to read contracts both in Yul and Sol format.
2//!
3//! Careful: some of the methods are reading the contracts based on the workspace environment variable.
4
5#![allow(clippy::derive_partial_eq_without_eq)]
6
7use std::{
8    fs::{self, File},
9    io::BufReader,
10    path::{Path, PathBuf},
11};
12
13use once_cell::sync::Lazy;
14use serde::{Deserialize, Serialize};
15use zksync_basic_types::{
16    bytecode::BytecodeHash,
17    ethabi::{Contract, Event, Function},
18    H256,
19};
20use zksync_utils::env::Workspace;
21
22mod serde_bytecode;
23#[cfg(test)]
24mod tests;
25
26#[derive(Debug, Clone)]
27pub enum ContractLanguage {
28    Sol,
29    Yul,
30}
31
32/// During the transition period we have to support both paths for contracts artifacts
33/// One for forge and another for hardhat.
34/// Meanwhile, hardhat has one more intermediate folder. That's why, we have to represent each contract
35/// by two constants, intermediate folder and actual contract name. For Forge we use only second part
36const HARDHAT_PATH_PREFIX: &str = "contracts/l1-contracts/artifacts/contracts";
37const FORGE_PATH_PREFIX: &str = "contracts/l1-contracts/out";
38
39const BRIDGEHUB_CONTRACT_FILE: (&str, &str) = ("bridgehub", "IBridgehub.sol/IBridgehub.json");
40const STATE_TRANSITION_CONTRACT_FILE: (&str, &str) = (
41    "state-transition",
42    "ChainTypeManager.sol/ChainTypeManager.json",
43);
44const BYTECODE_SUPPLIER_CONTRACT_FILE: (&str, &str) =
45    ("upgrades", "BytecodesSupplier.sol/BytecodesSupplier.json");
46const ZKSYNC_HYPERCHAIN_CONTRACT_FILE: (&str, &str) = (
47    "state-transition/chain-interfaces",
48    "IZKChain.sol/IZKChain.json",
49);
50const DIAMOND_INIT_CONTRACT_FILE: (&str, &str) = (
51    "state-transition",
52    "chain-interfaces/IDiamondInit.sol/IDiamondInit.json",
53);
54const GOVERNANCE_CONTRACT_FILE: (&str, &str) = ("governance", "IGovernance.sol/IGovernance.json");
55// TODO(EVM-924): We currently only support the "Ownable" chain admin.
56const CHAIN_ADMIN_CONTRACT_FILE: (&str, &str) = (
57    "governance",
58    "IChainAdminOwnable.sol/IChainAdminOwnable.json",
59);
60
61const SERVER_NOTIFIER_CONTRACT_FILE: (&str, &str) =
62    ("governance", "ServerNotifier.sol/ServerNotifier.json");
63
64const GETTERS_FACET_CONTRACT_FILE: (&str, &str) = (
65    "state-transition/chain-interfaces",
66    "IGetters.sol/IGetters.json",
67);
68
69const MULTICALL3_CONTRACT_FILE: (&str, &str) = ("dev-contracts", "Multicall3.sol/Multicall3.json");
70const L1_ASSET_ROUTER_FILE: (&str, &str) = (
71    "bridge/asset-router",
72    "L1AssetRouter.sol/L1AssetRouter.json",
73);
74const L2_WRAPPED_BASE_TOKEN_STORE: (&str, &str) = (
75    "bridge",
76    "L2WrappedBaseTokenStore.sol/L2WrappedBaseTokenStore.json",
77);
78
79const VERIFIER_CONTRACT_FILE: (&str, &str) = ("state-transition", "Verifier.sol/Verifier.json");
80const DUAL_VERIFIER_CONTRACT_FILE: (&str, &str) = (
81    "state-transition/verifiers",
82    "DualVerifier.sol/DualVerifier.json",
83);
84
85const _IERC20_CONTRACT_FILE: &str =
86    "contracts/l1-contracts/artifacts/contracts/common/interfaces/IERC20.sol/IERC20.json";
87const _FAIL_ON_RECEIVE_CONTRACT_FILE: &str =
88    "contracts/l1-contracts/artifacts/contracts/zksync/dev-contracts/FailOnReceive.sol/FailOnReceive.json";
89
90fn home_path() -> PathBuf {
91    Workspace::locate().root()
92}
93
94fn read_file_to_json_value(path: impl AsRef<Path> + std::fmt::Debug) -> Option<serde_json::Value> {
95    let zksync_home = home_path();
96    let path = Path::new(&zksync_home).join(path);
97    let file = File::open(&path).ok()?;
98    Some(
99        serde_json::from_reader(BufReader::new(file))
100            .unwrap_or_else(|e| panic!("Failed to parse file {:?}: {}", path, e)),
101    )
102}
103
104fn load_contract_if_present<P: AsRef<Path> + std::fmt::Debug>(path: P) -> Option<Contract> {
105    let zksync_home = home_path();
106    let path = Path::new(&zksync_home).join(path);
107    path.exists().then(|| {
108        serde_json::from_value(read_file_to_json_value(&path).unwrap()["abi"].take())
109            .unwrap_or_else(|e| panic!("Failed to parse contract abi from file {:?}: {}", path, e))
110    })
111}
112
113fn load_contract_for_hardhat(path: (&str, &str)) -> Option<Contract> {
114    let path = Path::new(HARDHAT_PATH_PREFIX).join(path.0).join(path.1);
115    load_contract_if_present(path)
116}
117
118fn load_contract_for_forge(file_path: &str) -> Option<Contract> {
119    let path = Path::new(FORGE_PATH_PREFIX).join(file_path);
120    load_contract_if_present(path)
121}
122
123fn load_contract_for_both_compilers(path: (&str, &str)) -> Contract {
124    if let Some(contract) = load_contract_for_forge(path.1) {
125        return contract;
126    };
127
128    load_contract_for_hardhat(path).unwrap_or_else(|| {
129        panic!("Failed to load contract from {:?}", path);
130    })
131}
132
133pub fn load_contract<P: AsRef<Path> + std::fmt::Debug>(path: P) -> Contract {
134    load_contract_if_present(&path).unwrap_or_else(|| {
135        panic!("Failed to load contract from {:?}", path);
136    })
137}
138
139pub fn load_sys_contract(contract_name: &str) -> Contract {
140    if let Some(contract) = load_contract_if_present(format!(
141        "contracts/system-contracts/artifacts-zk/contracts-preprocessed/{0}.sol/{0}.json",
142        contract_name
143    )) {
144        contract
145    } else {
146        load_contract(format!(
147            "contracts/system-contracts/zkout/{0}.sol/{0}.json",
148            contract_name
149        ))
150    }
151}
152
153pub fn read_contract_abi(path: impl AsRef<Path> + std::fmt::Debug) -> Option<String> {
154    Some(
155        read_file_to_json_value(path)?["abi"]
156            .as_str()
157            .expect("Failed to parse abi")
158            .to_string(),
159    )
160}
161
162pub fn bridgehub_contract() -> Contract {
163    load_contract_for_both_compilers(BRIDGEHUB_CONTRACT_FILE)
164}
165
166pub fn governance_contract() -> Contract {
167    load_contract_for_both_compilers(GOVERNANCE_CONTRACT_FILE)
168}
169
170pub fn chain_admin_contract() -> Contract {
171    load_contract_for_both_compilers(CHAIN_ADMIN_CONTRACT_FILE)
172}
173
174pub fn server_notifier_contract() -> Contract {
175    load_contract_for_both_compilers(SERVER_NOTIFIER_CONTRACT_FILE)
176}
177
178pub fn getters_facet_contract() -> Contract {
179    load_contract_for_both_compilers(GETTERS_FACET_CONTRACT_FILE)
180}
181
182pub fn state_transition_manager_contract() -> Contract {
183    load_contract_for_both_compilers(STATE_TRANSITION_CONTRACT_FILE)
184}
185
186pub fn bytecode_supplier_contract() -> Contract {
187    load_contract_for_both_compilers(BYTECODE_SUPPLIER_CONTRACT_FILE)
188}
189
190pub fn hyperchain_contract() -> Contract {
191    load_contract_for_both_compilers(ZKSYNC_HYPERCHAIN_CONTRACT_FILE)
192}
193
194pub fn diamond_init_contract() -> Contract {
195    load_contract_for_both_compilers(DIAMOND_INIT_CONTRACT_FILE)
196}
197
198pub fn multicall_contract() -> Contract {
199    load_contract_for_both_compilers(MULTICALL3_CONTRACT_FILE)
200}
201
202pub fn l1_asset_router_contract() -> Contract {
203    load_contract_for_both_compilers(L1_ASSET_ROUTER_FILE)
204}
205
206pub fn wrapped_base_token_store_contract() -> Contract {
207    load_contract_for_both_compilers(L2_WRAPPED_BASE_TOKEN_STORE)
208}
209
210pub fn verifier_contract() -> Contract {
211    let path = format!("{}/{}", FORGE_PATH_PREFIX, DUAL_VERIFIER_CONTRACT_FILE.1);
212    let zksync_home = home_path();
213    let path = Path::new(&zksync_home).join(path);
214
215    if path.exists() {
216        load_contract_for_both_compilers(DUAL_VERIFIER_CONTRACT_FILE)
217    } else {
218        load_contract_for_both_compilers(VERIFIER_CONTRACT_FILE)
219    }
220}
221
222pub fn deployer_contract() -> Contract {
223    load_sys_contract("ContractDeployer")
224}
225
226pub fn l1_messenger_contract() -> Contract {
227    load_sys_contract("L1Messenger")
228}
229
230pub fn l2_message_root() -> Contract {
231    load_l1_zk_contract("MessageRoot")
232}
233
234pub fn l2_asset_router() -> Contract {
235    load_l1_zk_contract("L2AssetRouter")
236}
237
238pub fn l2_native_token_vault() -> Contract {
239    load_l1_zk_contract("L2NativeTokenVault")
240}
241
242pub fn l2_legacy_shared_bridge() -> Contract {
243    load_l1_zk_contract("L2SharedBridgeLegacy")
244}
245
246pub fn l2_rollup_da_validator_bytecode() -> Vec<u8> {
247    read_bytecode("contracts/l2-contracts/zkout/RollupL2DAValidator.sol/RollupL2DAValidator.json")
248}
249
250pub fn read_l1_zk_contract(name: &str) -> Vec<u8> {
251    read_bytecode(format!(
252        "contracts/l1-contracts/zkout/{name}.sol/{name}.json"
253    ))
254}
255
256pub fn load_l1_zk_contract(name: &str) -> Contract {
257    load_contract(format!(
258        "contracts/l1-contracts/zkout/{name}.sol/{name}.json"
259    ))
260}
261
262/// Reads bytecode from the path RELATIVE to the Cargo workspace location.
263pub fn read_bytecode(relative_path: impl AsRef<Path> + std::fmt::Debug) -> Vec<u8> {
264    read_bytecode_from_path(relative_path).expect("Failed to open file")
265}
266
267pub fn eth_contract() -> Contract {
268    load_sys_contract("L2BaseToken")
269}
270
271pub fn known_codes_contract() -> Contract {
272    load_sys_contract("KnownCodesStorage")
273}
274
275/// Reads bytecode from a given path.
276pub fn read_bytecode_from_path(
277    artifact_path: impl AsRef<Path> + std::fmt::Debug,
278) -> Option<Vec<u8>> {
279    let artifact = read_file_to_json_value(&artifact_path)?;
280
281    let bytecode = artifact["bytecode"]
282        .as_str()
283        .or_else(|| artifact["bytecode"]["object"].as_str())
284        .unwrap_or_else(|| panic!("Bytecode not found in {:?}", artifact_path));
285    // Strip an optional `0x` prefix.
286    let bytecode = bytecode.strip_prefix("0x").unwrap_or(bytecode);
287    Some(
288        hex::decode(bytecode)
289            .unwrap_or_else(|err| panic!("Can't decode bytecode in {:?}: {}", artifact_path, err)),
290    )
291}
292
293pub fn read_deployed_bytecode_from_path(artifact_path: &Path) -> Option<Vec<u8>> {
294    let artifact = read_file_to_json_value(artifact_path)?;
295    let bytecode = artifact["deployedBytecode"]
296        .as_str()
297        .or_else(|| artifact["deployedBytecode"]["object"].as_str())
298        .unwrap_or_else(|| panic!("Deployed bytecode not found in {:?}", artifact_path));
299    // Strip an optional `0x` prefix.
300    let bytecode = bytecode.strip_prefix("0x").unwrap_or(bytecode);
301    Some(
302        hex::decode(bytecode)
303            .unwrap_or_else(|err| panic!("Can't decode bytecode in {:?}: {}", artifact_path, err)),
304    )
305}
306
307pub fn read_sys_contract_bytecode(directory: &str, name: &str, lang: ContractLanguage) -> Vec<u8> {
308    DEFAULT_SYSTEM_CONTRACTS_REPO.read_sys_contract_bytecode(directory, name, None, lang)
309}
310
311static DEFAULT_SYSTEM_CONTRACTS_REPO: Lazy<SystemContractsRepo> =
312    Lazy::new(SystemContractsRepo::default);
313
314/// Structure representing a system contract repository.
315///
316/// It allows to fetch contracts that are located there.
317/// As most of the static methods in this file, is loading data based on the Cargo workspace location.
318pub struct SystemContractsRepo {
319    // Path to the root of the system contracts repository.
320    pub root: PathBuf,
321}
322
323impl Default for SystemContractsRepo {
324    /// Returns the default system contracts repository with directory based on the Cargo workspace location.
325    fn default() -> Self {
326        SystemContractsRepo {
327            root: home_path().join("contracts/system-contracts"),
328        }
329    }
330}
331
332impl SystemContractsRepo {
333    pub fn read_sys_contract_bytecode(
334        &self,
335        directory: &str,
336        name: &str,
337        object_name: Option<&str>,
338        lang: ContractLanguage,
339    ) -> Vec<u8> {
340        match lang {
341            ContractLanguage::Sol => {
342                let possible_paths = [
343                    self.root
344                        .join(format!("zkout/{0}{1}.sol/{1}.json", directory, name)),
345                    self.root.join(format!(
346                        "artifacts-zk/contracts-preprocessed/{0}{1}.sol/{1}.json",
347                        directory, name
348                    )),
349                ];
350                for path in &possible_paths {
351                    if let Some(contracts) = read_bytecode_from_path(path) {
352                        return contracts;
353                    }
354                }
355                panic!("One of the outputs should exist for {directory}{name}. Checked paths: {possible_paths:?}");
356            }
357            ContractLanguage::Yul => {
358                // TODO: Newer versions of foundry-zksync no longer use directory for yul contracts, but we cannot
359                // easily get rid of the old lookup, because old foundry-zksync is compiled into `zk_environment`
360                // image. Once `foundry-zksync` is updated to at least 0.0.4, we can remove folder names from the
361                // `SYSTEM_CONTRACT_LIST` for yul contracts and merge two lookups below.
362                // in foundry-zksync starting from 0.0.8 json file name corresponds to the object inside the yul component
363                let object_name = object_name.unwrap_or(name);
364                let possible_paths = [
365                    self.root.join(format!("zkout/{0}.yul/{0}.json", name)),
366                    self.root
367                        .join(format!("zkout/{0}{1}.yul/{1}.json", directory, name)),
368                    self.root.join(format!(
369                        "zkout/{name}.yul/contracts-preprocessed/{directory}/{name}.yul.json",
370                    )),
371                    self.root
372                        .join(format!("zkout/{name}.yul/{object_name}.json",)),
373                    self.root.join(format!(
374                        "zkout/{name}.yul/contracts-preprocessed/{name}.yul.json",
375                    )),
376                ];
377
378                for path in &possible_paths {
379                    if let Some(contracts) = read_bytecode_from_path(path) {
380                        return contracts;
381                    }
382                }
383
384                // Fallback for very old versions.
385                let artifacts_path = self
386                    .root
387                    .join(format!("contracts-preprocessed/{directory}artifacts"));
388
389                let bytecode_path = artifacts_path.join(format!("{name}.yul/{name}.yul.zbin"));
390                // Legacy versions of zksolc use the following path for output data if a yul file is being compiled: <name>.yul.zbin
391                // New zksolc versions use <name>.yul/<name>.yul.zbin, for consistency with solidity files compilation.
392                // In addition, the output of the legacy zksolc in this case is a binary file, while in new versions it is hex encoded.
393                if fs::exists(&bytecode_path)
394                    .unwrap_or_else(|err| panic!("Invalid path: {bytecode_path:?}, {err}"))
395                {
396                    read_zbin_bytecode_from_hex_file(bytecode_path)
397                } else {
398                    let bytecode_path_legacy = artifacts_path.join(format!("{name}.yul.zbin"));
399
400                    if fs::exists(&bytecode_path_legacy).unwrap_or_else(|err| {
401                        panic!("Invalid path: {bytecode_path_legacy:?}, {err}")
402                    }) {
403                        read_zbin_bytecode_from_path(bytecode_path_legacy)
404                    } else {
405                        panic!(
406                            "Can't find bytecode for '{name}' yul contract at {artifacts_path:?} or {possible_paths:?}"
407                        )
408                    }
409                }
410            }
411        }
412    }
413}
414
415pub fn read_bootloader_code(bootloader_type: &str) -> Vec<u8> {
416    DEFAULT_SYSTEM_CONTRACTS_REPO.read_sys_contract_bytecode(
417        "bootloader",
418        bootloader_type,
419        Some("Bootloader"),
420        ContractLanguage::Yul,
421    )
422}
423
424/// Reads zbin bytecode from a given path, relative to workspace location.
425pub fn read_zbin_bytecode(relative_zbin_path: impl AsRef<Path>) -> Vec<u8> {
426    let bytecode_path = Path::new(&home_path()).join(relative_zbin_path);
427    read_zbin_bytecode_from_path(bytecode_path)
428}
429
430/// Reads zbin bytecode from a given path.
431fn read_zbin_bytecode_from_path(bytecode_path: PathBuf) -> Vec<u8> {
432    fs::read(&bytecode_path)
433        .unwrap_or_else(|err| panic!("Can't read .zbin bytecode at {bytecode_path:?}: {err}"))
434}
435
436/// Reads zbin bytecode from a given path as utf8 text file.
437fn read_zbin_bytecode_from_hex_file(bytecode_path: PathBuf) -> Vec<u8> {
438    let bytes = fs::read(&bytecode_path)
439        .unwrap_or_else(|err| panic!("Can't read .zbin bytecode at {bytecode_path:?}: {err}"));
440
441    hex::decode(bytes).unwrap_or_else(|err| panic!("Invalid input file: {bytecode_path:?}, {err}"))
442}
443
444/// Hash of code and code which consists of 32 bytes words
445#[derive(Debug, Clone, Serialize, Deserialize)]
446pub struct SystemContractCode {
447    #[serde(with = "serde_bytecode")]
448    pub code: Vec<u8>,
449    pub hash: H256,
450}
451
452#[derive(Debug, Clone, Serialize, Deserialize)]
453pub struct BaseSystemContracts {
454    pub bootloader: SystemContractCode,
455    pub default_aa: SystemContractCode,
456    pub evm_emulator: Option<SystemContractCode>,
457}
458
459#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq)]
460pub struct BaseSystemContractsHashes {
461    pub bootloader: H256,
462    pub default_aa: H256,
463    /// Optional for backward compatibility reasons. Having a hash present doesn't mean that EVM emulation is enabled for the network.
464    pub evm_emulator: Option<H256>,
465}
466
467impl PartialEq for BaseSystemContracts {
468    fn eq(&self, other: &Self) -> bool {
469        self.bootloader.hash == other.bootloader.hash
470            && self.default_aa.hash == other.default_aa.hash
471            && self.evm_emulator.as_ref().map(|contract| contract.hash)
472                == other.evm_emulator.as_ref().map(|contract| contract.hash)
473    }
474}
475
476impl BaseSystemContracts {
477    fn load_with_bootloader(bootloader_bytecode: Vec<u8>, load_evm_emulator: bool) -> Self {
478        let hash = BytecodeHash::for_bytecode(&bootloader_bytecode).value();
479        let bootloader = SystemContractCode {
480            code: bootloader_bytecode,
481            hash,
482        };
483
484        // `DefaultAccount` is not versioned.
485        let bytecode = read_sys_contract_bytecode("", "DefaultAccount", ContractLanguage::Sol);
486        let hash = BytecodeHash::for_bytecode(&bytecode).value();
487        let default_aa = SystemContractCode {
488            code: bytecode,
489            hash,
490        };
491
492        // EVM emulator is not versioned either. It is only accessed for protocol versions >=27.
493        let evm_emulator = load_evm_emulator.then(|| {
494            let bytecode = read_sys_contract_bytecode("", "EvmEmulator", ContractLanguage::Yul);
495            let hash = BytecodeHash::for_bytecode(&bytecode).value();
496            SystemContractCode {
497                code: bytecode,
498                hash,
499            }
500        });
501
502        BaseSystemContracts {
503            bootloader,
504            default_aa,
505            evm_emulator,
506        }
507    }
508
509    /// BaseSystemContracts with proved bootloader - for handling transactions.
510    pub fn load_from_disk() -> Self {
511        let bootloader_bytecode = read_bootloader_code("proved_batch");
512        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, true)
513    }
514
515    /// BaseSystemContracts with playground bootloader - used for handling eth_calls.
516    pub fn playground() -> Self {
517        let bootloader_bytecode = read_bootloader_code("playground_batch");
518        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, true)
519    }
520
521    pub fn playground_pre_virtual_blocks() -> Self {
522        let bootloader_bytecode = read_zbin_bytecode(
523            "etc/multivm_bootloaders/vm_1_3_2/playground_block.yul/playground_block.yul.zbin",
524        );
525        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, false)
526    }
527
528    pub fn playground_post_virtual_blocks() -> Self {
529        let bootloader_bytecode = read_zbin_bytecode("etc/multivm_bootloaders/vm_virtual_blocks/playground_batch.yul/playground_batch.yul.zbin");
530        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, false)
531    }
532
533    pub fn playground_post_virtual_blocks_finish_upgrade_fix() -> Self {
534        let bootloader_bytecode = read_zbin_bytecode("etc/multivm_bootloaders/vm_virtual_blocks_finish_upgrade_fix/playground_batch.yul/playground_batch.yul.zbin");
535        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, false)
536    }
537
538    pub fn playground_post_boojum() -> Self {
539        let bootloader_bytecode = read_zbin_bytecode("etc/multivm_bootloaders/vm_boojum_integration/playground_batch.yul/playground_batch.yul.zbin");
540        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, false)
541    }
542
543    pub fn playground_post_allowlist_removal() -> Self {
544        let bootloader_bytecode = read_zbin_bytecode("etc/multivm_bootloaders/vm_remove_allowlist/playground_batch.yul/playground_batch.yul.zbin");
545        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, false)
546    }
547
548    pub fn playground_post_1_4_1() -> Self {
549        let bootloader_bytecode = read_zbin_bytecode(
550            "etc/multivm_bootloaders/vm_1_4_1/playground_batch.yul/playground_batch.yul.zbin",
551        );
552        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, false)
553    }
554
555    pub fn playground_post_1_4_2() -> Self {
556        let bootloader_bytecode = read_zbin_bytecode(
557            "etc/multivm_bootloaders/vm_1_4_2/playground_batch.yul/playground_batch.yul.zbin",
558        );
559        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, false)
560    }
561
562    pub fn playground_1_5_0_small_memory() -> Self {
563        let bootloader_bytecode = read_zbin_bytecode(
564            "etc/multivm_bootloaders/vm_1_5_0_small_memory/playground_batch.yul/playground_batch.yul.zbin",
565        );
566        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, false)
567    }
568
569    pub fn playground_post_1_5_0_increased_memory() -> Self {
570        let bootloader_bytecode = read_zbin_bytecode(
571            "etc/multivm_bootloaders/vm_1_5_0_increased_memory/playground_batch.yul/playground_batch.yul.zbin",
572        );
573        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, false)
574    }
575
576    pub fn playground_post_protocol_defense() -> Self {
577        let bootloader_bytecode = read_zbin_bytecode(
578            "etc/multivm_bootloaders/vm_protocol_defense/playground_batch.yul/playground_batch.yul.zbin",
579        );
580        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, false)
581    }
582
583    pub fn playground_gateway() -> Self {
584        let bootloader_bytecode = read_zbin_bytecode(
585            "etc/multivm_bootloaders/vm_gateway/playground_batch.yul/playground_batch.yul.zbin",
586        );
587        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, false)
588    }
589
590    pub fn playground_evm_emulator() -> Self {
591        let bootloader_bytecode = read_zbin_bytecode(
592        "etc/multivm_bootloaders/vm_evm_emulator/playground_batch.yul/playground_batch.yul.zbin",
593        );
594
595        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, true)
596    }
597
598    pub fn playground_precompiles() -> Self {
599        let bootloader_bytecode = read_zbin_bytecode(
600            "etc/multivm_bootloaders/vm_precompiles/playground_batch.yul/Bootloader.zbin",
601        );
602
603        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, true)
604    }
605
606    pub fn estimate_gas_pre_virtual_blocks() -> Self {
607        let bootloader_bytecode = read_zbin_bytecode(
608            "etc/multivm_bootloaders/vm_1_3_2/fee_estimate.yul/fee_estimate.yul.zbin",
609        );
610        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, false)
611    }
612
613    pub fn estimate_gas_post_virtual_blocks() -> Self {
614        let bootloader_bytecode = read_zbin_bytecode(
615            "etc/multivm_bootloaders/vm_virtual_blocks/fee_estimate.yul/fee_estimate.yul.zbin",
616        );
617        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, false)
618    }
619
620    pub fn estimate_gas_post_virtual_blocks_finish_upgrade_fix() -> Self {
621        let bootloader_bytecode = read_zbin_bytecode(
622            "etc/multivm_bootloaders/vm_virtual_blocks_finish_upgrade_fix/fee_estimate.yul/fee_estimate.yul.zbin",
623        );
624        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, false)
625    }
626
627    pub fn estimate_gas_post_boojum() -> Self {
628        let bootloader_bytecode = read_zbin_bytecode(
629            "etc/multivm_bootloaders/vm_boojum_integration/fee_estimate.yul/fee_estimate.yul.zbin",
630        );
631        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, false)
632    }
633
634    pub fn estimate_gas_post_allowlist_removal() -> Self {
635        let bootloader_bytecode = read_zbin_bytecode(
636            "etc/multivm_bootloaders/vm_remove_allowlist/fee_estimate.yul/fee_estimate.yul.zbin",
637        );
638        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, false)
639    }
640
641    pub fn estimate_gas_post_1_4_1() -> Self {
642        let bootloader_bytecode = read_zbin_bytecode(
643            "etc/multivm_bootloaders/vm_1_4_1/fee_estimate.yul/fee_estimate.yul.zbin",
644        );
645        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, false)
646    }
647
648    pub fn estimate_gas_post_1_4_2() -> Self {
649        let bootloader_bytecode = read_zbin_bytecode(
650            "etc/multivm_bootloaders/vm_1_4_2/fee_estimate.yul/fee_estimate.yul.zbin",
651        );
652        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, false)
653    }
654
655    pub fn estimate_gas_1_5_0_small_memory() -> Self {
656        let bootloader_bytecode = read_zbin_bytecode(
657            "etc/multivm_bootloaders/vm_1_5_0_small_memory/fee_estimate.yul/fee_estimate.yul.zbin",
658        );
659        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, false)
660    }
661
662    pub fn estimate_gas_post_1_5_0_increased_memory() -> Self {
663        let bootloader_bytecode = read_zbin_bytecode(
664            "etc/multivm_bootloaders/vm_1_5_0_increased_memory/fee_estimate.yul/fee_estimate.yul.zbin",
665        );
666        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, false)
667    }
668
669    pub fn estimate_gas_post_protocol_defense() -> Self {
670        let bootloader_bytecode = read_zbin_bytecode(
671            "etc/multivm_bootloaders/vm_protocol_defense/fee_estimate.yul/fee_estimate.yul.zbin",
672        );
673        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, false)
674    }
675
676    pub fn estimate_gas_gateway() -> Self {
677        let bootloader_bytecode = read_zbin_bytecode(
678            "etc/multivm_bootloaders/vm_gateway/fee_estimate.yul/fee_estimate.yul.zbin",
679        );
680        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, false)
681    }
682
683    pub fn estimate_gas_evm_emulator() -> Self {
684        let bootloader_bytecode = read_zbin_bytecode(
685            "etc/multivm_bootloaders/vm_evm_emulator/fee_estimate.yul/fee_estimate.yul.zbin",
686        );
687        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, true)
688    }
689
690    pub fn estimate_gas_precompiles() -> Self {
691        let bootloader_bytecode = read_zbin_bytecode(
692            "etc/multivm_bootloaders/vm_precompiles/fee_estimate.yul/Bootloader.zbin",
693        );
694        BaseSystemContracts::load_with_bootloader(bootloader_bytecode, true)
695    }
696
697    pub fn hashes(&self) -> BaseSystemContractsHashes {
698        BaseSystemContractsHashes {
699            bootloader: self.bootloader.hash,
700            default_aa: self.default_aa.hash,
701            evm_emulator: self.evm_emulator.as_ref().map(|contract| contract.hash),
702        }
703    }
704}
705
706pub static PRE_BOOJUM_COMMIT_FUNCTION: Lazy<Function> = Lazy::new(|| {
707    let abi = r#"
708    {
709      "inputs": [
710        {
711          "components": [
712            {
713              "internalType": "uint64",
714              "name": "blockNumber",
715              "type": "uint64"
716            },
717            {
718              "internalType": "bytes32",
719              "name": "blockHash",
720              "type": "bytes32"
721            },
722            {
723              "internalType": "uint64",
724              "name": "indexRepeatedStorageChanges",
725              "type": "uint64"
726            },
727            {
728              "internalType": "uint256",
729              "name": "numberOfLayer1Txs",
730              "type": "uint256"
731            },
732            {
733              "internalType": "bytes32",
734              "name": "priorityOperationsHash",
735              "type": "bytes32"
736            },
737            {
738              "internalType": "bytes32",
739              "name": "l2LogsTreeRoot",
740              "type": "bytes32"
741            },
742            {
743              "internalType": "uint256",
744              "name": "timestamp",
745              "type": "uint256"
746            },
747            {
748              "internalType": "bytes32",
749              "name": "commitment",
750              "type": "bytes32"
751            }
752          ],
753          "internalType": "struct IExecutor.StoredBlockInfo",
754          "name": "_lastCommittedBlockData",
755          "type": "tuple"
756        },
757        {
758          "components": [
759            {
760              "internalType": "uint64",
761              "name": "blockNumber",
762              "type": "uint64"
763            },
764            {
765              "internalType": "uint64",
766              "name": "timestamp",
767              "type": "uint64"
768            },
769            {
770              "internalType": "uint64",
771              "name": "indexRepeatedStorageChanges",
772              "type": "uint64"
773            },
774            {
775              "internalType": "bytes32",
776              "name": "newStateRoot",
777              "type": "bytes32"
778            },
779            {
780              "internalType": "uint256",
781              "name": "numberOfLayer1Txs",
782              "type": "uint256"
783            },
784            {
785              "internalType": "bytes32",
786              "name": "l2LogsTreeRoot",
787              "type": "bytes32"
788            },
789            {
790              "internalType": "bytes32",
791              "name": "priorityOperationsHash",
792              "type": "bytes32"
793            },
794            {
795              "internalType": "bytes",
796              "name": "initialStorageChanges",
797              "type": "bytes"
798            },
799            {
800              "internalType": "bytes",
801              "name": "repeatedStorageChanges",
802              "type": "bytes"
803            },
804            {
805              "internalType": "bytes",
806              "name": "l2Logs",
807              "type": "bytes"
808            },
809            {
810              "internalType": "bytes[]",
811              "name": "l2ArbitraryLengthMessages",
812              "type": "bytes[]"
813            },
814            {
815              "internalType": "bytes[]",
816              "name": "factoryDeps",
817              "type": "bytes[]"
818            }
819          ],
820          "internalType": "struct IExecutor.CommitBlockInfo[]",
821          "name": "_newBlocksData",
822          "type": "tuple[]"
823        }
824      ],
825      "name": "commitBlocks",
826      "outputs": [],
827      "stateMutability": "nonpayable",
828      "type": "function"
829    }"#;
830    serde_json::from_str(abi).unwrap()
831});
832
833pub static GENESIS_UPGRADE_EVENT: Lazy<Event> = Lazy::new(|| {
834    let abi = r#"
835    {
836      "anonymous": false,
837      "inputs": [
838        {
839          "indexed": true,
840          "name": "_hyperchain",
841          "type": "address"
842        },
843        {
844          "components": [
845            {
846              "name": "txType",
847              "type": "uint256"
848            },
849            {
850              "name": "from",
851              "type": "uint256"
852            },
853            {
854              "name": "to",
855              "type": "uint256"
856            },
857            {
858              "name": "gasLimit",
859              "type": "uint256"
860            },
861            {
862              "name": "gasPerPubdataByteLimit",
863              "type": "uint256"
864            },
865            {
866              "name": "maxFeePerGas",
867              "type": "uint256"
868            },
869            {
870              "name": "maxPriorityFeePerGas",
871              "type": "uint256"
872            },
873            {
874              "name": "paymaster",
875              "type": "uint256"
876            },
877            {
878              "name": "nonce",
879              "type": "uint256"
880            },
881            {
882              "name": "value",
883              "type": "uint256"
884            },
885            {
886              "name": "reserved",
887              "type": "uint256[4]"
888            },
889            {
890              "name": "data",
891              "type": "bytes"
892            },
893            {
894              "name": "signature",
895              "type": "bytes"
896            },
897            {
898              "name": "factoryDeps",
899              "type": "uint256[]"
900            },
901            {
902              "name": "paymasterInput",
903              "type": "bytes"
904            },
905            {
906              "name": "reservedDynamic",
907              "type": "bytes"
908            }
909          ],
910          "indexed": false,
911          "name": "_l2Transaction",
912          "type": "tuple"
913        },
914        {
915          "indexed": true,
916          "name": "_protocolVersion",
917          "type": "uint256"
918        },
919        {
920          "indexed": false,
921          "name": "_factoryDeps",
922          "type": "bytes[]"
923        }
924      ],
925      "name": "GenesisUpgrade",
926      "type": "event"
927    }"#;
928    serde_json::from_str(abi).unwrap()
929});
930
931// The function that was used in the pre-v23 versions of the contract to upgrade the diamond proxy.
932pub static ADMIN_EXECUTE_UPGRADE_FUNCTION: Lazy<Function> = Lazy::new(|| {
933    let abi = r#"
934    {
935        "inputs": [
936          {
937            "components": [
938              {
939                "components": [
940                  {
941                    "internalType": "address",
942                    "name": "facet",
943                    "type": "address"
944                  },
945                  {
946                    "internalType": "enum Diamond.Action",
947                    "name": "action",
948                    "type": "uint8"
949                  },
950                  {
951                    "internalType": "bool",
952                    "name": "isFreezable",
953                    "type": "bool"
954                  },
955                  {
956                    "internalType": "bytes4[]",
957                    "name": "selectors",
958                    "type": "bytes4[]"
959                  }
960                ],
961                "internalType": "struct Diamond.FacetCut[]",
962                "name": "facetCuts",
963                "type": "tuple[]"
964              },
965              {
966                "internalType": "address",
967                "name": "initAddress",
968                "type": "address"
969              },
970              {
971                "internalType": "bytes",
972                "name": "initCalldata",
973                "type": "bytes"
974              }
975            ],
976            "internalType": "struct Diamond.DiamondCutData",
977            "name": "_diamondCut",
978            "type": "tuple"
979          }
980        ],
981        "name": "executeUpgrade",
982        "outputs": [],
983        "stateMutability": "nonpayable",
984        "type": "function"
985    }"#;
986    serde_json::from_str(abi).unwrap()
987});
988
989// The function that is used in post-v23 chains to upgrade the chain
990pub static ADMIN_UPGRADE_CHAIN_FROM_VERSION_FUNCTION: Lazy<Function> = Lazy::new(|| {
991    let abi = r#"
992    {
993        "inputs": [
994          {
995            "internalType": "uint256",
996            "name": "_oldProtocolVersion",
997            "type": "uint256"
998          },
999          {
1000            "components": [
1001              {
1002                "components": [
1003                  {
1004                    "internalType": "address",
1005                    "name": "facet",
1006                    "type": "address"
1007                  },
1008                  {
1009                    "internalType": "enum Diamond.Action",
1010                    "name": "action",
1011                    "type": "uint8"
1012                  },
1013                  {
1014                    "internalType": "bool",
1015                    "name": "isFreezable",
1016                    "type": "bool"
1017                  },
1018                  {
1019                    "internalType": "bytes4[]",
1020                    "name": "selectors",
1021                    "type": "bytes4[]"
1022                  }
1023                ],
1024                "internalType": "struct Diamond.FacetCut[]",
1025                "name": "facetCuts",
1026                "type": "tuple[]"
1027              },
1028              {
1029                "internalType": "address",
1030                "name": "initAddress",
1031                "type": "address"
1032              },
1033              {
1034                "internalType": "bytes",
1035                "name": "initCalldata",
1036                "type": "bytes"
1037              }
1038            ],
1039            "internalType": "struct Diamond.DiamondCutData",
1040            "name": "_diamondCut",
1041            "type": "tuple"
1042          }
1043        ],
1044        "name": "upgradeChainFromVersion",
1045        "outputs": [],
1046        "stateMutability": "nonpayable",
1047        "type": "function"
1048    }"#;
1049    serde_json::from_str(abi).unwrap()
1050});
1051
1052pub static DIAMOND_CUT: Lazy<Function> = Lazy::new(|| {
1053    let abi = r#"
1054    {
1055        "inputs": [
1056          {
1057            "components": [
1058              {
1059                "components": [
1060                  {
1061                    "internalType": "address",
1062                    "name": "facet",
1063                    "type": "address"
1064                  },
1065                  {
1066                    "internalType": "enum Diamond.Action",
1067                    "name": "action",
1068                    "type": "uint8"
1069                  },
1070                  {
1071                    "internalType": "bool",
1072                    "name": "isFreezable",
1073                    "type": "bool"
1074                  },
1075                  {
1076                    "internalType": "bytes4[]",
1077                    "name": "selectors",
1078                    "type": "bytes4[]"
1079                  }
1080                ],
1081                "internalType": "struct Diamond.FacetCut[]",
1082                "name": "facetCuts",
1083                "type": "tuple[]"
1084              },
1085              {
1086                "internalType": "address",
1087                "name": "initAddress",
1088                "type": "address"
1089              },
1090              {
1091                "internalType": "bytes",
1092                "name": "initCalldata",
1093                "type": "bytes"
1094              }
1095            ],
1096            "internalType": "struct Diamond.DiamondCutData",
1097            "name": "_diamondCut",
1098            "type": "tuple"
1099          }
1100        ],
1101        "name": "diamondCut",
1102        "outputs": [],
1103        "stateMutability": "nonpayable",
1104        "type": "function"
1105    }"#;
1106    serde_json::from_str(abi).unwrap()
1107});
1108
1109pub static POST_BOOJUM_COMMIT_FUNCTION: Lazy<Function> = Lazy::new(|| {
1110    let abi = r#"
1111    {
1112      "inputs": [
1113        {
1114          "components": [
1115            {
1116              "internalType": "uint64",
1117              "name": "batchNumber",
1118              "type": "uint64"
1119            },
1120            {
1121              "internalType": "bytes32",
1122              "name": "batchHash",
1123              "type": "bytes32"
1124            },
1125            {
1126              "internalType": "uint64",
1127              "name": "indexRepeatedStorageChanges",
1128              "type": "uint64"
1129            },
1130            {
1131              "internalType": "uint256",
1132              "name": "numberOfLayer1Txs",
1133              "type": "uint256"
1134            },
1135            {
1136              "internalType": "bytes32",
1137              "name": "priorityOperationsHash",
1138              "type": "bytes32"
1139            },
1140            {
1141              "internalType": "bytes32",
1142              "name": "l2LogsTreeRoot",
1143              "type": "bytes32"
1144            },
1145            {
1146              "internalType": "uint256",
1147              "name": "timestamp",
1148              "type": "uint256"
1149            },
1150            {
1151              "internalType": "bytes32",
1152              "name": "commitment",
1153              "type": "bytes32"
1154            }
1155          ],
1156          "internalType": "struct IExecutor.StoredBatchInfo",
1157          "name": "_lastCommittedBatchData",
1158          "type": "tuple"
1159        },
1160        {
1161          "components": [
1162            {
1163              "internalType": "uint64",
1164              "name": "batchNumber",
1165              "type": "uint64"
1166            },
1167            {
1168              "internalType": "uint64",
1169              "name": "timestamp",
1170              "type": "uint64"
1171            },
1172            {
1173              "internalType": "uint64",
1174              "name": "indexRepeatedStorageChanges",
1175              "type": "uint64"
1176            },
1177            {
1178              "internalType": "bytes32",
1179              "name": "newStateRoot",
1180              "type": "bytes32"
1181            },
1182            {
1183              "internalType": "uint256",
1184              "name": "numberOfLayer1Txs",
1185              "type": "uint256"
1186            },
1187            {
1188              "internalType": "bytes32",
1189              "name": "priorityOperationsHash",
1190              "type": "bytes32"
1191            },
1192            {
1193              "internalType": "bytes32",
1194              "name": "bootloaderHeapInitialContentsHash",
1195              "type": "bytes32"
1196            },
1197            {
1198              "internalType": "bytes32",
1199              "name": "eventsQueueStateHash",
1200              "type": "bytes32"
1201            },
1202            {
1203              "internalType": "bytes",
1204              "name": "systemLogs",
1205              "type": "bytes"
1206            },
1207            {
1208              "internalType": "bytes",
1209              "name": "pubdataCommitments",
1210              "type": "bytes"
1211            }
1212          ],
1213          "internalType": "struct IExecutor.CommitBatchInfo[]",
1214          "name": "_newBatchesData",
1215          "type": "tuple[]"
1216        }
1217      ],
1218      "name": "commitBatches",
1219      "outputs": [],
1220      "stateMutability": "nonpayable",
1221      "type": "function"
1222    }"#;
1223    serde_json::from_str(abi).unwrap()
1224});
1225
1226pub static POST_SHARED_BRIDGE_COMMIT_FUNCTION: Lazy<Function> = Lazy::new(|| {
1227    let abi = r#"
1228    {
1229      "inputs": [
1230        {
1231          "internalType": "uint256",
1232          "name": "_chainId",
1233          "type": "uint256"
1234        },
1235        {
1236          "components": [
1237            {
1238              "internalType": "uint64",
1239              "name": "batchNumber",
1240              "type": "uint64"
1241            },
1242            {
1243              "internalType": "bytes32",
1244              "name": "batchHash",
1245              "type": "bytes32"
1246            },
1247            {
1248              "internalType": "uint64",
1249              "name": "indexRepeatedStorageChanges",
1250              "type": "uint64"
1251            },
1252            {
1253              "internalType": "uint256",
1254              "name": "numberOfLayer1Txs",
1255              "type": "uint256"
1256            },
1257            {
1258              "internalType": "bytes32",
1259              "name": "priorityOperationsHash",
1260              "type": "bytes32"
1261            },
1262            {
1263              "internalType": "bytes32",
1264              "name": "l2LogsTreeRoot",
1265              "type": "bytes32"
1266            },
1267            {
1268              "internalType": "uint256",
1269              "name": "timestamp",
1270              "type": "uint256"
1271            },
1272            {
1273              "internalType": "bytes32",
1274              "name": "commitment",
1275              "type": "bytes32"
1276            }
1277          ],
1278          "internalType": "struct IExecutor.StoredBatchInfo",
1279          "name": "_lastCommittedBatchData",
1280          "type": "tuple"
1281        },
1282        {
1283          "components": [
1284            {
1285              "internalType": "uint64",
1286              "name": "batchNumber",
1287              "type": "uint64"
1288            },
1289            {
1290              "internalType": "uint64",
1291              "name": "timestamp",
1292              "type": "uint64"
1293            },
1294            {
1295              "internalType": "uint64",
1296              "name": "indexRepeatedStorageChanges",
1297              "type": "uint64"
1298            },
1299            {
1300              "internalType": "bytes32",
1301              "name": "newStateRoot",
1302              "type": "bytes32"
1303            },
1304            {
1305              "internalType": "uint256",
1306              "name": "numberOfLayer1Txs",
1307              "type": "uint256"
1308            },
1309            {
1310              "internalType": "bytes32",
1311              "name": "priorityOperationsHash",
1312              "type": "bytes32"
1313            },
1314            {
1315              "internalType": "bytes32",
1316              "name": "bootloaderHeapInitialContentsHash",
1317              "type": "bytes32"
1318            },
1319            {
1320              "internalType": "bytes32",
1321              "name": "eventsQueueStateHash",
1322              "type": "bytes32"
1323            },
1324            {
1325              "internalType": "bytes",
1326              "name": "systemLogs",
1327              "type": "bytes"
1328            },
1329            {
1330              "internalType": "bytes",
1331              "name": "pubdataCommitments",
1332              "type": "bytes"
1333            }
1334          ],
1335          "internalType": "struct IExecutor.CommitBatchInfo[]",
1336          "name": "_newBatchesData",
1337          "type": "tuple[]"
1338        }
1339      ],
1340      "name": "commitBatchesSharedBridge",
1341      "outputs": [],
1342      "stateMutability": "nonpayable",
1343      "type": "function"
1344    }"#;
1345    serde_json::from_str(abi).unwrap()
1346});
1347
1348pub static POST_SHARED_BRIDGE_PROVE_FUNCTION: Lazy<Function> = Lazy::new(|| {
1349    let abi = r#"
1350    {
1351      "inputs": [
1352        {
1353          "internalType": "uint256",
1354          "name": "_chainId",
1355          "type": "uint256"
1356        },
1357        {
1358          "components": [
1359            {
1360              "internalType": "uint64",
1361              "name": "batchNumber",
1362              "type": "uint64"
1363            },
1364            {
1365              "internalType": "bytes32",
1366              "name": "batchHash",
1367              "type": "bytes32"
1368            },
1369            {
1370              "internalType": "uint64",
1371              "name": "indexRepeatedStorageChanges",
1372              "type": "uint64"
1373            },
1374            {
1375              "internalType": "uint256",
1376              "name": "numberOfLayer1Txs",
1377              "type": "uint256"
1378            },
1379            {
1380              "internalType": "bytes32",
1381              "name": "priorityOperationsHash",
1382              "type": "bytes32"
1383            },
1384            {
1385              "internalType": "bytes32",
1386              "name": "l2LogsTreeRoot",
1387              "type": "bytes32"
1388            },
1389            {
1390              "internalType": "uint256",
1391              "name": "timestamp",
1392              "type": "uint256"
1393            },
1394            {
1395              "internalType": "bytes32",
1396              "name": "commitment",
1397              "type": "bytes32"
1398            }
1399          ],
1400          "internalType": "struct IExecutor.StoredBatchInfo",
1401          "name": "_prevBatch",
1402          "type": "tuple"
1403        },
1404        {
1405          "components": [
1406            {
1407              "internalType": "uint64",
1408              "name": "batchNumber",
1409              "type": "uint64"
1410            },
1411            {
1412              "internalType": "bytes32",
1413              "name": "batchHash",
1414              "type": "bytes32"
1415            },
1416            {
1417              "internalType": "uint64",
1418              "name": "indexRepeatedStorageChanges",
1419              "type": "uint64"
1420            },
1421            {
1422              "internalType": "uint256",
1423              "name": "numberOfLayer1Txs",
1424              "type": "uint256"
1425            },
1426            {
1427              "internalType": "bytes32",
1428              "name": "priorityOperationsHash",
1429              "type": "bytes32"
1430            },
1431            {
1432              "internalType": "bytes32",
1433              "name": "l2LogsTreeRoot",
1434              "type": "bytes32"
1435            },
1436            {
1437              "internalType": "uint256",
1438              "name": "timestamp",
1439              "type": "uint256"
1440            },
1441            {
1442              "internalType": "bytes32",
1443              "name": "commitment",
1444              "type": "bytes32"
1445            }
1446          ],
1447          "internalType": "struct IExecutor.StoredBatchInfo[]",
1448          "name": "_committedBatches",
1449          "type": "tuple[]"
1450        },
1451        {
1452          "components": [
1453            {
1454              "internalType": "uint256[]",
1455              "name": "recursiveAggregationInput",
1456              "type": "uint256[]"
1457            },
1458            {
1459              "internalType": "uint256[]",
1460              "name": "serializedProof",
1461              "type": "uint256[]"
1462            }
1463          ],
1464          "internalType": "struct IExecutor.ProofInput",
1465          "name": "_proof",
1466          "type": "tuple"
1467        }
1468      ],
1469      "name": "proveBatchesSharedBridge",
1470      "outputs": [],
1471      "stateMutability": "nonpayable",
1472      "type": "function"
1473    }"#;
1474    serde_json::from_str(abi).unwrap()
1475});
1476
1477pub static POST_SHARED_BRIDGE_EXECUTE_FUNCTION: Lazy<Function> = Lazy::new(|| {
1478    let abi = r#"
1479    {
1480      "inputs": [
1481        {
1482          "internalType": "uint256",
1483          "name": "_chainId",
1484          "type": "uint256"
1485        },
1486        {
1487          "components": [
1488            {
1489              "internalType": "uint64",
1490              "name": "batchNumber",
1491              "type": "uint64"
1492            },
1493            {
1494              "internalType": "bytes32",
1495              "name": "batchHash",
1496              "type": "bytes32"
1497            },
1498            {
1499              "internalType": "uint64",
1500              "name": "indexRepeatedStorageChanges",
1501              "type": "uint64"
1502            },
1503            {
1504              "internalType": "uint256",
1505              "name": "numberOfLayer1Txs",
1506              "type": "uint256"
1507            },
1508            {
1509              "internalType": "bytes32",
1510              "name": "priorityOperationsHash",
1511              "type": "bytes32"
1512            },
1513            {
1514              "internalType": "bytes32",
1515              "name": "l2LogsTreeRoot",
1516              "type": "bytes32"
1517            },
1518            {
1519              "internalType": "uint256",
1520              "name": "timestamp",
1521              "type": "uint256"
1522            },
1523            {
1524              "internalType": "bytes32",
1525              "name": "commitment",
1526              "type": "bytes32"
1527            }
1528          ],
1529          "internalType": "struct IExecutor.StoredBatchInfo[]",
1530          "name": "_batchesData",
1531          "type": "tuple[]"
1532        }
1533      ],
1534      "name": "executeBatchesSharedBridge",
1535      "outputs": [],
1536      "stateMutability": "nonpayable",
1537      "type": "function"
1538    }"#;
1539    serde_json::from_str(abi).unwrap()
1540});