diff --git a/Cargo.lock b/Cargo.lock index 07277bf37..1ec8c5004 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -267,7 +267,7 @@ dependencies = [ "derive_more", "once_cell", "serde", - "sha2", + "sha2 0.10.8", ] [[package]] @@ -285,7 +285,7 @@ dependencies = [ "derive_more", "once_cell", "serde", - "sha2", + "sha2 0.10.8", ] [[package]] @@ -1364,9 +1364,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.94" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "arbitrary" @@ -1867,7 +1867,7 @@ dependencies = [ "http 1.2.0", "once_cell", "percent-encoding", - "sha2", + "sha2 0.10.8", "time", "tracing", ] @@ -2094,6 +2094,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base-x" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" + [[package]] name = "base16ct" version = "0.1.1" @@ -2106,6 +2112,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base58" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" + [[package]] name = "base64" version = "0.21.7" @@ -2268,6 +2280,17 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "blake2b_simd" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "constant_time_eq", +] + [[package]] name = "blake2s_simd" version = "0.5.11" @@ -2341,13 +2364,19 @@ dependencies = [ "syn 2.0.90", ] +[[package]] +name = "boolinator" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfa8873f51c92e232f9bac4065cddef41b714152812bfc5f7672ba16d6ef8cd9" + [[package]] name = "bs58" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" dependencies = [ - "sha2", + "sha2 0.10.8", "tinyvec", ] @@ -2682,6 +2711,17 @@ dependencies = [ "half", ] +[[package]] +name = "cid" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8709d481fb78b9808f34a1b4b4fadd08a15a0971052c18bc2b751faefaed595e" +dependencies = [ + "multibase", + "multihash", + "unsigned-varint 0.3.3", +] + [[package]] name = "cipher" version = "0.4.4" @@ -2835,7 +2875,7 @@ dependencies = [ "hmac", "k256 0.13.4", "serde", - "sha2", + "sha2 0.10.8", "thiserror 1.0.69", ] @@ -2851,7 +2891,7 @@ dependencies = [ "once_cell", "pbkdf2 0.12.2", "rand 0.8.5", - "sha2", + "sha2 0.10.8", "thiserror 1.0.69", ] @@ -2869,7 +2909,7 @@ dependencies = [ "generic-array", "ripemd", "serde", - "sha2", + "sha2 0.10.8", "sha3 0.10.8", "thiserror 1.0.69", ] @@ -3347,6 +3387,26 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" +[[package]] +name = "data-encoding-macro" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1559b6cba622276d6d63706db152618eeb15b89b3e4041446b05876e352e639" +dependencies = [ + "data-encoding", + "data-encoding-macro-internal", +] + +[[package]] +name = "data-encoding-macro-internal" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "332d754c0af53bc87c108fed664d121ecf59207ec4196041f04d6ab9002ad33f" +dependencies = [ + "data-encoding", + "syn 1.0.109", +] + [[package]] name = "dbus" version = "0.9.7" @@ -3844,6 +3904,39 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "era-compiler-common" +version = "1.5.0" +source = "git+https://github.com/matter-labs/era-compiler-common?branch=main#10ea52ee6a27ae3392c25647f5f70fb60e3ce2a6" +dependencies = [ + "anyhow", + "base58", + "hex", + "ipfs-hasher", + "serde", + "serde_arrays", + "serde_json", + "serde_stacker", + "sha3 0.10.8", +] + +[[package]] +name = "era-solc" +version = "1.5.10" +source = "git+https://github.com/matter-labs/era-compiler-solidity.git?tag=1.5.10#0c9df3b260c95e0881799bb3b2c85bd16a6dbf4d" +dependencies = [ + "anyhow", + "boolinator", + "era-compiler-common", + "hex", + "num", + "rayon", + "semver 1.0.23", + "serde", + "serde_json", + "which 6.0.3", +] + [[package]] name = "errno" version = "0.3.10" @@ -3876,7 +3969,7 @@ dependencies = [ "scrypt", "serde", "serde_json", - "sha2", + "sha2 0.10.8", "sha3 0.10.8", "thiserror 1.0.69", "uuid 0.8.2", @@ -4607,6 +4700,7 @@ dependencies = [ "clap", "color-eyre", "dotenvy", + "era-solc", "eyre", "forge-fmt", "foundry-common", @@ -4730,7 +4824,7 @@ dependencies = [ "semver 1.0.23", "serde", "serde_json", - "sha2", + "sha2 0.10.8", "solar-parse", "svm-rs", "svm-rs-builds", @@ -4822,6 +4916,7 @@ dependencies = [ "alloy-primitives", "dirs-next", "dunce", + "era-solc", "eyre", "figment", "foundry-block-explorers", @@ -5157,6 +5252,7 @@ dependencies = [ "alloy-json-abi", "alloy-primitives", "dirs 5.0.1", + "era-solc", "eyre", "fd-lock", "foundry-compilers", @@ -6415,7 +6511,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" dependencies = [ - "parity-scale-codec 3.7.0", + "parity-scale-codec 3.6.12", ] [[package]] @@ -6589,6 +6685,29 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "ipfs-hasher" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "802d005faacdd9ad472aa89649150e0057b06ecf1e5d723be74933772a2b9f48" +dependencies = [ + "ipfs-unixfs", +] + +[[package]] +name = "ipfs-unixfs" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67d1cf65363f3d01682283456651d1cea436019de5be7a974bb61716c940d44f" +dependencies = [ + "cid", + "either", + "filetime", + "multihash", + "quick-protobuf 0.7.0", + "sha2 0.9.9", +] + [[package]] name = "ipnet" version = "2.10.1" @@ -6919,7 +7038,7 @@ dependencies = [ "cfg-if", "ecdsa 0.14.8", "elliptic-curve 0.12.3", - "sha2", + "sha2 0.10.8", ] [[package]] @@ -6932,7 +7051,7 @@ dependencies = [ "ecdsa 0.16.9", "elliptic-curve 0.13.8", "once_cell", - "sha2", + "sha2 0.10.8", "signature 2.2.0", ] @@ -7435,6 +7554,32 @@ dependencies = [ "syn 2.0.90", ] +[[package]] +name = "multibase" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b78c60039650ff12e140ae867ef5299a58e19dded4d334c849dc7177083667e2" +dependencies = [ + "base-x", + "data-encoding", + "data-encoding-macro", +] + +[[package]] +name = "multihash" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567122ab6492f49b59def14ecc36e13e64dca4188196dd0cd41f9f3f979f3df6" +dependencies = [ + "blake2b_simd", + "blake2s_simd", + "digest 0.9.0", + "sha-1", + "sha2 0.9.9", + "sha3 0.9.1", + "unsigned-varint 0.5.1", +] + [[package]] name = "multimap" version = "0.10.0" @@ -8054,7 +8199,7 @@ dependencies = [ "ecdsa 0.16.9", "elliptic-curve 0.13.8", "primeorder", - "sha2", + "sha2 0.10.8", ] [[package]] @@ -8073,16 +8218,15 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.7.0" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be4817d39f3272f69c59fe05d0535ae6456c2dc2fa1ba02910296c7e0a5c590" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ "arrayvec 0.7.6", "bitvec 1.0.1", "byte-slice-cast", "impl-trait-for-tuples", "parity-scale-codec-derive 3.7.0", - "rustversion", "serde", ] @@ -8260,7 +8404,7 @@ checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea" dependencies = [ "once_cell", "pest", - "sha2", + "sha2 0.10.8", ] [[package]] @@ -8861,6 +9005,15 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "psm" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200b9ff220857e53e184257720a14553b2f4aa02577d2ed9842d45d4b9654810" +dependencies = [ + "cc", +] + [[package]] name = "pulldown-cmark" version = "0.10.3" @@ -8900,6 +9053,15 @@ dependencies = [ "uuid 1.11.0", ] +[[package]] +name = "quick-protobuf" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e489d4a83c17ea69b0291630229b5d4c92a94a3bf0165f7f72f506e94cda8b4b" +dependencies = [ + "byteorder", +] + [[package]] name = "quick-protobuf" version = "0.8.1" @@ -9358,7 +9520,7 @@ dependencies = [ "revm-primitives", "ripemd", "secp256k1 0.29.1", - "sha2", + "sha2 0.10.8", "substrate-bn", ] @@ -9499,7 +9661,7 @@ dependencies = [ "fastrlp", "num-bigint", "num-traits", - "parity-scale-codec 3.7.0", + "parity-scale-codec 3.6.12", "primitive-types 0.12.2", "proptest", "rand 0.8.5", @@ -9807,7 +9969,7 @@ checksum = "346a3b32eba2640d17a9cb5927056b08f3de90f65b72fe09402c2ad07d684d0b" dependencies = [ "cfg-if", "derive_more", - "parity-scale-codec 3.7.0", + "parity-scale-codec 3.6.12", "scale-info-derive", ] @@ -9897,7 +10059,7 @@ dependencies = [ "hmac", "pbkdf2 0.11.0", "salsa20", - "sha2", + "sha2 0.10.8", ] [[package]] @@ -10189,9 +10351,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.215" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] @@ -10206,11 +10368,20 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_arrays" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38636132857f68ec3d5f3eb121166d2af33cb55174c4d5ff645db6165cbef0fd" +dependencies = [ + "serde", +] + [[package]] name = "serde_derive" -version = "1.0.215" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", @@ -10230,9 +10401,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.133" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "indexmap 2.7.0", "itoa", @@ -10281,6 +10452,16 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_stacker" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "babfccff5773ff80657f0ecf553c7c516bdc2eb16389c0918b36b73e7015276e" +dependencies = [ + "serde", + "stacker", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -10354,6 +10535,19 @@ dependencies = [ "syn 2.0.90", ] +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + [[package]] name = "sha1" version = "0.10.6" @@ -10371,6 +10565,19 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + [[package]] name = "sha2" version = "0.10.8" @@ -10779,7 +10986,7 @@ dependencies = [ "semver 1.0.23", "serde", "serde_json", - "sha2", + "sha2 0.10.8", "thiserror 2.0.6", "tokio", "toml_edit 0.22.22", @@ -10820,6 +11027,19 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "stacker" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799c883d55abdb5e98af1a7b3f23b9b6de8ecada0ecac058672d7635eb48ca7b" +dependencies = [ + "cc", + "cfg-if", + "libc", + "psm", + "windows-sys 0.59.0", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -10933,7 +11153,7 @@ dependencies = [ "semver 1.0.23", "serde", "serde_json", - "sha2", + "sha2 0.10.8", "tempfile", "thiserror 1.0.69", "url", @@ -11902,6 +12122,18 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +[[package]] +name = "unsigned-varint" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f67332660eb59a6f1eb24ff1220c9e8d01738a8503c6002e30bcfe4bd9f2b4a9" + +[[package]] +name = "unsigned-varint" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fdeedbf205afadfe39ae559b75c3240f24e257d0ca27e85f85cb82aa19ac35" + [[package]] name = "untrusted" version = "0.9.0" @@ -13004,7 +13236,7 @@ dependencies = [ "bitflags 1.3.2", "ethereum-types 0.14.1", "lazy_static", - "sha2", + "sha2 0.10.8", ] [[package]] @@ -13033,7 +13265,7 @@ dependencies = [ "ethereum-types 0.14.1", "k256 0.13.4", "lazy_static", - "sha2", + "sha2 0.10.8", "sha3 0.10.8", ] @@ -13050,7 +13282,7 @@ dependencies = [ "lazy_static", "p256", "serde", - "sha2", + "sha2 0.10.8", "sha3 0.10.8", ] @@ -13069,7 +13301,7 @@ dependencies = [ "serde", "serde_json", "serde_with", - "sha2", + "sha2 0.10.8", "strum", "thiserror 1.0.69", "tiny-keccak 2.0.2", @@ -13171,7 +13403,7 @@ dependencies = [ "secp256k1 0.27.0", "serde", "serde_json", - "sha2", + "sha2 0.10.8", "thiserror 1.0.69", "zksync_basic_types", ] @@ -13265,7 +13497,7 @@ dependencies = [ "once_cell", "prost 0.12.6", "prost-reflect", - "quick-protobuf", + "quick-protobuf 0.8.1", "rand 0.8.5", "serde", "serde_json", @@ -13343,7 +13575,7 @@ dependencies = [ "once_cell", "reqwest 0.12.9", "serde_json", - "sha2", + "sha2 0.10.8", "tokio", "tracing", "zksync_vlog", diff --git a/Cargo.toml b/Cargo.toml index 405f855af..2a9d9732b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -256,6 +256,7 @@ zksync_vm_interface = { git = "https://github.com/matter-labs/zksync-era.git", r zksync_multivm = { git = "https://github.com/matter-labs/zksync-era.git", rev = "core-v25.4.0" } zksync_utils = { git = "https://github.com/matter-labs/zksync-era.git", rev = "core-v25.4.0" } zksync_contracts = { git = "https://github.com/matter-labs/zksync-era.git", rev = "core-v25.4.0" } +era-solc = { git = "https://github.com/matter-labs/era-compiler-solidity.git", tag = "1.5.10", package = "era-solc" } # macros proc-macro2 = "1.0" @@ -303,7 +304,7 @@ regex = { version = "1", default-features = false } reqwest = { version = "0.12", default-features = false } semver = "1" serde = { version = "1.0", features = ["derive"] } -serde_json = { version = "1.0", features = ["arbitrary_precision"] } +serde_json = { version = "=1.0.128", features = ["arbitrary_precision"] } similar-asserts = "1.6" soldeer-commands = "=0.5.2" strum = "0.26" diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index e1a69343e..e131b5dad 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -54,6 +54,7 @@ tracing-tracy = { version = "0.11", optional = true } # zk foundry-zksync-compilers.workspace = true +era-solc.workspace = true [dev-dependencies] tempfile.workspace = true diff --git a/crates/cli/src/opts/build/zksync.rs b/crates/cli/src/opts/build/zksync.rs index 1a0cb9d74..4964ce230 100644 --- a/crates/cli/src/opts/build/zksync.rs +++ b/crates/cli/src/opts/build/zksync.rs @@ -2,8 +2,8 @@ use std::{collections::HashSet, path::PathBuf}; use alloy_primitives::{hex, Address, Bytes}; use clap::Parser; +use era_solc::standard_json::input::settings::{error_type::ErrorType, warning_type::WarningType}; use foundry_config::zksync::ZkSyncConfig; -use foundry_zksync_compilers::compilers::zksolc::settings::{ZkSolcError, ZkSolcWarning}; use serde::Serialize; #[derive(Clone, Debug, Default, Serialize, Parser)] @@ -117,22 +117,24 @@ pub struct ZkSyncArgs { /// Set the warnings to suppress for zksolc. #[clap( long = "zk-suppressed-warnings", - visible_alias = "suppressed-warnings", + alias = "suppressed-warnings", + visible_alias = "suppress-warnings", value_delimiter = ',', - help = "Set the warnings to suppress for zksolc, possible values: [txorigin]" + help = "Set the warnings to suppress for zksolc, possible values: [txorigin, assemblycreate]" )] #[serde(skip_serializing_if = "Option::is_none")] - pub suppressed_warnings: Option>, + pub suppressed_warnings: Option>, /// Set the errors to suppress for zksolc. #[clap( long = "zk-suppressed-errors", - visible_alias = "suppressed-errors", + alias = "suppressed-errors", + visible_alias = "suppress-errors", value_delimiter = ',', help = "Set the errors to suppress for zksolc, possible values: [sendtransfer]" )] #[serde(skip_serializing_if = "Option::is_none")] - pub suppressed_errors: Option>, + pub suppressed_errors: Option>, } impl ZkSyncArgs { diff --git a/crates/common/src/compile.rs b/crates/common/src/compile.rs index 9a408cdfc..c9d54835a 100644 --- a/crates/common/src/compile.rs +++ b/crates/common/src/compile.rs @@ -19,17 +19,14 @@ use foundry_compilers::{ solc::SolcSettings, Artifact, Project, ProjectBuilder, ProjectCompileOutput, ProjectPathsConfig, SolcConfig, }; -use foundry_zksync_compilers::{ - compilers::{ - artifact_output::zk::ZkArtifactOutput, - zksolc::{ZkSolc, ZkSolcCompiler}, - }, - libraries::{self, ZkMissingLibrary}, +use foundry_zksync_compilers::compilers::{ + artifact_output::zk::ZkArtifactOutput, + zksolc::{ZkSolc, ZkSolcCompiler}, }; use num_format::{Locale, ToFormattedString}; use std::{ - collections::{BTreeMap, HashSet}, + collections::BTreeMap, fmt::Display, io::IsTerminal, path::{Path, PathBuf}, @@ -336,7 +333,7 @@ impl ProjectCompiler { let zksolc_version = ZkSolc::get_version_for_path(&project.compiler.zksolc)?; Report::new(SpinnerReporter::spawn_with(format!("Using zksolc-{zksolc_version}"))); } - self.zksync_compile_with(&project.paths.root, || { + self.zksync_compile_with(|| { let files_to_compile = if !files.is_empty() { files } else { project.paths.input_files() }; let sources = Source::read_all(files_to_compile)?; @@ -349,7 +346,6 @@ impl ProjectCompiler { #[instrument(target = "forge::compile", skip_all)] fn zksync_compile_with( self, - root_path: impl AsRef, f: F, ) -> Result> where @@ -394,7 +390,7 @@ impl ProjectCompiler { sh_println!("{output}")?; } - self.zksync_handle_output(root_path, &output)?; + self.zksync_handle_output(&output)?; } Ok(output) @@ -403,71 +399,11 @@ impl ProjectCompiler { /// If configured, this will print sizes or names fn zksync_handle_output( &self, - root_path: impl AsRef, output: &ProjectCompileOutput, ) -> Result<()> { let print_names = self.print_names.unwrap_or(false); let print_sizes = self.print_sizes.unwrap_or(false); - // Process missing libraries - // TODO: skip this if project was not compiled using --detect-missing-libraries - let mut missing_libs_unique: HashSet = HashSet::new(); - for (artifact_id, artifact) in output.artifact_ids() { - // TODO: when compiling specific files, the output might still add cached artifacts - // that are not part of the file list to the output, which may cause missing libraries - // error to trigger for files that were not intended to be compiled. - // This behaviour needs to be investigated better on the foundry-compilers side. - // For now we filter, checking only the files passed to compile. - let is_target_file = - self.files.is_empty() || self.files.iter().any(|f| artifact_id.path == *f); - if is_target_file { - if let Some(mls) = artifact.missing_libraries() { - missing_libs_unique.extend(mls.clone()); - } - } - } - - let missing_libs: Vec = missing_libs_unique - .into_iter() - .map(|ml| { - let mut split = ml.split(':'); - let contract_path = - split.next().expect("Failed to extract contract path for missing library"); - let contract_name = - split.next().expect("Failed to extract contract name for missing library"); - - let mut abs_path_buf = PathBuf::new(); - abs_path_buf.push(root_path.as_ref()); - abs_path_buf.push(contract_path); - - let art = output.find(abs_path_buf.as_path(), contract_name).unwrap_or_else(|| { - panic!( - "Could not find contract {contract_name} at path {contract_path} for compilation output" - ) - }); - - ZkMissingLibrary { - contract_path: contract_path.to_string(), - contract_name: contract_name.to_string(), - missing_libraries: art.missing_libraries().cloned().unwrap_or_default(), - } - }) - .collect(); - - if !missing_libs.is_empty() { - libraries::add_dependencies_to_missing_libraries_cache( - root_path, - missing_libs.as_slice(), - ) - .expect("Error while adding missing libraries"); - let missing_libs_list = missing_libs - .iter() - .map(|ml| format!("{}:{}", ml.contract_path, ml.contract_name)) - .collect::>() - .join(", "); - eyre::bail!("Missing libraries detected: {missing_libs_list}\n\nRun the following command in order to deploy each missing library:\n\nforge create --private-key --rpc-url --chain --zksync\n\nThen pass the library addresses using the --libraries option"); - } - // print any sizes or names if print_names { let mut artifacts: BTreeMap<_, Vec<_>> = BTreeMap::new(); diff --git a/crates/config/Cargo.toml b/crates/config/Cargo.toml index b02c9904a..0f0a70087 100644 --- a/crates/config/Cargo.toml +++ b/crates/config/Cargo.toml @@ -48,6 +48,7 @@ yansi.workspace = true # zksync foundry-zksync-compilers.workspace = true +era-solc.workspace = true [target.'cfg(target_os = "windows")'.dependencies] path-slash = "0.2" diff --git a/crates/config/src/zksync.rs b/crates/config/src/zksync.rs index 0181bd18f..12db3a329 100644 --- a/crates/config/src/zksync.rs +++ b/crates/config/src/zksync.rs @@ -1,3 +1,4 @@ +use era_solc::standard_json::input::settings::{error_type::ErrorType, warning_type::WarningType}; use foundry_compilers::{ artifacts::{EvmVersion, Libraries, Severity}, error::SolcError, @@ -11,14 +12,13 @@ use foundry_zksync_compilers::{ zksolc::{ get_solc_version_info, settings::{ - BytecodeHash, Codegen, Optimizer, OptimizerDetails, SettingsMetadata, ZkSolcError, - ZkSolcSettings, ZkSolcWarning, + BytecodeHash, Codegen, Optimizer, OptimizerDetails, SettingsMetadata, + ZkSolcSettings, }, ZkSettings, ZkSolc, ZkSolcCompiler, }, }, }; - use semver::Version; use serde::{Deserialize, Serialize}; use std::{collections::HashSet, path::PathBuf}; @@ -70,10 +70,10 @@ pub struct ZkSyncConfig { pub optimizer_details: Option, // zksolc suppressed warnings. - pub suppressed_warnings: HashSet, + pub suppressed_warnings: HashSet, // zksolc suppressed errors. - pub suppressed_errors: HashSet, + pub suppressed_errors: HashSet, } impl Default for ZkSyncConfig { @@ -198,7 +198,7 @@ pub fn config_create_project( { zksolc } else if !config.offline { - let default_version = semver::Version::new(1, 5, 7); + let default_version = semver::Version::new(1, 5, 10); let mut zksolc = ZkSolc::find_installed_version(&default_version)?; if zksolc.is_none() { ZkSolc::blocking_install(&default_version)?; diff --git a/crates/forge/tests/it/test_helpers.rs b/crates/forge/tests/it/test_helpers.rs index b8be5ce8e..a9d34e679 100644 --- a/crates/forge/tests/it/test_helpers.rs +++ b/crates/forge/tests/it/test_helpers.rs @@ -201,7 +201,7 @@ impl ForgeTestProfile { zk_config.zksync.startup = true; zk_config.zksync.fallback_oz = true; zk_config.zksync.optimizer_mode = '3'; - zk_config.zksync.zksolc = Some(foundry_config::SolcReq::Version(Version::new(1, 5, 7))); + zk_config.zksync.zksolc = Some(foundry_config::SolcReq::Version(Version::new(1, 5, 10))); zk_config.fuzz.no_zksync_reserved_addresses = true; zk_config.invariant.depth = 15; diff --git a/crates/script/src/verify.rs b/crates/script/src/verify.rs index bf224f041..0ccc9a323 100644 --- a/crates/script/src/verify.rs +++ b/crates/script/src/verify.rs @@ -210,7 +210,7 @@ impl VerifyBundle { let contract_bytecode_hash = foundry_zksync_core::hash_bytecode(bytecode); if bytecode_hash == contract_bytecode_hash { - if artifact.source.extension().map_or(false, |e| e.to_str() == Some("vy")) { + if artifact.source.extension().is_some_and(|e| e.to_str() == Some("vy")) { warn!("Skipping verification of Vyper contract: {}", artifact.name); } diff --git a/crates/zksync/compilers/Cargo.toml b/crates/zksync/compilers/Cargo.toml index 40c345eb5..75168a002 100644 --- a/crates/zksync/compilers/Cargo.toml +++ b/crates/zksync/compilers/Cargo.toml @@ -31,6 +31,7 @@ path-slash = "0.2" # zk zksync_types.workspace = true +era-solc.workspace = true [dev-dependencies] similar-asserts.workspace = true diff --git a/crates/zksync/compilers/src/compilers/zksolc/input.rs b/crates/zksync/compilers/src/compilers/zksolc/input.rs index 3172e518c..ffa4cbdc7 100644 --- a/crates/zksync/compilers/src/compilers/zksolc/input.rs +++ b/crates/zksync/compilers/src/compilers/zksolc/input.rs @@ -1,8 +1,6 @@ //! zksolc input -use super::{ - settings::{ZkSolcError, ZkSolcSettings, ZkSolcWarning}, - ZkSettings, -}; +use super::{settings::ZkSolcSettings, ZkSettings}; +use era_solc::standard_json::input::settings::{error_type::ErrorType, warning_type::WarningType}; use foundry_compilers::{ compilers::{solc::SolcLanguage, CompilerInput}, solc, @@ -88,10 +86,10 @@ pub struct ZkSolcInput { // 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, + pub suppressed_warnings: HashSet, /// suppressed errors #[serde(default, skip_serializing_if = "HashSet::is_empty")] - pub suppressed_errors: HashSet, + pub suppressed_errors: HashSet, } /// Default `language` field is set to `"Solidity"`. diff --git a/crates/zksync/compilers/src/compilers/zksolc/mod.rs b/crates/zksync/compilers/src/compilers/zksolc/mod.rs index 3c29ef998..113abb301 100644 --- a/crates/zksync/compilers/src/compilers/zksolc/mod.rs +++ b/crates/zksync/compilers/src/compilers/zksolc/mod.rs @@ -40,7 +40,7 @@ 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); +pub const ZKSOLC_VERSION: Version = Version::new(1, 5, 10); #[cfg(test)] macro_rules! take_solc_installer_lock { diff --git a/crates/zksync/compilers/src/compilers/zksolc/settings.rs b/crates/zksync/compilers/src/compilers/zksolc/settings.rs index e111a4eb8..904175666 100644 --- a/crates/zksync/compilers/src/compilers/zksolc/settings.rs +++ b/crates/zksync/compilers/src/compilers/zksolc/settings.rs @@ -1,5 +1,6 @@ //! zksolc settings use crate::artifacts::output_selection::OutputSelection as ZkOutputSelection; +use era_solc::standard_json::input::settings::{error_type::ErrorType, warning_type::WarningType}; use foundry_compilers::{ artifacts::{serde_helpers, EvmVersion, Libraries}, compilers::CompilerSettings, @@ -14,7 +15,6 @@ use std::{ path::{Path, PathBuf}, str::FromStr, }; - /// /// The Solidity compiler codegen. #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] @@ -27,45 +27,6 @@ pub enum Codegen { EVMLA, } -/// `zksolc` warnings that can be suppressed. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] -#[serde(rename_all = "lowercase")] -#[non_exhaustive] -pub enum ZkSolcWarning { - /// `txorigin` warning: Using `tx.origin` in place of `msg.sender`. - TxOrigin, -} - -impl FromStr for ZkSolcWarning { - type Err = String; - fn from_str(s: &str) -> Result { - match s { - "txorigin" => Ok(Self::TxOrigin), - s => Err(format!("Unknown zksolc warning: {s}")), - } - } -} - -/// `zksolc` errors that can be suppressed. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] -#[serde(rename_all = "lowercase")] -#[non_exhaustive] -pub enum ZkSolcError { - /// `sendtransfer` error: Using `send()` or `transfer()` methods on `address payable` instead - /// of `call()`. - SendTransfer, -} - -impl FromStr for ZkSolcError { - type Err = String; - fn from_str(s: &str) -> Result { - match s { - "sendtransfer" => Ok(Self::SendTransfer), - s => Err(format!("Unknown zksolc error: {s}")), - } - } -} - /// zksolc standard json input settings. See: /// https://docs.zksync.io/zk-stack/components/compiler/toolchain/solidity.html#standard-json for differences #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] @@ -122,10 +83,10 @@ pub struct ZkSettings { pub force_evmla: bool, /// Suppressed `zksolc` warnings. #[serde(default, skip_serializing_if = "HashSet::is_empty")] - pub suppressed_warnings: HashSet, + pub suppressed_warnings: HashSet, /// Suppressed `zksolc` errors. #[serde(default, skip_serializing_if = "HashSet::is_empty")] - pub suppressed_errors: HashSet, + pub suppressed_errors: HashSet, } /// Analogous to SolcSettings for zksolc compiler diff --git a/crates/zksync/compilers/tests/zksync_tests.rs b/crates/zksync/compilers/tests/zksync_tests.rs index c78545951..bb3e4a2d1 100644 --- a/crates/zksync/compilers/tests/zksync_tests.rs +++ b/crates/zksync/compilers/tests/zksync_tests.rs @@ -11,15 +11,12 @@ use foundry_test_utils::foundry_compilers::{ CompilerOutput, Graph, ProjectBuilder, ProjectPathsConfig, }; +use era_solc::standard_json::input::settings::{error_type::ErrorType, warning_type::WarningType}; use foundry_zksync_compilers::{ artifacts::{contract::Contract, error::Error}, compilers::{ artifact_output::zk::ZkArtifactOutput, - zksolc::{ - input::ZkSolcInput, - settings::{ZkSolcError, ZkSolcWarning}, - ZkSolc, ZkSolcCompiler, ZkSolcSettings, - }, + zksolc::{input::ZkSolcInput, ZkSolc, ZkSolcCompiler, ZkSolcSettings}, }, }; @@ -82,7 +79,7 @@ fn test_zksync_can_compile_contract_with_suppressed_errors(compiler: ZkSolcCompi assert!(compiled.has_compiler_errors()); project.project_mut().settings.settings.suppressed_errors = - HashSet::from([ZkSolcError::SendTransfer]); + HashSet::from([ErrorType::SendTransfer]); let compiled = project.compile().unwrap(); compiled.assert_success(); @@ -139,7 +136,7 @@ fn test_zksync_can_compile_contract_with_suppressed_warnings(compiler: ZkSolcCom ); project.project_mut().settings.settings.suppressed_warnings = - HashSet::from([ZkSolcWarning::TxOrigin]); + HashSet::from([WarningType::TxOrigin]); let compiled = project.compile().unwrap(); compiled.assert_success(); @@ -169,6 +166,69 @@ fn zksync_pre_1_5_7_can_compile_contract_with_suppressed_warnings() { test_zksync_can_compile_contract_with_suppressed_warnings(compiler); } +fn test_zksync_can_compile_contract_with_assembly_create_suppressed_warnings( + compiler: ZkSolcCompiler, +) { + let mut project = TempProject::::dapptools().unwrap(); + project.project_mut().compiler = compiler; + + project + .add_source( + "Warning", + r#" + // SPDX-License-Identifier: MIT OR Apache-2.0 + pragma solidity ^0.8.10; + contract Warning { + function deployWithCreate(bytes memory bytecode) public returns (address addr) { + assembly { + addr := create(0, add(bytecode, 0x20), mload(bytecode)) + } + } + } + "#, + ) + .unwrap(); + + // Compile the project and ensure it succeeds with warnings + let compiled = project.compile().unwrap(); + compiled.assert_success(); + assert!( + compiled + .output() + .errors + .iter() + .any(|err| err.is_warning() && err.message.contains("create")), + "Expected assembly `create` warning, but none found: {:#?}", + compiled.output().errors + ); + + project.project_mut().settings.settings.suppressed_warnings = + HashSet::from([WarningType::AssemblyCreate]); + + let compiled = project.compile().unwrap(); + compiled.assert_success(); + assert!(compiled.find_first("Warning").is_some()); + + assert!( + !compiled + .output() + .errors + .iter() + .any(|err| err.is_warning() && err.message.contains("create")), + "Assembly `create` warning was not suppressed: {:#?}", + compiled.output().errors + ) +} + +#[test] +fn zksync_can_compile_contract_with_assembly_create_suppressed_warnings_1_5_10() { + let compiler = ZkSolcCompiler { + zksolc: ZkSolc::get_path_for_version(&semver::Version::new(1, 5, 10)).unwrap(), + solc: Default::default(), + }; + test_zksync_can_compile_contract_with_assembly_create_suppressed_warnings(compiler); +} + #[test] fn zksync_can_compile_dapp_detect_changes_in_libs() { // let _ = tracing_subscriber::fmt() @@ -496,7 +556,7 @@ contract Util {} assert!(compiled.output().errors.iter().any(|error| error .formatted_message .as_ref() - .map_or(false, |msg| msg.contains("File outside of allowed directories")))); + .is_some_and(|msg| msg.contains("File outside of allowed directories")))); } #[test]