From a7403c97e85611ca26022fe48ee6ef8e97725cc7 Mon Sep 17 00:00:00 2001 From: Maddiaa <47148561+Maddiaa0@users.noreply.github.com> Date: Sat, 8 Jul 2023 09:33:16 -0600 Subject: [PATCH] feat(huffc): enable specifying evm version (#281) * feat: make literal gen reusable and default to push0 * feat: update tests to reflect push0 codegen change * feat: make changes, cleanup doc tests * feat: evm version scaffold * feat: user can specify whether to implement push0 * chore(huffc): bump packages version * fix: update tests to use evm_version * feat: add paris codegen tests * fix: clippy * fix: update benchmarks clean * fix: rename is_shanghai to has_push0 * revert: accidental removal of help * chore: update lock * chore(lint): clippy + fmt --------- Co-authored-by: Philogy Co-authored-by: Maddiaa0 --- Cargo.lock | 400 ++++++++++-------- README.md | 45 +- huff_cli/Cargo.toml | 2 +- huff_cli/README.md | 90 +++- huff_cli/src/huffc.rs | 12 +- huff_codegen/Cargo.toml | 2 +- huff_codegen/README.md | 14 +- huff_codegen/src/irgen/constants.rs | 5 +- huff_codegen/src/irgen/statements.rs | 3 + huff_codegen/src/lib.rs | 16 +- huff_codegen/tests/constructor_args.rs | 10 +- huff_core/Cargo.toml | 2 +- huff_core/README.md | 6 +- huff_core/benches/huff_benchmark.rs | 18 +- huff_core/src/lib.rs | 15 +- .../tests/alternative_constructor_macro.rs | 6 +- huff_core/tests/alternative_main_macro.rs | 4 +- huff_core/tests/breaking_jumptable.rs | 2 +- huff_core/tests/builtins.rs | 28 +- huff_core/tests/codegen_errors.rs | 14 +- huff_core/tests/compiling.rs | 11 +- huff_core/tests/erc20.rs | 47 +- huff_core/tests/erc721.rs | 48 ++- huff_core/tests/file_resolution.rs | 7 +- huff_core/tests/free_storage_pointer.rs | 7 +- huff_core/tests/functions.rs | 6 +- huff_core/tests/gen_artifact.rs | 8 +- huff_core/tests/in_memory.rs | 3 + huff_core/tests/macro_invoc_args.rs | 32 +- huff_core/tests/push_overrides.rs | 8 +- huff_core/tests/recurse_bytecode.rs | 6 +- huff_core/tests/test_circular_constructor.rs | 8 +- huff_core/tests/tests.rs | 4 +- huff_core/tests/verbatim.rs | 4 +- huff_js/Cargo.toml | 2 +- huff_js/src/lib.rs | 6 +- huff_lexer/Cargo.toml | 2 +- huff_parser/Cargo.toml | 2 +- huff_tests/src/runner.rs | 6 +- huff_utils/src/ast.rs | 15 +- huff_utils/src/bytecode.rs | 7 +- huff_utils/src/bytes_util.rs | 21 +- huff_utils/src/evm_version.rs | 58 +++ huff_utils/src/lib.rs | 7 +- 44 files changed, 661 insertions(+), 358 deletions(-) create mode 100644 huff_utils/src/evm_version.rs diff --git a/Cargo.lock b/Cargo.lock index 6e9dbe60..d42d6fef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,18 +15,24 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "arrayvec" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "atty" @@ -155,11 +161,11 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.24" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" dependencies = [ - "num-integer", + "android-tzdata", "num-traits", ] @@ -184,7 +190,7 @@ dependencies = [ "bitflags", "clap_derive", "clap_lex", - "indexmap", + "indexmap 1.9.3", "once_cell", "strsim", "termcolor", @@ -232,9 +238,9 @@ dependencies = [ [[package]] name = "comfy-table" -version = "6.1.4" +version = "6.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e7b787b0dc42e8111badfdbe4c3059158ccb2db8780352fa1b01e8ccf45cc4d" +checksum = "7e959d788268e3bf9d35ace83e81b124190378e4c91c9067524675e33394b8ba" dependencies = [ "crossterm", "strum", @@ -244,9 +250,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" +checksum = "6340df57935414636969091153f35f68d9f00bbc8fb4a9c6054706c213e6c6bc" [[package]] name = "convert_case" @@ -256,9 +262,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "cpufeatures" -version = "0.2.7" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" dependencies = [ "libc", ] @@ -322,9 +328,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.14" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if 1.0.0", @@ -335,18 +341,18 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" dependencies = [ "cfg-if 1.0.0", ] [[package]] name = "crossterm" -version = "0.25.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" +checksum = "a84cda67535339806297f1b331d6dd6320470d2a0fe65381e79ee9e156dd3d13" dependencies = [ "bitflags", "crossterm_winapi", @@ -360,9 +366,9 @@ dependencies = [ [[package]] name = "crossterm_winapi" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" dependencies = [ "winapi", ] @@ -409,9 +415,9 @@ dependencies = [ [[package]] name = "csv" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b015497079b9a9d69c02ad25de6c0a6edef051ea6360a327d0bd05802ef64ad" +checksum = "626ae34994d3d8d668f4269922248239db4ae42d538b14c398b74a52208e8086" dependencies = [ "csv-core", "itoa", @@ -440,9 +446,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56acb310e15652100da43d130af8d97b509e95af61aab1c5a7939ef24337ee17" +checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946" dependencies = [ "const-oid", "zeroize", @@ -491,7 +497,7 @@ version = "0.16.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" dependencies = [ - "der 0.7.6", + "der 0.7.7", "digest", "elliptic-curve 0.13.5", "rfc6979 0.4.0", @@ -543,15 +549,21 @@ dependencies = [ [[package]] name = "enumn" -version = "0.1.8" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48016319042fb7c87b78d2993084a831793a897a5cd1a2a67cab9d1eeb4b7d76" +checksum = "c9838a970f5de399d3070ae1739e131986b2f5dcc223c7423ca0927e3a878522" dependencies = [ "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.23", ] +[[package]] +name = "equivalent" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" + [[package]] name = "ethabi" version = "18.0.0" @@ -677,9 +689,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -731,6 +743,12 @@ dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + [[package]] name = "heck" version = "0.4.1" @@ -748,12 +766,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.2.6" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" [[package]] name = "hex" @@ -778,7 +793,7 @@ dependencies = [ [[package]] name = "huff_cli" -version = "0.3.1" +version = "0.3.2" dependencies = [ "clap 3.2.25", "comfy-table", @@ -796,7 +811,7 @@ dependencies = [ [[package]] name = "huff_codegen" -version = "0.3.1" +version = "0.3.2" dependencies = [ "ethers-core", "hex", @@ -809,7 +824,7 @@ dependencies = [ [[package]] name = "huff_core" -version = "0.3.1" +version = "0.3.2" dependencies = [ "cfg-if 1.0.0", "criterion", @@ -831,7 +846,7 @@ dependencies = [ [[package]] name = "huff_lexer" -version = "0.3.1" +version = "0.3.2" dependencies = [ "huff_utils", "regex", @@ -840,7 +855,7 @@ dependencies = [ [[package]] name = "huff_parser" -version = "0.3.1" +version = "0.3.2" dependencies = [ "hex", "huff_lexer", @@ -861,7 +876,7 @@ dependencies = [ "huff_parser", "huff_utils", "lazy_static", - "phf 0.11.1", + "phf 0.11.2", "revm", "serde", "serde_json", @@ -894,7 +909,7 @@ dependencies = [ [[package]] name = "huffc-js" -version = "0.3.1" +version = "0.3.2" dependencies = [ "huff_core", "huff_utils", @@ -952,6 +967,16 @@ dependencies = [ "hashbrown 0.12.3", ] +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", +] + [[package]] name = "isatty" version = "0.1.9" @@ -975,15 +1000,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" [[package]] name = "js-sys" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f37a4a5928311ac501dee68b3c7613a1037d0edb30c8e5427bd832d55d1b790" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" dependencies = [ "wasm-bindgen", ] @@ -1033,15 +1058,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.144" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "lock_api" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ "autocfg", "scopeguard", @@ -1049,12 +1074,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if 1.0.0", -] +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "maplit" @@ -1068,7 +1090,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" dependencies = [ - "regex-automata", + "regex-automata 0.1.10", ] [[package]] @@ -1079,18 +1101,18 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] [[package]] name = "mio" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "log", @@ -1186,19 +1208,19 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi 0.3.2", "libc", ] [[package]] name = "once_cell" -version = "1.17.1" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "oorandom" @@ -1233,9 +1255,9 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "6.5.0" +version = "6.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" +checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" [[package]] name = "overload" @@ -1245,9 +1267,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "parity-scale-codec" -version = "3.5.0" +version = "3.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ddb756ca205bd108aee3c62c6d3c994e1df84a59b9d6d4a5ea42ee1fd5a9a28" +checksum = "756d439303e94fae44f288ba881ad29670c65b0c4b0e05674ca81061bb65f2c5" dependencies = [ "arrayvec", "bitvec", @@ -1259,9 +1281,9 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.1.4" +version = "3.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b26a931f824dd4eca30b3e43bb4f31cd5f0d3a403c5f5ff27106b805bfde7b" +checksum = "9d884d78fcf214d70b1e239fcd1c6e5e95aa3be1881918da2e488cc946c7a476" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -1281,15 +1303,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.2.16", + "redox_syscall 0.3.5", "smallvec", - "windows-sys", + "windows-targets", ] [[package]] @@ -1311,12 +1333,12 @@ dependencies = [ [[package]] name = "phf" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ - "phf_macros 0.11.1", - "phf_shared 0.11.1", + "phf_macros 0.11.2", + "phf_shared 0.11.2", ] [[package]] @@ -1331,11 +1353,11 @@ dependencies = [ [[package]] name = "phf_generator" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" dependencies = [ - "phf_shared 0.11.1", + "phf_shared 0.11.2", "rand", ] @@ -1355,15 +1377,15 @@ dependencies = [ [[package]] name = "phf_macros" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92aacdc5f16768709a569e913f7451034034178b05bdc8acda226659a3dccc66" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" dependencies = [ - "phf_generator 0.11.1", - "phf_shared 0.11.1", + "phf_generator 0.11.2", + "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.23", ] [[package]] @@ -1377,18 +1399,18 @@ dependencies = [ [[package]] name = "phf_shared" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" dependencies = [ "siphasher", ] [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" [[package]] name = "pkcs8" @@ -1402,9 +1424,9 @@ dependencies = [ [[package]] name = "plotters" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" +checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" dependencies = [ "num-traits", "plotters-backend", @@ -1415,15 +1437,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" +checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" [[package]] name = "plotters-svg" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" +checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" dependencies = [ "plotters-backend", ] @@ -1490,18 +1512,18 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.59" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aeca18b86b413c660b781aa319e4e2648a3e6f9eadc9b47e9038e6fe9f3451b" +checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.28" +version = "1.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" dependencies = [ "proc-macro2", ] @@ -1572,22 +1594,23 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ "bitflags", ] [[package]] name = "regex" -version = "1.8.3" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81ca098a9821bd52d6b24fd8b10bd081f47d39c22778cafaa75a2857a62c6390" +checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.2", + "regex-automata 0.3.2", + "regex-syntax 0.7.3", ] [[package]] @@ -1599,6 +1622,17 @@ dependencies = [ "regex-syntax 0.6.29", ] +[[package]] +name = "regex-automata" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83d3daa6976cffb758ec878f108ba0e062a45b2d6ca3a2cca965338855476caf" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.7.3", +] + [[package]] name = "regex-syntax" version = "0.6.29" @@ -1607,9 +1641,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +checksum = "2ab07dc67230e4a4718e70fd5c20055a4334b121f1f9db8fe63ef39ce9b8c846" [[package]] name = "revm" @@ -1760,15 +1794,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" +checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f" [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" [[package]] name = "same-file" @@ -1781,9 +1815,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.7.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b569c32c806ec3abdf3b5869fb8bf1e0d275a7c1c9b0b05603d9464632649edf" +checksum = "35c0a159d0c45c12b20c5a844feb1fe4bea86e28f17b92a5f0c42193634d3782" dependencies = [ "cfg-if 1.0.0", "derive_more", @@ -1793,9 +1827,9 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.6.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53012eae69e5aa5c14671942a5dd47de59d4cdcff8532a6dd0e081faf1119482" +checksum = "912e55f6d20e0e80d63733872b40e1227c0bce1e1ab81ba67d696339bfd7fd29" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -1830,7 +1864,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e" dependencies = [ "base16ct 0.2.0", - "der 0.7.6", + "der 0.7.7", "generic-array", "subtle", "zeroize", @@ -1862,9 +1896,9 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.163" +version = "1.0.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" +checksum = "7daf513456463b42aa1d94cff7e0c24d682b429f020b9afa4f5ba5c40a22b237" dependencies = [ "serde_derive", ] @@ -1892,20 +1926,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.163" +version = "1.0.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" +checksum = "b69b106b68bc8054f0e974e70d19984040f8a5cf9215ca82626ea4853f82c4b9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.23", ] [[package]] name = "serde_json" -version = "1.0.96" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c" dependencies = [ "itoa", "ryu", @@ -1914,9 +1948,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -2000,9 +2034,9 @@ checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" [[package]] name = "spin" @@ -2097,9 +2131,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.17" +version = "2.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45b6ddbb36c5b969c182aec3c4a0bce7df3fbad4b77114706a49aacc80567388" +checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" dependencies = [ "proc-macro2", "quote", @@ -2138,22 +2172,22 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.23", ] [[package]] @@ -2196,17 +2230,17 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a76a9312f5ba4c2dec6b9161fdf25d87ad8a09256ccea5a556fef03c706a10f" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" [[package]] name = "toml_edit" -version = "0.19.10" +version = "0.19.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380d56e8670370eee6566b0bfd4265f65b3f432e8c6d85623f728d4fa31f739" +checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78" dependencies = [ - "indexmap", + "indexmap 2.0.0", "toml_datetime", "winnow", ] @@ -2225,13 +2259,13 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.24" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.23", ] [[package]] @@ -2316,9 +2350,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" [[package]] name = "unicode-width" @@ -2334,9 +2368,9 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "uuid" -version = "1.3.3" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2" +checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be" dependencies = [ "getrandom", ] @@ -2371,9 +2405,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bba0e8cb82ba49ff4e229459ff22a191bbe9a1cb3a341610c9c33efc27ddf73" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -2381,24 +2415,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b04bc93f9d6bdee709f6bd2118f57dd6679cf1176a1af464fca3ab0d66d8fb" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.23", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14d6b024f1a526bb0234f52840389927257beb670610081360e5a03c5df9c258" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2406,28 +2440,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.17", + "syn 2.0.23", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.86" +version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9d5b4305409d1fc9482fee2d7f9bcbf24b3972bf59817ef757e23982242a93" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "web-sys" -version = "0.3.63" +version = "0.3.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bdd9ef4e984da1187bf8110c5cf5b845fbc87a23602cdf912386a76fcd3a7c2" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" dependencies = [ "js-sys", "wasm-bindgen", @@ -2466,18 +2500,18 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.45.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" -version = "0.42.2" +version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -2490,51 +2524,51 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.2" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" [[package]] name = "windows_aarch64_msvc" -version = "0.42.2" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] name = "windows_i686_gnu" -version = "0.42.2" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" [[package]] name = "windows_i686_msvc" -version = "0.42.2" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] name = "windows_x86_64_gnu" -version = "0.42.2" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.2" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" [[package]] name = "windows_x86_64_msvc" -version = "0.42.2" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.4.6" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699" +checksum = "81a2094c43cc94775293eaa0e499fbc30048a6d824ac82c0351a8c0bf9112529" dependencies = [ "memchr", ] diff --git a/README.md b/README.md index 7487db04..39a3815b 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ > `huff-rs` is a [Huff](https://github.com/huff-language) compiler built in rust. - ## What is a Huff? Huff is a low-level programming language designed for developing highly optimized smart contracts that run on the Ethereum Virtual Machine (EVM). Huff does not hide the inner workings of the EVM. Instead, Huff exposes its programming stack to the developer for manual manipulation. @@ -17,7 +16,6 @@ While EVM experts can use Huff to write highly-efficient smart contracts for use To dive deeper into [Huff](https://github.com/huff-language), visit the [Official Huff Docs](https://huff.sh)(also available on [github](https://github.com/huff-language/huff-docs)). - ## Installation _Something not working? Send a message in [discord](https://discord.huff.sh)._ @@ -33,14 +31,16 @@ To avoid redirecting the script directly into bash, download and run the [huffup To install the Huff compiler, simply run `huffup`. If you have the old [huffc (TypeScript version)](https://github.com/huff-language/huffc) npm package installed globally, you can remove it with: + ```bash sudo yarn global remove huffc ``` -To make sure you are running the rust version, you can run `huffc --version` and it should respond with `huff_cli `. If it responds with `2.0.0` that means you are running the Typescript version. +To make sure you are running the rust version, you can run `huffc --version` and it should respond with `huff_cli `. If it responds with `2.0.0` that means you are running the Typescript version. + ```bash $ huffc --version -huff_cli 0.3.1 +huff_cli 0.3.2 ``` **Alternatively** @@ -59,43 +59,41 @@ OR cargo install --git https://raw.githubusercontent.com/huff-language/huff-rs --locked huff_cli ``` - ## How Fast? **Compilation Benchmarks** | Compiler | Cold (No Cache) | Light Cache | Deep Cache | Full Cache | | -------------------------------- | --------------- | ----------- | ---------- | ---------- | -| [huff-language/huff-rs][huff-rs] | XXXms | XXXms | XXXms | XXXms | -| [huff-language/huffc][huffc] | XXXms | XXXms | XXXms | XXXms | +| [huff-language/huff-rs][huff-rs] | XXXms | XXXms | XXXms | XXXms | +| [huff-language/huffc][huffc] | XXXms | XXXms | XXXms | XXXms | _Note: Compilation benchmarks were performed on [huff-examples erc20](https://github.com/huff-language/huff-examples/tree/main/erc20/contracts/ERC20.huff)._ - ## Architecture ![Huff Compiler Architecture](./assets/huffc.png) - ## Modules -* [huff_core](./huff_core): The core module to huff-rs. Resolves source file paths, executes compilation, and exports artifacts. -* [huff_cli](./huff_cli): The command line interface for the Huff compiler. -* [huff_js](./huff_js): A wasm compatible interface to the Huff compiler for JavaScript bindings. -* [huff_lexer](./huff_lexer): Takes in the source of a `.huff` file and generates a vector of `Token`s. -* [huff_parser](./huff_parser): Crafts a `Contract` AST from the vector of `Token`s generated by [huff_lexer](./huff_lexer). -* [huff_codegen](./huff_codegen): EVM Bytecode generation module that accepts an AST generated by [huff_parser](./huff_parser). -* [huff_utils](./huff_utils): Various utilities and types used by all modules. -* [huffup](./huffup): Update or revert to a specific huff-rs branch with ease. (Forked from [foundry](https://github.com/foundry-rs/foundry)) +- [huff_core](./huff_core): The core module to huff-rs. Resolves source file paths, executes compilation, and exports artifacts. +- [huff_cli](./huff_cli): The command line interface for the Huff compiler. +- [huff_js](./huff_js): A wasm compatible interface to the Huff compiler for JavaScript bindings. +- [huff_lexer](./huff_lexer): Takes in the source of a `.huff` file and generates a vector of `Token`s. +- [huff_parser](./huff_parser): Crafts a `Contract` AST from the vector of `Token`s generated by [huff_lexer](./huff_lexer). +- [huff_codegen](./huff_codegen): EVM Bytecode generation module that accepts an AST generated by [huff_parser](./huff_parser). +- [huff_utils](./huff_utils): Various utilities and types used by all modules. +- [huffup](./huffup): Update or revert to a specific huff-rs branch with ease. (Forked from [foundry](https://github.com/foundry-rs/foundry)) ## Contributing All contributions are welcome! We want to make contributing to this project as easy and transparent as possible, whether it's: - - Reporting a bug - - Discussing the current state of the code - - Submitting a fix - - Proposing new features - - Becoming a maintainer + +- Reporting a bug +- Discussing the current state of the code +- Submitting a fix +- Proposing new features +- Becoming a maintainer We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/huff-language/huff-rs/issues/new); it's that easy! @@ -141,7 +139,6 @@ When the PR checklist isn't complete, it is **highly** recommended to make it a For breaking changes: make sure to edit the [excalidraw asset](https://excalidraw.com/#json=9YvTZp-rY9NOQnX9TC8Dz,sVM8vpgvQqGiXNXrBNshTg) and export the file to [./assets/huffc.excalidraw](./assets/huffc.excalidraw) along with an image to [./assets/huffc.png](./assets/huffc.png). - ## Safety > **Warning** @@ -150,13 +147,13 @@ For breaking changes: make sure to edit the [excalidraw asset](https://excalidra > Expect rapid iteration and **use at your own risk**. > > This code is **not designed for safety**. +> > - There are untested invariants in the code that may break. > - **You can easily shoot yourself in the foot if you're not careful.** > - You should thoroughly read the documentation and examples. > > We **do not give any warranties** and **will not be liable for any loss** incurred through any use of this codebase. - ## Acknowledgements The original [Huff Language](https://github.com/huff-language) compiler: [`huffc`](https://github.com/huff-language/huffc). diff --git a/huff_cli/Cargo.toml b/huff_cli/Cargo.toml index b5ac3aa0..5e94d20e 100644 --- a/huff_cli/Cargo.toml +++ b/huff_cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "huff_cli" -version = "0.3.1" +version = "0.3.2" edition = "2021" authors = ["refcell", "clabby", "exp.table", "maddiaa"] readme = "README.md" diff --git a/huff_cli/README.md b/huff_cli/README.md index 18c0f264..3970afc5 100644 --- a/huff_cli/README.md +++ b/huff_cli/README.md @@ -5,43 +5,87 @@ The `huffc` CLI is written using [clap's](https://docs.rs/clap) [derive feature] ## huffc ``` -huffc 0.3.1 +huffc 0.3.2 Huff Language Compiler built in Pure Rust. USAGE: - huffc [OPTIONS] [--] [PATH] + huffc [OPTIONS] [PATH] [SUBCOMMAND] ARGS: The contract(s) to compile OPTIONS: - -a, --artifacts Whether to generate artifacts or not - -b, --bytecode Generate and log bytecode - -d, --output-directory The output directory [default: ./artifacts] - -g, --interface Generate solidity interface for a Huff artifact - -h, --help Print help information - -i, --inputs ... The input constructor arguments - -n, --interactive Interactively input the constructor args - -o, --output The output file path - -p, --print Prints out to the terminal - -r, --bin-runtime Generate and log runtime bytecode - -s, --source-path The contracts source path [default: ./contracts] - -v, --verbose Verbose output - -V, --version Print version information - -z, --optimize Optimize compilation [WIP] + -a, --artifacts + Whether to generate artifacts or not + + -b, --bytecode + Generate and log bytecode + + -c, --constants ... + Override / set constants for the compilation environment + + -d, --output-directory + The output directory [default: ./artifacts] + + -e, --evm-version + Set the EVM version + + -g, --interface [...] + Generate solidity interface for a Huff artifact + + -h, --help + Print help information + + -i, --inputs ... + The input constructor arguments + + -l, --label-indices + Prints out the jump label PC indices for the specified contract + + -m, --alt-main + Compile a specific macro + + -n, --interactive + Interactively input the constructor args + + -o, --output + The output file path + + -p, --print + Prints out to the terminal + + -r, --bin-runtime + Generate and log runtime bytecode + + -s, --source-path + The contracts source path [default: ./contracts] + + -t, --alt-constructor + Compile a specific constructor macro + + -v, --verbose + Verbose output + + -V, --version + Print version information + + -z, --optimize + Optimize compilation [WIP] + ``` _NOTE: To generate the above output, run: `huffc --help`_ - ## Usage To run `huffc` from the command line, you can simply run: + ```bash huffc --help ``` By default, huffc will attempt to compile all contracts in the `contracts` directory. If there is no `contracts` directory present, the following will spit out an error like so: + ```bash,color=red ~ huffc @@ -90,18 +134,19 @@ huffc -o ./artifact.json ./huff-examples/erc20/contracts/ERC20.huff ``` **NOTE**: The following will _not_ compile since multiple artifacts cannot be output to the same artifact json file. + ```bash huffc -o ./artifact.json ./contracts/ ``` - #### Entering Constructor Arguments `huffc` supports passing in constructor arguments to the contract. This is done by passing in the `--interactive` (shorthand: `-n`) flag or passing the `--inputs` (shorthand: `-i`) flag. - and passing in the arguments as a comma separated list. +and passing in the arguments as a comma separated list. For example, to compile a contract (let's call it `example.huff`) with the following constructor definition: + ```huff #define macro CONSTRUCTOR(uint256, address) = takes(0) returns (0) { 0x04 calldataload @@ -119,14 +164,14 @@ $ huffc -b -n ./contracts/example.huff [INTERACTIVE] Enter a uint256 for constructor param: 100 [INTERACTIVE] Enter a address for constructor param: 0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef -33600.....f30000000000000000000000000000000000000000000000000000000000000064000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeef +335f.....f30000000000000000000000000000000000000000000000000000000000000064000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeef ``` Alternatively, you can enter the arguments as a comma separated list by using the `-i` or `--inputs` flag like so: ```bash $ huffc -b -i 100, 0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef ./contracts/example.huff -33600.....f30000000000000000000000000000000000000000000000000000000000000064000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeef +335f0.....f30000000000000000000000000000000000000000000000000000000000000064000000000000000000000000deadbeefdeadbeefdeadbeefdeadbeefdeadbeef ``` #### Other Options @@ -136,15 +181,16 @@ $ huffc -b -i 100, 0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef ./contracts/exampl - `-z` or `--optimize`: Optimizes the contract compilation - a work in progress. - `-g` or `--interface`: Generates a solidity interface for the contract. - ## Building huffc from source To run `huffc` from the command line, you can use the following command: + ```bash cargo run --bin huffc ``` To pass arguments into the `huffc` binary, simply pass them in after a `--` flag. For example, to get the `huffc` version (a `-V` flag), you can run: + ```bash cargo run --bin huffc -- -V ``` diff --git a/huff_cli/src/huffc.rs b/huff_cli/src/huffc.rs index cac7ce1b..f0605bc0 100644 --- a/huff_cli/src/huffc.rs +++ b/huff_cli/src/huffc.rs @@ -20,7 +20,8 @@ use huff_utils::{ file_provider::FileSystemFileProvider, prelude::{ export_interfaces, gen_sol_interfaces, str_to_bytes32, unpack_files, AstSpan, BytecodeRes, - CodegenError, CodegenErrorKind, CompilerError, FileSource, Literal, OutputLocation, Span, + CodegenError, CodegenErrorKind, CompilerError, EVMVersion, FileSource, Literal, + OutputLocation, Span, }, }; use isatty::stdout_isatty; @@ -99,6 +100,10 @@ struct Huff { #[clap(short = 't', long = "alt-constructor")] alternative_constructor: Option, + /// Set the EVM version + #[clap(short = 'e', long = "evm-version")] + evm_version: Option, + /// Test subcommand #[clap(subcommand)] test: Option, @@ -185,6 +190,9 @@ fn main() { .collect() }); + // Parse the EVM version + let evm_version = EVMVersion::from(cli.evm_version); + let mut use_cache = true; if cli.interactive { // Don't accept configured inputs @@ -204,6 +212,7 @@ fn main() { }; let compiler: Compiler = Compiler { + evm_version: &evm_version, sources: Arc::clone(&sources), output, alternative_main: cli.alternative_main.clone(), @@ -244,6 +253,7 @@ fn main() { // Recurse through the macro and generate bytecode let bytecode_res: BytecodeRes = Codegen::macro_to_bytecode( + &evm_version, macro_def, contract, &mut vec![macro_def], diff --git a/huff_codegen/Cargo.toml b/huff_codegen/Cargo.toml index 247801e3..bc46ba22 100644 --- a/huff_codegen/Cargo.toml +++ b/huff_codegen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "huff_codegen" -version = "0.3.1" +version = "0.3.2" edition = "2021" authors = ["refcell", "clabby", "exp.table", "maddiaa"] readme = "README.md" diff --git a/huff_codegen/README.md b/huff_codegen/README.md index 1cd5ba81..7c5d2b8c 100644 --- a/huff_codegen/README.md +++ b/huff_codegen/README.md @@ -36,13 +36,13 @@ assert!(cg.ast.is_none()); assert!(cg.artifact.is_none()); // ERC20 Bytecode -let main_bytecode = "60003560E01c8063a9059cbb1461004857806340c10f19146100de57806370a082311461014e57806318160ddd1461016b578063095ea7b314610177578063dd62ed3e1461018e575b600435336024358160016000526000602001526040600020548082116100d8578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020556000527fDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF60206000a3600160005260206000f35b60006000fd5b60005433146100ed5760006000fd5b600435600060243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002556000527fDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF60206000a35b600435600160005260006020015260406000205460005260206000f35b60025460005260206000f35b602435600435336000526000602001526040600020555b60243560043560005260006020015260406000205460005260206000f3"; -let constructor_bytecode = "33600055"; +let main_bytecode = "5f3560e01c8063a9059cbb1461004757806340c10f19146100d757806370a082311461014157806318160ddd1461015c578063095ea7b314610166578063dd62ed3e1461017d575b600435336024358160016000526000602001526040600020548082116100d3578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020555f527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60205fa360015f5260205ff35b5f5ffd5b5f5433146100e3575f5ffd5b6004355f60243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002555f527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60205fa35b60043560016000526000602001526040600020545f5260205ff35b6002545f5260205ff35b602435600435336000526000602001526040600020555b6024356004356000526000602001526040600020545f5260205ff3"; +let constructor_bytecode = "335f55"; let inputs = vec![]; let churn_res = cg.churn(Arc::new(FileSource::default()), inputs, main_bytecode, constructor_bytecode, false); // Validate the output bytecode -assert_eq!(churn_res.unwrap().bytecode, "336000556101ac80600e3d393df360003560e01c8063a9059cbb1461004857806340c10f19146100de57806370a082311461014e57806318160ddd1461016b578063095ea7b314610177578063dd62ed3e1461018e575b600435336024358160016000526000602001526040600020548082116100d8578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020556000527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a3600160005260206000f35b60006000fd5b60005433146100ed5760006000fd5b600435600060243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002556000527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a35b600435600160005260006020015260406000205460005260206000f35b60025460005260206000f35b602435600435336000526000602001526040600020555b60243560043560005260006020015260406000205460005260206000f3".to_lowercase()); +assert_eq!(churn_res.unwrap().bytecode, "335f5561019980600d3d393df35f3560e01c8063a9059cbb1461004757806340c10f19146100d757806370a082311461014157806318160ddd1461015c578063095ea7b314610166578063dd62ed3e1461017d575b600435336024358160016000526000602001526040600020548082116100d3578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020555f527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60205fa360015f5260205ff35b5f5ffd5b5f5433146100e3575f5ffd5b6004355f60243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002555f527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60205fa35b60043560016000526000602001526040600020545f5260205ff35b6002545f5260205ff35b602435600435336000526000602001526040600020555b6024356004356000526000602001526040600020545f5260205ff3".to_lowercase()); // Write the compile artifact out to a file // cg.export("./output.json"); @@ -97,10 +97,10 @@ let contract = Contract { }; // Generate the main bytecode -let main_bytecode: String = Codegen::generate_main_bytecode(&contract, None).unwrap(); +let main_bytecode: String = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); // Validate the output bytecode -assert_eq!(main_bytecode, "60003560e01c"); +assert_eq!(main_bytecode, "5f3560e01c"); ``` Similarly, once you have a [Contract](../huff_utils/ast/struct.Contract.html) instance with a simple **CONSTRUCTOR** macro definition. You can generate the constructor/creation bytecode using the [generate_constructor_bytecode](struct.Codegen.html#method.generate_constructor_bytecode) function. @@ -152,9 +152,9 @@ let contract = Contract { }; // Generate the constructor bytecode -let (constructor_bytecode, has_custom_bootstrap): (String, bool) = Codegen::generate_constructor_bytecode(&contract, None).unwrap(); +let (constructor_bytecode, has_custom_bootstrap): (String, bool) = Codegen::generate_constructor_bytecode(&EVMVersion::default(), &contract, None).unwrap(); // Validate the output bytecode -assert_eq!(constructor_bytecode, "60003560e01c"); +assert_eq!(constructor_bytecode, "5f3560e01c"); assert_eq!(has_custom_bootstrap, false); ``` diff --git a/huff_codegen/src/irgen/constants.rs b/huff_codegen/src/irgen/constants.rs index e1696501..b9706bda 100644 --- a/huff_codegen/src/irgen/constants.rs +++ b/huff_codegen/src/irgen/constants.rs @@ -1,9 +1,10 @@ use huff_utils::prelude::{ - literal_gen, AstSpan, CodegenError, CodegenErrorKind, ConstVal, Contract, + literal_gen, AstSpan, CodegenError, CodegenErrorKind, ConstVal, Contract, EVMVersion, }; /// Transforms a constant definition into it's respective bytecode pub fn constant_gen( + evm_version: &EVMVersion, name: &str, contract: &Contract, ir_byte_span: &AstSpan, @@ -30,7 +31,7 @@ pub fn constant_gen( // prior to generating the IR bytes. tracing::info!(target: "codegen", "FOUND CONSTANT DEFINITION: {}", constant.name); let push_bytes = match &constant.value { - ConstVal::Literal(l) => literal_gen(l), + ConstVal::Literal(l) => literal_gen(evm_version, l), ConstVal::FreeStoragePointer(fsp) => { // If this is reached in codegen stage, the `derive_storage_pointers` // method was not called on the AST. diff --git a/huff_codegen/src/irgen/statements.rs b/huff_codegen/src/irgen/statements.rs index da67a7a7..96688202 100644 --- a/huff_codegen/src/irgen/statements.rs +++ b/huff_codegen/src/irgen/statements.rs @@ -5,6 +5,7 @@ use crate::Codegen; /// Generates the respective Bytecode for a given Statement #[allow(clippy::too_many_arguments)] pub fn statement_gen<'a>( + evm_version: &EVMVersion, s: &Statement, contract: &'a Contract, macro_def: &MacroDefinition, @@ -97,6 +98,7 @@ pub fn statement_gen<'a>( mis.push((*offset, mi.clone())); let mut res: BytecodeRes = match Codegen::macro_to_bytecode( + evm_version, ir_macro, contract, scope, @@ -205,6 +207,7 @@ pub fn statement_gen<'a>( } else { // We will still need to recurse to get accurate values let res: BytecodeRes = match Codegen::macro_to_bytecode( + evm_version, ir_macro, contract, scope, diff --git a/huff_codegen/src/lib.rs b/huff_codegen/src/lib.rs index 640147c1..aca743ab 100644 --- a/huff_codegen/src/lib.rs +++ b/huff_codegen/src/lib.rs @@ -12,7 +12,7 @@ use huff_utils::{ bytes_util, error::CodegenError, evm::Opcode, - prelude::{format_even_bytes, pad_n_bytes, CodegenErrorKind, FileSource, Span}, + prelude::{format_even_bytes, pad_n_bytes, CodegenErrorKind, EVMVersion, FileSource, Span}, types::EToken, }; use regex::Regex; @@ -56,6 +56,7 @@ impl Codegen { /// Generates main bytecode from a Contract AST pub fn generate_main_bytecode( + evm_version: &EVMVersion, contract: &Contract, alternative_main: Option, ) -> Result { @@ -67,6 +68,7 @@ impl Codegen { // For each MacroInvocation Statement, recurse into bytecode let bytecode_res: BytecodeRes = Codegen::macro_to_bytecode( + evm_version, m_macro, contract, &mut vec![m_macro], @@ -84,6 +86,7 @@ impl Codegen { /// Generates constructor bytecode from a Contract AST pub fn generate_constructor_bytecode( + evm_version: &EVMVersion, contract: &Contract, alternative_constructor: Option, ) -> Result<(String, bool), CodegenError> { @@ -96,6 +99,7 @@ impl Codegen { // For each MacroInvocation Statement, recurse into bytecode let bytecode_res: BytecodeRes = Codegen::macro_to_bytecode( + evm_version, c_macro, contract, &mut vec![c_macro], @@ -272,7 +276,9 @@ impl Codegen { /// * `scope` - Current scope of the recursion. Contains all macro definitions recursed so far. /// * `offset` - Current bytecode offset /// * `mis` - Vector of tuples containing parent macro invocations as well as their offsets. + #[allow(clippy::too_many_arguments)] pub fn macro_to_bytecode<'a>( + evm_version: &EVMVersion, macro_def: &'a MacroDefinition, contract: &'a Contract, scope: &mut Vec<&'a MacroDefinition>, @@ -283,7 +289,7 @@ impl Codegen { ) -> Result { // Get intermediate bytecode representation of the macro definition let mut bytes: Vec<(usize, Bytes)> = Vec::default(); - let ir_bytes = macro_def.to_irbytecode()?.0; + let ir_bytes = macro_def.to_irbytecode(evm_version)?.0; // Define outer loop variables let mut jump_table = JumpTable::new(); @@ -302,7 +308,7 @@ impl Codegen { bytes.push((starting_offset, b.to_owned())); } IRByteType::Constant(name) => { - let push_bytes = constant_gen(name, contract, ir_byte.span)?; + let push_bytes = constant_gen(evm_version, name, contract, ir_byte.span)?; offset += push_bytes.len() / 2; tracing::debug!(target: "codegen", "OFFSET: {}, PUSH BYTES: {:?}", offset, push_bytes); bytes.push((starting_offset, Bytes(push_bytes))); @@ -314,6 +320,7 @@ impl Codegen { continue } let mut push_bytes = statement_gen( + evm_version, s, contract, macro_def, @@ -355,6 +362,7 @@ impl Codegen { // (i.e., we're at the top level of recursion) if scope.len() == 1 { bytes = Codegen::append_functions( + evm_version, contract, scope, &mut offset, @@ -535,6 +543,7 @@ impl Codegen { /// On failure, returns a CodegenError. #[allow(clippy::too_many_arguments)] pub fn append_functions<'a>( + evm_version: &EVMVersion, contract: &'a Contract, scope: &mut Vec<&'a MacroDefinition>, offset: &mut usize, @@ -550,6 +559,7 @@ impl Codegen { // Add 1 to starting offset to account for the JUMPDEST opcode let mut res = Codegen::macro_to_bytecode( + evm_version, macro_def, contract, scope, diff --git a/huff_codegen/tests/constructor_args.rs b/huff_codegen/tests/constructor_args.rs index 065c175f..24287e66 100644 --- a/huff_codegen/tests/constructor_args.rs +++ b/huff_codegen/tests/constructor_args.rs @@ -13,7 +13,7 @@ fn encode_simple_constructor_args() { let expected_bytes32: Vec = str_to_vec("87674fa174add091f082eab424cc60625118fa4c553592a4e54a76fb9e8512f6").unwrap(); // Bogus constructors args - let args: Vec = vec![ + let args: Vec = [ "Hello", "10000", "false", @@ -44,7 +44,7 @@ fn encode_array_constructor_args() { let _expected_bytes32: Vec = str_to_vec("87674fa174add091f082eab424cc60625118fa4c553592a4e54a76fb9e8512f6").unwrap(); // Bogus constructors args - let args: Vec = vec![ + let args: Vec = [ "[100, 200, 300]", "[0x646dB8ffC21e7ddc2B6327448dd9Fa560Df41087, 0x646dB8ffC21e7ddc2B6327448dd9Fa560Df41087]", "[true, false, false]", @@ -95,14 +95,12 @@ fn encode_missing_brackets_array_constructor_args() { let _expected_bytes32: Vec = str_to_vec("87674fa174add091f082eab424cc60625118fa4c553592a4e54a76fb9e8512f6").unwrap(); // Bogus constructors args - let args: Vec = vec![ - " 100, 200, 300 ", + let args: Vec = [" 100, 200, 300 ", " 0x646dB8ffC21e7ddc2B6327448dd9Fa560Df41087, 0x646dB8ffC21e7ddc2B6327448dd9Fa560Df41087", "true, false, false", "Hello, World, Yes", " \"Hello\", \"World\", \"Yes\"", - "'Hello', 'World', 'Yes' ", - ] + "'Hello', 'World', 'Yes' "] .iter() .map(|s| s.to_string()) .collect(); diff --git a/huff_core/Cargo.toml b/huff_core/Cargo.toml index e6d8eb0e..9249a887 100644 --- a/huff_core/Cargo.toml +++ b/huff_core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "huff_core" -version = "0.3.1" +version = "0.3.2" edition = "2021" authors = ["refcell", "clabby", "exp.table", "maddiaa"] readme = "README.md" diff --git a/huff_core/README.md b/huff_core/README.md index edc2f902..9d33f152 100644 --- a/huff_core/README.md +++ b/huff_core/README.md @@ -18,12 +18,14 @@ Below we demonstrate taking a source file `../huff-examples/erc20/contracts/ERC2 use huff_core::Compiler; use huff_utils::error::CompilerError; use huff_utils::artifact::Artifact; +use huff_utils::prelude::EVMVersion; use std::sync::Arc; use std::cell::RefCell; use std::rc::Rc; -// Instantiate the Compiler Instance -let mut compiler = Compiler::new(Arc::new(vec!["../huff-examples/erc20/contracts/ERC20.huff".to_string()]), None, None, None, None, None, false, false); +// Instantiate the Compiler Instance with a targeted evm version. +let evm_version = &EVMVersion::default(); +let mut compiler = Compiler::new(evm_version, Arc::new(vec!["../huff-examples/erc20/contracts/ERC20.huff".to_string()]), None, None, None, None, None, false, false); // Execute the compiler let res: Result>, Arc> = compiler.execute(); diff --git a/huff_core/benches/huff_benchmark.rs b/huff_core/benches/huff_benchmark.rs index a67a5c0a..e001cf71 100644 --- a/huff_core/benches/huff_benchmark.rs +++ b/huff_core/benches/huff_benchmark.rs @@ -102,11 +102,13 @@ fn codegen_erc20_benchmark(c: &mut Criterion) { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = &EVMVersion::default(); + // Isolate codegen to benchmark c.bench_function("Codegen: ERC-20", |b| b.iter(|| { // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); - let (constructor_bytecode, has_custom_bootstrap) = Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(evm_version,&contract, None).unwrap(); + let (constructor_bytecode, has_custom_bootstrap) = Codegen::generate_constructor_bytecode(evm_version,&contract, None).unwrap(); // Churn let mut cg = Codegen::new(); @@ -149,9 +151,11 @@ fn erc20_compilation_benchmark(c: &mut Criterion) { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = &EVMVersion::default(); + // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); - let (constructor_bytecode, has_custom_bootstrap) = Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(evm_version,&contract, None).unwrap(); + let (constructor_bytecode, has_custom_bootstrap) = Codegen::generate_constructor_bytecode(evm_version, &contract, None).unwrap(); // Churn let mut cg = Codegen::new(); @@ -194,9 +198,11 @@ fn erc721_compilation_benchmark(c: &mut Criterion) { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = &EVMVersion::default(); + // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); - let (constructor_bytecode, has_custom_bootstrap) = Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(evm_version, &contract, None).unwrap(); + let (constructor_bytecode, has_custom_bootstrap) = Codegen::generate_constructor_bytecode(evm_version,&contract, None).unwrap(); // Churn let mut cg = Codegen::new(); diff --git a/huff_core/src/lib.rs b/huff_core/src/lib.rs index 5aeb5eb3..e40e0151 100644 --- a/huff_core/src/lib.rs +++ b/huff_core/src/lib.rs @@ -43,9 +43,11 @@ pub(crate) mod cache; /// /// ```rust /// use huff_core::Compiler; +/// use huff_utils::prelude::EVMVersion; /// use std::sync::Arc; /// /// let compiler = Compiler::new( +/// &EVMVersion::default(), /// Arc::new(vec!["../huff-examples/erc20/contracts/ERC20.huff".to_string()]), /// Some("./artifacts".to_string()), /// None, @@ -57,7 +59,9 @@ pub(crate) mod cache; /// ); /// ``` #[derive(Debug, Clone)] -pub struct Compiler<'a> { +pub struct Compiler<'a, 'l> { + /// The EVM version to compile for + pub evm_version: &'l EVMVersion, /// The location of the files to compile pub sources: Arc>, /// The output location @@ -80,10 +84,11 @@ pub struct Compiler<'a> { pub file_provider: Arc>, } -impl<'a> Compiler<'a> { +impl<'a, 'l> Compiler<'a, 'l> { /// Public associated function to instantiate a new compiler. #[allow(clippy::too_many_arguments)] pub fn new( + evm_version: &'l EVMVersion, sources: Arc>, output: Option, alternative_main: Option, @@ -97,6 +102,7 @@ impl<'a> Compiler<'a> { Compiler::init_tracing_subscriber(Some(vec![tracing::Level::INFO.into()])); } Self { + evm_version, sources, output, alternative_main, @@ -112,7 +118,9 @@ impl<'a> Compiler<'a> { /// Creates a new instance of a compiler with an in-memory FileReader from the supplied sources /// map. + #[allow(clippy::too_many_arguments)] pub fn new_in_memory( + evm_version: &'l EVMVersion, sources: Arc>, file_sources: HashMap, alternative_main: Option, @@ -125,6 +133,7 @@ impl<'a> Compiler<'a> { Compiler::init_tracing_subscriber(Some(vec![tracing::Level::INFO.into()])); } Self { + evm_version, sources, output: None, alternative_main, @@ -399,6 +408,7 @@ impl<'a> Compiler<'a> { // Primary Bytecode Generation let mut cg = Codegen::new(); let main_bytecode = match Codegen::generate_main_bytecode( + self.evm_version, &contract, self.alternative_main.clone(), ) { @@ -426,6 +436,7 @@ impl<'a> Compiler<'a> { let inputs = self.get_constructor_args(); let (constructor_bytecode, has_custom_bootstrap) = match Codegen::generate_constructor_bytecode( + self.evm_version, &contract, self.alternative_constructor.clone(), ) { diff --git a/huff_core/tests/alternative_constructor_macro.rs b/huff_core/tests/alternative_constructor_macro.rs index 4d9b36a9..256923f9 100644 --- a/huff_core/tests/alternative_constructor_macro.rs +++ b/huff_core/tests/alternative_constructor_macro.rs @@ -27,7 +27,11 @@ fn test_alternative_constructor_macro_provided() { let alternative_constructor_label = Some(String::from("ALT_CONSTRUCTOR")); // Create constructor bytecode - match Codegen::generate_constructor_bytecode(&contract, alternative_constructor_label) { + match Codegen::generate_constructor_bytecode( + &EVMVersion::default(), + &contract, + alternative_constructor_label, + ) { Ok((mb, _)) => assert_eq!(mb, "6004355f602435".to_string()), Err(_) => panic!("moose"), } diff --git a/huff_core/tests/alternative_main_macro.rs b/huff_core/tests/alternative_main_macro.rs index 2c9bea0a..bbc2c5bc 100644 --- a/huff_core/tests/alternative_main_macro.rs +++ b/huff_core/tests/alternative_main_macro.rs @@ -26,8 +26,8 @@ fn test_alternative_main_macro_provided() { let alternative_main = Some(String::from("MINT")); - // Createconstructor bytecode - match Codegen::generate_main_bytecode(&contract, alternative_main) { + // Create main bytecode + match Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, alternative_main) { Ok(mb) => assert_eq!(mb, "6004355f602435".to_string()), Err(_) => panic!("moose"), } diff --git a/huff_core/tests/breaking_jumptable.rs b/huff_core/tests/breaking_jumptable.rs index 7d8ee40f..9866179a 100644 --- a/huff_core/tests/breaking_jumptable.rs +++ b/huff_core/tests/breaking_jumptable.rs @@ -150,6 +150,6 @@ fn test_breaking_jump_table() { assert!(cg.artifact.is_none()); // Have the Codegen create the main macro bytecode - let mbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let mbytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(mbytes, String::from("60fe6100ca5f395f80fd5b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b805b80000a000c000e00100012001400160018001a001c001e00200022002400260028002a002c002e00300032003400360038003a003c003e00400042004400460048004a004c004e00500052005400560058005a005c005e00600062006400660068006a006c006e00700072007400760078007a007c007e00800082008400860088008a008c008e00900092009400960098009a009c009e00a000a200a400a600a800aa00ac00ae00b000b200b400b600b800ba00bc00be00c000c200c400c600c800aa00ac00ae00b000b200b400b600b800ba00bc00be00c000c200c400c600c800aa00ac00ae00b000b200b400b600b800ba00bc00be00c000c200c400c6")); } diff --git a/huff_core/tests/builtins.rs b/huff_core/tests/builtins.rs index 2751d216..d2188ebc 100644 --- a/huff_core/tests/builtins.rs +++ b/huff_core/tests/builtins.rs @@ -42,7 +42,7 @@ fn test_codesize_builtin() { // Have the Codegen create the constructor bytecode let (cbytes, custom_bootstrap) = - Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + Codegen::generate_constructor_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(cbytes, String::from("6003")); assert!(!custom_bootstrap); } @@ -76,10 +76,12 @@ fn test_dyn_constructor_arg_builtin() { // The codegen instance should have no artifact assert!(cg.artifact.is_none()); + let evm_version = &EVMVersion::default(); + // Have the Codegen create the constructor bytecode let (constructor_code, has_custom_bootstrap) = - Codegen::generate_constructor_bytecode(&contract, None).unwrap(); - let main_code = Codegen::generate_main_bytecode(&contract, None).unwrap(); + Codegen::generate_constructor_bytecode(evm_version, &contract, None).unwrap(); + let main_code = Codegen::generate_main_bytecode(evm_version, &contract, None).unwrap(); let args = Codegen::encode_constructor_args(vec![String::from("testing")]); let final_bytecode = cg.churn( @@ -166,7 +168,7 @@ fn test_tablesize_builtin() { assert!(cg.artifact.is_none()); // Have the Codegen create the constructor bytecode - let mbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let mbytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(mbytes, String::from("600860806100235f3960205b5f5ff35b5f5ff35b5f5ff35b5f5ff3000b000f00130017000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000130000000000000000000000000000000000000000000000000000000000000017DEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF")); } @@ -231,7 +233,7 @@ fn test_tablestart_builtin() { // Have the Codegen create the constructor bytecode let (cbytes, custom_bootstrap) = - Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + Codegen::generate_constructor_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(cbytes, String::from("61001661001e5b5f5ff35b5f5ff35b5f5ff35b5f5ff30006000a000e00120000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000012")); assert!(custom_bootstrap); } @@ -295,7 +297,7 @@ fn test_jump_table_exhaustive_usage() { assert!(cg.artifact.is_none()); // Have the Codegen create the constructor bytecode - let mbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let mbytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(mbytes, String::from("608061003e5f395f3560e01c8063a9059cbb14610017575b60208703516202ffe016806020015b60206020015b60206020015b60206020015b60206020010000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000038")); } @@ -355,7 +357,7 @@ fn test_jump_table_packed_exhaustive_usage() { assert!(cg.artifact.is_none()); // Have the Codegen create the main macro bytecode - let mbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let mbytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(mbytes, String::from("600861003e5f395f3560e01c8063a9059cbb14610017575b60208703516202ffe016806020015b60206020015b60206020015b60206020015b60206020010026002c00320038")); } @@ -422,7 +424,7 @@ fn test_label_clashing() { assert!(cg.artifact.is_none()); // Have the Codegen create the main macro bytecode - let mbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let mbytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(mbytes, String::from("60086100455f39608061004d5f395f3560e01c8063a9059cbb1461001e575b60208703516202ffe016806020015b60206020015b60206020015b60206020015b6020602001002d00330039003f000000000000000000000000000000000000000000000000000000000000002d00000000000000000000000000000000000000000000000000000000000000330000000000000000000000000000000000000000000000000000000000000039000000000000000000000000000000000000000000000000000000000000003f")); } @@ -466,7 +468,7 @@ fn test_func_sig_builtin() { assert!(cg.artifact.is_none()); // Have the Codegen create the constructor bytecode - let cbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let cbytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); // `transfer(address,uint256) signature = 0xa9059cbb assert_eq!(&cbytes[14..22], "a9059cbb"); assert_eq!(&cbytes[36..44], "a9059cbb"); @@ -498,6 +500,8 @@ fn test_event_hash_builtin() { let tokens = lexer.into_iter().map(|x| x.unwrap()).collect::>(); let mut parser = Parser::new(tokens, None); + let evm_version = EVMVersion::default(); + // Parse the AST let mut contract = parser.parse().unwrap(); @@ -511,7 +515,7 @@ fn test_event_hash_builtin() { assert!(cg.artifact.is_none()); // Have the Codegen create the constructor bytecode - let cbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let cbytes = Codegen::generate_main_bytecode(&evm_version, &contract, None).unwrap(); // `transfer(address,address,uint256) signature = // 0xbeabacc8ffedac16e9a60acdb2ca743d80c2ebb44977a93fa8e483c74d2b35a8 assert_eq!(&cbytes[2..66], "beabacc8ffedac16e9a60acdb2ca743d80c2ebb44977a93fa8e483c74d2b35a8"); @@ -586,7 +590,7 @@ fn test_error_selector_builtin() { assert!(cg.artifact.is_none()); // Have Codegen create the runtime bytecode - let r_bytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let r_bytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(&r_bytes[2..66], "be20788c00000000000000000000000000000000000000000000000000000000"); assert_eq!(&r_bytes[94..102], "08c379a0"); assert_eq!( @@ -626,7 +630,7 @@ fn test_rightpad_builtin() { assert!(cg.artifact.is_none()); // Have Codegen create the runtime bytecode - let r_bytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let r_bytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(&r_bytes[2..66], "a57b000000000000000000000000000000000000000000000000000000000000"); assert_eq!( &r_bytes[68..132], diff --git a/huff_core/tests/codegen_errors.rs b/huff_core/tests/codegen_errors.rs index a4d5754a..57454f05 100644 --- a/huff_core/tests/codegen_errors.rs +++ b/huff_core/tests/codegen_errors.rs @@ -39,7 +39,7 @@ fn test_storage_pointers_not_derived() { let contract = parser.parse().unwrap(); // Create main and constructor bytecode - match Codegen::generate_main_bytecode(&contract, None) { + match Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None) { Ok(_) => panic!("moose"), Err(e) => { assert_eq!( @@ -99,7 +99,7 @@ fn test_invalid_constant_definition() { contract.derive_storage_pointers(); // Create main and constructor bytecode - match Codegen::generate_main_bytecode(&contract, None) { + match Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None) { Ok(_) => panic!("moose"), Err(e) => { assert_eq!( @@ -142,7 +142,7 @@ fn test_missing_constructor() { contract.derive_storage_pointers(); // Create constructor bytecode - match Codegen::generate_constructor_bytecode(&contract, None) { + match Codegen::generate_constructor_bytecode(&EVMVersion::default(), &contract, None) { Ok(_) => panic!("moose"), Err(e) => { assert_eq!( @@ -175,7 +175,7 @@ fn test_missing_main() { contract.derive_storage_pointers(); // Createconstructor bytecode - match Codegen::generate_main_bytecode(&contract, None) { + match Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None) { Ok(_) => panic!("moose"), Err(e) => { assert_eq!( @@ -210,7 +210,7 @@ fn test_missing_when_alternative_main_provided() { let alternative_main = Some(String::from("NAH")); // Createconstructor bytecode - match Codegen::generate_main_bytecode(&contract, alternative_main) { + match Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, alternative_main) { Ok(_) => panic!("moose"), Err(e) => { assert_eq!( @@ -251,7 +251,7 @@ fn test_unknown_macro_definition() { contract.derive_storage_pointers(); // Create main and constructor bytecode - match Codegen::generate_main_bytecode(&contract, None) { + match Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None) { Ok(_) => panic!("moose"), Err(e) => { assert_eq!( @@ -298,7 +298,7 @@ fn test_unmatched_jump_label() { contract.derive_storage_pointers(); // Create main and constructor bytecode - match Codegen::generate_main_bytecode(&contract, None) { + match Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None) { Ok(_) => panic!("moose"), Err(e) => { assert_eq!( diff --git a/huff_core/tests/compiling.rs b/huff_core/tests/compiling.rs index 3688d371..a84e71f9 100644 --- a/huff_core/tests/compiling.rs +++ b/huff_core/tests/compiling.rs @@ -57,7 +57,7 @@ fn compiles_constructor_bytecode() { // Have the Codegen create the constructor bytecode let (cbytes, custom_bootstrap) = - Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + Codegen::generate_constructor_bytecode(&EVMVersion::default(), &contract, None).unwrap(); println!("Constructor Bytecode Result: {cbytes:?}"); assert_eq!(cbytes, String::from("335f55")); assert!(!custom_bootstrap); @@ -83,15 +83,16 @@ fn compiles_runtime_bytecode() { assert!(cg.artifact.is_none()); // Have the Codegen create the constructor bytecode - let (cbytes, cbootstrap) = Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + let (cbytes, cbootstrap) = + Codegen::generate_constructor_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(cbytes, String::from("335f55")); assert!(!cbootstrap); let inputs: Vec = vec![]; // ERC20 Bytecode let main_bytecode = - "60003560E01c8063a9059cbb1461004857806340c10f19146100de57806370a082311461014e57806318160ddd1461016b578063095ea7b314610177578063dd62ed3e1461018e575b600435336024358160016000526000602001526040600020548082116100d8578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020556000527fDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF60206000a3600160005260206000f35b60006000fd5b60005433146100ed5760006000fd5b600435600060243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002556000527fDDF252AD1BE2C89B69C2B068FC378DAA952BA7F163C4A11628F55A4DF523B3EF60206000a35b600435600160005260006020015260406000205460005260206000f35b60025460005260206000f35b602435600435336000526000602001526040600020555b60243560043560005260006020015260406000205460005260206000f3"; - let constructor_bytecode = "33600055"; + "5f3560e01c8063a9059cbb1461004757806340c10f19146100d757806370a082311461014157806318160ddd1461015c578063095ea7b314610166578063dd62ed3e1461017d575b600435336024358160016000526000602001526040600020548082116100d3578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020555f527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60205fa360015f5260205ff35b5f5ffd5b5f5433146100e3575f5ffd5b6004355f60243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002555f527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60205fa35b60043560016000526000602001526040600020545f5260205ff35b6002545f5260205ff35b602435600435336000526000602001526040600020555b6024356004356000526000602001526040600020545f5260205ff3"; + let constructor_bytecode = "335f55"; let churn_res = cg.churn( Arc::new(FileSource::default()), inputs, @@ -101,7 +102,7 @@ fn compiles_runtime_bytecode() { ); assert!(churn_res.is_ok()); assert_eq!(churn_res.unwrap().bytecode, - "336000556101ac80600e3d393df360003560e01c8063a9059cbb1461004857806340c10f19146100de57806370a082311461014e57806318160ddd1461016b578063095ea7b314610177578063dd62ed3e1461018e575b600435336024358160016000526000602001526040600020548082116100d8578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020556000527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a3600160005260206000f35b60006000fd5b60005433146100ed5760006000fd5b600435600060243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002556000527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a35b600435600160005260006020015260406000205460005260206000f35b60025460005260206000f35b602435600435336000526000602001526040600020555b60243560043560005260006020015260406000205460005260206000f3".to_lowercase() + "335f5561019980600d3d393df35f3560e01c8063a9059cbb1461004757806340c10f19146100d757806370a082311461014157806318160ddd1461015c578063095ea7b314610166578063dd62ed3e1461017d575b600435336024358160016000526000602001526040600020548082116100d3578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020555f527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60205fa360015f5260205ff35b5f5ffd5b5f5433146100e3575f5ffd5b6004355f60243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002555f527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60205fa35b60043560016000526000602001526040600020545f5260205ff35b6002545f5260205ff35b602435600435336000526000602001526040600020555b6024356004356000526000602001526040600020545f5260205ff3".to_lowercase() ); // Validate the Codegen Artifact diff --git a/huff_core/tests/erc20.rs b/huff_core/tests/erc20.rs index 09f721f6..3c1144fe 100644 --- a/huff_core/tests/erc20.rs +++ b/huff_core/tests/erc20.rs @@ -34,25 +34,52 @@ fn test_erc20_compile() { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); - // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); - let (constructor_bytecode, has_custom_bootstrap) = - Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + // Create main and constructor bytecode using the paris compatible evm version + let paris_evm = EVMVersion::new(SupportedEVMVersions::Paris); + + let paris_main_bytecode = Codegen::generate_main_bytecode(&paris_evm, &contract, None).unwrap(); + let (paris_constructor_bytecode, paris_has_custom_bootstrap) = + Codegen::generate_constructor_bytecode(&paris_evm, &contract, None).unwrap(); + + // Create main and constructor bytecode using the shanghai compatible evm version + let shanghai_evm = EVMVersion::new(SupportedEVMVersions::Shanghai); + + let shanghai_main_bytecode = + Codegen::generate_main_bytecode(&shanghai_evm, &contract, None).unwrap(); + let (shanghai_constructor_bytecode, has_custom_bootstrap) = + Codegen::generate_constructor_bytecode(&shanghai_evm, &contract, None).unwrap(); // Churn let mut cg = Codegen::new(); - let artifact = cg + let paris_artifact = cg .churn( Arc::clone(file_source), vec![], - &main_bytecode, - &constructor_bytecode, - has_custom_bootstrap, + &paris_main_bytecode, + &paris_constructor_bytecode, + paris_has_custom_bootstrap, ) .unwrap(); // Full expected bytecode output (generated from huffc) - let expected_bytecode = "336000556101ac80600e3d393df360003560e01c8063a9059cbb1461004857806340c10f19146100de57806370a082311461014e57806318160ddd1461016b578063095ea7b314610177578063dd62ed3e1461018e575b600435336024358160016000526000602001526040600020548082116100d8578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020556000527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a3600160005260206000f35b60006000fd5b60005433146100ed5760006000fd5b600435600060243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002556000527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a35b600435600160005260006020015260406000205460005260206000f35b60025460005260206000f35b602435600435336000526000602001526040600020555b60243560043560005260006020015260406000205460005260206000f3"; + let expected_paris_bytecode = "336000556101ac80600e3d393df360003560e01c8063a9059cbb1461004857806340c10f19146100de57806370a082311461014e57806318160ddd1461016b578063095ea7b314610177578063dd62ed3e1461018e575b600435336024358160016000526000602001526040600020548082116100d8578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020556000527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a3600160005260206000f35b60006000fd5b60005433146100ed5760006000fd5b600435600060243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002556000527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a35b600435600160005260006020015260406000205460005260206000f35b60025460005260206000f35b602435600435336000526000602001526040600020555b60243560043560005260006020015260406000205460005260206000f3"; + + assert_eq!(paris_artifact.bytecode.to_lowercase(), expected_paris_bytecode.to_lowercase()); + + let shanghai_artifact = cg + .churn( + Arc::clone(file_source), + vec![], + &shanghai_main_bytecode, + &shanghai_constructor_bytecode, + has_custom_bootstrap, + ) + .unwrap(); + + let expected_shanghai_bytecode = "335f5561019980600d3d393df35f3560e01c8063a9059cbb1461004757806340c10f19146100d757806370a082311461014157806318160ddd1461015c578063095ea7b314610166578063dd62ed3e1461017d575b600435336024358160016000526000602001526040600020548082116100d3578190038260016000526000602001526040600020558281906001600052600060200152604060002054018360016000526000602001526040600020555f527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60205fa360015f5260205ff35b5f5ffd5b5f5433146100e3575f5ffd5b6004355f60243582819060016000526000602001526040600020540183600160005260006020015260406000205580600254016002555f527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60205fa35b60043560016000526000602001526040600020545f5260205ff35b6002545f5260205ff35b602435600435336000526000602001526040600020555b6024356004356000526000602001526040600020545f5260205ff3"; - assert_eq!(artifact.bytecode.to_lowercase(), expected_bytecode.to_lowercase()); + assert_eq!( + shanghai_artifact.bytecode.to_lowercase(), + expected_shanghai_bytecode.to_lowercase() + ); } diff --git a/huff_core/tests/erc721.rs b/huff_core/tests/erc721.rs index a8ab17f7..3460cec3 100644 --- a/huff_core/tests/erc721.rs +++ b/huff_core/tests/erc721.rs @@ -34,26 +34,52 @@ fn test_erc721_compile() { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); - // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); - let (constructor_bytecode, has_custom_bootstrap) = - Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + // Create main and constructor bytecode using the paris compatible evm version + let paris_evm = EVMVersion::new(SupportedEVMVersions::Paris); + + let paris_main_bytecode = Codegen::generate_main_bytecode(&paris_evm, &contract, None).unwrap(); + let (paris_constructor_bytecode, paris_has_custom_bootstrap) = + Codegen::generate_constructor_bytecode(&paris_evm, &contract, None).unwrap(); + + // Create main and constructor bytecode using the shanghai compatible evm version + let shanghai_evm = EVMVersion::new(SupportedEVMVersions::Shanghai); + + let shanghai_main_bytecode = + Codegen::generate_main_bytecode(&shanghai_evm, &contract, None).unwrap(); + let (shanghai_constructor_bytecode, has_custom_bootstrap) = + Codegen::generate_constructor_bytecode(&shanghai_evm, &contract, None).unwrap(); // Churn let mut cg = Codegen::new(); - let artifact = cg + let paris_artifact = cg + .churn( + Arc::clone(file_source), + vec![], + &paris_main_bytecode, + &paris_constructor_bytecode, + paris_has_custom_bootstrap, + ) + .unwrap(); + + // Full expected bytecode output (generated from huffc) + let expected_paris_bytecode = "336000556103b180600e3d393df360003560e01c8063a9059cbb146100a057806342842e0e146101a3578063b88d4fde146101a9578063095ea7b31461027b578063a22cb46514610310578063081812fc146102f357806340c10f19146101af57806370a082311461025e5780636352211e1461039457806306fdde031461035e57806395d89b4114610364578063c87b56dd1461036a57806301ffc9a714610370578063e985e9c514610376575b6044356024356004358083600160005260006020015260406000205491146100c75761019d565b8033146101005733816000526000602001526040600020546101005782600260005260006020015260406000205433146101005761019d565b6001816003600052600060200152604060002054038160036000526000602001526040600020558160036000526000602001526040600020546001018260036000526000602001526040600020558183600160005260006020015260406000205560008360026000526000602001526040600020557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a4005b60006000fd5b60006000fd5b60006000fd5b60005433146101be5760006000fd5b6024356004356000826001600052600060200152604060002054156101e257610258565b8160036000526000602001526040600020546001018260036000526000602001526040600020558183600160005260006020015260406000205560008360026000526000602001526040600020557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60006000a4005b60006000fd5b600435600360005260006020015260406000205460005260206000f35b6024358060016000526000602001526040600020548033143382600052600060200152604060002054176102ae576102ed565b60043580836002600052600060200152604060002055907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560006000a4005b60006000fd5b600435600260005260006020015260406000205460005260206000f35b60243560043533600052600060200152604060002055600435336024356000527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160006000a4005b60006000fd5b60006000fd5b60006000fd5b60006000fd5b60006000fd5b60243560043560005260006020015260406000205460005260206000f35b600435600160005260006020015260406000205460005260206000f3"; + + assert_eq!(paris_artifact.bytecode.to_lowercase(), expected_paris_bytecode.to_lowercase()); + + let shanghai_artifact = cg .churn( Arc::clone(file_source), vec![], - &main_bytecode, - &constructor_bytecode, + &shanghai_main_bytecode, + &shanghai_constructor_bytecode, has_custom_bootstrap, ) .unwrap(); - // Full expected bytecode output (different from huffc since our storage pointer derivation is - // depth first) - let expected_bytecode = "336000556103b180600e3d393df360003560e01c8063a9059cbb146100a057806342842e0e146101a3578063b88d4fde146101a9578063095ea7b31461027b578063a22cb46514610310578063081812fc146102f357806340c10f19146101af57806370a082311461025e5780636352211e1461039457806306fdde031461035e57806395d89b4114610364578063c87b56dd1461036a57806301ffc9a714610370578063e985e9c514610376575b6044356024356004358083600160005260006020015260406000205491146100c75761019d565b8033146101005733816000526000602001526040600020546101005782600260005260006020015260406000205433146101005761019d565b6001816003600052600060200152604060002054038160036000526000602001526040600020558160036000526000602001526040600020546001018260036000526000602001526040600020558183600160005260006020015260406000205560008360026000526000602001526040600020557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60206000a4005b60006000fd5b60006000fd5b60006000fd5b60005433146101be5760006000fd5b6024356004356000826001600052600060200152604060002054156101e257610258565b8160036000526000602001526040600020546001018260036000526000602001526040600020558183600160005260006020015260406000205560008360026000526000602001526040600020557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60006000a4005b60006000fd5b600435600360005260006020015260406000205460005260206000f35b6024358060016000526000602001526040600020548033143382600052600060200152604060002054176102ae576102ed565b60043580836002600052600060200152604060002055907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560006000a4005b60006000fd5b600435600260005260006020015260406000205460005260206000f35b60243560043533600052600060200152604060002055600435336024356000527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160006000a4005b60006000fd5b60006000fd5b60006000fd5b60006000fd5b60006000fd5b60243560043560005260006020015260406000205460005260206000f35b600435600160005260006020015260406000205460005260206000f3"; + let expected_shanghai_bytecode = "335f5561038680600d3d393df35f3560e01c8063a9059cbb1461009f57806342842e0e1461019e578063b88d4fde146101a2578063095ea7b314610267578063a22cb465146102f6578063081812fc146102db57806340c10f19146101a657806370a082311461024c5780636352211e1461036b57806306fdde031461033f57806395d89b4114610343578063c87b56dd1461034757806301ffc9a71461034b578063e985e9c51461034f575b6044356024356004358083600160005260006020015260406000205491146100c65761019a565b8033146100ff5733816000526000602001526040600020546100ff5782600260005260006020015260406000205433146100ff5761019a565b600181600360005260006020015260406000205403816003600052600060200152604060002055816003600052600060200152604060002054600101826003600052600060200152604060002055818360016000526000602001526040600020555f8360026000526000602001526040600020557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60205fa4005b5f5ffd5b5f5ffd5b5f5ffd5b5f5433146101b2575f5ffd5b6024356004355f826001600052600060200152604060002054156101d557610248565b816003600052600060200152604060002054600101826003600052600060200152604060002055818360016000526000602001526040600020555f8360026000526000602001526040600020557fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef5f5fa4005b5f5ffd5b60043560036000526000602001526040600020545f5260205ff35b60243580600160005260006020015260406000205480331433826000526000602001526040600020541761029a576102d7565b60043580836002600052600060200152604060002055907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9255f5fa4005b5f5ffd5b60043560026000526000602001526040600020545f5260205ff35b60243560043533600052600060200152604060002055600435336024355f527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c315f5fa4005b5f5ffd5b5f5ffd5b5f5ffd5b5f5ffd5b5f5ffd5b6024356004356000526000602001526040600020545f5260205ff35b60043560016000526000602001526040600020545f5260205ff3"; - assert_eq!(artifact.bytecode.to_lowercase(), expected_bytecode.to_lowercase()); + assert_eq!( + shanghai_artifact.bytecode.to_lowercase(), + expected_shanghai_bytecode.to_lowercase() + ); } diff --git a/huff_core/tests/file_resolution.rs b/huff_core/tests/file_resolution.rs index d3ec9385..ae09d7c3 100644 --- a/huff_core/tests/file_resolution.rs +++ b/huff_core/tests/file_resolution.rs @@ -3,20 +3,23 @@ use std::{path::PathBuf, sync::Arc}; use huff_core::Compiler; use huff_utils::{ file_provider::{FileProvider, FileSystemFileProvider}, - prelude::{CompilerError, OutputLocation, UnpackError}, + prelude::{CompilerError, EVMVersion, OutputLocation, UnpackError}, }; #[test] fn test_get_outputs_no_output() { + let evm_version = EVMVersion::default(); let compiler: Compiler = - Compiler::new(Arc::new(vec![]), None, None, None, None, None, false, false); + Compiler::new(&evm_version, Arc::new(vec![]), None, None, None, None, None, false, false); let ol: OutputLocation = compiler.get_outputs(); assert_eq!(ol, OutputLocation::default()); } #[test] fn test_get_outputs_with_output() { + let evm_version = EVMVersion::default(); let compiler: Compiler = Compiler::new( + &evm_version, Arc::new(vec![]), Some("./test_out/".to_string()), None, diff --git a/huff_core/tests/free_storage_pointer.rs b/huff_core/tests/free_storage_pointer.rs index 8dddebe0..888e99c8 100644 --- a/huff_core/tests/free_storage_pointer.rs +++ b/huff_core/tests/free_storage_pointer.rs @@ -1,7 +1,10 @@ use huff_codegen::Codegen; use huff_lexer::*; use huff_parser::Parser; -use huff_utils::{prelude::FullFileSource, token::Token}; +use huff_utils::{ + prelude::{EVMVersion, FullFileSource}, + token::Token, +}; /// Check that free storage pointers referenced outside of macro bodies /// are assigned correctly at compilation @@ -32,6 +35,6 @@ fn test_set_free_storage_pointers() { contract.derive_storage_pointers(); // Assert the Free storage pointer has been set to 0 - let mbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let mbytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert!(mbytes.starts_with("6000")); } diff --git a/huff_core/tests/functions.rs b/huff_core/tests/functions.rs index 652f19c1..50bca7f7 100644 --- a/huff_core/tests/functions.rs +++ b/huff_core/tests/functions.rs @@ -1,7 +1,7 @@ use huff_codegen::Codegen; use huff_lexer::*; use huff_parser::Parser; -use huff_utils::prelude::{FileSource, FullFileSource, Token}; +use huff_utils::prelude::{EVMVersion, FileSource, FullFileSource, Token}; use std::sync::Arc; #[test] @@ -110,7 +110,7 @@ fn test_function() { assert!(cg.artifact.is_none()); // Have the Codegen create the runtime bytecode - let rbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let rbytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); // Churn let mut cg = Codegen::new(); let artifact = @@ -204,7 +204,7 @@ fn test_nested_function() { assert!(cg.artifact.is_none()); // Have the Codegen create the runtime bytecode - let rbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let rbytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); // Churn let mut cg = Codegen::new(); let artifact = diff --git a/huff_core/tests/gen_artifact.rs b/huff_core/tests/gen_artifact.rs index 25ebe90d..a490991a 100644 --- a/huff_core/tests/gen_artifact.rs +++ b/huff_core/tests/gen_artifact.rs @@ -30,8 +30,11 @@ fn test_missing_constructor() { dependencies: None, }; + let evm_version = EVMVersion::default(); + // Instantiate a new compiler - let compiler = Compiler::new(Arc::new(vec![]), None, None, None, None, None, false, false); + let compiler = + Compiler::new(&evm_version, Arc::new(vec![]), None, None, None, None, None, false, false); // Generate the compile artifact let arc_source = Arc::new(full_source); @@ -74,8 +77,11 @@ fn test_missing_constructor_with_inputs() { dependencies: None, }; + let evm_version = EVMVersion::default(); + // Instantiate a new compiler let compiler = Compiler::new( + &evm_version, Arc::new(vec![]), None, None, diff --git a/huff_core/tests/in_memory.rs b/huff_core/tests/in_memory.rs index 069860f8..320cbb2c 100644 --- a/huff_core/tests/in_memory.rs +++ b/huff_core/tests/in_memory.rs @@ -1,6 +1,7 @@ use std::{collections::HashMap, sync::Arc}; use huff_core::Compiler; +use huff_utils::prelude::EVMVersion; #[test] fn test_in_memory_compiler() { @@ -31,7 +32,9 @@ fn test_in_memory_compiler() { file_sources.insert(String::from("lib/mint.huff"), String::from(source_mint)); // Instantiate a new compiler + let evm_version = EVMVersion::default(); let compiler = Compiler::new_in_memory( + &evm_version, Arc::new(vec![main_file_name.clone()]), file_sources, None, diff --git a/huff_core/tests/macro_invoc_args.rs b/huff_core/tests/macro_invoc_args.rs index ab11f559..1ddc850f 100644 --- a/huff_core/tests/macro_invoc_args.rs +++ b/huff_core/tests/macro_invoc_args.rs @@ -25,8 +25,10 @@ fn test_opcode_macro_args() { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = EVMVersion::default(); + // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(&evm_version, &contract, None).unwrap(); // Full expected bytecode output (generated from huffc) (placed here as a reference) let expected_bytecode = "60088060093d393df360ff3d5260203df3"; @@ -61,8 +63,10 @@ fn test_all_opcodes_in_macro_args() { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = EVMVersion::default(); + // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(&evm_version, &contract, None).unwrap(); // Full expected bytecode output (generated from huffc) (placed here as a reference) let expected_bytecode = format!("60088060093d393df360ff{}", Opcode::from_str(o).unwrap()); @@ -97,8 +101,10 @@ fn test_constant_macro_arg() { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = EVMVersion::default(); + // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(&evm_version, &contract, None).unwrap(); // Full expected bytecode output (generated from huffc) (placed here as a reference) let expected_bytecode = "60088060093d393df360ff6002"; @@ -135,8 +141,10 @@ fn test_bubbled_label_call_macro_arg() { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = EVMVersion::default(); + // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(&evm_version, &contract, None).unwrap(); // Full expected bytecode output (generated from huffc) (placed here as a reference) let expected_bytecode = "60088060093d393df360ff5b610000"; @@ -172,8 +180,10 @@ fn test_bubbled_literal_macro_arg() { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = EVMVersion::default(); + // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(&evm_version, &contract, None).unwrap(); // Full expected bytecode output (generated from huffc) (placed here as a reference) let expected_bytecode = "60088060093d393df360ff610420"; @@ -209,8 +219,10 @@ fn test_bubbled_opcode_macro_arg() { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = EVMVersion::default(); + // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(&evm_version, &contract, None).unwrap(); // Full expected bytecode output (generated from huffc) (placed here as a reference) let expected_bytecode = "60088060093d393df360ff3d"; @@ -248,8 +260,10 @@ fn test_bubbled_constant_macro_arg() { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = EVMVersion::default(); + // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(&evm_version, &contract, None).unwrap(); // Full expected bytecode output (generated from huffc) (placed here as a reference) let expected_bytecode = "60088060093d393df360ff6002"; @@ -283,8 +297,10 @@ fn test_bubbled_arg_with_different_name() { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = EVMVersion::default(); + // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(&evm_version, &contract, None).unwrap(); // Full expected bytecode output (generated from huffc) (placed here as a reference) let expected_bytecode = "6001"; diff --git a/huff_core/tests/push_overrides.rs b/huff_core/tests/push_overrides.rs index 73e54ac0..b0678928 100644 --- a/huff_core/tests/push_overrides.rs +++ b/huff_core/tests/push_overrides.rs @@ -32,7 +32,7 @@ fn test_gracefully_pads_push_override() { // Have the Codegen create the constructor bytecode let (cbytes, has_custom_bootstrap) = - Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + Codegen::generate_constructor_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!( cbytes, String::from("7f0000000000000000000000000000000000000000000000000000000000000234") @@ -69,7 +69,7 @@ fn test_constructs_exact_push_override() { // Have the Codegen create the constructor bytecode let (cbytes, has_custom_bootstrap) = - Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + Codegen::generate_constructor_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(cbytes, String::from("6034")); assert!(!has_custom_bootstrap); } @@ -103,7 +103,7 @@ fn test_no_push0_override() { // Have the Codegen create the constructor bytecode let (cbytes, has_custom_bootstrap) = - Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + Codegen::generate_constructor_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(cbytes, String::from("5f")); assert!(!has_custom_bootstrap); } @@ -158,6 +158,6 @@ fn test_literal_to_push0() { assert!(cg.artifact.is_none()); // Have the Codegen create the constructor bytecode - let cbytes = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let cbytes = Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).unwrap(); assert_eq!(cbytes, String::from("5f5f5f60005f6001")); } diff --git a/huff_core/tests/recurse_bytecode.rs b/huff_core/tests/recurse_bytecode.rs index 045cf21d..9cd040a4 100644 --- a/huff_core/tests/recurse_bytecode.rs +++ b/huff_core/tests/recurse_bytecode.rs @@ -52,10 +52,12 @@ fn recurse_macro_bytecode() { let mut contract = parser.parse().unwrap(); contract.derive_storage_pointers(); + let evm_version = &EVMVersion::default(); + // Create main and constructor bytecode - let main_bytecode = Codegen::generate_main_bytecode(&contract, None).unwrap(); + let main_bytecode = Codegen::generate_main_bytecode(evm_version, &contract, None).unwrap(); let (constructor_bytecode, has_custom_bootstrap) = - Codegen::generate_constructor_bytecode(&contract, None).unwrap(); + Codegen::generate_constructor_bytecode(evm_version, &contract, None).unwrap(); assert!(!has_custom_bootstrap); // Full expected bytecode output (generated from huffc) (placed here as a reference) diff --git a/huff_core/tests/test_circular_constructor.rs b/huff_core/tests/test_circular_constructor.rs index d5eb3f51..4d0acd20 100644 --- a/huff_core/tests/test_circular_constructor.rs +++ b/huff_core/tests/test_circular_constructor.rs @@ -44,7 +44,7 @@ fn test_circular_large_constructors() { contract.derive_storage_pointers(); // Create constructor bytecode - match Codegen::generate_constructor_bytecode(&contract, None) { + match Codegen::generate_constructor_bytecode(&EVMVersion::default(),&contract, None) { Ok((mb, _)) => assert_eq!("60ff58585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858".to_string(), mb), Err(_) => panic!("moose"), } @@ -92,7 +92,7 @@ fn test_circular_constructor_at_word_boundry() { contract.derive_storage_pointers(); // Create constructor bytecode - match Codegen::generate_constructor_bytecode(&contract, None) { + match Codegen::generate_constructor_bytecode(&EVMVersion::default(),&contract, None) { Ok((mb, _)) => assert_eq!("61010358585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858585858610103".to_string(), mb), Err(_) => panic!("moose"), } @@ -125,7 +125,7 @@ fn test_double_circular_constructor_multiple_macro_invocations() { contract.derive_storage_pointers(); // Create constructor bytecode - match Codegen::generate_constructor_bytecode(&contract, None) { + match Codegen::generate_constructor_bytecode(&EVMVersion::default(), &contract, None) { Ok((mb, _)) => assert_eq!("60075860076007".to_string(), mb), Err(_) => panic!("moose"), } @@ -162,7 +162,7 @@ fn test_double_circular_constructor_nested_macro_invocations() { contract.derive_storage_pointers(); // Create constructor bytecode - match Codegen::generate_constructor_bytecode(&contract, None) { + match Codegen::generate_constructor_bytecode(&EVMVersion::default(), &contract, None) { Ok((mb, _)) => assert_eq!("600a58600a586003600a".to_string(), mb), Err(_) => panic!("moose"), } diff --git a/huff_core/tests/tests.rs b/huff_core/tests/tests.rs index 4c181a8a..ba2b653e 100644 --- a/huff_core/tests/tests.rs +++ b/huff_core/tests/tests.rs @@ -3,7 +3,7 @@ use huff_lexer::*; use huff_parser::Parser; use huff_utils::{ error::CodegenErrorKind, - prelude::{FullFileSource, Token}, + prelude::{EVMVersion, FullFileSource, Token}, }; #[test] @@ -42,7 +42,7 @@ fn test_invocation_should_fail() { // Have the Codegen create the runtime bytecode. Should throw an error because test // invocation is not allowed. - match Codegen::generate_main_bytecode(&contract, None) { + match Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None) { Ok(_) => panic!("Expected an error"), Err(e) => { assert_eq!( diff --git a/huff_core/tests/verbatim.rs b/huff_core/tests/verbatim.rs index b345f1c0..d5f6e595 100644 --- a/huff_core/tests/verbatim.rs +++ b/huff_core/tests/verbatim.rs @@ -19,7 +19,7 @@ fn test_verbatim() { contract.derive_storage_pointers(); // Get main bytecode with verbatim - match Codegen::generate_main_bytecode(&contract, None) { + match Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None) { Ok(mb) => assert_eq!(mb, "1234567890abcdef".to_string()), Err(_) => panic!("moose"), } @@ -41,5 +41,5 @@ fn test_verbatim_invalid_hex() { contract.derive_storage_pointers(); // Expect failure to generate bytecode with verbatim - assert!(Codegen::generate_main_bytecode(&contract, None).is_err()); + assert!(Codegen::generate_main_bytecode(&EVMVersion::default(), &contract, None).is_err()); } diff --git a/huff_js/Cargo.toml b/huff_js/Cargo.toml index e1dbd813..9970e75e 100644 --- a/huff_js/Cargo.toml +++ b/huff_js/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "huffc-js" -version = "0.3.1" +version = "0.3.2" authors = ["refcell", "clabby", "exp.table", "kanewallmann"] edition = "2021" readme = "README.md" diff --git a/huff_js/src/lib.rs b/huff_js/src/lib.rs index 406e092f..2d339028 100644 --- a/huff_js/src/lib.rs +++ b/huff_js/src/lib.rs @@ -9,7 +9,7 @@ use std::{collections::HashMap, sync::Arc}; use wasm_bindgen::prelude::*; use huff_core::Compiler; -use huff_utils::{abi::Abi, artifact::Artifact, error::CompilerError}; +use huff_utils::{abi::Abi, artifact::Artifact, error::CompilerError, prelude::EVMVersion}; use serde::{Deserialize, Serialize}; /// Converts a CompilerError into a returnable JsValue @@ -20,6 +20,7 @@ fn compiler_error_to_js_value(ce: Arc) -> JsValue { #[derive(Serialize, Deserialize)] struct CompilerInput { + evm_version: Option, sources: Vec, files: HashMap, construct_args: Option>, @@ -45,7 +46,10 @@ struct CompilerOutput { pub fn compile(input: JsValue) -> Result { let input: CompilerInput = serde_wasm_bindgen::from_value(input)?; + let evm_version = EVMVersion::from(input.evm_version); + let compiler = Compiler::new_in_memory( + &evm_version, Arc::new(input.sources), input.files, input.alternative_main, diff --git a/huff_lexer/Cargo.toml b/huff_lexer/Cargo.toml index 5a4594a0..dabed711 100644 --- a/huff_lexer/Cargo.toml +++ b/huff_lexer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "huff_lexer" -version = "0.3.1" +version = "0.3.2" edition = "2021" authors = ["refcell", "clabby", "exp.table", "maddiaa"] readme = "README.md" diff --git a/huff_parser/Cargo.toml b/huff_parser/Cargo.toml index bf447f30..8c139e5e 100644 --- a/huff_parser/Cargo.toml +++ b/huff_parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "huff_parser" -version = "0.3.1" +version = "0.3.2" edition = "2021" authors = ["refcell", "clabby", "exp.table", "maddiaa"] readme = "README.md" diff --git a/huff_tests/src/runner.rs b/huff_tests/src/runner.rs index 4d93d527..912a31b0 100644 --- a/huff_tests/src/runner.rs +++ b/huff_tests/src/runner.rs @@ -7,7 +7,7 @@ use ethers_core::{ use huff_codegen::Codegen; use huff_utils::{ ast::{DecoratorFlag, MacroDefinition}, - prelude::{pad_n_bytes, CompilerError, Contract}, + prelude::{pad_n_bytes, CompilerError, Contract, EVMVersion}, }; use revm::{ db::DbAccount, @@ -170,10 +170,14 @@ impl TestRunner { m: &MacroDefinition, contract: &Contract, ) -> Result { + // TODO: set to non default + let evm_version = EVMVersion::default(); + let name = m.name.to_owned(); // Compile the passed test macro match Codegen::macro_to_bytecode( + &evm_version, m, contract, &mut vec![m], diff --git a/huff_utils/src/ast.rs b/huff_utils/src/ast.rs index 8ffb8e5d..72cf8fe6 100644 --- a/huff_utils/src/ast.rs +++ b/huff_utils/src/ast.rs @@ -6,6 +6,7 @@ use crate::{ bytes_util::*, error::CodegenError, evm::Opcode, + evm_version::EVMVersion, prelude::{MacroArg::Ident, Span, TokenKind}, }; use std::{ @@ -547,8 +548,9 @@ pub struct MacroDefinition { } impl ToIRBytecode for MacroDefinition { - fn to_irbytecode(&self) -> Result { - let inner_irbytes: Vec = MacroDefinition::to_irbytes(&self.statements); + fn to_irbytecode(&self, evm_version: &EVMVersion) -> Result { + let inner_irbytes: Vec = + MacroDefinition::to_irbytes(evm_version, &self.statements); Ok(IRBytecode(inner_irbytes)) } } @@ -581,14 +583,17 @@ impl MacroDefinition { } /// Translate statements into IRBytes - pub fn to_irbytes(statements: &[Statement]) -> Vec { + pub fn to_irbytes<'a>( + evm_version: &EVMVersion, + statements: &'a [Statement], + ) -> Vec> { let mut inner_irbytes: Vec = vec![]; let mut statement_iter = statements.iter(); while let Some(statement) = statement_iter.next() { match &statement.ty { StatementType::Literal(l) => { - let push_bytes = literal_gen(l); + let push_bytes = literal_gen(evm_version, l); inner_irbytes.push(IRBytes { ty: IRByteType::Bytes(Bytes(push_bytes)), span: &statement.span, @@ -670,7 +675,7 @@ impl MacroDefinition { }); // Recurse label statements to IRBytes Bytes - inner_irbytes.append(&mut MacroDefinition::to_irbytes(&l.inner)); + inner_irbytes.append(&mut MacroDefinition::to_irbytes(evm_version, &l.inner)); } StatementType::BuiltinFunctionCall(builtin) => { inner_irbytes.push(IRBytes { diff --git a/huff_utils/src/bytecode.rs b/huff_utils/src/bytecode.rs index ffdb79e1..5b67fe2f 100644 --- a/huff_utils/src/bytecode.rs +++ b/huff_utils/src/bytecode.rs @@ -2,7 +2,10 @@ //! //! Abstract translating state into bytecode. -use crate::prelude::{AstSpan, Statement, TableDefinition}; +use crate::{ + evm_version::EVMVersion, + prelude::{AstSpan, Statement, TableDefinition}, +}; use std::{ collections::{BTreeMap, BTreeSet}, fmt::{self, Display}, @@ -43,7 +46,7 @@ pub struct IRBytecode<'a>(pub Vec>); /// Converts a stateful object to intermediate bytecode pub trait ToIRBytecode { /// Translates `self` to intermediate bytecode representation - fn to_irbytecode(&self) -> Result; + fn to_irbytecode(&self, evm_version: &EVMVersion) -> Result; } /// Full Bytecode diff --git a/huff_utils/src/bytes_util.rs b/huff_utils/src/bytes_util.rs index 583c71a3..feb862e7 100644 --- a/huff_utils/src/bytes_util.rs +++ b/huff_utils/src/bytes_util.rs @@ -1,4 +1,4 @@ -use crate::evm::Opcode; +use crate::{evm::Opcode, evm_version::EVMVersion}; use std::num::ParseIntError; use tiny_keccak::{Hasher, Keccak}; @@ -70,10 +70,23 @@ pub fn hash_bytes(dest: &mut [u8], to_hash: &String) { } /// Converts a value literal to its smallest equivalent `PUSHX` bytecode -pub fn literal_gen(l: &[u8; 32]) -> String { +pub fn literal_gen(evm_version: &EVMVersion, l: &[u8; 32]) -> String { let hex_literal: String = bytes32_to_string(l, false); match hex_literal.as_str() { - "00" => Opcode::Push0.to_string(), - _ => format!("{:02x}{hex_literal}", 95 + hex_literal.len() / 2), + "00" => format_push0(evm_version, hex_literal), + _ => format_literal(hex_literal), } } + +fn format_push0(evm_version: &EVMVersion, hex_literal: String) -> String { + if evm_version.has_push0() { + Opcode::Push0.to_string() + } else { + format_literal(hex_literal) + } +} + +/// Converts a literal into its bytecode string representation +pub fn format_literal(hex_literal: String) -> String { + format!("{:02x}{hex_literal}", 95 + hex_literal.len() / 2) +} diff --git a/huff_utils/src/evm_version.rs b/huff_utils/src/evm_version.rs new file mode 100644 index 00000000..44e1a2af --- /dev/null +++ b/huff_utils/src/evm_version.rs @@ -0,0 +1,58 @@ +use std::cmp::PartialOrd; + +/// Evm Version +/// +/// Determines which features will be available when compiling. + +#[derive(Debug, PartialEq, PartialOrd)] +pub enum SupportedEVMVersions { + /// Introduced prevrandao, disallow difficulty opcode (does not affect codegen) + Paris, + /// Introduce Push0, compiler will use by default + Shanghai, +} + +#[derive(Debug)] +/// EVM Version +pub struct EVMVersion { + version: SupportedEVMVersions, +} + +impl EVMVersion { + /// Create a new EVM Version with the specified value + pub fn new(version: SupportedEVMVersions) -> Self { + Self { version } + } + + /// As PartialOrd is implemented in the struct, all versions after shanghai will support this + pub fn has_push0(&self) -> bool { + self.version >= SupportedEVMVersions::Shanghai + } +} + +impl Default for EVMVersion { + fn default() -> Self { + Self::new(SupportedEVMVersions::Shanghai) + } +} + +/// Convert from Option to EVMVersion +impl From> for EVMVersion { + fn from(version: Option) -> Self { + match version { + Some(version) => Self::from(version), + None => Self::default(), + } + } +} + +/// Convert from String to EVMVersion +impl From for EVMVersion { + fn from(version: String) -> Self { + match version.as_str() { + "shanghai" => Self::new(SupportedEVMVersions::Shanghai), + "paris" => Self::new(SupportedEVMVersions::Paris), + _ => Self::default(), + } + } +} diff --git a/huff_utils/src/lib.rs b/huff_utils/src/lib.rs index 21f3b236..3dd3fc87 100644 --- a/huff_utils/src/lib.rs +++ b/huff_utils/src/lib.rs @@ -54,10 +54,13 @@ pub mod time; /// Wasm Module pub mod wasm; +/// EVM Version Module +pub mod evm_version; + /// Prelude wraps common utilities. pub mod prelude { pub use crate::{ - abi::*, artifact::*, ast::*, bytecode::*, bytes_util::*, error::*, evm::*, files::*, io::*, - report::*, sol_interface::*, token::*, types::*, + abi::*, artifact::*, ast::*, bytecode::*, bytes_util::*, error::*, evm::*, evm_version::*, + files::*, io::*, report::*, sol_interface::*, token::*, types::*, }; }