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::ContextTr;
8use spec::Vm::{assumeImplicitApprovalCall, isImplicitlyApprovedCall};
9use tempo_chainspec::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
16/// Resolves the active Tempo hardfork from the cheatcode-visible spec, or `None` on non-Tempo
17/// networks. Goes through the spec's stable string name because the context is generic over
18/// the network type.
19fn active_tempo_hardfork<FEN: FoundryEvmNetwork>(
20    ccx: &CheatsCtxt<'_, '_, FEN>,
21) -> Option<TempoHardfork> {
22    let spec = *ccx.ecx.cfg().spec();
23    TempoHardfork::from_str(&spec.evm_version_name()).ok()
24}
25
26impl Cheatcode for isImplicitlyApprovedCall {
27    fn apply_stateful<FEN: FoundryEvmNetwork>(&self, ccx: &mut CheatsCtxt<'_, '_, FEN>) -> Result {
28        let Self { spender } = *self;
29        let approved = match active_tempo_hardfork(ccx) {
30            Some(hardfork) => address_registry::is_implicitly_approved(spender, hardfork),
31            None => false,
32        };
33        Ok(approved.abi_encode())
34    }
35}
36
37impl Cheatcode for assumeImplicitApprovalCall {
38    fn apply_stateful<FEN: FoundryEvmNetwork>(&self, ccx: &mut CheatsCtxt<'_, '_, FEN>) -> Result {
39        let Self { spender } = *self;
40        let approved = match active_tempo_hardfork(ccx) {
41            Some(hardfork) => address_registry::is_implicitly_approved(spender, hardfork),
42            None => false,
43        };
44        if approved { Ok(Default::default()) } else { Err(Error::from(MAGIC_ASSUME)) }
45    }
46}