diff --git a/crates/config/src/zksync.rs b/crates/config/src/zksync.rs index af6a6b84d..56ce76072 100644 --- a/crates/config/src/zksync.rs +++ b/crates/config/src/zksync.rs @@ -210,7 +210,7 @@ pub fn config_create_project( ZkSolc::blocking_install(&default_version)?; zksolc = ZkSolc::find_installed_version(&default_version)?; } - zksolc.unwrap_or_else(|| panic!("Could not install zksolc v{}", default_version)) + zksolc.unwrap_or_else(|| panic!("Could not install zksolc v{default_version}")) } else { "zksolc".into() }; diff --git a/crates/evm/coverage/src/lib.rs b/crates/evm/coverage/src/lib.rs index c55fec62f..52ec329ad 100644 --- a/crates/evm/coverage/src/lib.rs +++ b/crates/evm/coverage/src/lib.rs @@ -5,9 +5,6 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -#[macro_use] -extern crate foundry_common; - #[macro_use] extern crate tracing; diff --git a/crates/forge/src/multi_runner.rs b/crates/forge/src/multi_runner.rs index a1c9ab633..5da39b005 100644 --- a/crates/forge/src/multi_runner.rs +++ b/crates/forge/src/multi_runner.rs @@ -598,7 +598,7 @@ impl MultiContractRunnerBuilder { coverage: self.coverage, debug: self.debug, decode_internal: self.decode_internal, - inline_config: Arc::new(InlineConfig::new_parsed(&output, &self.config)?), + inline_config: Arc::new(InlineConfig::new_parsed(output, &self.config)?), isolation: self.isolation, odyssey: self.odyssey, diff --git a/crates/zksync/compilers/src/artifacts/contract.rs b/crates/zksync/compilers/src/artifacts/contract.rs index 04d1f4243..7ec459da9 100644 --- a/crates/zksync/compilers/src/artifacts/contract.rs +++ b/crates/zksync/compilers/src/artifacts/contract.rs @@ -12,11 +12,15 @@ use std::{borrow::Cow, collections::BTreeMap}; #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct Contract { + /// The contract abi pub abi: Option, + /// The contract metadata #[serde(default, skip_serializing_if = "Option::is_none")] pub metadata: Option, + /// The contract userdoc #[serde(default)] pub userdoc: UserDoc, + /// The contract devdoc #[serde(default)] pub devdoc: DevDoc, /// The contract optimized IR code. @@ -44,10 +48,12 @@ fn storage_layout_is_empty(storage_layout: &StorageLayout) -> bool { } impl Contract { + /// Returns true if contract is not linked pub fn is_unlinked(&self) -> bool { self.hash.is_none() || !self.missing_libraries.is_empty() } + /// takes missing libraries output and transforms into link references pub fn missing_libs_to_link_references( missing_libraries: &[String], ) -> BTreeMap>> { @@ -72,6 +78,7 @@ impl Contract { Self::missing_libs_to_link_references(self.missing_libraries.as_slice()) } + /// Get bytecode pub fn bytecode(&self) -> Option { self.eravm.as_ref().and_then(|eravm| eravm.bytecode(self.is_unlinked())).map(|object| { let mut bytecode: Bytecode = object.into(); diff --git a/crates/zksync/compilers/src/artifacts/error.rs b/crates/zksync/compilers/src/artifacts/error.rs index 72c5a40a9..6097518a6 100644 --- a/crates/zksync/compilers/src/artifacts/error.rs +++ b/crates/zksync/compilers/src/artifacts/error.rs @@ -1,3 +1,4 @@ +//! zksolc error from std json output use foundry_compilers_artifacts_solc::error::{Severity, SourceLocation}; use foundry_compilers_artifacts_solc::serde_helpers; diff --git a/crates/zksync/compilers/src/artifacts/mod.rs b/crates/zksync/compilers/src/artifacts/mod.rs index 41cd7e72d..d21befa2d 100644 --- a/crates/zksync/compilers/src/artifacts/mod.rs +++ b/crates/zksync/compilers/src/artifacts/mod.rs @@ -1,14 +1,11 @@ -/// ZKsolc compiler artifacts to be used in foundry-compilers +//! zksolc artifacts to be used in `foundry-compilers` use foundry_compilers_artifacts_solc::{ BytecodeObject, CompactContractRef, FileToContractsMap, SourceFile, SourceFiles, }; use semver::Version; use serde::{Deserialize, Serialize}; -use std::{ - collections::{BTreeMap, HashSet}, - path::{Path, PathBuf}, -}; +use std::{collections::BTreeMap, path::PathBuf}; pub mod contract; pub mod error; @@ -59,6 +56,7 @@ impl CompilerOutput { } } +/// `zksolc` eravm output field #[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)] #[serde(rename_all = "camelCase")] pub struct EraVM { @@ -72,6 +70,7 @@ pub struct EraVM { } impl EraVM { + /// Get bytecode object pub fn bytecode(&self, should_be_unlinked: bool) -> Option { self.bytecode.as_ref().map(|object| match (should_be_unlinked, object) { (true, BytecodeObject::Bytecode(bc)) => { @@ -88,6 +87,7 @@ impl EraVM { }) } + /// Get bytecode object ref // TODO: tmp to make compiler abstraction sample work, needs some thought on // how do transform linked/to unlinked pub fn bytecode_ref(&self) -> Option<&BytecodeObject> { diff --git a/crates/zksync/compilers/src/artifacts/output_selection.rs b/crates/zksync/compilers/src/artifacts/output_selection.rs index e05b27515..7db51d0fe 100644 --- a/crates/zksync/compilers/src/artifacts/output_selection.rs +++ b/crates/zksync/compilers/src/artifacts/output_selection.rs @@ -1,3 +1,4 @@ +//! zksolc output selection use serde::{Deserialize, Serialize}; use std::collections::HashSet; @@ -11,6 +12,7 @@ pub struct OutputSelection { pub all: FileOutputSelection, } +/// The `solc --standard-json` expected output selection value. #[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq)] pub struct FileOutputSelection { /// The per-file output selections. diff --git a/crates/zksync/compilers/src/compilers/artifact_output/mod.rs b/crates/zksync/compilers/src/compilers/artifact_output/mod.rs index fc4887264..6dc8fa538 100644 --- a/crates/zksync/compilers/src/compilers/artifact_output/mod.rs +++ b/crates/zksync/compilers/src/compilers/artifact_output/mod.rs @@ -1 +1,2 @@ +//! `foundry-compilers` `ArtifactOutput` implementations for ZK Sync pub mod zk; diff --git a/crates/zksync/compilers/src/compilers/artifact_output/zk.rs b/crates/zksync/compilers/src/compilers/artifact_output/zk.rs index b28f4b0e3..58409e44f 100644 --- a/crates/zksync/compilers/src/compilers/artifact_output/zk.rs +++ b/crates/zksync/compilers/src/compilers/artifact_output/zk.rs @@ -1,3 +1,4 @@ +//! ZK Sync artifact output use crate::artifacts::contract::Contract; use alloy_json_abi::JsonAbi; use foundry_compilers::{ @@ -15,26 +16,37 @@ use std::{borrow::Cow, collections::BTreeMap, path::Path}; mod bytecode; pub use bytecode::ZkArtifactBytecode; +/// Artifact representing a compiled contract #[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct ZkContractArtifact { + /// contract abi pub abi: Option, #[serde(default, skip_serializing_if = "Option::is_none")] + /// contract bytecodee pub bytecode: Option, + /// contract assembly #[serde(default, skip_serializing_if = "Option::is_none")] pub assembly: Option, #[serde(default, skip_serializing_if = "Option::is_none")] + /// contract metadata pub metadata: Option, + /// contract storage layout #[serde(default, skip_serializing_if = "Option::is_none")] pub storage_layout: Option, + /// contract userdoc #[serde(default, skip_serializing_if = "Option::is_none")] pub userdoc: Option, + /// contract devdoc #[serde(default, skip_serializing_if = "Option::is_none")] pub devdoc: Option, + /// contract optimized IR code #[serde(default, skip_serializing_if = "Option::is_none")] pub ir_optimized: Option, + /// contract hash #[serde(default, skip_serializing_if = "Option::is_none")] pub hash: Option, + /// contract factory dependencies #[serde(default, skip_serializing_if = "Option::is_none")] pub factory_dependencies: Option>, /// The identifier of the source file @@ -43,6 +55,7 @@ pub struct ZkContractArtifact { } impl ZkContractArtifact { + /// Get contract missing libraries pub fn missing_libraries(&self) -> Option<&Vec> { self.bytecode.as_ref().map(|bc| &bc.missing_libraries) } @@ -90,6 +103,7 @@ impl From for CompactContract { } } +/// ZK Sync ArtifactOutput #[derive(Debug, Copy, Clone, Eq, PartialEq, Default)] pub struct ZkArtifactOutput(); diff --git a/crates/zksync/compilers/src/compilers/artifact_output/zk/bytecode.rs b/crates/zksync/compilers/src/compilers/artifact_output/zk/bytecode.rs index 19c2045bf..ef0473c74 100644 --- a/crates/zksync/compilers/src/compilers/artifact_output/zk/bytecode.rs +++ b/crates/zksync/compilers/src/compilers/artifact_output/zk/bytecode.rs @@ -7,16 +7,19 @@ use foundry_compilers_artifacts_solc::{ }; use serde::{Deserialize, Serialize}; +/// Bytecode compiled by zksolc #[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)] pub struct ZkArtifactBytecode { object: Bytes, is_unlinked: bool, + /// Bytecode missing libraries #[serde(default)] pub missing_libraries: Vec, } impl ZkArtifactBytecode { + /// Get Bytecode from parts pub fn with_object( object: BytecodeObject, is_unlinked: bool, @@ -35,6 +38,7 @@ impl ZkArtifactBytecode { Contract::missing_libs_to_link_references(self.missing_libraries.as_slice()) } + /// Get bytecode object pub fn object(&self) -> BytecodeObject { if self.is_unlinked { // convert to unlinked diff --git a/crates/zksync/compilers/src/compilers/mod.rs b/crates/zksync/compilers/src/compilers/mod.rs index a044344d7..7a847ea64 100644 --- a/crates/zksync/compilers/src/compilers/mod.rs +++ b/crates/zksync/compilers/src/compilers/mod.rs @@ -1,3 +1,4 @@ +//! `foundry-compilers` core trait implementations and overrides for ZK Sync pub mod artifact_output; pub mod zksolc; @@ -12,6 +13,7 @@ use foundry_compilers::{ }; use zksolc::{input::StandardJsonCompilerInput, ZkSolcCompiler, ZkSolcSettings}; +/// zksolc specific standard_json_input to be used in verification // https://github.com/foundry-rs/compilers/blob/ff2a8d68a0d85d8f40c545a7a948e84d1bc2488e/crates/compilers/src/lib.rs#L165 // TODO: foundry_compilers only implements this for compilers that impment Into. // Maybe this works for us or maybe we can submit required changes upstream diff --git a/crates/zksync/compilers/src/compilers/zksolc/input.rs b/crates/zksync/compilers/src/compilers/zksolc/input.rs index fe8de50c6..3172e518c 100644 --- a/crates/zksync/compilers/src/compilers/zksolc/input.rs +++ b/crates/zksync/compilers/src/compilers/zksolc/input.rs @@ -1,3 +1,4 @@ +//! zksolc input use super::{ settings::{ZkSolcError, ZkSolcSettings, ZkSolcWarning}, ZkSettings, @@ -16,11 +17,15 @@ use std::{ }; use tracing::warn; +/// Versioned input for zksolc #[derive(Debug, Clone, Serialize)] pub struct ZkSolcVersionedInput { + /// zksolc json input #[serde(flatten)] pub input: ZkSolcInput, + /// solc version to be used along zksolc pub solc_version: Version, + /// zksolc cli settings pub cli_settings: solc::CliSettings, } @@ -72,14 +77,19 @@ impl CompilerInput for ZkSolcVersionedInput { #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct ZkSolcInput { + /// source code language pub language: SolcLanguage, + /// sources to compile pub sources: Sources, + /// compiler settings set by the user pub settings: ZkSettings, + /// suppressed warnings // For `zksolc` versions <1.5.7, suppressed warnings / errors were specified on the same level // as `settings`. For `zksolc` 1.5.7+, they are specified inside `settings`. Since we want to // support both options at the time, we duplicate fields from `settings` here. #[serde(default, skip_serializing_if = "HashSet::is_empty")] pub suppressed_warnings: HashSet, + /// suppressed errors #[serde(default, skip_serializing_if = "HashSet::is_empty")] pub suppressed_errors: HashSet, } @@ -125,6 +135,7 @@ impl ZkSolcInput { self } + /// Add remappings to settings pub fn with_remappings(mut self, remappings: Vec) -> Self { if self.language == SolcLanguage::Yul { if !remappings.is_empty() { @@ -146,13 +157,17 @@ impl ZkSolcInput { /// the verified contracts #[derive(Clone, Debug, Serialize, Deserialize)] pub struct StandardJsonCompilerInput { + /// compiler language pub language: SolcLanguage, + /// sources to compile #[serde(with = "serde_helpers::tuple_vec_map")] pub sources: Vec<(PathBuf, Source)>, + /// compiler settings pub settings: ZkSettings, } impl StandardJsonCompilerInput { + /// new StandardJsonCompilerInput pub fn new(sources: Vec<(PathBuf, Source)>, settings: ZkSettings) -> Self { Self { language: SolcLanguage::Solidity, sources, settings } } diff --git a/crates/zksync/compilers/src/compilers/zksolc/mod.rs b/crates/zksync/compilers/src/compilers/zksolc/mod.rs index 8518249f7..1a4935573 100644 --- a/crates/zksync/compilers/src/compilers/zksolc/mod.rs +++ b/crates/zksync/compilers/src/compilers/zksolc/mod.rs @@ -1,3 +1,4 @@ +//! foundry-compilers trait implementations for zksolc use self::input::{ZkSolcInput, ZkSolcVersionedInput}; use crate::artifacts::{contract::Contract, error::Error, CompilerOutput as ZkCompilerOutput}; use alloy_json_abi::JsonAbi; @@ -34,8 +35,11 @@ pub mod input; pub mod settings; pub use settings::{ZkSettings, ZkSolcSettings}; +/// zksolc command pub const ZKSOLC: &str = "zksolc"; +/// ZKsync solc release used for all ZKsync solc versions pub const ZKSYNC_SOLC_RELEASE: Version = Version::new(1, 0, 1); +/// Default zksolc version pub const ZKSOLC_VERSION: Version = Version::new(1, 5, 7); #[cfg(test)] @@ -116,9 +120,12 @@ impl ZkSolcOS { } } +/// ZkSolc compiler #[derive(Debug, Clone)] pub struct ZkSolcCompiler { + /// zksolc path pub zksolc: PathBuf, + /// solc compiler to use along zksolc pub solc: SolcCompiler, } @@ -204,6 +211,7 @@ impl Compiler for ZkSolcCompiler { } impl ZkSolcCompiler { + /// Get zksolc command wrapper pub fn zksolc(&self, input: &ZkSolcVersionedInput) -> Result { let solc = match &self.solc { SolcCompiler::Specific(solc) => Some(solc.solc.clone()), @@ -321,6 +329,7 @@ impl ZkSolc { }) } + /// Get zksolc path for a given version pub fn get_path_for_version(version: &Version) -> Result { let maybe_zksolc = Self::find_installed_version(version)?; @@ -363,6 +372,7 @@ impl ZkSolc { Ok(compiler_output) } + /// Get installed versions of zksync solc pub fn solc_installed_versions() -> Vec { if let Ok(dir) = Self::compilers_dir() { let os = get_operating_system().unwrap(); @@ -387,6 +397,7 @@ impl ZkSolc { } } + /// Get available zksync solc versions pub fn solc_available_versions() -> Vec { let mut ret = vec![]; let min_max_patch_by_minor_versions = @@ -529,6 +540,7 @@ impl ZkSolc { compiler_blocking_install(solc_path, lock_path, &download_url, &label) } + /// Get path for installed zksolc version. Returns `Ok(None)` if not installed pub fn find_installed_version(version: &Version) -> Result> { let zksolc = Self::compiler_path(version)?; @@ -538,6 +550,7 @@ impl ZkSolc { Ok(Some(zksolc)) } + /// Get path for installed ZKsync solc version. Returns `Ok(None)` if not installed pub fn find_solc_installed_version(version_str: &str) -> Result> { let solc = Self::solc_path(version_str)?; diff --git a/crates/zksync/compilers/src/compilers/zksolc/settings.rs b/crates/zksync/compilers/src/compilers/zksolc/settings.rs index c79aaff99..c10cca0c0 100644 --- a/crates/zksync/compilers/src/compilers/zksolc/settings.rs +++ b/crates/zksync/compilers/src/compilers/zksolc/settings.rs @@ -1,3 +1,4 @@ +//! zksolc settings use crate::artifacts::output_selection::OutputSelection as ZkOutputSelection; use foundry_compilers::{ artifacts::{serde_helpers, EvmVersion, Libraries},