foundry_cheatcodes/inspector/
utils.rs

1use super::InnerEcx;
2use crate::inspector::Cheatcodes;
3use alloy_primitives::{Address, Bytes, U256};
4use revm::interpreter::{CreateInputs, CreateScheme, EOFCreateInputs, EOFCreateKind};
5
6/// Common behaviour of legacy and EOF create inputs.
7pub(crate) trait CommonCreateInput {
8    fn caller(&self) -> Address;
9    fn gas_limit(&self) -> u64;
10    fn value(&self) -> U256;
11    fn init_code(&self) -> Bytes;
12    fn scheme(&self) -> Option<CreateScheme>;
13    fn set_caller(&mut self, caller: Address);
14    fn log_debug(&self, cheatcode: &mut Cheatcodes, scheme: &CreateScheme);
15    fn allow_cheatcodes(&self, cheatcodes: &mut Cheatcodes, ecx: InnerEcx) -> Address;
16    fn computed_created_address(&self) -> Option<Address>;
17}
18
19impl CommonCreateInput for &mut CreateInputs {
20    fn caller(&self) -> Address {
21        self.caller
22    }
23    fn gas_limit(&self) -> u64 {
24        self.gas_limit
25    }
26    fn value(&self) -> U256 {
27        self.value
28    }
29    fn init_code(&self) -> Bytes {
30        self.init_code.clone()
31    }
32    fn scheme(&self) -> Option<CreateScheme> {
33        Some(self.scheme)
34    }
35    fn set_caller(&mut self, caller: Address) {
36        self.caller = caller;
37    }
38    fn log_debug(&self, cheatcode: &mut Cheatcodes, scheme: &CreateScheme) {
39        let kind = match scheme {
40            CreateScheme::Create => "create",
41            CreateScheme::Create2 { .. } => "create2",
42        };
43        debug!(target: "cheatcodes", tx=?cheatcode.broadcastable_transactions.back().unwrap(), "broadcastable {kind}");
44    }
45    fn allow_cheatcodes(&self, cheatcodes: &mut Cheatcodes, ecx: InnerEcx) -> Address {
46        let old_nonce = ecx
47            .journaled_state
48            .state
49            .get(&self.caller)
50            .map(|acc| acc.info.nonce)
51            .unwrap_or_default();
52        let created_address = self.created_address(old_nonce);
53        cheatcodes.allow_cheatcodes_on_create(ecx, self.caller, created_address);
54        created_address
55    }
56    fn computed_created_address(&self) -> Option<Address> {
57        None
58    }
59}
60
61impl CommonCreateInput for &mut EOFCreateInputs {
62    fn caller(&self) -> Address {
63        self.caller
64    }
65    fn gas_limit(&self) -> u64 {
66        self.gas_limit
67    }
68    fn value(&self) -> U256 {
69        self.value
70    }
71    fn init_code(&self) -> Bytes {
72        match &self.kind {
73            EOFCreateKind::Tx { initdata } => initdata.clone(),
74            EOFCreateKind::Opcode { initcode, .. } => initcode.raw.clone(),
75        }
76    }
77    fn scheme(&self) -> Option<CreateScheme> {
78        None
79    }
80    fn set_caller(&mut self, caller: Address) {
81        self.caller = caller;
82    }
83    fn log_debug(&self, cheatcode: &mut Cheatcodes, _scheme: &CreateScheme) {
84        debug!(target: "cheatcodes", tx=?cheatcode.broadcastable_transactions.back().unwrap(), "broadcastable eofcreate");
85    }
86    fn allow_cheatcodes(&self, cheatcodes: &mut Cheatcodes, ecx: InnerEcx) -> Address {
87        let created_address =
88            <&mut EOFCreateInputs as CommonCreateInput>::computed_created_address(self)
89                .unwrap_or_default();
90        cheatcodes.allow_cheatcodes_on_create(ecx, self.caller, created_address);
91        created_address
92    }
93    fn computed_created_address(&self) -> Option<Address> {
94        self.kind.created_address().copied()
95    }
96}