Skip to content

chore: activate prague hardfork and Solidity version 0.8.30 as default #10565

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Jun 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7f46db2
start defaulting to prague, add fix for blob handle scaling post cancun
zerosnacks May 20, 2025
3eb91bb
fix anvil test
zerosnacks May 20, 2025
9ed7285
switch to 0.8.30 for tests
zerosnacks May 20, 2025
e62c33b
Merge branch 'master' into zerosnacks/chore-activate-prague-hardfork
zerosnacks May 20, 2025
898c2eb
fix merge conflict
zerosnacks May 20, 2025
1eca04d
switch foundry-compilers to default to prague, small test fixes
zerosnacks May 21, 2025
cdac80d
Merge branch 'master' into zerosnacks/chore-activate-prague-hardfork
zerosnacks May 21, 2025
1dd0d54
Merge branch 'master' into zerosnacks/chore-activate-prague-hardfork
zerosnacks May 26, 2025
fff560a
add workaround for Vyper not yet supporting Prague
zerosnacks May 26, 2025
2ee2f17
fix issues
zerosnacks May 27, 2025
ac42452
fix tests, questionable gas difference and address difference
zerosnacks May 27, 2025
ca6259c
make prague explicit
zerosnacks May 27, 2025
ee7d074
fix clippy
zerosnacks May 27, 2025
4e9348a
merge in master, upgrade Anvil to Prague
zerosnacks May 27, 2025
d67eadb
Merge branch 'master' into zerosnacks/chore-activate-prague-hardfork
zerosnacks May 28, 2025
f8f3b1c
bump compilers version
zerosnacks May 28, 2025
9edcccf
bump to 0.16.3
zerosnacks May 28, 2025
bd039fd
Merge branch 'master' into zerosnacks/chore-activate-prague-hardfork
zerosnacks Jun 2, 2025
d4a76cb
pass in blob params, add normalize vyper evm version helper, fix sola…
zerosnacks Jun 2, 2025
d6c18ec
temporarily allow compilers git patch
zerosnacks Jun 2, 2025
0355cc2
bump to msrv 1.87 in line with foundry-compilers
zerosnacks Jun 2, 2025
dd270f8
bump compilers version
zerosnacks Jun 2, 2025
32811de
bump to foundry-compilers 0.17.1
zerosnacks Jun 2, 2025
372d89d
Merge branch 'master' into zerosnacks/chore-activate-prague-hardfork
zerosnacks Jun 2, 2025
c5d39b5
Merge branch 'master' into zerosnacks/chore-activate-prague-hardfork
zerosnacks Jun 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
351 changes: 176 additions & 175 deletions Cargo.lock

Large diffs are not rendered by default.

15 changes: 8 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ resolver = "2"
version = "1.2.2"
edition = "2021"
# Remember to update clippy.toml as well
rust-version = "1.86"
rust-version = "1.87"
authors = ["Foundry Contributors"]
license = "MIT OR Apache-2.0"
homepage = "https://github.com/foundry-rs/foundry"
Expand Down Expand Up @@ -198,14 +198,14 @@ foundry-wallets = { path = "crates/wallets" }
foundry-linking = { path = "crates/linking" }

# solc & compilation utilities
foundry-block-explorers = { version = "0.17.0", default-features = false }
foundry-compilers = { version = "0.16.1", default-features = false }
foundry-block-explorers = { version = "0.18.0", default-features = false }
foundry-compilers = { version = "0.17.1", default-features = false }
foundry-fork-db = "0.15"
solang-parser = { version = "=0.3.9", package = "foundry-solang-parser" }
solar-ast = { version = "=0.1.3", default-features = false }
solar-parse = { version = "=0.1.3", default-features = false }
solar-interface = { version = "=0.1.3", default-features = false }
solar-sema = { version = "=0.1.3", default-features = false }
solar-ast = { version = "=0.1.4", default-features = false }
solar-parse = { version = "=0.1.4", default-features = false }
solar-interface = { version = "=0.1.4", default-features = false }
solar-sema = { version = "=0.1.4", default-features = false }

## alloy
alloy-consensus = { version = "1.0.7", default-features = false }
Expand Down Expand Up @@ -401,4 +401,5 @@ zip-extract = "=0.2.1"
# revm-inspectors = { git = "https://github.com/paradigmxyz/revm-inspectors.git", rev = "a625c04" }

## foundry
# foundry-compilers = { git = "https://github.com/foundry-rs/compilers.git", rev = "855dee4" }
# foundry-fork-db = { git = "https://github.com/foundry-rs/foundry-fork-db", rev = "811a61a" }
2 changes: 1 addition & 1 deletion clippy.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
msrv = "1.86"
msrv = "1.87"

