Repository: huff-language/huff-rs
Pull request #281 (2023-05-26 00:18:38)

feat(huffc): enable specifying evm version
## Overview

Adds compiler flag `-e | --evm-version` that can take in either "paris" or "shanghai" ("shanghai" by default). This will allow users to choose whether to compile 0x00 to push0 by default or not.   

Starting off with a subset of supported versions as there is little need to support beyond these two.

<!--
Thank you for creating a Pull Request!
Please provide a short description here and review the requirements below.
Bug fixes and new features should include tests.

Make sure to run these checks before opening a pr!
```sh
cargo check --all
cargo test --all --all-features
cargo +nightly fmt -- --check
cargo +nightly clippy --all --all-features -- -D warnings
```

Recommended method to auto format your code before pushing:
```sh
cargo +nightly fmt --all
```
-->



Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 6e9dbe6..d42d6fe 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 7487db0..39a3815 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 <version>`.  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 <version>`. 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 b5ac3aa..5e94d20 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 18c0f26..3970afc 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:
     <PATH>    The contract(s) to compile
 
 OPTIONS:
-    -a, --artifacts                       Whether to generate artifacts or not
-    -b, --bytecode                        Generate and log bytecode
-    -d, --output-directory <OUTPUTDIR>    The output directory [default: ./artifacts]
-    -g, --interface                       Generate solidity interface for a Huff artifact
-    -h, --help                            Print help information
-    -i, --inputs <INPUTS>...              The input constructor arguments
-    -n, --interactive                     Interactively input the constructor args
-    -o, --output <OUTPUT>                 The output file path
-    -p, --print                           Prints out to the terminal
-    -r, --bin-runtime                     Generate and log runtime bytecode
-    -s, --source-path <SOURCE>            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 <CONSTANTS>...
+            Override / set constants for the compilation environment
+
+    -d, --output-directory <OUTPUTDIR>
+            The output directory [default: ./artifacts]
+
+    -e, --evm-version <EVM_VERSION>
+            Set the EVM version
+
+    -g, --interface [<INTERFACE>...]
+            Generate solidity interface for a Huff artifact
+
+    -h, --help
+            Print help information
+
+    -i, --inputs <INPUTS>...
+            The input constructor arguments
+
+    -l, --label-indices
+            Prints out the jump label PC indices for the specified contract
+
+    -m, --alt-main <ALTERNATIVE_MAIN>
+            Compile a specific macro
+
+    -n, --interactive
+            Interactively input the constructor args
+
+    -o, --output <OUTPUT>
+            The output file path
+
+    -p, --print
+            Prints out to the terminal
+
+    -r, --bin-runtime
+            Generate and log runtime bytecode
+
+    -s, --source-path <SOURCE>
+            The contracts source path [default: ./contracts]
+
+    -t, --alt-constructor <ALTERNATIVE_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 cac7ce1..f0605bc 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<String>,
 
+    /// Set the EVM version
+    #[clap(short = 'e', long = "evm-version")]
+    evm_version: Option<String>,
+
     /// Test subcommand
     #[clap(subcommand)]
     test: Option<TestCommands>,
@@ -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 247801e..bc46ba2 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 1cd5ba8..7c5d2b8 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 e169650..b9706bd 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 da67a7a..9668820 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 640147c..aca743a 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<String>,
     ) -> Result<String, CodegenError> {
@@ -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<String>,
     ) -> 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<BytecodeRes, CodegenError> {
         // 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_core/Cargo.toml b/huff_core/Cargo.toml
index e6d8eb0..9249a88 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 edc2f90..9d33f15 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<Vec<Arc<Artifact>>, Arc<CompilerError>> = compiler.execute();
diff --git a/huff_core/benches/huff_benchmark.rs b/huff_core/benches/huff_benchmark.rs
index a67a5c0..e001cf7 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 5aeb5eb..e40e015 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<Vec<String>>,
     /// The output location
@@ -80,10 +84,11 @@ pub struct Compiler<'a> {
     pub file_provider: Arc<dyn FileProvider<'a>>,
 }
 
-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<Vec<String>>,
         output: Option<String>,
         alternative_main: Option<String>,
@@ -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<Vec<String>>,
         file_sources: HashMap<String, String>,
         alternative_main: Option<String>,
