Skip to main content

foundry_evm/inspectors/
script.rs

1use alloy_primitives::{Address, Bytes};
2use revm::{
3    Inspector,
4    bytecode::opcode::ADDRESS,
5    interpreter::{
6        InstructionResult, Interpreter, InterpreterAction,
7        interpreter_types::{Jumps, LoopControl},
8    },
9};
10
11/// An inspector that enforces certain rules during script execution.
12///
13/// Currently, it only warns if the `ADDRESS` opcode is used within the script's main contract.
14#[derive(Clone, Debug, Default)]
15pub struct ScriptExecutionInspector {
16    /// The address of the script contract being executed.
17    pub script_address: Address,
18}
19
20impl<CTX> Inspector<CTX> for ScriptExecutionInspector {
21    fn step(&mut self, interpreter: &mut Interpreter, _ecx: &mut CTX) {
22        // Check if both target and bytecode address are the same as script contract address
23        // (allow calling external libraries when bytecode address is different).
24        if interpreter.bytecode.opcode() == ADDRESS
25            && interpreter.input.target_address == self.script_address
26            && interpreter.input.bytecode_address == Some(self.script_address)
27        {
28            interpreter.bytecode.set_action(InterpreterAction::new_return(
29                InstructionResult::Revert,
30                Bytes::from("Usage of `address(this)` detected in script contract. Script contracts are ephemeral and their addresses should not be relied upon."),
31                interpreter.gas,
32            ));
33        }
34    }
35}