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_evm::eth::EthEvmContext;
19use alloy_primitives::Address;
20use foundry_evm_core::backend::DatabaseExt;
21use spec::Status;
22
23pub use Vm::ForgeContext;
24pub use config::CheatsConfig;
25pub use error::{Error, ErrorKind, Result, precompile_error};
26pub use inspector::{
27 BroadcastableTransaction, BroadcastableTransactions, Cheatcodes, CheatcodesExecutor,
28};
29pub use spec::{CheatcodeDef, Vm};
30
31pub use evm::journaled_account;
32
33#[macro_use]
34mod error;
35
36mod base64;
37
38mod config;
39
40mod crypto;
41
42mod version;
43
44mod env;
45pub use env::set_execution_context;
46
47mod evm;
48
49mod fs;
50
51mod inspector;
52pub use inspector::{CommonCreateInput, Ecx};
53
54mod json;
55
56mod script;
57pub use script::{Broadcast, Wallets, WalletsInner};
58
59mod strategy;
60pub use evm::mock::{MockCallDataContext, MockCallReturnData};
61pub use strategy::{
62 CheatcodeInspectorStrategy, CheatcodeInspectorStrategyContext, CheatcodeInspectorStrategyExt,
63 CheatcodeInspectorStrategyRunner, CheatcodesStrategy, EvmCheatcodeInspectorStrategyRunner,
64};
65
66mod string;
67
68mod test;
69pub use test::expect::{ExpectedCallTracker, ExpectedCreate, handle_expect_emit};
70
71mod toml;
72
73mod utils;
74
75pub use evm::DealRecord;
76
77pub(crate) trait Cheatcode: CheatcodeDef + DynCheatcode {
79 fn apply(&self, state: &mut Cheatcodes) -> Result {
83 let _ = state;
84 unimplemented!("{}", Self::CHEATCODE.func.id)
85 }
86
87 #[inline(always)]
91 fn apply_stateful(&self, ccx: &mut CheatsCtxt) -> Result {
92 self.apply(ccx.state)
93 }
94
95 #[inline(always)]
99 fn apply_full(&self, ccx: &mut CheatsCtxt, executor: &mut dyn CheatcodesExecutor) -> Result {
100 let _ = executor;
101 self.apply_stateful(ccx)
102 }
103}
104
105pub trait DynCheatcode: 'static + std::any::Any {
106 fn cheatcode(&self) -> &'static spec::Cheatcode<'static>;
107
108 fn as_debug(&self) -> &dyn std::fmt::Debug;
109
110 fn dyn_apply(&self, ccx: &mut CheatsCtxt, executor: &mut dyn CheatcodesExecutor) -> Result;
111
112 fn as_any(&self) -> &dyn std::any::Any;
113}
114
115impl<T: Cheatcode> DynCheatcode for T {
116 #[inline]
117 fn cheatcode(&self) -> &'static spec::Cheatcode<'static> {
118 Self::CHEATCODE
119 }
120
121 #[inline]
122 fn as_debug(&self) -> &dyn std::fmt::Debug {
123 self
124 }
125
126 #[inline]
127 fn dyn_apply(&self, ccx: &mut CheatsCtxt, executor: &mut dyn CheatcodesExecutor) -> Result {
128 self.apply_full(ccx, executor)
129 }
130
131 #[inline]
132 fn as_any(&self) -> &dyn std::any::Any {
133 self
134 }
135}
136
137impl dyn DynCheatcode {
138 pub(crate) fn name(&self) -> &'static str {
139 self.cheatcode().func.signature.split('(').next().unwrap()
140 }
141
142 pub(crate) fn id(&self) -> &'static str {
143 self.cheatcode().func.id
144 }
145
146 pub(crate) fn signature(&self) -> &'static str {
147 self.cheatcode().func.signature
148 }
149
150 pub(crate) fn status(&self) -> &Status<'static> {
151 &self.cheatcode().status
152 }
153}
154
155pub struct CheatsCtxt<'cheats, 'evm, 'db, 'db2> {
157 pub state: &'cheats mut Cheatcodes,
159 pub ecx: &'evm mut EthEvmContext<&'db mut (dyn DatabaseExt + 'db2)>,
161 pub(crate) caller: Address,
163 pub(crate) gas_limit: u64,
165}
166
167impl<'db, 'db2> std::ops::Deref for CheatsCtxt<'_, '_, 'db, 'db2> {
168 type Target = EthEvmContext<&'db mut (dyn DatabaseExt + 'db2)>;
169
170 #[inline(always)]
171 fn deref(&self) -> &Self::Target {
172 self.ecx
173 }
174}
175
176impl std::ops::DerefMut for CheatsCtxt<'_, '_, '_, '_> {
177 #[inline(always)]
178 fn deref_mut(&mut self) -> &mut Self::Target {
179 &mut *self.ecx
180 }
181}
182
183impl CheatsCtxt<'_, '_, '_, '_> {
184 #[inline]
185 pub fn is_precompile(&self, address: &Address) -> bool {
186 self.ecx.journaled_state.inner.precompiles.contains(address)
187 }
188}