# `bytes::Bytes` is included by default and `alloy_primitives::Bytes` is a wrapper around it,
# so it is safe to ignore it as well.
Expand Down
14 changes: 10 additions & 4 deletions crates/anvil/src/eth/backend/mem/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -780,11 +780,17 @@ impl Backend {

/// Returns [`BlobParams`] corresponding to the current spec.
pub fn blob_params(&self) -> BlobParams {
if self.env.read().evm_env.cfg_env.spec >= SpecId::PRAGUE {
BlobParams::prague()
} else {
BlobParams::cancun()
let spec_id = self.env.read().evm_env.cfg_env.spec;

if spec_id >= SpecId::OSAKA {
return BlobParams::osaka();
}

if spec_id >= SpecId::PRAGUE {
return BlobParams::prague();
}

BlobParams::cancun()
}

/// Returns an error if EIP1559 is not active (pre Berlin)
Expand Down
14 changes: 12 additions & 2 deletions crates/anvil/src/eth/fees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ pub fn calculate_next_block_base_fee(gas_used: u64, gas_limit: u64, base_fee: u6

/// An async service that takes care of the `FeeHistory` cache
pub struct FeeHistoryService {
/// blob parameters for the current spec
blob_params: BlobParams,
/// incoming notifications about new blocks
new_blocks: NewBlockNotifications,
/// contains all fee history related entries
Expand All @@ -204,11 +206,18 @@ pub struct FeeHistoryService {

impl FeeHistoryService {
pub fn new(
blob_params: BlobParams,
new_blocks: NewBlockNotifications,
cache: FeeHistoryCache,
storage_info: StorageInfo,
) -> Self {
Self { new_blocks, cache, fee_history_limit: MAX_FEE_HISTORY_CACHE_SIZE, storage_info }
Self {
blob_params,
new_blocks,
cache,
fee_history_limit: MAX_FEE_HISTORY_CACHE_SIZE,
storage_info,
}
}

/// Returns the configured history limit
Expand Down Expand Up @@ -245,7 +254,8 @@ impl FeeHistoryService {
let base_fee = header.base_fee_per_gas.map(|g| g as u128).unwrap_or_default();
let excess_blob_gas = header.excess_blob_gas.map(|g| g as u128);
let blob_gas_used = header.blob_gas_used.map(|g| g as u128);
let base_fee_per_blob_gas = header.blob_fee(BlobParams::cancun());
let base_fee_per_blob_gas = header.blob_fee(self.blob_params);

let mut item = FeeHistoryCacheItem {
base_fee,
gas_used_ratio: 0f64,
Expand Down
7 changes: 7 additions & 0 deletions crates/anvil/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ use crate::{
shutdown::Signal,
tasks::TaskManager,
};
use alloy_eips::eip7840::BlobParams;
use alloy_primitives::{Address, U256};
use alloy_signer_local::PrivateKeySigner;
use eth::backend::fork::ClientFork;
use eyre::Result;
use foundry_common::provider::{ProviderBuilder, RetryProvider};
use futures::{FutureExt, TryFutureExt};
use parking_lot::Mutex;
use revm::primitives::hardfork::SpecId;
use server::try_spawn_ipc;
use std::{
future::Future,
Expand Down Expand Up @@ -198,6 +200,11 @@ pub async fn try_spawn(mut config: NodeConfig) -> Result<(EthApi, NodeHandle)> {

let fee_history_cache = Arc::new(Mutex::new(Default::default()));
let fee_history_service = FeeHistoryService::new(
match backend.spec_id() {
SpecId::OSAKA => BlobParams::osaka(),
SpecId::PRAGUE => BlobParams::prague(),
_ => BlobParams::cancun(),
},
backend.new_block_notifications(),
Arc::clone(&fee_history_cache),
StorageInfo::new(Arc::clone(&backend)),
Expand Down
2 changes: 1 addition & 1 deletion crates/cast/src/cmd/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ impl RunArgs {
if evm_version.is_none() {
// if the block has the excess_blob_gas field, we assume it's a Cancun block
if block.header.excess_blob_gas.is_some() {
evm_version = Some(EvmVersion::Cancun);
evm_version = Some(EvmVersion::Prague);
}
}
apply_chain_and_block_specific_env_changes::<AnyNetwork>(env.as_env_mut(), block);
Expand Down
2 changes: 1 addition & 1 deletion crates/cast/tests/cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2329,7 +2329,7 @@ contract CounterInExternalLibScript is Script {
...
Traces:
[..] → new <unknown>@0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512
├─ [..] 0x52F3e85EC3F0f9D0a2200D646482fcD134D5adc9::updateCounterInExternalLib(0, 100) [delegatecall]
├─ [..] 0x6fD8bf6770F4bEe578348D24028000cE9c4D2bB9::updateCounterInExternalLib(0, 100) [delegatecall]
│ └─ ← [Stop]
└─ ← [Return] 62 bytes of code

Expand Down
2 changes: 1 addition & 1 deletion crates/common/src/preprocessor/deps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ impl<'hir> Visit<'hir> for BytecodeDependencyCollector<'hir> {
for &var in clause.args {
self.visit_nested_var(var)?;
}
for stmt in clause.block {
for stmt in clause.block.stmts {
self.visit_stmt(stmt)?;
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ allow_paths = []
# additional solc include paths
include_paths = []
force = false
evm_version = 'shanghai'
evm_version = 'prague'
gas_reports = ['*']
gas_reports_ignore = []
## Sets the concrete solc version to use, this overrides the `auto_detect_solc` value
Expand Down
6 changes: 3 additions & 3 deletions crates/config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ pub mod soldeer;
use soldeer::{SoldeerConfig, SoldeerDependencyConfig};

mod vyper;
use vyper::VyperConfig;
pub use vyper::{normalize_evm_version_vyper, VyperConfig};

mod bind_json;
use bind_json::BindJsonConfig;
Expand Down Expand Up @@ -1549,7 +1549,7 @@ impl Config {
/// - evm version
pub fn vyper_settings(&self) -> Result<VyperSettings, SolcError> {
Ok(VyperSettings {
evm_version: Some(self.evm_version),
evm_version: Some(normalize_evm_version_vyper(self.evm_version)),
optimize: self.vyper.optimize,
bytecode_metadata: None,
// TODO: We don't yet have a way to deserialize other outputs correctly, so request only
Expand Down Expand Up @@ -2315,7 +2315,7 @@ impl Default for Config {
allow_paths: vec![],
include_paths: vec![],
force: false,
evm_version: EvmVersion::Cancun,
evm_version: EvmVersion::Prague,
gas_reports: vec!["*".to_string()],
gas_reports_ignore: vec![],
gas_reports_include_tests: false,
Expand Down
12 changes: 11 additions & 1 deletion crates/config/src/vyper.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Vyper specific configuration types.

use foundry_compilers::artifacts::vyper::VyperOptimizationMode;
use foundry_compilers::artifacts::{vyper::VyperOptimizationMode, EvmVersion};
use serde::{Deserialize, Serialize};
use std::path::PathBuf;

Expand All @@ -16,3 +16,13 @@ pub struct VyperConfig {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub experimental_codegen: Option<bool>,
}

/// Vyper does not yet support the Prague EVM version, so we normalize it to Cancun.
/// This is a temporary workaround until Vyper supports Prague.
pub fn normalize_evm_version_vyper(evm_version: EvmVersion) -> EvmVersion {
if evm_version >= EvmVersion::Prague {
return EvmVersion::Cancun;
}

evm_version
}
17 changes: 11 additions & 6 deletions crates/forge/src/cmd/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use clap::{Parser, Subcommand, ValueHint};
use eyre::Result;
use foundry_common::shell;
use foundry_compilers::{artifacts::EvmVersion, Graph};
use foundry_config::Config;
use foundry_config::{normalize_evm_version_vyper, Config};
use semver::Version;
use serde::Serialize;
use std::{collections::BTreeMap, path::PathBuf};
Expand Down Expand Up @@ -93,11 +93,16 @@ impl ResolveArgs {
.collect();

let evm_version = if shell::verbosity() > 1 {
Some(
EvmVersion::default()
.normalize_version_solc(version)
.unwrap_or_default(),
)
let evm = EvmVersion::default()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe can be simplified, or for future have a normalize_evm_version(version, language) in foundry compilers?

                        let mut evm = EvmVersion::default()
                            .normalize_version_solc(version)
                            .unwrap_or_default();
                        // Vyper does not yet support Prague, so we normalize it to Cancun.
                        if language.is_vyper() {
                            evm = normalize_evm_version_vyper(evm);
                        }
                        Some(evm)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, opened a follow-up ticket for me here: foundry-rs/compilers#278

We should either upstream this Vyper exception as is or create a unified helper as proposed

.normalize_version_solc(version)
.unwrap_or_default();

// Vyper does not yet support Prague, so we normalize it to Cancun.
if language.is_vyper() {
Some(normalize_evm_version_vyper(evm))
} else {
Some(evm)
}
} else {
None
};
Expand Down
2 changes: 1 addition & 1 deletion crates/forge/tests/cli/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3673,7 +3673,7 @@ forgetest_init!(can_inspect_standard_json, |prj, cmd| {
]
}
},
"evmVersion": "cancun",
"evmVersion": "prague",
"viaIR": false,
"libraries": {}
}
Expand Down
16 changes: 8 additions & 8 deletions crates/forge/tests/cli/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ contract ContractB {}

const CONTRACT_C: &str = r#"
// SPDX-license-identifier: MIT
pragma solidity 0.8.27;
pragma solidity 0.8.30;

contract ContractC {}
"#;

const CONTRACT_D: &str = r#"
// SPDX-license-identifier: MIT
pragma solidity 0.8.27;
pragma solidity 0.8.30;

contract ContractD {}
"#;
Expand Down Expand Up @@ -111,7 +111,7 @@ forgetest!(can_list_resolved_compiler_versions_verbose, |prj, cmd| {
cmd.args(["compiler", "resolve", "-v"]).assert_success().stdout_eq(str![[r#"
Solidity:

0.8.27:
0.8.30:
├── src/ContractC.sol
└── src/ContractD.sol

Expand All @@ -128,7 +128,7 @@ forgetest!(can_list_resolved_compiler_versions_verbose_json, |prj, cmd| {
{
"Solidity": [
{
"version": "0.8.27",
"version": "0.8.30",
"paths": [
"src/ContractC.sol",
"src/ContractD.sol"
Expand All @@ -153,7 +153,7 @@ forgetest!(can_list_resolved_multiple_compiler_versions, |prj, cmd| {
Solidity:
- 0.8.4
- 0.8.11
- 0.8.27
- 0.8.30

Vyper:
- 0.4.0
Expand Down Expand Up @@ -198,7 +198,7 @@ forgetest!(can_list_resolved_multiple_compiler_versions_skipped_json, |prj, cmd|
{
"Solidity": [
{
"version": "0.8.27",
"version": "0.8.30",
"paths": [
"src/ContractD.sol"
]
Expand Down Expand Up @@ -236,7 +236,7 @@ Solidity:
0.8.11 (<= london):
└── src/ContractB.sol

0.8.27 (<= [..]):
0.8.30 (<= prague):
├── src/ContractC.sol
└── src/ContractD.sol

Expand Down Expand Up @@ -277,7 +277,7 @@ forgetest!(can_list_resolved_multiple_compiler_versions_verbose_json, |prj, cmd|
]
},
{
"version": "0.8.27",
"version": "0.8.30",
"evm_version": "[..]",
"paths": [
"src/ContractC.sol",
Expand Down
12 changes: 6 additions & 6 deletions crates/forge/tests/cli/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -983,7 +983,7 @@ allow_paths = []
include_paths = []
skip = []
force = false
evm_version = "cancun"
evm_version = "prague"
gas_reports = ["*"]
gas_reports_ignore = []
gas_reports_include_tests = false
Expand Down Expand Up @@ -1146,7 +1146,7 @@ exclude = []
"include_paths": [],
"skip": [],
"force": false,
"evm_version": "cancun",
"evm_version": "prague",
"gas_reports": [
"*"
],
Expand Down Expand Up @@ -1712,7 +1712,7 @@ contract Counter {
let v1_profile = SettingsOverrides {
name: "v1".to_string(),
via_ir: Some(true),
evm_version: Some(EvmVersion::Cancun),
evm_version: Some(EvmVersion::Prague),
optimizer: None,
optimizer_runs: Some(44444444),
bytecode_hash: None,
Expand Down Expand Up @@ -1798,19 +1798,19 @@ contract Counter {

let (via_ir, evm_version, enabled, runs) = artifact_settings("Counter.sol/Counter.json");
assert_eq!(None, via_ir);
assert_eq!("\"cancun\"", evm_version.unwrap().to_string());
assert_eq!("\"prague\"", evm_version.unwrap().to_string());
assert_eq!("false", enabled.unwrap().to_string());
assert_eq!("200", runs.unwrap().to_string());

let (via_ir, evm_version, enabled, runs) = artifact_settings("v1/Counter.sol/Counter.json");
assert_eq!("true", via_ir.unwrap().to_string());
assert_eq!("\"cancun\"", evm_version.unwrap().to_string());
assert_eq!("\"prague\"", evm_version.unwrap().to_string());
assert_eq!("true", enabled.unwrap().to_string());
assert_eq!("44444444", runs.unwrap().to_string());

let (via_ir, evm_version, enabled, runs) = artifact_settings("v2/Counter.sol/Counter.json");
assert_eq!("true", via_ir.unwrap().to_string());
assert_eq!("\"cancun\"", evm_version.unwrap().to_string());
assert_eq!("\"prague\"", evm_version.unwrap().to_string());
assert_eq!("true", enabled.unwrap().to_string());
assert_eq!("111", runs.unwrap().to_string());

Expand Down
2 changes: 1 addition & 1 deletion crates/forge/tests/cli/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2576,7 +2576,7 @@ Chain 31337

accessList []
chainId 31337
gasLimit 228231
gasLimit [..]
gasPrice
input [..]
maxFeePerBlobGas
Expand Down
Loading