From 28433c6dbad3159881d9db9beccfc1f2c1634e6d Mon Sep 17 00:00:00 2001 From: elfedy Date: Wed, 8 Jan 2025 10:20:18 -0300 Subject: [PATCH] fix: sanitize yul artifact contract names --- .../compilers/src/compilers/zksolc/mod.rs | 23 ++++++++++++++++++- crates/zksync/compilers/tests/zksync_tests.rs | 6 ++--- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/crates/zksync/compilers/src/compilers/zksolc/mod.rs b/crates/zksync/compilers/src/compilers/zksolc/mod.rs index 203a0fd45..1e59c7d7a 100644 --- a/crates/zksync/compilers/src/compilers/zksolc/mod.rs +++ b/crates/zksync/compilers/src/compilers/zksolc/mod.rs @@ -358,13 +358,34 @@ impl ZkSolc { /// Compiles with `--standard-json` and deserializes the output as [`CompilerOutput`]. pub fn compile(&self, input: &ZkSolcInput) -> Result { - // If solc is zksync solc, override the returned version to put the complete zksolc one let output = self.compile_output(input)?; // Only run UTF-8 validation once. let output = std::str::from_utf8(&output).map_err(|_| SolcError::InvalidUtf8)?; let mut compiler_output: ZkCompilerOutput = serde_json::from_str(output)?; + // Sanitize contract names that are source file paths, using the file name without + // path or .yul extension. This happens in older zksolc versions and creates issues. + // See: https://github.com/matter-labs/era-compiler-solidity/issues/243 + if input.is_yul() { + for contracts in compiler_output.contracts.values_mut() { + let contract_names = contracts.keys().cloned().collect::>(); + for name in contract_names { + if name.ends_with(".yul") { + let sanitized_name = name + .split('/') + .last() + .unwrap() + .strip_suffix(".yul") + .expect("Error sanitizing path into name"); + // Removing and inserting should be fine because there cannot be + // two contracts named the same in a source file + let contract = contracts.remove(&name).expect("Error replacing yul key"); + contracts.insert(sanitized_name.into(), contract); + } + } + } + } // Add zksync version so that there's some way to identify if zksync solc was used // by looking at build info compiler_output.zksync_solc_version = self.solc_version_info.zksync_version.clone(); diff --git a/crates/zksync/compilers/tests/zksync_tests.rs b/crates/zksync/compilers/tests/zksync_tests.rs index 274569458..c78545951 100644 --- a/crates/zksync/compilers/tests/zksync_tests.rs +++ b/crates/zksync/compilers/tests/zksync_tests.rs @@ -581,10 +581,10 @@ fn zksync_can_compile_yul_sample() { .find_map(|contracts| { contracts .iter() - .find(|(name, _)| name.ends_with("SimpleStore.yul")) + .find(|(name, _)| name.ends_with("SimpleStore")) .and_then(|(_, artifacts)| artifacts.first()) }) - .expect("SimpleStore.yul artifact not found") + .expect("SimpleStore artifact not found") .artifact .bytecode .clone() @@ -592,5 +592,5 @@ fn zksync_can_compile_yul_sample() { let yul_bytecode = simple_store_artifact.object().into_bytes().unwrap(); - assert!(!yul_bytecode.is_empty(), "SimpleStore.yul bytecode is empty"); + assert!(!yul_bytecode.is_empty(), "SimpleStore bytecode is empty"); }