foundry_cheatcodes/inspector/
utils.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use super::InnerEcx;
use crate::inspector::Cheatcodes;
use alloy_primitives::{Address, Bytes, U256};
use revm::interpreter::{CreateInputs, CreateScheme, EOFCreateInputs, EOFCreateKind};

/// Common behaviour of legacy and EOF create inputs.
pub(crate) trait CommonCreateInput {
    fn caller(&self) -> Address;
    fn gas_limit(&self) -> u64;
    fn value(&self) -> U256;
    fn init_code(&self) -> Bytes;
    fn scheme(&self) -> Option<CreateScheme>;
    fn set_caller(&mut self, caller: Address);
    fn log_debug(&self, cheatcode: &mut Cheatcodes, scheme: &CreateScheme);
    fn allow_cheatcodes(&self, cheatcodes: &mut Cheatcodes, ecx: InnerEcx) -> Address;
    fn computed_created_address(&self) -> Option<Address>;
}

impl CommonCreateInput for &mut CreateInputs {
    fn caller(&self) -> Address {
        self.caller
    }
    fn gas_limit(&self) -> u64 {
        self.gas_limit
    }
    fn value(&self) -> U256 {
        self.value
    }
    fn init_code(&self) -> Bytes {
        self.init_code.clone()
    }
    fn scheme(&self) -> Option<CreateScheme> {
        Some(self.scheme)
    }
    fn set_caller(&mut self, caller: Address) {
        self.caller = caller;
    }
    fn log_debug(&self, cheatcode: &mut Cheatcodes, scheme: &CreateScheme) {
        let kind = match scheme {
            CreateScheme::Create => "create",
            CreateScheme::Create2 { .. } => "create2",
        };
        debug!(target: "cheatcodes", tx=?cheatcode.broadcastable_transactions.back().unwrap(), "broadcastable {kind}");
    }
    fn allow_cheatcodes(&self, cheatcodes: &mut Cheatcodes, ecx: InnerEcx) -> Address {
        let old_nonce = ecx
            .journaled_state
            .state
            .get(&self.caller)
            .map(|acc| acc.info.nonce)
            .unwrap_or_default();
        let created_address = self.created_address(old_nonce);
        cheatcodes.allow_cheatcodes_on_create(ecx, self.caller, created_address);
        created_address
    }
    fn computed_created_address(&self) -> Option<Address> {
        None
    }
}

impl CommonCreateInput for &mut EOFCreateInputs {
    fn caller(&self) -> Address {
        self.caller
    }
    fn gas_limit(&self) -> u64 {
        self.gas_limit
    }
    fn value(&self) -> U256 {
        self.value
    }
    fn init_code(&self) -> Bytes {
        match &self.kind {
            EOFCreateKind::Tx { initdata } => initdata.clone(),
            EOFCreateKind::Opcode { initcode, .. } => initcode.raw.clone(),
        }
    }
    fn scheme(&self) -> Option<CreateScheme> {
        None
    }
    fn set_caller(&mut self, caller: Address) {
        self.caller = caller;
    }
    fn log_debug(&self, cheatcode: &mut Cheatcodes, _scheme: &CreateScheme) {
        debug!(target: "cheatcodes", tx=?cheatcode.broadcastable_transactions.back().unwrap(), "broadcastable eofcreate");
    }
    fn allow_cheatcodes(&self, cheatcodes: &mut Cheatcodes, ecx: InnerEcx) -> Address {
        let created_address =
            <&mut EOFCreateInputs as CommonCreateInput>::computed_created_address(self)
                .unwrap_or_default();
        cheatcodes.allow_cheatcodes_on_create(ecx, self.caller, created_address);
        created_address
    }
    fn computed_created_address(&self) -> Option<Address> {
        self.kind.created_address().copied()
    }
}