Skip to content

Commit f2b260f

Browse files
Incorrect Default EVM Version for Solidity Compiler 0.4.21-0.5.4 (#189)
The default EVM version for Solidity compilers ranging from 0.4.21 to 0.5.4 is incorrectly implemented. Specifically, although the `Constantinople` hard fork had been introduced during this period, the default EVM version remains as `Byzantium`. After version 0.5.5, the default EVM version shifts to `Petersburg`. That is, `Constantinople` is never used as the default EVM version for Solidity compilers. This can be confirmed by running `solc --help`, with the output indicating the default EVM version as follows: ```bash $ solc --help solc, the Solidity commandline compiler. ... Allowed options: --help Show help message and exit. --version Show version and exit. --license Show licensing information and exit. --evm-version version Select desired EVM version. Either homestead, tangerineWhistle, spuriousDragon, byzantium (default) or constantinople. ... $ solc --version solc, the Solidity commandline interface Version: 0.4.24+commit.e67f0147.Linux.g++ ```
1 parent d7a4b87 commit f2b260f

File tree

1 file changed

+58
-0
lines changed
  • crates/artifacts/solc/src

1 file changed

+58
-0
lines changed

crates/artifacts/solc/src/lib.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,30 @@ pub enum EvmVersion {
816816
}
817817

818818
impl EvmVersion {
819+
/// Find the default EVM version for the given compiler version.
820+
pub fn default_version_solc(version: &Version) -> Option<Self> {
821+
// In most cases, Solc compilers use the highest EVM version available at the time.
822+
let default = Self::default().normalize_version_solc(version)?;
823+
824+
// However, there are some exceptions where the default is lower than the highest available.
825+
match default {
826+
Self::Constantinople => {
827+
// Actually, Constantinople is never used as the default EVM version by Solidity
828+
// compilers.
829+
Some(Self::Byzantium)
830+
}
831+
Self::Cancun if *version == Version::new(0, 8, 24) => {
832+
// While Cancun is introduced at the time of releasing 0.8.24, it has not been
833+
// supported by the mainnet. So, the default EVM version of Solc 0.8.24 remains as
834+
// Shanghai.
835+
//
836+
// <https://soliditylang.org/blog/2024/01/26/solidity-0.8.24-release-announcement/>
837+
Some(Self::Shanghai)
838+
}
839+
_ => Some(default),
840+
}
841+
}
842+
819843
/// Normalizes this EVM version by checking against the given Solc [`Version`].
820844
pub fn normalize_version_solc(self, version: &Version) -> Option<Self> {
821845
// The EVM version flag was only added in 0.4.21; we work our way backwards
@@ -1903,6 +1927,40 @@ mod tests {
19031927
}
19041928
}
19051929

1930+
#[test]
1931+
fn test_evm_version_default() {
1932+
for &(solc_version, expected) in &[
1933+
// Everything before 0.4.21 should always return None
1934+
("0.4.20", None),
1935+
// Byzantium clipping
1936+
("0.4.21", Some(EvmVersion::Byzantium)),
1937+
// Constantinople bug fix
1938+
("0.4.22", Some(EvmVersion::Byzantium)),
1939+
// Petersburg
1940+
("0.5.5", Some(EvmVersion::Petersburg)),
1941+
// Istanbul
1942+
("0.5.14", Some(EvmVersion::Istanbul)),
1943+
// Berlin
1944+
("0.8.5", Some(EvmVersion::Berlin)),
1945+
// London
1946+
("0.8.7", Some(EvmVersion::London)),
1947+
// Paris
1948+
("0.8.18", Some(EvmVersion::Paris)),
1949+
// Shanghai
1950+
("0.8.20", Some(EvmVersion::Shanghai)),
1951+
// Cancun
1952+
("0.8.24", Some(EvmVersion::Shanghai)),
1953+
("0.8.25", Some(EvmVersion::Cancun)),
1954+
] {
1955+
let version = Version::from_str(solc_version).unwrap();
1956+
assert_eq!(
1957+
EvmVersion::default_version_solc(&version),
1958+
expected,
1959+
"({version}, {expected:?})"
1960+
)
1961+
}
1962+
}
1963+
19061964
#[test]
19071965
fn test_evm_version_normalization() {
19081966
for &(solc_version, evm_version, expected) in &[

0 commit comments

Comments
 (0)