Skip to content

Commit d223552

Browse files
wellnana0xrusowsky
andauthored
chore: check compatibility of evm_version and solc (foundry-rs#11418)
* chore: check compatibility of evm_version and solc * use 'eprintln' instead * remove unnecessary expect * add unit test * fix test * final fix --------- Co-authored-by: 0xrusowsky <[email protected]>
1 parent 4b207fd commit d223552

File tree

2 files changed

+80
-7
lines changed

2 files changed

+80
-7
lines changed

crates/config/src/lib.rs

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2117,19 +2117,44 @@ impl Config {
21172117
/// This normalizes the default `evm_version` if a `solc` was provided in the config.
21182118
///
21192119
/// See also <https://github.com/foundry-rs/foundry/issues/7014>
2120+
#[expect(clippy::disallowed_macros)]
21202121
fn normalize_defaults(&self, mut figment: Figment) -> Figment {
2121-
// TODO: add a warning if evm_version is provided but incompatible
2122+
let evm_version = figment.extract_inner::<EvmVersion>("evm_version").ok().or_else(|| {
2123+
figment
2124+
.extract_inner::<String>("evm_version")
2125+
.ok()
2126+
.and_then(|s| s.parse::<EvmVersion>().ok())
2127+
});
2128+
2129+
let solc_version = figment
2130+
.extract_inner::<SolcReq>("solc")
2131+
.ok()
2132+
.and_then(|solc| solc.try_version().ok())
2133+
.and_then(|v| self.evm_version.normalize_version_solc(&v));
2134+
21222135
if figment.contains("evm_version") {
2136+
// Check compatibility if both evm_version and solc are provided
2137+
// First try to extract as EvmVersion directly, then fallback to string parsing for
2138+
// case-insensitive support
2139+
if let Some(evm_version) = evm_version {
2140+
figment = figment.merge(("evm_version", evm_version));
2141+
2142+
if let Some(solc_version) = solc_version
2143+
&& solc_version != evm_version
2144+
{
2145+
eprintln!(
2146+
"{}",
2147+
yansi::Paint::yellow(&format!(
2148+
"Warning: evm_version '{evm_version}' may be incompatible with solc version. Consider using '{solc_version}'"
2149+
))
2150+
);
2151+
}
2152+
}
21232153
return figment;
21242154
}
21252155

21262156
// Normalize `evm_version` based on the provided solc version.
2127-
if let Ok(solc) = figment.extract_inner::<SolcReq>("solc")
2128-
&& let Some(version) = solc
2129-
.try_version()
2130-
.ok()
2131-
.and_then(|version| self.evm_version.normalize_version_solc(&version))
2132-
{
2157+
if let Some(version) = solc_version {
21332158
figment = figment.merge(("evm_version", version));
21342159
}
21352160

@@ -6193,4 +6218,23 @@ mod tests {
61936218
Ok(())
61946219
});
61956220
}
6221+
6222+
#[test]
6223+
fn test_evm_version_solc_compatibility_warning() {
6224+
figment::Jail::expect_with(|jail| {
6225+
// Create a config with incompatible evm_version and solc version
6226+
// Using Cancun with an older solc version (Berlin) that doesn't support it
6227+
jail.create_file(
6228+
"foundry.toml",
6229+
r#"
6230+
[profile.default]
6231+
evm_version = "Cancun"
6232+
solc = "0.8.5"
6233+
"#,
6234+
)?;
6235+
6236+
let _config = Config::load().unwrap();
6237+
Ok(())
6238+
});
6239+
}
61966240
}

crates/forge/tests/cli/config.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1907,3 +1907,32 @@ contract AnotherCounterTest is Test {
19071907
);
19081908
cmd.args(["test", "--fail-fast"]).assert_failure();
19091909
});
1910+
1911+
// Test that EVM version configuration works and the incompatibility check is available
1912+
forgetest_init!(evm_version_incompatibility_check, |prj, cmd| {
1913+
// Clear default contracts
1914+
prj.wipe_contracts();
1915+
1916+
// Add a simple contract
1917+
prj.add_source(
1918+
"Simple.sol",
1919+
r#"
1920+
pragma solidity ^0.8.5;
1921+
1922+
contract Simple {
1923+
uint public value = 42;
1924+
}
1925+
"#,
1926+
)
1927+
.unwrap();
1928+
1929+
prj.update_config(|config| {
1930+
config.evm_version = EvmVersion::Cancun;
1931+
config.solc = Some(SolcReq::Version("0.8.5".parse().unwrap()));
1932+
});
1933+
1934+
let result = cmd.args(["build"]).assert_success();
1935+
let output = result.get_output();
1936+
let stderr = String::from_utf8_lossy(&output.stderr);
1937+
assert!(stderr.contains("Warning: evm_version 'cancun' may be incompatible with solc version. Consider using 'berlin'"));
1938+
});

0 commit comments

Comments
 (0)