foundry_cheatcodes/inspector/
utils.rs

1use super::Ecx;
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: Ecx) -> 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            CreateScheme::Custom { .. } => "custom",
43        };
44        debug!(target: "cheatcodes", tx=?cheatcode.broadcastable_transactions.back().unwrap(), "broadcastable {kind}");
45    }
46    fn allow_cheatcodes(&self, cheatcodes: &mut Cheatcodes, ecx: Ecx) -> Address {
47        let old_nonce = ecx
48            .journaled_state
49            .state
50            .get(&self.caller)
51            .map(|acc| acc.info.nonce)
52            .unwrap_or_default();
53        let created_address = self.created_address(old_nonce);
54        cheatcodes.allow_cheatcodes_on_create(ecx, self.caller, created_address);
55        created_address
56    }
57    fn computed_created_address(&self) -> Option<Address> {
58        None
59    }
60}
61
62impl CommonCreateInput for &mut EOFCreateInputs {
63    fn caller(&self) -> Address {
64        self.caller
65    }
66    fn gas_limit(&self) -> u64 {
67        self.gas_limit
68    }
69    fn value(&self) -> U256 {
70        self.value
71    }
72    fn init_code(&self) -> Bytes {
73        match &self.kind {
74            EOFCreateKind::Tx { initdata } => initdata.clone(),
75            EOFCreateKind::Opcode { initcode, .. } => initcode.raw.clone(),
76        }
77    }
78    fn scheme(&self) -> Option<CreateScheme> {
79        None
80    }
81    fn set_caller(&mut self, caller: Address) {
82        self.caller = caller;
83    }
84    fn log_debug(&self, cheatcode: &mut Cheatcodes, _scheme: &CreateScheme) {
85        debug!(target: "cheatcodes", tx=?cheatcode.broadcastable_transactions.back().unwrap(), "broadcastable eofcreate");
86    }
87    fn allow_cheatcodes(&self, cheatcodes: &mut Cheatcodes, ecx: Ecx) -> Address {
88        let created_address =
89            <&mut EOFCreateInputs as CommonCreateInput>::computed_created_address(self)
90                .unwrap_or_default();
91        cheatcodes.allow_cheatcodes_on_create(ecx, self.caller, created_address);
92        created_address
93    }
94    fn computed_created_address(&self) -> Option<Address> {
95        self.kind.created_address().copied()
96    }
97}