Skip to main content

foundry_cheatcodes/
version.rs

1use crate::{Cheatcode, Cheatcodes, Result, Vm::*};
2use alloy_sol_types::SolValue;
3use foundry_common::version::SEMVER_VERSION;
4use foundry_evm_core::evm::FoundryEvmNetwork;
5use semver::Version;
6use std::cmp::Ordering;
7
8impl Cheatcode for foundryVersionCmpCall {
9    fn apply<FEN: FoundryEvmNetwork>(&self, _state: &mut Cheatcodes<FEN>) -> Result {
10        let Self { version } = self;
11        foundry_version_cmp(version).map(|cmp| (cmp as i8).abi_encode())
12    }
13}
14
15impl Cheatcode for foundryVersionAtLeastCall {
16    fn apply<FEN: FoundryEvmNetwork>(&self, _state: &mut Cheatcodes<FEN>) -> Result {
17        let Self { version } = self;
18        foundry_version_cmp(version).map(|cmp| cmp.is_ge().abi_encode())
19    }
20}
21
22fn foundry_version_cmp(version: &str) -> Result<Ordering> {
23    version_cmp(SEMVER_VERSION.split('-').next().unwrap(), version)
24}
25
26fn version_cmp(version_a: &str, version_b: &str) -> Result<Ordering> {
27    let version_a = parse_version(version_a)?;
28    let version_b = parse_version(version_b)?;
29    Ok(version_a.cmp(&version_b))
30}
31
32fn parse_version(version: &str) -> Result<Version> {
33    let version =
34        Version::parse(version).map_err(|e| fmt_err!("invalid version `{version}`: {e}"))?;
35    if !version.pre.is_empty() {
36        return Err(fmt_err!(
37            "invalid version `{version}`: pre-release versions are not supported"
38        ));
39    }
40    if !version.build.is_empty() {
41        return Err(fmt_err!("invalid version `{version}`: build metadata is not supported"));
42    }
43    Ok(version)
44}