diff --git a/Cargo.lock b/Cargo.lock index a167fa83..7b610881 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,18 +19,24 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "anyhow" -version = "1.0.80" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" + +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" [[package]] name = "arrayvec" @@ -57,20 +63,20 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] name = "autocfg" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ "addr2line", "cc", @@ -128,9 +134,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" dependencies = [ "serde", ] @@ -185,15 +191,19 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cc" version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +dependencies = [ + "jobserver", + "libc", +] [[package]] name = "cfg-if" @@ -259,6 +269,21 @@ dependencies = [ "zkevm_tester", ] +[[package]] +name = "compiler-tester-fuzz" +version = "0.0.0" +dependencies = [ + "anyhow", + "compiler-tester", + "era-compiler-llvm-context", + "era-compiler-solidity", + "libfuzzer-sys", + "semver", + "solidity-adapter", + "zkevm-assembly", + "zkevm_tester", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -362,9 +387,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "zeroize", @@ -476,7 +501,7 @@ dependencies = [ [[package]] name = "era-compiler-llvm-context" version = "1.4.1" -source = "git+https://github.com/matter-labs/era-compiler-llvm-context?branch=main#f1ae37a655c55ddc9c0bf08f3fbd00f99d38809e" +source = "git+https://github.com/matter-labs/era-compiler-llvm-context?branch=main#7a7d7f8d1772c558c9dc6543148176700a6d9d51" dependencies = [ "anyhow", "era-compiler-common", @@ -498,7 +523,7 @@ dependencies = [ [[package]] name = "era-compiler-solidity" version = "1.4.1" -source = "git+https://github.com/matter-labs/era-compiler-solidity?branch=main#25ef5438bcfbf5cfb773214830d56cec52f0aabd" +source = "git+https://github.com/matter-labs/era-compiler-solidity?branch=main#6a2861cc6fb7557bee9a2aa29075c950e9020b34" dependencies = [ "anyhow", "colored", @@ -526,8 +551,8 @@ dependencies = [ [[package]] name = "era-compiler-vyper" -version = "1.4.0" -source = "git+https://github.com/matter-labs/era-compiler-vyper?branch=main#f60d8409b42e8da3f0999e862338f3961045629a" +version = "1.4.1" +source = "git+https://github.com/matter-labs/era-compiler-vyper?branch=main#8c58782c8bb18cbd5abaf0c5bf0ce8f79f3d6444" dependencies = [ "anyhow", "colored", @@ -733,7 +758,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] @@ -819,9 +844,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.24" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", @@ -1046,9 +1071,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.5" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown", @@ -1095,9 +1120,18 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "jobserver" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +dependencies = [ + "libc", +] [[package]] name = "js-sys" @@ -1158,6 +1192,17 @@ version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +[[package]] +name = "libfuzzer-sys" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" +dependencies = [ + "arbitrary", + "cc", + "once_cell", +] + [[package]] name = "libmath" version = "0.2.1" @@ -1219,9 +1264,9 @@ checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "mimalloc" @@ -1367,7 +1412,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] @@ -1463,14 +1508,14 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -1553,9 +1598,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -1654,9 +1699,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4963ed1bc86e4f3ee217022bd855b297cef07fb9eac5dfa1f788b220b49b3bd" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -1692,9 +1737,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.3" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", @@ -1715,15 +1760,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "reqwest" -version = "0.11.25" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eea5a9eb898d3783f17c6407670e3592fd174cb81a10e51d4c37f49450b9946" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ "base64", "bytes", @@ -1802,7 +1847,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ "base64", - "bitflags 2.4.2", + "bitflags 2.5.0", "serde", "serde_derive", ] @@ -1830,11 +1875,11 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.31" +version = "0.38.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "errno", "libc", "linux-raw-sys", @@ -1880,9 +1925,9 @@ checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "scale-info" -version = "2.10.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7d66a1128282b7ef025a8ead62a4a9fcf017382ec53b8ffbf4d7bf77bd3c60" +checksum = "788745a868b0e751750388f4e6546eb921ef714a4317fa6954f7cde114eb2eb7" dependencies = [ "bitvec", "cfg-if", @@ -1893,9 +1938,9 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.10.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf2c68b89cafb3b8d918dd07b42be0da66ff202cf1155c5739a4e0c1ea0dc19" +checksum = "7dc2f4e8bc344b9fc3d5f74f72c2e55bfc38d28dc2ebc69c194a3df424e4d9ac" dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", @@ -1977,14 +2022,14 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" dependencies = [ "itoa", "ryu", @@ -2015,9 +2060,9 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.32" +version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd075d994154d4a774f95b51fb96bdc2832b0ea48425c92546073816cda1f2f" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ "indexmap", "itoa", @@ -2079,9 +2124,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" @@ -2187,9 +2232,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.52" +version = "2.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" +checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" dependencies = [ "proc-macro2", "quote", @@ -2204,20 +2249,20 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "system-configuration" -version = "0.6.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bc6ee10a9b4fcf576e9b0819d95ec16f4d2c02d39fd83ac1c8789785c4a42" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ - "bitflags 2.4.2", + "bitflags 1.3.2", "core-foundation", "system-configuration-sys", ] [[package]] name = "system-configuration-sys" -version = "0.6.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" dependencies = [ "core-foundation-sys", "libc", @@ -2249,22 +2294,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.57" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] @@ -2293,9 +2338,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.36.0" +version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" dependencies = [ "backtrace", "bytes", @@ -2383,7 +2428,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", ] [[package]] @@ -2454,9 +2499,9 @@ checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] name = "unsafe-libyaml" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] name = "untrusted" @@ -2523,7 +2568,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", "wasm-bindgen-shared", ] @@ -2557,7 +2602,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.52", + "syn 2.0.58", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2876,7 +2921,7 @@ name = "zkevm_opcode_defs" version = "1.4.1" source = "git+https://github.com/matter-labs/era-zkevm_opcode_defs?branch=v1.4.1#ba8228ff0582d21f64d6a319d50d0aec48e9e7b6" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.5.0", "blake2", "ethereum-types", "k256", diff --git a/Cargo.toml b/Cargo.toml index b6cba5bd..064aa885 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,5 +4,6 @@ members = [ "solidity_adapter", "coverage_watcher", "benchmark_analyzer", + "fuzz" ] resolver = "2" diff --git a/LLVM.lock b/LLVM.lock index e59e9c5e..d400a48b 100644 --- a/LLVM.lock +++ b/LLVM.lock @@ -1,2 +1,6 @@ url = "https://github.com/matter-labs/era-compiler-llvm" +<<<<<<< HEAD branch = "v1.4.1" +======= +branch = "main" +>>>>>>> d020375 (Final sync with the private repo) diff --git a/README.md b/README.md index 35afb3cf..bdb9efc7 100644 --- a/README.md +++ b/README.md @@ -129,7 +129,11 @@ Use: - Yul optimizations enabled (`+`) - level 3 optimizations in LLVM middle-end (`M3`) - level 3 optimizations in LLVM back-end (`B3`) +<<<<<<< HEAD - Solidity compiler version (`0.8.24`) +======= +- Solidity compiler version (`0.8.23`) +>>>>>>> d020375 (Final sync with the private repo) Output: @@ -140,7 +144,11 @@ Output: ```bash cargo run --release --bin compiler-tester -- -DT \ --path='tests/solidity/simple/default.sol' \ +<<<<<<< HEAD --mode='Y+M3B3 0.8.24' \ +======= + --mode='Y+M3B3 0.8.23' \ +>>>>>>> d020375 (Final sync with the private repo) --zksolc '../era-compiler-solidity/target/release/zksolc' ``` @@ -191,7 +199,11 @@ zkevm-llvm checkout && zkevm-llvm build ``` ./target/release/compiler-tester \ --path='tests/solidity/simple/default.sol' \ +<<<<<<< HEAD --mode='Y+M^B3 0.8.24' \ +======= + --mode='Y+M^B3 0.8.23' \ +>>>>>>> d020375 (Final sync with the private repo) --benchmark='reference.json' ``` @@ -204,7 +216,11 @@ zkevm-llvm checkout && zkevm-llvm build ``` ./target/release/compiler-tester \ --path='tests/solidity/simple/default.sol' \ +<<<<<<< HEAD --mode='Y+M^B3 0.8.24' \ +======= + --mode='Y+M^B3 0.8.23' \ +>>>>>>> d020375 (Final sync with the private repo) --benchmark='candidate.json' ``` diff --git a/compiler_tester/Cargo.toml b/compiler_tester/Cargo.toml index e7f03cb7..10efbdda 100644 --- a/compiler_tester/Cargo.toml +++ b/compiler_tester/Cargo.toml @@ -47,6 +47,11 @@ era-compiler-llvm-context = { git = "https://github.com/matter-labs/era-compiler era-compiler-solidity = { git = "https://github.com/matter-labs/era-compiler-solidity", branch = "main" } era-compiler-vyper = { git = "https://github.com/matter-labs/era-compiler-vyper", branch = "main" } +# era-compiler-common = { path = "../../era-compiler-common" } +# era-compiler-llvm-context = { path = "../../era-compiler-llvm-context" } +# era-compiler-solidity = { path = "../../era-compiler-solidity" } +# era-compiler-vyper = { path = "../../era-compiler-vyper" } + solidity-adapter = { path = "../solidity_adapter" } benchmark-analyzer = { path = "../benchmark_analyzer" } diff --git a/compiler_tester/src/compilers/eravm.rs b/compiler_tester/src/compilers/eravm.rs index fc9e9fd3..50e8da1e 100644 --- a/compiler_tester/src/compilers/eravm.rs +++ b/compiler_tester/src/compilers/eravm.rs @@ -19,6 +19,15 @@ use crate::vm::evm::input::Input as EVMInput; #[allow(non_camel_case_types)] pub struct EraVMCompiler; +impl EraVMCompiler { + /// + /// A shortcut constructor. + /// + pub fn new() -> Self { + Self::default() + } +} + impl Compiler for EraVMCompiler { fn compile_for_eravm( &self, diff --git a/compiler_tester/src/compilers/llvm.rs b/compiler_tester/src/compilers/llvm.rs index 902f452a..94ad2a85 100644 --- a/compiler_tester/src/compilers/llvm.rs +++ b/compiler_tester/src/compilers/llvm.rs @@ -33,6 +33,15 @@ lazy_static::lazy_static! { }; } +impl LLVMCompiler { + /// + /// A shortcut constructor. + /// + pub fn new() -> Self { + Self::default() + } +} + impl Compiler for LLVMCompiler { fn compile_for_eravm( &self, diff --git a/compiler_tester/src/compilers/solidity/mod.rs b/compiler_tester/src/compilers/solidity/mod.rs index 3a84918c..872d3cbc 100644 --- a/compiler_tester/src/compilers/solidity/mod.rs +++ b/compiler_tester/src/compilers/solidity/mod.rs @@ -178,6 +178,7 @@ impl SolidityCompiler { &mode.solc_version, false, false, + None, ); let evm_version = if mode.solc_version == semver::Version::new(0, 8, 24) { diff --git a/compiler_tester/src/compilers/yul.rs b/compiler_tester/src/compilers/yul.rs index 8208185d..97d361fb 100644 --- a/compiler_tester/src/compilers/yul.rs +++ b/compiler_tester/src/compilers/yul.rs @@ -33,6 +33,15 @@ lazy_static::lazy_static! { }; } +impl YulCompiler { + /// + /// A shortcut constructor. + /// + pub fn new() -> Self { + Self::default() + } +} + impl Compiler for YulCompiler { fn compile_for_eravm( &self, diff --git a/compiler_tester/src/directories/ethereum/test.rs b/compiler_tester/src/directories/ethereum/test.rs index b49f874f..ff2671c9 100644 --- a/compiler_tester/src/directories/ethereum/test.rs +++ b/compiler_tester/src/directories/ethereum/test.rs @@ -25,9 +25,9 @@ use crate::vm::AddressPredictorIterator; /// pub struct EthereumTest { /// The index test entity. - index_entity: solidity_adapter::EnabledTest, + pub index_entity: solidity_adapter::EnabledTest, /// The test data. - test: solidity_adapter::Test, + pub test: solidity_adapter::Test, } impl EthereumTest { diff --git a/compiler_tester/src/lib.rs b/compiler_tester/src/lib.rs index a80f364f..26d7dae7 100644 --- a/compiler_tester/src/lib.rs +++ b/compiler_tester/src/lib.rs @@ -27,18 +27,20 @@ use itertools::Itertools; use rayon::iter::IntoParallelIterator; use rayon::iter::ParallelIterator; -use crate::compilers::eravm::EraVMCompiler; -use crate::compilers::llvm::LLVMCompiler; -use crate::compilers::mode::Mode; -use crate::compilers::solidity::SolidityCompiler; -use crate::compilers::vyper::VyperCompiler; -use crate::compilers::yul::YulCompiler; -use crate::compilers::Compiler; -use crate::directories::ethereum::EthereumDirectory; -use crate::directories::matter_labs::MatterLabsDirectory; -use crate::directories::Buildable; -use crate::directories::TestsDirectory; -use crate::vm::eravm::deployers::Deployer as EraVMDeployer; +pub use crate::compilers::eravm::EraVMCompiler; +pub use crate::compilers::llvm::LLVMCompiler; +pub use crate::compilers::mode::solidity::Mode as SolidityMode; +pub use crate::compilers::mode::Mode; +pub use crate::compilers::solidity::SolidityCompiler; +pub use crate::compilers::vyper::VyperCompiler; +pub use crate::compilers::yul::YulCompiler; +pub use crate::compilers::Compiler; +pub use crate::directories::ethereum::test::EthereumTest; +pub use crate::directories::ethereum::EthereumDirectory; +pub use crate::directories::matter_labs::MatterLabsDirectory; +pub use crate::directories::Buildable; +pub use crate::directories::TestsDirectory; +pub use crate::vm::eravm::deployers::Deployer as EraVMDeployer; /// The debug directory path. pub const DEBUG_DIRECTORY: &str = "./debug/"; @@ -56,11 +58,11 @@ type Test = (Arc, Arc, Mode); /// pub struct CompilerTester { /// The summary. - summary: Arc>, + pub summary: Arc>, /// The filters. - filters: Filters, + pub filters: Filters, /// The debug config. - debug_config: Option, + pub debug_config: Option, } impl CompilerTester { @@ -190,9 +192,9 @@ impl CompilerTester { fn all_tests(&self) -> anyhow::Result> { let solidity_compiler = Arc::new(SolidityCompiler::new()); let vyper_compiler = Arc::new(VyperCompiler::new()); - let yul_compiler = Arc::new(YulCompiler); - let llvm_compiler = Arc::new(LLVMCompiler); - let eravm_compiler = Arc::new(EraVMCompiler); + let yul_compiler = Arc::new(YulCompiler::new()); + let llvm_compiler = Arc::new(LLVMCompiler::new()); + let eravm_compiler = Arc::new(EraVMCompiler::new()); let mut tests = Vec::with_capacity(16384); diff --git a/compiler_tester/src/vm/eravm/system_contracts.rs b/compiler_tester/src/vm/eravm/system_contracts.rs index dd20f22a..22a5a349 100644 --- a/compiler_tester/src/vm/eravm/system_contracts.rs +++ b/compiler_tester/src/vm/eravm/system_contracts.rs @@ -230,12 +230,8 @@ impl SystemContracts { yul_file_paths.push(file_path.to_owned()); } let yul_mode = YulMode::new(era_compiler_llvm_context::OptimizerSettings::cycles()).into(); - let mut builds = Self::compile( - YulCompiler, - &yul_mode, - yul_file_paths, - debug_config.clone(), - )?; + let mut builds = + Self::compile(YulCompiler, &yul_mode, yul_file_paths, debug_config.clone())?; let mut solidity_file_paths = Vec::with_capacity(solidity_system_contracts.len() + 1); for (_, path) in solidity_system_contracts.iter() { diff --git a/configs/solc-bin-default.json b/configs/solc-bin-default.json index 6c0700a0..de77783d 100644 --- a/configs/solc-bin-default.json +++ b/configs/solc-bin-default.json @@ -463,6 +463,12 @@ "destination": "./solc-bin/solc-${VERSION}" }, "0.8.24": { + "is_enabled": false, + "protocol": "https", + "source": "https://github.com/matter-labs/era-solidity/releases/download/${VERSION}-1.0.0/solc-${PLATFORM}-${VERSION}-1.0.0", + "destination": "./solc-bin/solc-${VERSION}" + }, + "0.8.25": { "is_enabled": true, "protocol": "https", "source": "https://github.com/matter-labs/era-solidity/releases/download/${VERSION}-1.0.0/solc-${PLATFORM}-${VERSION}-1.0.0", diff --git a/configs/solc-bin-zkevm-candidate-0.8.25.json b/configs/solc-bin-zkevm-candidate-0.8.25.json new file mode 100644 index 00000000..7e331a7f --- /dev/null +++ b/configs/solc-bin-zkevm-candidate-0.8.25.json @@ -0,0 +1,16 @@ +{ + "binaries": { + "0.8.25": { + "is_enabled": true, + "protocol": "file", + "source": "./solc-bin/solc-${VERSION}", + "destination": "./solc-bin/solc-${VERSION}" + } + }, + "platforms": { + "linux-amd64": "linux-amd64", + "linux-arm64": "linux-arm64", + "macos-amd64": "macosx-amd64", + "macos-arm64": "macosx-arm64" + } +} diff --git a/configs/solc-bin-zkevm-reference-0.8.25.json b/configs/solc-bin-zkevm-reference-0.8.25.json new file mode 100644 index 00000000..297ce19e --- /dev/null +++ b/configs/solc-bin-zkevm-reference-0.8.25.json @@ -0,0 +1,16 @@ +{ + "binaries": { + "0.8.25": { + "is_enabled": true, + "protocol": "https", + "source": "https://github.com/matter-labs/era-solidity/releases/download/${VERSION}-1.0.0/solc-${PLATFORM}-${VERSION}-1.0.0", + "destination": "./solc-bin/solc-${VERSION}" + } + }, + "platforms": { + "linux-amd64": "linux-amd64", + "linux-arm64": "linux-arm64", + "macos-amd64": "macosx-amd64", + "macos-arm64": "macosx-arm64" + } +} diff --git a/fuzz/.gitignore b/fuzz/.gitignore new file mode 100644 index 00000000..1a45eee7 --- /dev/null +++ b/fuzz/.gitignore @@ -0,0 +1,4 @@ +target +corpus +artifacts +coverage diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml new file mode 100644 index 00000000..c6c457e6 --- /dev/null +++ b/fuzz/Cargo.toml @@ -0,0 +1,38 @@ +[package] +name = "compiler-tester-fuzz" +version = "0.0.0" +publish = false +edition = "2021" + +[package.metadata] +cargo-fuzz = true + +[dependencies] +libfuzzer-sys = "0.4" +era-compiler-llvm-context = { git = "https://github.com/matter-labs/era-compiler-llvm-context", branch = "main" } +era-compiler-solidity = { git = "https://github.com/matter-labs/era-compiler-solidity", branch = "main" } +zkevm-assembly = { git = "https://github.com/matter-labs/era-zkEVM-assembly", branch = "v1.4.1" } +zkevm_tester = { git = "https://github.com/matter-labs/era-zkevm_tester", branch = "v1.4.1" } +anyhow = "1.0" +semver = { version = "1.0", features = ["serde"] } + +[dependencies.compiler-tester] +path = "../compiler_tester" + +[dependencies.solidity-adapter] +path = "../solidity_adapter" + + +[[bin]] +name = "demo" +path = "fuzz_targets/demo.rs" +test = false +doc = false +bench = false + +[[bin]] +name = "optimizer_bug" +path = "fuzz_targets/optimizer_bug.rs" +test = false +doc = false +bench = false diff --git a/fuzz/README.md b/fuzz/README.md new file mode 100644 index 00000000..065c5cc6 --- /dev/null +++ b/fuzz/README.md @@ -0,0 +1,52 @@ +# Solidity Contracts Fuzzing + +This is the skeleton for Solidity smart contracts fuzzing based on the [Rust fuzz](https://rust-fuzz.github.io/book/introduction.html) engine. + +## Project structure + +The project consists of the following directories: + +- `fuzz_contracts` - Solidity smart contracts to be fuzzed. +- `fuzz_targets` - fuzzing targets definitions. + +### Fuzzing targets + +Each fuzzing target is a separate Rust binary crate and defined in the `fuzz_targets` directory. The `Cargo.toml` file in the root directory contains the dependencies and the configuration for the fuzzing engine. + +For example, the `simple` fuzzing target is defined in the `fuzz_targets/simple.rs` file. The `Cargo.toml` file contains the following section: + +```properties +[[bin]] +name = "simple" +path = "fuzz_targets/simple.rs" +... +``` + +`cargo fuzz add ` command can be used to add a new empty fuzzing target. + +## Running fuzzing + +To run the fuzzing, execute the following command: + +```bash +cargo fuzz run +``` + +## Supported targets + +- [`demo`](./fuzz_contracts/demo/demo.md) - demonstrates the basic fuzzing setup. +- `optimizer_bug` - demonstrates fuzzer finding a bug in the optimizer. + +## Current limitations + +- The current setup uses the fixed hardcoded version of optimization settings (`Y+M3B3`) and `solc` compiler version (`0.8.24`). +- The current targets are using the simplest contracts and fuzzing strategy that mutates only the function arguments. +- The current setup uses only EraVM as the execution engine as well as `EthereumTest` as the test type. + +## Roadmap + +- [ ] Add the ability to specify the optimization settings and compiler versions. +- [ ] Support for more complex contracts (real-life use cases). +- [ ] Support on-the-fly fuzzing function generation. +- [ ] Support mutating of the contract source code with Solidity vocabulary. +- [ ] Support CI execution in OSS Fuzz infrastructure. diff --git a/fuzz/fuzz_contracts/demo/demo.md b/fuzz/fuzz_contracts/demo/demo.md new file mode 100644 index 00000000..60db8469 --- /dev/null +++ b/fuzz/fuzz_contracts/demo/demo.md @@ -0,0 +1,119 @@ +# Demo fuzzing target + +This tutorial demonstrates the basic fuzzing setup for a demo Solidity smart contract. + +As part of this tutorial, we will: + +1. Define a Solidity contract to fuzz. +2. Define a fuzzing target. +3. Run the fuzzing. +4. Analyze the results. + +## 1. Contract to fuzz + +As a demo example, we will use the following simple Solidity contract: + +```solidity +contract test { + function should_always_return_0(uint8 input) public pure returns (uint8) { + if (input == 10) { + return 1; + } + return 0; + } +} +``` + +As you can see, the contract has a single function `should_always_return_0` that returns `1` if the input is `10` and `0` otherwise. Our goal is to fuzz this function and find the "edge case" when the function returns `1`. + +## 2. Defining fuzzing target + +Our Rust fuzzing target will call the `should_always_return_0` function with with the inputs generated by the fuzzer and check if the output is `0`. Our goal is to find the input that will make the function return `1`. + +When we define fuzzing target in the `fuzz_targets/demo.rs` file, we should provide the following: + +1. The input contract file path. +2. The function to fuzz. +3. The input parameter types. +4. The expected output. + +Here is the example of the `FuzzingCase` structure definition for the `fuzz_targets/demo.rs` target: + +```rust +let case = common::FuzzingCase { + contract_path: String::from("fuzz/fuzz_contracts/demo/demo.sol"), + function_name: String::from("should_always_return_0"), + input_types: vec![common::TypeVariant::integer_unsigned(8)], // <-- input types must match the contract function signature + inputs: vec![common::integer_literal(data)], // <-- use the fuzzer input here + expected_output: common::integer_literal(0), // <-- expect the output to be 0 +}; +``` + +It's important that the input types and the expected output are defined correctly to match the contract function signature. Otherwise, the contract function will throw an exception and the fuzzing fails. + +After defining the fuzzing case, we can generate the test and execute it: + +```rust +// Generate fuzzing test +let test = common::gen_fuzzing_test(case).expect("Error: cannot build fuzzing test!"); +// Run test and check the results +let result = common::build_and_run(test).expect("Error: cannot execute fuzzing test!"); +// Check if the test was successful +assert!(result.is_successful()) +``` + +## 3. Running the fuzzing + +To run the fuzzing, execute the following command: + +```bash +cargo fuzz run demo +``` + +The fuzzer will start generating the inputs and running the tests. If the fuzzer finds the input that makes the function return `1`, it will report the test as failed and stops fuzzing. + +## 4. Analyzing the results + +Sooner or later, the fuzzer will find the input that makes the function return `1`. The fuzzer will report the test as failed and stop fuzzing. + +Here is an example of the output: + +```bash +INFO: Running with entropic power schedule (0xFF, 100). +INFO: Seed: 1801896173 +INFO: Loaded 1 modules (1847630 inline 8-bit counters): 1847630 [0x10db478d0, 0x10dd0aa1e), +INFO: Loaded 1 PC tables (1847630 PCs): 1847630 [0x10dd0aa20,0x10f93bf00), +INFO: 24 files found in /Users/abalias/projects/compiler-tester/fuzz/corpus/demo +INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 4096 bytes +INFO: seed corpus: files: 24 min: 1b max: 4b total: 45b rss: 92Mb +Generating fuzzing test with input 47... +Y+M3B3 0.8.24 PASSED fuzz/fuzz_contracts/demo/demo.sol[#deployer:fuzz/fuzz_contracts/demo/demo.sol:test] (size 864, cycles 1550, gas 1125949) +Y+M3B3 0.8.24 PASSED fuzz/fuzz_contracts/demo/demo.sol[should_always_return_0:1] (cycles 29, gas 348) +Generating fuzzing test with input 39... +Y+M3B3 0.8.24 PASSED fuzz/fuzz_contracts/demo/demo.sol[#deployer:fuzz/fuzz_contracts/demo/demo.sol:test] (size 864, cycles 1550, gas 1125949) +Y+M3B3 0.8.24 PASSED fuzz/fuzz_contracts/demo/demo.sol[should_always_return_0:1] (cycles 29, gas 348) +... ... +Generating fuzzing test with input 10... + Downloading compiler binaries + Finished downloading compiler binaries in 0m00s + Loaded the System Contracts from `system-contracts-stable-build` + Saved the System Contracts to `system-contracts-stable-build` +Y+M3B3 0.8.24 PASSED fuzz/fuzz_contracts/demo/demo.sol[#deployer:fuzz/fuzz_contracts/demo/demo.sol:test] (size 864, cycles 1550, gas 1125949) +Y+M3B3 0.8.24 FAILED fuzz/fuzz_contracts/demo/demo.sol[should_always_return_0:1] (expected ( + return_data: [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + ], + exception: false, + events: [], +), found ( + return_data: [ + "0x0000000000000000000000000000000000000000000000000000000000000001", + ], + exception: false, + events: [], +), calldata 0a1a369d000000000000000000000000000000000000000000000000000000000000000a) +thread '' panicked at fuzz/fuzz_targets/demo.rs:26:5: +assertion failed: result.is_successful() +``` + +As you can see, the fuzzer found the input `10` that makes the function return `1`. The test failed as expected. diff --git a/fuzz/fuzz_contracts/demo/demo.sol b/fuzz/fuzz_contracts/demo/demo.sol new file mode 100644 index 00000000..04ec2125 --- /dev/null +++ b/fuzz/fuzz_contracts/demo/demo.sol @@ -0,0 +1,11 @@ +contract test { + + function should_always_return_0(uint8 input) public pure returns (uint8) { + if (input == 10) { + return 1; + } + return 0; + } + +} +// ---- diff --git a/fuzz/fuzz_contracts/optimizer_bug/optimizer_bug.sol b/fuzz/fuzz_contracts/optimizer_bug/optimizer_bug.sol new file mode 100644 index 00000000..1d2c8a32 --- /dev/null +++ b/fuzz/fuzz_contracts/optimizer_bug/optimizer_bug.sol @@ -0,0 +1,8 @@ +contract test { + function function_to_fuzz(uint8 a, bool b) external pure returns (uint8) { + uint8 c = b ? 1 : 0; + uint8 d = a + c; // this arithmetic incorrectly throws an overflow panic + return b ? c : d; + } +} +// ---- diff --git a/fuzz/fuzz_targets/common.rs b/fuzz/fuzz_targets/common.rs new file mode 100644 index 00000000..bb2463f0 --- /dev/null +++ b/fuzz/fuzz_targets/common.rs @@ -0,0 +1,208 @@ +use std::{ + path::{Path, PathBuf}, + sync::Arc, +}; + +use compiler_tester::{Buildable, EthereumTest, Mode, SolidityCompiler, SolidityMode, Summary}; +pub use solidity_adapter::{ + test::function_call::parser::{ + lexical::token::{ + lexeme::literal::boolean::Boolean as LexicalBooleanLiteral, + lexeme::literal::integer::Integer, location::Location, + }, + syntax::tree::{ + call::builder::Builder as CallBuilder, + identifier::Identifier, + literal::{ + alignment::Alignment, boolean::Literal as BooleanLiteral, + integer::Literal as IntegerLiteral, Literal, + }, + r#type::{variant::Variant as TypeVariant, Type}, + }, + }, + EnabledTest, FunctionCall, +}; + +use era_compiler_solidity::SolcPipeline; + +/// +/// Fuzzing case definition +/// +pub struct FuzzingCase { + // The path to the contract to fuzz + pub contract_path: String, + // The smart contract function name to fuzz + pub function_name: String, + // The function inputs types + pub input_types: Vec, + // The inputs values + pub inputs: Vec, + // The expected output + pub expected_output: Literal, +} + +/// Create an integer literal primitive from input data +/// +/// # Arguments +/// +/// * `data` - The input data +/// +/// # Returns +/// +/// * `Literal` - The integer literal +/// +pub fn integer_literal(data: T) -> Literal { + Literal::Integer(IntegerLiteral::new( + Location::new(), + Integer::new_decimal(data.to_string(), false), + Alignment::default(), + )) +} + +/// Create a boolean literal primitive from input data +/// +/// # Arguments +/// +/// * `data` - boolean input +/// +/// # Returns +/// +/// * `Literal` - The boolean literal +/// +pub fn boolean_literal(data: bool) -> Literal { + Literal::Boolean(BooleanLiteral::new( + Location::new(), + if data { + LexicalBooleanLiteral::True + } else { + LexicalBooleanLiteral::False + }, + Alignment::default(), + )) +} + +/// Build function call from fuzzing data +/// +/// # Arguments +/// +/// * `case` - The fuzzing case +/// +/// # Returns +/// +/// * `FunctionCall` - The function call +/// +pub fn build_function_call(case: FuzzingCase) -> anyhow::Result { + // Initialize function call builder + let mut builder: CallBuilder = CallBuilder::default(); + builder.set_location(Location::new()); + + // Set function name + builder.set_call(Identifier::new(Location::new(), case.function_name.clone())); + // Set input parameter type + for ftype in case.input_types.iter() { + builder.push_types(Type::new(Location::new(), ftype.clone())); + } + + // Set input parameter value + for input in case.inputs.iter() { + builder.push_input(input.clone()); + } + + // Set expected output + builder.push_expected(case.expected_output.clone()); + + // Finalize function call + let call = builder.finish(); + FunctionCall::try_from(call) +} + +/// Generates fuzzing test +/// +/// # Arguments +/// +/// * `test_path` - The path to the test contract +/// * `data` - The fuzzing data +/// +/// # Returns +/// +/// * `EthereumTest` - The Ethereum test +pub fn gen_fuzzing_test(case: FuzzingCase) -> anyhow::Result { + let test_path = Path::new(&case.contract_path); + + // Generate Test objects for the fuzzing contract + let enabled_test = EnabledTest::new(test_path.to_path_buf(), None, None, None); + let mut test = solidity_adapter::Test::try_from(test_path)?; + let fcall = build_function_call(case)?; + test.calls.push(fcall); + Ok(EthereumTest { + index_entity: enabled_test, + test, + }) +} + +/// Build and run the test +/// +/// # Arguments +/// +/// * `test` - The Ethereum test +/// +/// # Returns +/// +/// * `Summary` - The test summary +pub fn build_and_run(test: EthereumTest) -> anyhow::Result { + // TODO: this should be parametrized + let solc_version = semver::Version::new(0, 8, 24); + let mode = Mode::Solidity(SolidityMode::new( + solc_version, + SolcPipeline::Yul, + true, + true, + era_compiler_llvm_context::OptimizerSettings::try_from_cli('3') + .expect("Error: optimization settings incorrect!"), + )); + + // Initialization + era_compiler_llvm_context::initialize_target(era_compiler_llvm_context::Target::EraVM); + era_compiler_solidity::EXECUTABLE.get_or_try_init(|| -> Result { + Ok(PathBuf::from( + era_compiler_solidity::DEFAULT_EXECUTABLE_NAME, + )) + })?; + compiler_tester::LLVMOptions::initialize(false, false)?; + let compiler_tester = compiler_tester::CompilerTester::new( + compiler_tester::Summary::new(true, false).wrap(), + compiler_tester::Filters::new(vec![], vec![], vec![]), + None, + )?; + zkevm_tester::runners::compiler_tests::set_tracing_mode( + zkevm_tester::runners::compiler_tests::VmTracingOptions::from_u64(0), + ); + zkevm_assembly::set_encoding_mode(zkevm_assembly::RunningVmEncodingMode::Testing); + + // Compile and run test + if let Some(test) = test.build_for_eravm( + mode, + Arc::new(SolidityCompiler::new()), + compiler_tester.summary.clone(), + &compiler_tester.filters, + compiler_tester.debug_config.clone(), + ) { + test.run::( + compiler_tester.summary.clone(), + Arc::new(compiler_tester::EraVM::new( + vec![ + PathBuf::from("./configs/solc-bin-default.json"), + PathBuf::from("./configs/vyper-bin-default.json"), + ], + PathBuf::from("./configs/solc-bin-system-contracts.json"), + None, + Some(PathBuf::from("system-contracts-stable-build")), + Some(PathBuf::from("system-contracts-stable-build")), + )?), + ); + } + + // Get the results + let summary = compiler_tester::Summary::unwrap_arc(compiler_tester.summary); + Ok(summary) +} diff --git a/fuzz/fuzz_targets/demo.rs b/fuzz/fuzz_targets/demo.rs new file mode 100644 index 00000000..691a448e --- /dev/null +++ b/fuzz/fuzz_targets/demo.rs @@ -0,0 +1,31 @@ +//! +//! The fuzzer demo. +//! + +#![no_main] + +/// This module contains the fuzzing target for the simple contract. +use libfuzzer_sys::fuzz_target; + +pub(crate) mod common; + +fuzz_target!(|data: u8| { + // Fuzzing case definition + let case = common::FuzzingCase { + contract_path: String::from("fuzz/fuzz_contracts/demo/demo.sol"), + function_name: String::from("should_always_return_0"), + input_types: vec![common::TypeVariant::integer_unsigned(8)], + inputs: vec![common::integer_literal(data)], + expected_output: common::integer_literal(0), + }; + + // Generate fuzzing test + println!("Generating fuzzing test with input {data}..."); + let test = common::gen_fuzzing_test(case).expect("Error: cannot build fuzzing test!"); + + // Run test and check the results + let result = common::build_and_run(test).expect("Error: cannot execute fuzzing test!"); + + // Check if the test was successful + assert!(result.is_successful()) +}); diff --git a/fuzz/fuzz_targets/optimizer_bug.rs b/fuzz/fuzz_targets/optimizer_bug.rs new file mode 100644 index 00000000..8e01dd16 --- /dev/null +++ b/fuzz/fuzz_targets/optimizer_bug.rs @@ -0,0 +1,32 @@ +//! +//! The optimizer bug demo. +//! + +#![no_main] + +use libfuzzer_sys::fuzz_target; + +pub(crate) mod common; + +fuzz_target!(|data: u8| { + // Fuzzing case definition + let case = common::FuzzingCase { + contract_path: String::from("fuzz/fuzz_contracts/optimizer_bug/optimizer_bug.sol"), + function_name: String::from("function_to_fuzz"), + input_types: vec![ + common::TypeVariant::integer_unsigned(8), + common::TypeVariant::boolean(), + ], + inputs: vec![common::integer_literal(data), common::boolean_literal(true)], + expected_output: common::integer_literal(1), + }; + + // Generate fuzzing test + let test = common::gen_fuzzing_test(case).expect("Error: cannot build fuzzing test!"); + + // Run test and check the results + let result = common::build_and_run(test).expect("Error: cannot execute fuzzing test!"); + + // Check if the test was successful + assert!(result.is_successful()) +}); diff --git a/solidity b/solidity index c0ef06c3..6040a521 160000 --- a/solidity +++ b/solidity @@ -1 +1 @@ -Subproject commit c0ef06c362f86e1e35c4663e27913e1cabd3f5e6 +Subproject commit 6040a521021f8168107ced1b54a21625b8cce632 diff --git a/solidity_adapter/src/lib.rs b/solidity_adapter/src/lib.rs index 6c86c190..9e3a0ed2 100644 --- a/solidity_adapter/src/lib.rs +++ b/solidity_adapter/src/lib.rs @@ -2,8 +2,8 @@ //! The Solidity adapter library. //! -pub(crate) mod index; -mod test; +pub mod index; +pub mod test; use std::ops::Add; use std::str::FromStr; diff --git a/solidity_adapter/src/test/function_call/parser/lexical/mod.rs b/solidity_adapter/src/test/function_call/parser/lexical/mod.rs index 1047b449..1d2d9b2a 100644 --- a/solidity_adapter/src/test/function_call/parser/lexical/mod.rs +++ b/solidity_adapter/src/test/function_call/parser/lexical/mod.rs @@ -5,9 +5,9 @@ #[cfg(test)] mod tests; -mod error; -mod stream; -mod token; +pub mod error; +pub mod stream; +pub mod token; pub use self::error::Error; pub use self::stream::TokenStream; diff --git a/solidity_adapter/src/test/function_call/parser/lexical/token/lexeme/keyword.rs b/solidity_adapter/src/test/function_call/parser/lexical/token/lexeme/keyword.rs index afe1da02..83808cf9 100644 --- a/solidity_adapter/src/test/function_call/parser/lexical/token/lexeme/keyword.rs +++ b/solidity_adapter/src/test/function_call/parser/lexical/token/lexeme/keyword.rs @@ -41,6 +41,8 @@ pub enum Keyword { Legacy, /// The `legacyOptimized` keyword. LegacyOptimized, + /// The `code` keyword. + Code, /// The `bool` type keyword. Bool, @@ -153,6 +155,7 @@ impl TryFrom<&str> for Keyword { "irOptimized" => return Ok(Self::IrOptimized), "legacy" => return Ok(Self::Legacy), "legacyOptimized" => return Ok(Self::LegacyOptimized), + "code" => return Ok(Self::Code), "bool" => return Ok(Self::Bool), "string" => return Ok(Self::String), @@ -249,6 +252,7 @@ impl fmt::Display for Keyword { Self::IrOptimized => write!(f, "irOptimized"), Self::Legacy => write!(f, "legacy"), Self::LegacyOptimized => write!(f, "legacyOptimized"), + Self::Code => write!(f, "code"), Self::Bool => write!(f, "bool"), Self::String => write!(f, "string"), diff --git a/solidity_adapter/src/test/function_call/parser/mod.rs b/solidity_adapter/src/test/function_call/parser/mod.rs index e258099a..fc0f8a1e 100644 --- a/solidity_adapter/src/test/function_call/parser/mod.rs +++ b/solidity_adapter/src/test/function_call/parser/mod.rs @@ -2,8 +2,8 @@ //! The Solidity tests metadata parser. //! -mod lexical; -mod syntax; +pub mod lexical; +pub mod syntax; pub use syntax::Call; pub use syntax::CallVariant; diff --git a/solidity_adapter/src/test/function_call/parser/syntax/mod.rs b/solidity_adapter/src/test/function_call/parser/syntax/mod.rs index 661bfdbc..ddfc528c 100644 --- a/solidity_adapter/src/test/function_call/parser/syntax/mod.rs +++ b/solidity_adapter/src/test/function_call/parser/syntax/mod.rs @@ -4,7 +4,7 @@ mod error; mod parser; -mod tree; +pub mod tree; pub use self::parser::Parser; pub use self::tree::call::variant::Variant as CallVariant; diff --git a/solidity_adapter/src/test/function_call/parser/syntax/parser/event.rs b/solidity_adapter/src/test/function_call/parser/syntax/parser/event.rs index d0cbdc17..d600fa5f 100644 --- a/solidity_adapter/src/test/function_call/parser/syntax/parser/event.rs +++ b/solidity_adapter/src/test/function_call/parser/syntax/parser/event.rs @@ -339,25 +339,23 @@ impl Parser { #[cfg(test)] mod tests { + use crate::test::function_call::parser::lexical::token::lexeme::identifier::Identifier as LexicalIdentifier; + use crate::test::function_call::parser::lexical::IntegerLiteral as LexicalIntegerLiteral; use crate::test::function_call::parser::lexical::Lexeme; - use crate::test::function_call::parser::lexical::Location; - - use crate::test::function_call::parser::lexical::IntegerLiteral as LexicalIntegerLiteral; use crate::test::function_call::parser::lexical::Token; use crate::test::function_call::parser::lexical::TokenStream; - - use super::Parser; use crate::test::function_call::parser::syntax::error::Error as SyntaxError; use crate::test::function_call::parser::syntax::error::ParsingError; + use crate::test::function_call::parser::syntax::parser::event::Parser; use crate::test::function_call::parser::syntax::tree::event::literal::EventLiteral; use crate::test::function_call::parser::syntax::tree::event::variant::Variant; use crate::test::function_call::parser::syntax::tree::event::Event; use crate::test::function_call::parser::syntax::tree::literal::alignment::Alignment; + use crate::test::function_call::parser::syntax::tree::literal::integer::Literal as IntegerLiteral; use crate::test::function_call::parser::syntax::tree::literal::Literal; use crate::test::function_call::parser::syntax::tree::r#type::variant::Variant as TypeVariant; use crate::test::function_call::parser::syntax::Identifier; - use crate::test::function_call::parser::syntax::IntegerLiteral; use crate::test::function_call::parser::syntax::Type; #[test] diff --git a/solidity_adapter/src/test/function_call/parser/syntax/parser/gas.rs b/solidity_adapter/src/test/function_call/parser/syntax/parser/gas.rs index 98441b9f..25b7819a 100644 --- a/solidity_adapter/src/test/function_call/parser/syntax/parser/gas.rs +++ b/solidity_adapter/src/test/function_call/parser/syntax/parser/gas.rs @@ -28,6 +28,8 @@ pub enum State { /// The `gas` has been parsed so far. Variant, /// The `gas {variant}` has been parsed so far. + ColonOrCode, + /// The `gas {variant}` has been parsed so far. Colon, /// The `gas {variant}:` has been parsed so far. Value, @@ -93,7 +95,7 @@ impl Parser { .. } => { self.builder.set_keyword(keyword); - self.state = State::Colon; + self.state = State::ColonOrCode; } Token { lexeme, location } => { return Err(SyntaxError::new( @@ -104,6 +106,24 @@ impl Parser { .into()); } }, + State::ColonOrCode => match parser::take_or_next(self.next.take(), stream.clone())? + { + Token { + lexeme: Lexeme::Keyword(Keyword::Code), + .. + } => { + self.state = State::Colon; + } + Token { + lexeme: Lexeme::Symbol(Symbol::Colon), + .. + } => { + self.state = State::Value; + } + Token { lexeme, location } => { + return Err(SyntaxError::new(location, vec!["code", ":"], lexeme).into()); + } + }, State::Colon => match parser::take_or_next(self.next.take(), stream.clone())? { Token { lexeme: Lexeme::Symbol(Symbol::Colon), diff --git a/system-contracts-stable-build b/system-contracts-stable-build index b559b130..01e0ffd8 100644 Binary files a/system-contracts-stable-build and b/system-contracts-stable-build differ diff --git a/tests b/tests index 102f0fdd..a61b8159 160000 --- a/tests +++ b/tests @@ -1 +1 @@ -Subproject commit 102f0fddf185b9b6eaf1a96ab9c2693c1f05ed56 +Subproject commit a61b815996bc623b5bc4adfe232b418a4253bb5c