foundry_evm/inspectors/
chisel_state.rs

1use alloy_primitives::U256;
2use foundry_evm_core::backend::DatabaseError;
3use revm::{
4    Database, Inspector,
5    context::ContextTr,
6    inspector::JournalExt,
7    interpreter::{Interpreter, interpreter::EthInterpreter, interpreter_types::Jumps},
8};
9
10/// An inspector for Chisel
11#[derive(Clone, Debug, Default)]
12pub struct ChiselState {
13    /// The PC of the final instruction
14    pub final_pc: usize,
15    /// The final state of the REPL contract call
16    pub state: Option<(Vec<U256>, Vec<u8>)>,
17}
18
19impl ChiselState {
20    /// Create a new Chisel state inspector.
21    #[inline]
22    pub fn new(final_pc: usize) -> Self {
23        Self { final_pc, state: None }
24    }
25}
26
27impl<CTX, D> Inspector<CTX, EthInterpreter> for ChiselState
28where
29    D: Database<Error = DatabaseError>,
30    CTX: ContextTr<Db = D>,
31    CTX::Journal: JournalExt,
32{
33    #[cold]
34    fn step_end(&mut self, interpreter: &mut Interpreter, _context: &mut CTX) {
35        // If we are at the final pc of the REPL contract execution, set the state.
36        // Subtraction can't overflow because `pc` is always at least 1 in `step_end`.
37        if self.final_pc == interpreter.bytecode.pc() - 1 {
38            self.state = Some((
39                interpreter.stack.data().clone(),
40                interpreter.memory.context_memory().to_vec(),
41            ))
42        }
43    }
44}