Skip to main content

foundry_cheatcodes/inspector/
utils.rs

1use crate::inspector::Cheatcodes;
2use alloy_primitives::{Address, Bytes, U256};
3use foundry_evm_core::backend::DatabaseExt;
4use revm::{
5    context::ContextTr,
6    inspector::JournalExt,
7    interpreter::{CreateInputs, CreateScheme},
8};
9
10/// Common behaviour of legacy and EOF create inputs.
11pub(crate) trait CommonCreateInput {
12    fn caller(&self) -> Address;
13    fn gas_limit(&self) -> u64;
14    fn value(&self) -> U256;
15    fn init_code(&self) -> Bytes;
16    fn scheme(&self) -> Option<CreateScheme>;
17    fn set_caller(&mut self, caller: Address);
18    fn log_debug(&self, cheatcode: &mut Cheatcodes, scheme: &CreateScheme);
19    fn allow_cheatcodes<CTX: ContextTr<Journal: JournalExt, Db: DatabaseExt>>(
20        &self,
21        cheatcodes: &mut Cheatcodes,
22        ecx: &mut CTX,
23    ) -> Address;
24}
25
26impl CommonCreateInput for &mut CreateInputs {
27    fn caller(&self) -> Address {
28        CreateInputs::caller(self)
29    }
30    fn gas_limit(&self) -> u64 {
31        CreateInputs::gas_limit(self)
32    }
33    fn value(&self) -> U256 {
34        CreateInputs::value(self)
35    }
36    fn init_code(&self) -> Bytes {
37        CreateInputs::init_code(self).clone()
38    }
39    fn scheme(&self) -> Option<CreateScheme> {
40        Some(CreateInputs::scheme(self))
41    }
42    fn set_caller(&mut self, caller: Address) {
43        CreateInputs::set_call(self, caller);
44    }
45    fn log_debug(&self, cheatcode: &mut Cheatcodes, scheme: &CreateScheme) {
46        let kind = match scheme {
47            CreateScheme::Create => "create",
48            CreateScheme::Create2 { .. } => "create2",
49            CreateScheme::Custom { .. } => "custom",
50        };
51        debug!(target: "cheatcodes", tx=?cheatcode.broadcastable_transactions.back().unwrap(), "broadcastable {kind}");
52    }
53    fn allow_cheatcodes<CTX: ContextTr<Journal: JournalExt, Db: DatabaseExt>>(
54        &self,
55        cheatcodes: &mut Cheatcodes,
56        ecx: &mut CTX,
57    ) -> Address {
58        let caller = CreateInputs::caller(self);
59        let old_nonce =
60            ecx.journal().evm_state().get(&caller).map(|acc| acc.info.nonce).unwrap_or_default();
61        let created_address = self.created_address(old_nonce);
62        cheatcodes.allow_cheatcodes_on_create(ecx, caller, created_address);
63        created_address
64    }
65}