Skip to main content

foundry_cheatcodes/
tempo.rs

1//! Cheatcodes that delegate to the imported Tempo precompile crates.
2
3use std::str::FromStr;
4
5use alloy_sol_types::SolValue;
6use foundry_evm_core::evm::FoundryEvmNetwork;
7use revm::context::{Cfg, ContextTr};
8use spec::Vm::{assumeImplicitApprovalCall, isImplicitlyApprovedCall};
9use tempo_hardfork::TempoHardfork;
10use tempo_precompiles::address_registry;
11
12use crate::{Cheatcode, CheatsCtxt, Error, Result};
13use foundry_config::ExecutionSpec;
14use foundry_evm_core::constants::MAGIC_ASSUME;
15
16impl Cheatcode for isImplicitlyApprovedCall {
17    fn apply_stateful<FEN: FoundryEvmNetwork>(&self, ccx: &mut CheatsCtxt<'_, '_, FEN>) -> Result {
18        let Self { spender } = *self;
19        let approved = match active_tempo_hardfork(ccx) {
20            Some(hardfork) => address_registry::is_implicitly_approved(spender, hardfork),
21            None => false,
22        };
23        Ok(approved.abi_encode())
24    }
25}
26
27impl Cheatcode for assumeImplicitApprovalCall {
28    fn apply_stateful<FEN: FoundryEvmNetwork>(&self, ccx: &mut CheatsCtxt<'_, '_, FEN>) -> Result {
29        let Self { spender } = *self;
30        let approved = match active_tempo_hardfork(ccx) {
31            Some(hardfork) => address_registry::is_implicitly_approved(spender, hardfork),
32            None => false,
33        };
34        if approved { Ok(Default::default()) } else { Err(Error::from(MAGIC_ASSUME)) }
35    }
36}
37
38/// Resolves the active Tempo hardfork from the cheatcode-visible spec, or `None` on non-Tempo
39/// networks. Goes through the spec's stable string name because the context is generic over
40/// the network type.
41fn active_tempo_hardfork<FEN: FoundryEvmNetwork>(
42    ccx: &CheatsCtxt<'_, '_, FEN>,
43) -> Option<TempoHardfork> {
44    let spec = ccx.ecx.cfg().spec();
45    TempoHardfork::from_str(&spec.evm_version_name()).ok()
46}