foundry_cheatcodes/
lib.rs1#![cfg_attr(not(test), warn(unused_crate_dependencies))]
6#![cfg_attr(docsrs, feature(doc_cfg))]
7#![allow(elided_lifetimes_in_paths)] #[macro_use]
10extern crate foundry_common;
11
12#[macro_use]
13pub extern crate foundry_cheatcodes_spec as spec;
14
15#[macro_use]
16extern crate tracing;
17
18use alloy_primitives::Address;
19use foundry_evm_core::{
20 backend::DatabaseExt,
21 evm::{FoundryContextFor, FoundryEvmNetwork},
22};
23use revm::context::{ContextTr, JournalTr};
24
25pub use Vm::ForgeContext;
26pub use config::CheatsConfig;
27pub use error::{Error, ErrorKind, Result};
28pub use foundry_evm_core::evm::NestedEvmClosureFor;
29pub use inspector::{
30 BroadcastableTransaction, BroadcastableTransactions, Cheatcodes, CheatcodesExecutor,
31};
32pub use spec::{CheatcodeDef, Vm};
33
34#[macro_use]
35mod error;
36
37mod base64;
38
39mod config;
40
41mod crypto;
42
43mod version;
44
45mod env;
46pub use env::set_execution_context;
47
48mod evm;
49
50mod fs;
51
52mod inspector;
53pub use inspector::CheatcodeAnalysis;
54
55mod json;
56
57#[cfg(feature = "monad")]
58mod monad;
59
60mod script;
61pub use script::{Wallets, WalletsInner};
62
63mod string;
64
65mod tempo;
66
67mod test;
68pub use test::expect::ExpectedCallTracker;
69
70mod toml;
71
72mod utils;
73
74pub(crate) trait Cheatcode: CheatcodeDef {
76 fn apply<FEN: FoundryEvmNetwork>(&self, state: &mut Cheatcodes<FEN>) -> Result {
80 let _ = state;
81 unimplemented!("{}", Self::CHEATCODE.func.id)
82 }
83
84 #[inline(always)]
88 fn apply_stateful<FEN: FoundryEvmNetwork>(&self, ccx: &mut CheatsCtxt<'_, '_, FEN>) -> Result {
89 self.apply(ccx.state)
90 }
91
92 #[inline(always)]
96 fn apply_full<FEN: FoundryEvmNetwork>(
97 &self,
98 ccx: &mut CheatsCtxt<'_, '_, FEN>,
99 executor: &mut dyn CheatcodesExecutor<FEN>,
100 ) -> Result {
101 let _ = executor;
102 self.apply_stateful(ccx)
103 }
104}
105
106pub struct CheatsCtxt<'a, 'db, FEN: FoundryEvmNetwork + 'db> {
108 pub(crate) state: &'a mut Cheatcodes<FEN>,
110 pub(crate) ecx: &'a mut FoundryContextFor<'db, FEN>,
112 pub(crate) caller: Address,
114 pub(crate) gas_limit: u64,
116}
117
118impl<'a, 'db, FEN: FoundryEvmNetwork> std::ops::Deref for CheatsCtxt<'a, 'db, FEN> {
119 type Target = FoundryContextFor<'db, FEN>;
120
121 #[inline(always)]
122 fn deref(&self) -> &Self::Target {
123 self.ecx
124 }
125}
126
127impl<'db, FEN: FoundryEvmNetwork> std::ops::DerefMut for CheatsCtxt<'_, 'db, FEN> {
128 #[inline(always)]
129 fn deref_mut(&mut self) -> &mut Self::Target {
130 self.ecx
131 }
132}
133
134impl<FEN: FoundryEvmNetwork> CheatsCtxt<'_, '_, FEN> {
135 pub(crate) fn ensure_not_precompile(&self, address: &Address) -> Result<()> {
136 if self.is_precompile(address) { Err(precompile_error(address)) } else { Ok(()) }
137 }
138
139 pub(crate) fn is_precompile(&self, address: &Address) -> bool {
140 self.ecx.journal().precompile_addresses().contains(address)
141 }
142}
143
144#[cold]
145fn precompile_error(address: &Address) -> Error {
146 fmt_err!("cannot use precompile {address} as an argument")
147}