1use std::fmt::Debug;
2
3pub use alloy_evm::EvmEnv;
4use alloy_primitives::{Address, B256, Bytes, U256};
5use revm::{
6 Context, Database,
7 context::{Block, BlockEnv, Cfg, CfgEnv, Transaction, TxEnv},
8 context_interface::{ContextTr, transaction::AccessList},
9 inspector::JournalExt,
10 primitives::{TxKind, hardfork::SpecId},
11};
12
13use crate::backend::{DatabaseExt, JournaledState};
14
15pub trait FoundryBlock: Block {
17 fn set_number(&mut self, number: U256);
19
20 fn set_beneficiary(&mut self, beneficiary: Address);
22
23 fn set_timestamp(&mut self, timestamp: U256);
25
26 fn set_gas_limit(&mut self, gas_limit: u64);
28
29 fn set_basefee(&mut self, basefee: u64);
31
32 fn set_difficulty(&mut self, difficulty: U256);
34
35 fn set_prevrandao(&mut self, prevrandao: Option<B256>);
37
38 fn set_blob_excess_gas_and_price(
40 &mut self,
41 _excess_blob_gas: u64,
42 _base_fee_update_fraction: u64,
43 );
44}
45
46impl FoundryBlock for BlockEnv {
47 fn set_number(&mut self, number: U256) {
48 self.number = number;
49 }
50
51 fn set_beneficiary(&mut self, beneficiary: Address) {
52 self.beneficiary = beneficiary;
53 }
54
55 fn set_timestamp(&mut self, timestamp: U256) {
56 self.timestamp = timestamp;
57 }
58
59 fn set_gas_limit(&mut self, gas_limit: u64) {
60 self.gas_limit = gas_limit;
61 }
62
63 fn set_basefee(&mut self, basefee: u64) {
64 self.basefee = basefee;
65 }
66
67 fn set_difficulty(&mut self, difficulty: U256) {
68 self.difficulty = difficulty;
69 }
70
71 fn set_prevrandao(&mut self, prevrandao: Option<B256>) {
72 self.prevrandao = prevrandao;
73 }
74
75 fn set_blob_excess_gas_and_price(
76 &mut self,
77 excess_blob_gas: u64,
78 base_fee_update_fraction: u64,
79 ) {
80 self.set_blob_excess_gas_and_price(excess_blob_gas, base_fee_update_fraction);
81 }
82}
83
84pub trait FoundryTransaction: Transaction {
87 fn set_tx_type(&mut self, tx_type: u8);
89
90 fn set_caller(&mut self, caller: Address);
92
93 fn set_gas_limit(&mut self, gas_limit: u64);
95
96 fn set_gas_price(&mut self, gas_price: u128);
98
99 fn set_kind(&mut self, kind: TxKind);
101
102 fn set_value(&mut self, value: U256);
104
105 fn set_data(&mut self, data: Bytes);
107
108 fn set_nonce(&mut self, nonce: u64);
110
111 fn set_chain_id(&mut self, chain_id: Option<u64>);
113
114 fn set_access_list(&mut self, access_list: AccessList);
116
117 fn set_gas_priority_fee(&mut self, gas_priority_fee: Option<u128>);
119
120 fn set_blob_hashes(&mut self, blob_hashes: Vec<B256>);
122
123 fn set_max_fee_per_blob_gas(&mut self, max_fee_per_blob_gas: u128);
125}
126
127impl FoundryTransaction for TxEnv {
128 fn set_tx_type(&mut self, tx_type: u8) {
129 self.tx_type = tx_type;
130 }
131
132 fn set_caller(&mut self, caller: Address) {
133 self.caller = caller;
134 }
135
136 fn set_gas_limit(&mut self, gas_limit: u64) {
137 self.gas_limit = gas_limit;
138 }
139
140 fn set_gas_price(&mut self, gas_price: u128) {
141 self.gas_price = gas_price;
142 }
143
144 fn set_kind(&mut self, kind: TxKind) {
145 self.kind = kind;
146 }
147
148 fn set_value(&mut self, value: U256) {
149 self.value = value;
150 }
151
152 fn set_data(&mut self, data: Bytes) {
153 self.data = data;
154 }
155
156 fn set_nonce(&mut self, nonce: u64) {
157 self.nonce = nonce;
158 }
159
160 fn set_chain_id(&mut self, chain_id: Option<u64>) {
161 self.chain_id = chain_id;
162 }
163
164 fn set_access_list(&mut self, access_list: AccessList) {
165 self.access_list = access_list;
166 }
167
168 fn set_gas_priority_fee(&mut self, gas_priority_fee: Option<u128>) {
169 self.gas_priority_fee = gas_priority_fee;
170 }
171
172 fn set_blob_hashes(&mut self, blob_hashes: Vec<B256>) {
173 self.blob_hashes = blob_hashes;
174 }
175
176 fn set_max_fee_per_blob_gas(&mut self, max_fee_per_blob_gas: u128) {
177 self.max_fee_per_blob_gas = max_fee_per_blob_gas;
178 }
179}
180
181pub trait FoundryCfg: Cfg + Clone + Debug {
183 type Spec: Into<SpecId> + Clone + Debug;
184}
185
186impl<SPEC: Into<SpecId> + Clone + Debug> FoundryCfg for CfgEnv<SPEC> {
187 type Spec = SPEC;
188}
189
190pub trait FoundryContextExt:
195 ContextTr<
196 Block: FoundryBlock + Clone,
197 Tx: FoundryTransaction + Clone,
198 Cfg: FoundryCfg,
199 Journal: JournalExt,
200 >
201{
202 fn block_mut(&mut self) -> &mut Self::Block;
204 fn tx_mut(&mut self) -> &mut Self::Tx;
206 fn cfg_mut(&mut self) -> &mut Self::Cfg;
208 fn db_journal_inner_mut(&mut self) -> (&mut Self::Db, &mut JournaledState);
210 fn set_block(&mut self, block: Self::Block) {
212 *self.block_mut() = block;
213 }
214 fn set_tx(&mut self, tx: Self::Tx) {
216 *self.tx_mut() = tx;
217 }
218 fn set_cfg(&mut self, cfg: Self::Cfg) {
220 *self.cfg_mut() = cfg;
221 }
222 fn set_journal_inner(&mut self, journal_inner: JournaledState) {
224 *self.db_journal_inner_mut().1 = journal_inner;
225 }
226 fn set_evm(&mut self, evm_env: EvmEnv<<Self::Cfg as FoundryCfg>::Spec, Self::Block>)
228 where
229 Self::Cfg: From<CfgEnv<<Self::Cfg as FoundryCfg>::Spec>>,
230 {
231 *self.cfg_mut() = evm_env.cfg_env.into();
232 *self.block_mut() = evm_env.block_env;
233 }
234 fn tx_clone(&self) -> Self::Tx {
236 self.tx().clone()
237 }
238 fn evm_clone(&self) -> EvmEnv<<Self::Cfg as FoundryCfg>::Spec, Self::Block>
240 where
241 Self::Cfg: Into<CfgEnv<<Self::Cfg as FoundryCfg>::Spec>>,
242 {
243 EvmEnv::new(self.cfg().clone().into(), self.block().clone())
244 }
245}
246
247impl<BLOCK: FoundryBlock + Clone, TX: FoundryTransaction + Clone, CFG: FoundryCfg, DB: Database>
248 FoundryContextExt for Context<BLOCK, TX, CFG, DB>
249{
250 fn block_mut(&mut self) -> &mut Self::Block {
251 &mut self.block
252 }
253 fn tx_mut(&mut self) -> &mut Self::Tx {
254 &mut self.tx
255 }
256 fn cfg_mut(&mut self) -> &mut Self::Cfg {
257 &mut self.cfg
258 }
259 fn db_journal_inner_mut(&mut self) -> (&mut Self::Db, &mut JournaledState) {
260 (&mut self.journaled_state.database, &mut self.journaled_state.inner)
261 }
262}
263
264pub trait EthCheatCtx:
271 FoundryContextExt<
272 Block = BlockEnv,
273 Tx = TxEnv,
274 Cfg = CfgEnv,
275 Db: DatabaseExt<Self::Block, Self::Tx, <Self::Cfg as FoundryCfg>::Spec>,
276 >
277{
278}
279impl<CTX> EthCheatCtx for CTX where
280 CTX: FoundryContextExt<
281 Block = BlockEnv,
282 Tx = TxEnv,
283 Cfg = CfgEnv,
284 Db: DatabaseExt<Self::Block, Self::Tx, <Self::Cfg as FoundryCfg>::Spec>,
285 >
286{
287}