@@ -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_js/Cargo.toml b/huff_js/Cargo.toml
index e1dbd81..9970e75 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 406e092..2d33902 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<CompilerError>) -> JsValue {
 
 #[derive(Serialize, Deserialize)]
 struct CompilerInput {
+    evm_version: Option<String>,
     sources: Vec<String>,
     files: HashMap<String, String>,
     construct_args: Option<Vec<String>>,
@@ -45,7 +46,10 @@ struct CompilerOutput {
 pub fn compile(input: JsValue) -> Result<JsValue, JsValue> {
     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 5a4594a..dabed71 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 bf447f3..8c139e5 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_utils/src/ast.rs b/huff_utils/src/ast.rs
index 8ffb8e5..72cf8fe 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<CodegenError> for MacroDefinition {
-    fn to_irbytecode(&self) -> Result<IRBytecode, CodegenError> {
-        let inner_irbytes: Vec<IRBytes> = MacroDefinition::to_irbytes(&self.statements);
+    fn to_irbytecode(&self, evm_version: &EVMVersion) -> Result<IRBytecode, CodegenError> {
+        let inner_irbytes: Vec<IRBytes> =
+            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<IRBytes> {
+    pub fn to_irbytes<'a>(
+        evm_version: &EVMVersion,
+        statements: &'a [Statement],
+    ) -> Vec<IRBytes<'a>> {
         let mut inner_irbytes: Vec<IRBytes> = 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 ffdb79e..5b67fe2 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<IRBytes<'a>>);
 /// Converts a stateful object to intermediate bytecode
 pub trait ToIRBytecode<E> {
     /// Translates `self` to intermediate bytecode representation
-    fn to_irbytecode(&self) -> Result<IRBytecode, E>;
+    fn to_irbytecode(&self, evm_version: &EVMVersion) -> Result<IRBytecode, E>;
 }
 
 /// Full Bytecode
diff --git a/huff_utils/src/bytes_util.rs b/huff_utils/src/bytes_util.rs
index 583c71a..feb862e 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 0000000..44e1a2a
--- /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<String> to EVMVersion
+impl From<Option<String>> for EVMVersion {
+    fn from(version: Option<String>) -> Self {
+        match version {
+            Some(version) => Self::from(version),
+            None => Self::default(),
+        }
+    }
+}
+
+/// Convert from String to EVMVersion
+impl From<String> 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 21f3b23..3dd3fc8 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::*,
     };
 }


Test patch:
diff --git a/huff_codegen/tests/constructor_args.rs b/huff_codegen/tests/constructor_args.rs
index 065c175..24287e6 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<u8> =
         str_to_vec("87674fa174add091f082eab424cc60625118fa4c553592a4e54a76fb9e8512f6").unwrap();
     // Bogus constructors args
-    let args: Vec<String> = vec![
+    let args: Vec<String> = [
         "Hello",
         "10000",
         "false",
@@ -44,7 +44,7 @@ fn encode_array_constructor_args() {
     let _expected_bytes32: Vec<u8> =
         str_to_vec("87674fa174add091f082eab424cc60625118fa4c553592a4e54a76fb9e8512f6").unwrap();
     // Bogus constructors args
-    let args: Vec<String> = vec![
+    let args: Vec<String> = [
         "[100, 200, 300]",
         "[0x646dB8ffC21e7ddc2B6327448dd9Fa560Df41087, 0x646dB8ffC21e7ddc2B6327448dd9Fa560Df41087]",
         "[true, false, false]",
@@ -95,14 +95,12 @@ fn encode_missing_brackets_array_constructor_args() {
     let _expected_bytes32: Vec<u8> =
         str_to_vec("87674fa174add091f082eab424cc60625118fa4c553592a4e54a76fb9e8512f6").unwrap();
     // Bogus constructors args
-    let args: Vec<String> = vec![
-        "  100,  200,  300   ",
+    let args: Vec<String> = ["  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/tests/alternative_constructor_macro.rs b/huff_core/tests/alternative_constructor_macro.rs
index 4d9b36a..256923f 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 2c9bea0..bbc2c5b 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 7d8ee40..9866179 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 2751d21..d2188eb 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::<Vec<Token>>();
     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 a4d5754..57454f0 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 3688d37..a84e71f 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<ethers_core::abi::Token> = 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 09f721f..3c1144f 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 a8ab17f..3460cec 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 d3ec938..ae09d7c 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 8dddebe..888e99c 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 652f19c..50bca7f 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 25ebe90..a490991 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 069860f..320cbb2 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 ab11f55..1ddc850 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 73e54ac..b067892 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 045cf21..9cd040a 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 d5eb3f5..4d0acd2 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 4c181a8..ba2b653 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 b345f1c..d5f6e59 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_tests/src/runner.rs b/huff_tests/src/runner.rs
index 4d93d52..912a31b 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<TestResult, RunnerError> {
+        // 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],