From 9a34d7e472bd5951275b7fda3b9dce98b37944d7 Mon Sep 17 00:00:00 2001 From: Federico Gimenez Date: Fri, 8 Mar 2024 13:16:26 +0100 Subject: [PATCH] added patched forge --- Dockerfile | 28 +- patches/forge.diff | 774 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 799 insertions(+), 3 deletions(-) create mode 100644 patches/forge.diff diff --git a/Dockerfile b/Dockerfile index a64edfd..fa0ff3b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:jammy-20240212 as builder +FROM ubuntu:jammy-20240212 as solc-builder # Install build dependencies RUN apt-get update && apt-get install -y --no-install-recommends \ @@ -27,11 +27,33 @@ RUN git apply solc.diff && \ cmake .. -DCMAKE_BUILD_TYPE=Release && \ make solc +FROM rust:1.76.0-slim-buster as forge-builder + +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + git + +ENV FORGE_COMMIT=5b7e4cb3c882b28f3c32ba580de27ce7381f415a + +RUN git clone https://github.com/foundry-rs/foundry.git /app/foundry + +WORKDIR /app/foundry + +RUN git checkout $FORGE_COMMIT + +COPY ./patches/forge.diff . + +RUN git apply forge.diff && \ + cargo build --bin forge --release + FROM ubuntu:jammy-20240212 # Copy the compiled solc binary to a standard location -COPY --from=builder /app/solidity/build/solc/solc /usr/local/bin/solc -RUN chmod +x /usr/local/bin/solc +COPY --from=solc-builder /app/solidity/build/solc/solc /usr/local/bin/solc +COPY --from=forge-builder /app/foundry/target/release/forge /usr/local/bin/forge + +RUN chmod +x /usr/local/bin/solc && \ + chmod +x /usr/local/bin/forge # Set the entrypoint to the solc binary ENTRYPOINT ["/usr/local/bin/solc"] diff --git a/patches/forge.diff b/patches/forge.diff new file mode 100644 index 0000000..cce0c74 --- /dev/null +++ b/patches/forge.diff @@ -0,0 +1,774 @@ +diff --git a/Cargo.lock b/Cargo.lock +index 67259910005..88eb5b9d118 100644 +--- a/Cargo.lock ++++ b/Cargo.lock +@@ -2082,7 +2082,7 @@ dependencies = [ + [[package]] + name = "ethers" + version = "2.0.11" +-source = "git+https://github.com/gakonst/ethers-rs?rev=f0e5b194f09c533feb10d1a686ddb9e5946ec107#f0e5b194f09c533feb10d1a686ddb9e5946ec107" ++source = "git+https://github.com/clabby/ethers-rs?branch=cl/call-type-3074#2ffcdc579fac2032c706ee81c5697aec1a731db6" + dependencies = [ + "ethers-addressbook", + "ethers-contract", +@@ -2097,7 +2097,7 @@ dependencies = [ + [[package]] + name = "ethers-addressbook" + version = "2.0.11" +-source = "git+https://github.com/gakonst/ethers-rs?rev=f0e5b194f09c533feb10d1a686ddb9e5946ec107#f0e5b194f09c533feb10d1a686ddb9e5946ec107" ++source = "git+https://github.com/clabby/ethers-rs?branch=cl/call-type-3074#2ffcdc579fac2032c706ee81c5697aec1a731db6" + dependencies = [ + "ethers-core", + "once_cell", +@@ -2108,7 +2108,7 @@ dependencies = [ + [[package]] + name = "ethers-contract" + version = "2.0.11" +-source = "git+https://github.com/gakonst/ethers-rs?rev=f0e5b194f09c533feb10d1a686ddb9e5946ec107#f0e5b194f09c533feb10d1a686ddb9e5946ec107" ++source = "git+https://github.com/clabby/ethers-rs?branch=cl/call-type-3074#2ffcdc579fac2032c706ee81c5697aec1a731db6" + dependencies = [ + "const-hex", + "ethers-contract-abigen", +@@ -2126,7 +2126,7 @@ dependencies = [ + [[package]] + name = "ethers-contract-abigen" + version = "2.0.11" +-source = "git+https://github.com/gakonst/ethers-rs?rev=f0e5b194f09c533feb10d1a686ddb9e5946ec107#f0e5b194f09c533feb10d1a686ddb9e5946ec107" ++source = "git+https://github.com/clabby/ethers-rs?branch=cl/call-type-3074#2ffcdc579fac2032c706ee81c5697aec1a731db6" + dependencies = [ + "Inflector", + "const-hex", +@@ -2149,7 +2149,7 @@ dependencies = [ + [[package]] + name = "ethers-contract-derive" + version = "2.0.11" +-source = "git+https://github.com/gakonst/ethers-rs?rev=f0e5b194f09c533feb10d1a686ddb9e5946ec107#f0e5b194f09c533feb10d1a686ddb9e5946ec107" ++source = "git+https://github.com/clabby/ethers-rs?branch=cl/call-type-3074#2ffcdc579fac2032c706ee81c5697aec1a731db6" + dependencies = [ + "Inflector", + "const-hex", +@@ -2164,7 +2164,7 @@ dependencies = [ + [[package]] + name = "ethers-core" + version = "2.0.11" +-source = "git+https://github.com/gakonst/ethers-rs?rev=f0e5b194f09c533feb10d1a686ddb9e5946ec107#f0e5b194f09c533feb10d1a686ddb9e5946ec107" ++source = "git+https://github.com/clabby/ethers-rs?branch=cl/call-type-3074#2ffcdc579fac2032c706ee81c5697aec1a731db6" + dependencies = [ + "arrayvec", + "bytes", +@@ -2193,7 +2193,7 @@ dependencies = [ + [[package]] + name = "ethers-etherscan" + version = "2.0.11" +-source = "git+https://github.com/gakonst/ethers-rs?rev=f0e5b194f09c533feb10d1a686ddb9e5946ec107#f0e5b194f09c533feb10d1a686ddb9e5946ec107" ++source = "git+https://github.com/clabby/ethers-rs?branch=cl/call-type-3074#2ffcdc579fac2032c706ee81c5697aec1a731db6" + dependencies = [ + "chrono", + "ethers-core", +@@ -2208,7 +2208,7 @@ dependencies = [ + [[package]] + name = "ethers-middleware" + version = "2.0.11" +-source = "git+https://github.com/gakonst/ethers-rs?rev=f0e5b194f09c533feb10d1a686ddb9e5946ec107#f0e5b194f09c533feb10d1a686ddb9e5946ec107" ++source = "git+https://github.com/clabby/ethers-rs?branch=cl/call-type-3074#2ffcdc579fac2032c706ee81c5697aec1a731db6" + dependencies = [ + "async-trait", + "auto_impl", +@@ -2233,7 +2233,7 @@ dependencies = [ + [[package]] + name = "ethers-providers" + version = "2.0.11" +-source = "git+https://github.com/gakonst/ethers-rs?rev=f0e5b194f09c533feb10d1a686ddb9e5946ec107#f0e5b194f09c533feb10d1a686ddb9e5946ec107" ++source = "git+https://github.com/clabby/ethers-rs?branch=cl/call-type-3074#2ffcdc579fac2032c706ee81c5697aec1a731db6" + dependencies = [ + "async-trait", + "auto_impl", +@@ -2271,7 +2271,7 @@ dependencies = [ + [[package]] + name = "ethers-signers" + version = "2.0.11" +-source = "git+https://github.com/gakonst/ethers-rs?rev=f0e5b194f09c533feb10d1a686ddb9e5946ec107#f0e5b194f09c533feb10d1a686ddb9e5946ec107" ++source = "git+https://github.com/clabby/ethers-rs?branch=cl/call-type-3074#2ffcdc579fac2032c706ee81c5697aec1a731db6" + dependencies = [ + "async-trait", + "coins-bip32", +@@ -2299,7 +2299,7 @@ dependencies = [ + [[package]] + name = "ethers-solc" + version = "2.0.11" +-source = "git+https://github.com/gakonst/ethers-rs?rev=f0e5b194f09c533feb10d1a686ddb9e5946ec107#f0e5b194f09c533feb10d1a686ddb9e5946ec107" ++source = "git+https://github.com/clabby/ethers-rs?branch=cl/call-type-3074#2ffcdc579fac2032c706ee81c5697aec1a731db6" + dependencies = [ + "cfg-if", + "const-hex", +@@ -5706,7 +5706,7 @@ dependencies = [ + [[package]] + name = "revm" + version = "3.5.0" +-source = "git+https://github.com/bluealloy/revm?branch=reth_freeze#b00ebab8b3477f87e3d876a11b8f18d00a8f4103" ++source = "git+https://github.com/clabby/revm?branch=cl/eip-3074#7b6365ab030f94b88fde70c934af736a58ae2e04" + dependencies = [ + "auto_impl", + "revm-interpreter", +@@ -5718,7 +5718,7 @@ dependencies = [ + [[package]] + name = "revm-interpreter" + version = "1.3.0" +-source = "git+https://github.com/bluealloy/revm?branch=reth_freeze#b00ebab8b3477f87e3d876a11b8f18d00a8f4103" ++source = "git+https://github.com/clabby/revm?branch=cl/eip-3074#7b6365ab030f94b88fde70c934af736a58ae2e04" + dependencies = [ + "revm-primitives", + "serde", +@@ -5727,15 +5727,13 @@ dependencies = [ + [[package]] + name = "revm-precompile" + version = "2.2.0" +-source = "git+https://github.com/bluealloy/revm?branch=reth_freeze#b00ebab8b3477f87e3d876a11b8f18d00a8f4103" ++source = "git+https://github.com/clabby/revm?branch=cl/eip-3074#7b6365ab030f94b88fde70c934af736a58ae2e04" + dependencies = [ + "aurora-engine-modexp", + "c-kzg", +- "k256", + "once_cell", + "revm-primitives", + "ripemd", +- "secp256k1", + "sha2 0.10.8", + "substrate-bn", + ] +@@ -5743,7 +5741,7 @@ dependencies = [ + [[package]] + name = "revm-primitives" + version = "1.3.0" +-source = "git+https://github.com/bluealloy/revm?branch=reth_freeze#b00ebab8b3477f87e3d876a11b8f18d00a8f4103" ++source = "git+https://github.com/clabby/revm?branch=cl/eip-3074#7b6365ab030f94b88fde70c934af736a58ae2e04" + dependencies = [ + "alloy-primitives", + "alloy-rlp", +@@ -5754,6 +5752,8 @@ dependencies = [ + "enumn", + "hashbrown 0.14.3", + "hex", ++ "k256", ++ "secp256k1", + "serde", + ] + +diff --git a/Cargo.toml b/Cargo.toml +index 19a26c63bb2..6db993d054b 100644 +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -187,17 +187,17 @@ tower-http = "0.4" + #ethers-solc = { path = "../ethers-rs/ethers-solc" } + + [patch.crates-io] +-ethers = { git = "https://github.com/gakonst/ethers-rs", rev = "f0e5b194f09c533feb10d1a686ddb9e5946ec107" } +-ethers-core = { git = "https://github.com/gakonst/ethers-rs", rev = "f0e5b194f09c533feb10d1a686ddb9e5946ec107" } +-ethers-contract = { git = "https://github.com/gakonst/ethers-rs", rev = "f0e5b194f09c533feb10d1a686ddb9e5946ec107" } +-ethers-contract-abigen = { git = "https://github.com/gakonst/ethers-rs", rev = "f0e5b194f09c533feb10d1a686ddb9e5946ec107" } +-ethers-providers = { git = "https://github.com/gakonst/ethers-rs", rev = "f0e5b194f09c533feb10d1a686ddb9e5946ec107" } +-ethers-signers = { git = "https://github.com/gakonst/ethers-rs", rev = "f0e5b194f09c533feb10d1a686ddb9e5946ec107" } +-ethers-middleware = { git = "https://github.com/gakonst/ethers-rs", rev = "f0e5b194f09c533feb10d1a686ddb9e5946ec107" } +-ethers-solc = { git = "https://github.com/gakonst/ethers-rs", rev = "f0e5b194f09c533feb10d1a686ddb9e5946ec107" } +- +-revm = { git = "https://github.com/bluealloy/revm", branch = "reth_freeze" } +-revm-interpreter = { git = "https://github.com/bluealloy/revm", branch = "reth_freeze" } +-revm-precompile = { git = "https://github.com/bluealloy/revm", branch = "reth_freeze" } +-revm-primitives = { git = "https://github.com/bluealloy/revm", branch = "reth_freeze" } ++ethers = { git = "https://github.com/clabby/ethers-rs", branch = "cl/call-type-3074" } ++ethers-core = { git = "https://github.com/clabby/ethers-rs", branch = "cl/call-type-3074" } ++ethers-contract = { git = "https://github.com/clabby/ethers-rs", branch = "cl/call-type-3074" } ++ethers-contract-abigen = { git = "https://github.com/clabby/ethers-rs", branch = "cl/call-type-3074" } ++ethers-providers = { git = "https://github.com/clabby/ethers-rs", branch = "cl/call-type-3074" } ++ethers-signers = { git = "https://github.com/clabby/ethers-rs", branch = "cl/call-type-3074" } ++ethers-middleware = { git = "https://github.com/clabby/ethers-rs", branch = "cl/call-type-3074" } ++ethers-solc = { git = "https://github.com/clabby/ethers-rs", branch = "cl/call-type-3074" } ++ ++revm = { git = "https://github.com/clabby/revm", branch = "cl/eip-3074" } ++revm-interpreter = { git = "https://github.com/clabby/revm", branch = "cl/eip-3074" } ++revm-precompile = { git = "https://github.com/clabby/revm", branch = "cl/eip-3074" } ++revm-primitives = { git = "https://github.com/clabby/revm", branch = "cl/eip-3074" } + +diff --git a/crates/anvil/core/src/eth/transaction/mod.rs b/crates/anvil/core/src/eth/transaction/mod.rs +index 68cd9b48fa8..b07914480f8 100644 +--- a/crates/anvil/core/src/eth/transaction/mod.rs ++++ b/crates/anvil/core/src/eth/transaction/mod.rs +@@ -137,7 +137,7 @@ impl EthTransactionRequest { + gas_limit: gas.unwrap_or_default(), + is_system_tx: optimism_fields.clone()?.is_system_tx, + input: data.clone().unwrap_or_default(), +- })); ++ })) + } + match ( + transaction_type, +@@ -860,9 +860,7 @@ impl Decodable for TypedTransaction { + if rlp.is_list() { + return Ok(TypedTransaction::Legacy(rlp.as_val()?)) + } +- let [first, s @ ..] = rlp.data()? else { +- return Err(DecoderError::Custom("empty slice")); +- }; ++ let [first, s @ ..] = rlp.data()? else { return Err(DecoderError::Custom("empty slice")) }; + // "advance" the header, see comments in fastrlp impl below + let s = if s.is_empty() { &rlp.as_raw()[1..] } else { s }; + +diff --git a/crates/anvil/src/eth/util.rs b/crates/anvil/src/eth/util.rs +index 4181df4e8d4..d3c6e9d7e97 100644 +--- a/crates/anvil/src/eth/util.rs ++++ b/crates/anvil/src/eth/util.rs +@@ -79,6 +79,7 @@ pub fn to_precompile_id(spec_id: SpecId) -> revm::precompile::SpecId { + SpecId::MERGE | + SpecId::SHANGHAI | + SpecId::CANCUN | ++ SpecId::PRAGUE | + SpecId::BEDROCK | + SpecId::REGOLITH | + SpecId::CANYON | +diff --git a/crates/anvil/src/genesis.rs b/crates/anvil/src/genesis.rs +index 23afd5fc3c9..43ba7030b80 100644 +--- a/crates/anvil/src/genesis.rs ++++ b/crates/anvil/src/genesis.rs +@@ -199,6 +199,8 @@ pub struct Config { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub cancun_block: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] ++ pub prague_block: Option, ++ #[serde(default, skip_serializing_if = "Option::is_none")] + pub terminal_total_difficulty: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub terminal_total_difficulty_passed: Option, +diff --git a/crates/anvil/src/hardfork.rs b/crates/anvil/src/hardfork.rs +index 42745fb80ce..62e20c3e9e5 100644 +--- a/crates/anvil/src/hardfork.rs ++++ b/crates/anvil/src/hardfork.rs +@@ -22,6 +22,7 @@ pub enum Hardfork { + Paris, + Shanghai, + Cancun, ++ Prague, + #[default] + Latest, + } +@@ -48,6 +49,7 @@ impl Hardfork { + + // TODO: set block number after activation + Hardfork::Cancun => unreachable!(), ++ Hardfork::Prague => unreachable!(), + } + } + +@@ -100,6 +102,10 @@ impl Hardfork { + // TODO: set fork hash once known + ForkId { hash: ForkHash([0xc1, 0xfd, 0xf1, 0x81]), next: 0 } + } ++ Hardfork::Prague => { ++ // TODO: set fork hash once known ++ ForkId { hash: ForkHash([0xc1, 0xfd, 0xf1, 0x81]), next: 0 } ++ } + } + } + } +@@ -127,6 +133,7 @@ impl FromStr for Hardfork { + "paris" | "merge" | "15" => Hardfork::Paris, + "shanghai" | "16" => Hardfork::Shanghai, + "cancun" | "17" => Hardfork::Cancun, ++ "prague" | "18" => Hardfork::Prague, + "latest" => Hardfork::Latest, + _ => return Err(format!("Unknown hardfork {s}")), + }; +@@ -156,6 +163,7 @@ impl From for SpecId { + + // TODO: switch to latest after activation + Hardfork::Cancun => SpecId::CANCUN, ++ Hardfork::Prague => SpecId::PRAGUE, + } + } + } +diff --git a/crates/cast/bin/cmd/create2.rs b/crates/cast/bin/cmd/create2.rs +index 661ea3cb185..44f9bef1bf1 100644 +--- a/crates/cast/bin/cmd/create2.rs ++++ b/crates/cast/bin/cmd/create2.rs +@@ -196,7 +196,7 @@ impl Create2Args { + loop { + // Stop if a result was found in another thread. + if found.load(Ordering::Relaxed) { +- break None; ++ break None + } + + // Calculate the `CREATE2` address. +@@ -211,7 +211,7 @@ impl Create2Args { + if regex.matches(s).into_iter().count() == regex_len { + // Notify other threads that we found a result. + found.store(true, Ordering::Relaxed); +- break Some((salt.0, addr)); ++ break Some((salt.0, addr)) + } + + // Increment the salt for the next iteration. +diff --git a/crates/cast/bin/cmd/storage.rs b/crates/cast/bin/cmd/storage.rs +index 676d9e4db1f..94efe374ce0 100644 +--- a/crates/cast/bin/cmd/storage.rs ++++ b/crates/cast/bin/cmd/storage.rs +@@ -217,7 +217,7 @@ async fn fetch_storage_slots( + fn print_storage(layout: StorageLayout, values: Vec, pretty: bool) -> Result<()> { + if !pretty { + println!("{}", serde_json::to_string_pretty(&serde_json::to_value(layout)?)?); +- return Ok(()); ++ return Ok(()) + } + + let mut table = Table::new(); +diff --git a/crates/cast/src/rlp_converter.rs b/crates/cast/src/rlp_converter.rs +index 3a520844d76..c67c99cf520 100644 +--- a/crates/cast/src/rlp_converter.rs ++++ b/crates/cast/src/rlp_converter.rs +@@ -24,7 +24,7 @@ impl Decodable for Item { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { + let h = Header::decode(buf)?; + if buf.len() < h.payload_length { +- return Err(alloy_rlp::Error::InputTooShort); ++ return Err(alloy_rlp::Error::InputTooShort) + } + let mut d = &buf[..h.payload_length]; + let r = if h.list { +diff --git a/crates/cheatcodes/spec/src/vm.rs b/crates/cheatcodes/spec/src/vm.rs +index a9421d087da..676640a2e30 100644 +--- a/crates/cheatcodes/spec/src/vm.rs ++++ b/crates/cheatcodes/spec/src/vm.rs +@@ -47,6 +47,8 @@ interface Vm { + CallCode, + /// The account was called via staticcall. + StaticCall, ++ /// The account was called via authcall. ++ AuthCall, + /// The account was created. + Create, + /// The account was selfdestructed. +diff --git a/crates/cheatcodes/src/inspector.rs b/crates/cheatcodes/src/inspector.rs +index 2eef1975502..9151c1d8b70 100644 +--- a/crates/cheatcodes/src/inspector.rs ++++ b/crates/cheatcodes/src/inspector.rs +@@ -826,6 +826,7 @@ impl Inspector for Cheatcodes { + CallScheme::CallCode => crate::Vm::AccountAccessKind::CallCode, + CallScheme::DelegateCall => crate::Vm::AccountAccessKind::DelegateCall, + CallScheme::StaticCall => crate::Vm::AccountAccessKind::StaticCall, ++ CallScheme::AuthCall => crate::Vm::AccountAccessKind::AuthCall, + }; + // Record this call by pushing it to a new pending vector; all subsequent calls at + // that depth will be pushed to the same vector. When the call ends, the +diff --git a/crates/cheatcodes/src/string.rs b/crates/cheatcodes/src/string.rs +index f55350592ea..d40e1d8d2f1 100644 +--- a/crates/cheatcodes/src/string.rs ++++ b/crates/cheatcodes/src/string.rs +@@ -138,7 +138,7 @@ fn parse_value_fallback(s: &str, ty: &DynSolType) -> Option false, + _ => return None, + }; +- return Some(Ok(DynSolValue::Bool(b))); ++ return Some(Ok(DynSolValue::Bool(b))) + } + DynSolType::Int(_) | + DynSolType::Uint(_) | +diff --git a/crates/cheatcodes/src/test/expect.rs b/crates/cheatcodes/src/test/expect.rs +index bdecef14204..64266ae319e 100644 +--- a/crates/cheatcodes/src/test/expect.rs ++++ b/crates/cheatcodes/src/test/expect.rs +@@ -457,7 +457,7 @@ pub(crate) fn handle_expect_revert( + + // If None, accept any revert + let Some(expected_revert) = expected_revert else { +- return Ok(success_return()); ++ return Ok(success_return()) + }; + + if !expected_revert.is_empty() && retdata.is_empty() { +diff --git a/crates/common/src/fmt/dynamic.rs b/crates/common/src/fmt/dynamic.rs +index 2e30f2f7e5e..d8a8d2072ec 100644 +--- a/crates/common/src/fmt/dynamic.rs ++++ b/crates/common/src/fmt/dynamic.rs +@@ -41,7 +41,7 @@ impl DynValueFormatter { + DynSolValue::Bool(inner) => write!(f, "{inner}"), + DynSolValue::CustomStruct { name, prop_names, tuple } => { + if self.raw { +- return self.tuple(tuple, f); ++ return self.tuple(tuple, f) + } + + f.write_str(name)?; +diff --git a/crates/common/src/fmt/mod.rs b/crates/common/src/fmt/mod.rs +index fbe1670fc6c..ea03a98274d 100644 +--- a/crates/common/src/fmt/mod.rs ++++ b/crates/common/src/fmt/mod.rs +@@ -68,7 +68,7 @@ pub fn format_uint_exp(num: U256) -> String { + pub fn format_int_exp(num: I256) -> String { + let (sign, abs) = num.into_sign_and_abs(); + if abs < U256::from(10_000) { +- return format!("{sign}{abs}"); ++ return format!("{sign}{abs}") + } + + let exp = to_exp_notation(abs, 4, true, sign); +diff --git a/crates/common/src/provider.rs b/crates/common/src/provider.rs +index 730260d9ab4..bea5e18bc58 100644 +--- a/crates/common/src/provider.rs ++++ b/crates/common/src/provider.rs +@@ -302,7 +302,7 @@ fn resolve_path(path: &Path) -> Result { + fn resolve_path(path: &Path) -> Result { + if let Some(s) = path.to_str() { + if s.starts_with(r"\\.\pipe\") { +- return Ok(path.to_path_buf()); ++ return Ok(path.to_path_buf()) + } + } + Err(()) +diff --git a/crates/config/src/lib.rs b/crates/config/src/lib.rs +index 5175775315d..31b1bd423cf 100644 +--- a/crates/config/src/lib.rs ++++ b/crates/config/src/lib.rs +@@ -369,6 +369,9 @@ pub struct Config { + /// Should be removed once EvmVersion Cancun is supported by solc + pub cancun: bool, + ++ /// Temporary config to enable [SpecId::PRAGUE] ++ pub prague: bool, ++ + /// The root path where the config detection started from, `Config::with_root` + #[doc(hidden)] + // We're skipping serialization here, so it won't be included in the [`Config::to_string()`] +@@ -694,7 +697,9 @@ impl Config { + /// Returns the [SpecId] derived from the configured [EvmVersion] + #[inline] + pub fn evm_spec_id(&self) -> SpecId { +- if self.cancun { ++ if self.prague { ++ return SpecId::PRAGUE ++ } else if self.cancun { + return SpecId::CANCUN + } + evm_spec_id(&self.evm_version) +@@ -1752,6 +1757,7 @@ impl Default for Config { + profile: Self::DEFAULT_PROFILE, + fs_permissions: FsPermissions::new([PathPermission::read("out")]), + cancun: false, ++ prague: false, + __root: Default::default(), + src: "src".into(), + test: "test".into(), +diff --git a/crates/debugger/src/tui.rs b/crates/debugger/src/tui.rs +index 7cd2b67efd0..9d9fbfcab82 100644 +--- a/crates/debugger/src/tui.rs ++++ b/crates/debugger/src/tui.rs +@@ -677,6 +677,7 @@ Line::from(Span::styled("[t]: stack labels | [m]: memory decoding | [shift + j/k + CallKind::StaticCall => "Contract staticcall", + CallKind::CallCode => "Contract callcode", + CallKind::DelegateCall => "Contract delegatecall", ++ CallKind::AuthCall => "Contract authcall", + }) + .borders(Borders::ALL); + +@@ -1257,7 +1258,8 @@ Line::from(Span::styled("[t]: stack labels | [m]: memory decoding | [shift + j/k + (i == (offset + size - 1) / 32 && + j <= (offset + size - 1) % 32) + { +- // [offset, offset + size] is the memory region to be colored. ++ // [offset, offset + size] is the memory region to be ++ // colored. + // If a byte at row i and column j in the memory panel + // falls in this region, set the color. + Style::default().fg(color) +diff --git a/crates/doc/src/builder.rs b/crates/doc/src/builder.rs +index 692e69b82e1..1826f3518f6 100644 +--- a/crates/doc/src/builder.rs ++++ b/crates/doc/src/builder.rs +@@ -133,13 +133,13 @@ impl DocBuilder { + Err(err) => { + if from_library { + // Ignore failures for library files +- return Ok(Vec::new()); ++ return Ok(Vec::new()) + } else { + return Err(eyre::eyre!( + "Failed to parse Solidity code for {}\nDebug info: {:?}", + path.display(), + err +- )); ++ )) + } + } + }; +diff --git a/crates/doc/src/preprocessor/contract_inheritance.rs b/crates/doc/src/preprocessor/contract_inheritance.rs +index 7b4b28e10e0..b4972ac9017 100644 +--- a/crates/doc/src/preprocessor/contract_inheritance.rs ++++ b/crates/doc/src/preprocessor/contract_inheritance.rs +@@ -54,7 +54,7 @@ impl ContractInheritance { + fn try_link_base(&self, base: &str, documents: &Vec) -> Option { + for candidate in documents { + if candidate.from_library && !self.include_libraries { +- continue; ++ continue + } + if let DocumentContent::Single(ref item) = candidate.content { + if let ParseSource::Contract(ref contract) = item.source { +diff --git a/crates/doc/src/preprocessor/git_source.rs b/crates/doc/src/preprocessor/git_source.rs +index eaa53e6268d..a72764c6548 100644 +--- a/crates/doc/src/preprocessor/git_source.rs ++++ b/crates/doc/src/preprocessor/git_source.rs +@@ -29,7 +29,7 @@ impl Preprocessor for GitSource { + let commit = self.commit.clone().unwrap_or("master".to_owned()); + for document in documents.iter() { + if document.from_library { +- continue; ++ continue + } + let git_url = format!( + "{repo}/blob/{commit}/{}", +diff --git a/crates/evm/core/src/decode.rs b/crates/evm/core/src/decode.rs +index 6812cfd4f50..3d09bb51b7d 100644 +--- a/crates/evm/core/src/decode.rs ++++ b/crates/evm/core/src/decode.rs +@@ -57,7 +57,7 @@ pub fn maybe_decode_revert( + if err.len() < SELECTOR_LEN { + if let Some(status) = status { + if !status.is_ok() { +- return Some(format!("EvmError: {status:?}")); ++ return Some(format!("EvmError: {status:?}")) + } + } + return if err.is_empty() { +@@ -69,12 +69,12 @@ pub fn maybe_decode_revert( + + if err == crate::constants::MAGIC_SKIP { + // Also used in forge fuzz runner +- return Some("SKIPPED".to_string()); ++ return Some("SKIPPED".to_string()) + } + + // Solidity's `Error(string)` or `Panic(uint256)` + if let Ok(e) = alloy_sol_types::GenericContractError::abi_decode(err, false) { +- return Some(e.to_string()); ++ return Some(e.to_string()) + } + + let (selector, data) = err.split_at(SELECTOR_LEN); +@@ -84,17 +84,17 @@ pub fn maybe_decode_revert( + // `CheatcodeError(string)` + Vm::CheatcodeError::SELECTOR => { + let e = Vm::CheatcodeError::abi_decode_raw(data, false).ok()?; +- return Some(e.message); ++ return Some(e.message) + } + // `expectRevert(bytes)` + Vm::expectRevert_2Call::SELECTOR => { + let e = Vm::expectRevert_2Call::abi_decode_raw(data, false).ok()?; +- return maybe_decode_revert(&e.revertData[..], maybe_abi, status); ++ return maybe_decode_revert(&e.revertData[..], maybe_abi, status) + } + // `expectRevert(bytes4)` + Vm::expectRevert_1Call::SELECTOR => { + let e = Vm::expectRevert_1Call::abi_decode_raw(data, false).ok()?; +- return maybe_decode_revert(&e.revertData[..], maybe_abi, status); ++ return maybe_decode_revert(&e.revertData[..], maybe_abi, status) + } + _ => {} + } +@@ -108,19 +108,19 @@ pub fn maybe_decode_revert( + "{}({})", + abi_error.name, + decoded.iter().map(foundry_common::fmt::format_token).format(", ") +- )); ++ )) + } + } + } + + // ABI-encoded `string` + if let Ok(s) = String::abi_decode(err, false) { +- return Some(s); ++ return Some(s) + } + + // UTF-8-encoded string + if let Ok(s) = std::str::from_utf8(err) { +- return Some(s.to_string()); ++ return Some(s.to_string()) + } + + // Generic custom error +diff --git a/crates/evm/core/src/opts.rs b/crates/evm/core/src/opts.rs +index 1ccac43d422..dd99a391fb7 100644 +--- a/crates/evm/core/src/opts.rs ++++ b/crates/evm/core/src/opts.rs +@@ -182,14 +182,14 @@ impl EvmOpts { + if let Some(ref url) = self.fork_url { + if url.contains("mainnet") { + trace!(?url, "auto detected mainnet chain"); +- return Some(Chain::mainnet()); ++ return Some(Chain::mainnet()) + } + trace!(?url, "retrieving chain via eth_chainId"); + let provider = Provider::try_from(url.as_str()) + .unwrap_or_else(|_| panic!("Failed to establish provider to {url}")); + + if let Ok(id) = RuntimeOrHandle::new().block_on(provider.get_chainid()) { +- return Some(Chain::from(id.as_u64())); ++ return Some(Chain::from(id.as_u64())) + } + } + +diff --git a/crates/evm/core/src/utils.rs b/crates/evm/core/src/utils.rs +index 8edaa4e21e0..879d09774e4 100644 +--- a/crates/evm/core/src/utils.rs ++++ b/crates/evm/core/src/utils.rs +@@ -22,6 +22,7 @@ pub enum CallKind { + StaticCall, + CallCode, + DelegateCall, ++ AuthCall, + Create, + Create2, + } +@@ -33,6 +34,7 @@ impl From for CallKind { + CallScheme::StaticCall => CallKind::StaticCall, + CallScheme::CallCode => CallKind::CallCode, + CallScheme::DelegateCall => CallKind::DelegateCall, ++ CallScheme::AuthCall => CallKind::AuthCall, + } + } + } +@@ -49,9 +51,11 @@ impl From for CallKind { + impl From for ActionType { + fn from(kind: CallKind) -> Self { + match kind { +- CallKind::Call | CallKind::StaticCall | CallKind::DelegateCall | CallKind::CallCode => { +- ActionType::Call +- } ++ CallKind::Call | ++ CallKind::StaticCall | ++ CallKind::DelegateCall | ++ CallKind::CallCode | ++ CallKind::AuthCall => ActionType::Call, + CallKind::Create => ActionType::Create, + CallKind::Create2 => ActionType::Create, + } +@@ -65,6 +69,7 @@ impl From for CallType { + CallKind::StaticCall => CallType::StaticCall, + CallKind::CallCode => CallType::CallCode, + CallKind::DelegateCall => CallType::DelegateCall, ++ CallKind::AuthCall => CallType::AuthCall, + CallKind::Create => CallType::None, + CallKind::Create2 => CallType::None, + } +@@ -129,6 +134,7 @@ pub fn halt_to_instruction_result(halt: Halt) -> InstructionResult { + Halt::CreateInitcodeSizeLimit => InstructionResult::CreateInitcodeSizeLimit, + Halt::OverflowPayment => InstructionResult::OverflowPayment, + Halt::StateChangeDuringStaticCall => InstructionResult::StateChangeDuringStaticCall, ++ Halt::ActiveAccountUnsetAuthCall => InstructionResult::ActiveAccountUnsetAuthCall, + Halt::CallNotAllowedInsideStatic => InstructionResult::CallNotAllowedInsideStatic, + Halt::OutOfFund => InstructionResult::OutOfFund, + Halt::CallTooDeep => InstructionResult::CallTooDeep, +diff --git a/crates/evm/traces/src/decoder/mod.rs b/crates/evm/traces/src/decoder/mod.rs +index 2866d8319a3..ece2f13b41b 100644 +--- a/crates/evm/traces/src/decoder/mod.rs ++++ b/crates/evm/traces/src/decoder/mod.rs +@@ -460,7 +460,7 @@ impl CallTraceDecoder { + fn apply_label(&self, value: &DynSolValue) -> String { + if let DynSolValue::Address(addr) = value { + if let Some(label) = self.labels.get(addr) { +- return format!("{label}: [{addr}]"); ++ return format!("{label}: [{addr}]") + } + } + format_token(value) +diff --git a/crates/evm/traces/src/lib.rs b/crates/evm/traces/src/lib.rs +index 3d88ee23ff1..4dd1e5ae6e7 100644 +--- a/crates/evm/traces/src/lib.rs ++++ b/crates/evm/traces/src/lib.rs +@@ -535,6 +535,7 @@ impl fmt::Display for CallTrace { + CallKind::StaticCall => " [staticcall]", + CallKind::CallCode => " [callcode]", + CallKind::DelegateCall => " [delegatecall]", ++ CallKind::AuthCall => " [authcall]", + CallKind::Create | CallKind::Create2 => unreachable!(), + }; + +diff --git a/crates/evm/traces/src/node.rs b/crates/evm/traces/src/node.rs +index e68840b69e9..b7539027069 100644 +--- a/crates/evm/traces/src/node.rs ++++ b/crates/evm/traces/src/node.rs +@@ -37,12 +37,14 @@ impl CallTraceNode { + /// Returns the `Res` for a parity trace + pub fn parity_result(&self) -> Res { + match self.kind() { +- CallKind::Call | CallKind::StaticCall | CallKind::CallCode | CallKind::DelegateCall => { +- Res::Call(CallResult { +- gas_used: self.trace.gas_cost.into(), +- output: self.trace.output.to_raw().into(), +- }) +- } ++ CallKind::Call | ++ CallKind::StaticCall | ++ CallKind::CallCode | ++ CallKind::DelegateCall | ++ CallKind::AuthCall => Res::Call(CallResult { ++ gas_used: self.trace.gas_cost.into(), ++ output: self.trace.output.to_raw().into(), ++ }), + CallKind::Create | CallKind::Create2 => Res::Create(CreateResult { + gas_used: self.trace.gas_cost.into(), + code: self.trace.output.to_raw().into(), +@@ -62,16 +64,18 @@ impl CallTraceNode { + }) + } + match self.kind() { +- CallKind::Call | CallKind::StaticCall | CallKind::CallCode | CallKind::DelegateCall => { +- Action::Call(Call { +- from: self.trace.caller.to_ethers(), +- to: self.trace.address.to_ethers(), +- value: self.trace.value.to_ethers(), +- gas: self.trace.gas_cost.into(), +- input: self.trace.data.as_bytes().to_vec().into(), +- call_type: self.kind().into(), +- }) +- } ++ CallKind::Call | ++ CallKind::StaticCall | ++ CallKind::CallCode | ++ CallKind::DelegateCall | ++ CallKind::AuthCall => Action::Call(Call { ++ from: self.trace.caller.to_ethers(), ++ to: self.trace.address.to_ethers(), ++ value: self.trace.value.to_ethers(), ++ gas: self.trace.gas_cost.into(), ++ input: self.trace.data.as_bytes().to_vec().into(), ++ call_type: self.kind().into(), ++ }), + CallKind::Create | CallKind::Create2 => Action::Create(Create { + from: self.trace.caller.to_ethers(), + value: self.trace.value.to_ethers(), +diff --git a/crates/forge/bin/cmd/script/multi.rs b/crates/forge/bin/cmd/script/multi.rs +index 7fa4709a963..2eb5e2b4ef7 100644 +--- a/crates/forge/bin/cmd/script/multi.rs ++++ b/crates/forge/bin/cmd/script/multi.rs +@@ -144,7 +144,7 @@ impl ScriptArgs { + join_all(futs).await.into_iter().filter(|res| res.is_err()).collect::>(); + + if !errors.is_empty() { +- return Err(eyre::eyre!("{errors:?}")); ++ return Err(eyre::eyre!("{errors:?}")) + } + } + +diff --git a/crates/forge/tests/cli/config.rs b/crates/forge/tests/cli/config.rs +index 27001b73217..30fa8f4d94e 100644 +--- a/crates/forge/tests/cli/config.rs ++++ b/crates/forge/tests/cli/config.rs +@@ -112,6 +112,7 @@ forgetest!(can_extract_config_values, |prj, cmd| { + doc: Default::default(), + fs_permissions: Default::default(), + cancun: true, ++ prague: true, + __non_exhaustive: (), + __warnings: vec![], + };