@@ -2,12 +2,14 @@ use crate::{
22 executors:: { Executor , ExecutorBuilder } ,
33 Env ,
44} ;
5- use alloy_primitives:: Address ;
5+ use alloy_primitives:: { map:: HashMap , Address , U256 } ;
6+ use alloy_rpc_types:: state:: StateOverride ;
7+ use eyre:: Context ;
68use foundry_compilers:: artifacts:: EvmVersion ;
79use foundry_config:: { utils:: evm_spec_id, Chain , Config } ;
810use foundry_evm_core:: { backend:: Backend , fork:: CreateFork , opts:: EvmOpts } ;
911use foundry_evm_traces:: TraceMode ;
10- use revm:: primitives:: hardfork:: SpecId ;
12+ use revm:: { primitives:: hardfork:: SpecId , state :: Bytecode } ;
1113use std:: ops:: { Deref , DerefMut } ;
1214
1315/// A default executor with tracing enabled
@@ -23,18 +25,48 @@ impl TracingExecutor {
2325 trace_mode : TraceMode ,
2426 odyssey : bool ,
2527 create2_deployer : Address ,
28+ state_overrides : Option < StateOverride > ,
2629 ) -> eyre:: Result < Self > {
2730 let db = Backend :: spawn ( fork) ?;
28- Ok ( Self {
29- // configures a bare version of the evm executor: no cheatcode inspector is enabled,
30- // tracing will be enabled only for the targeted transaction
31- executor : ExecutorBuilder :: new ( )
32- . inspectors ( |stack| {
33- stack. trace_mode ( trace_mode) . odyssey ( odyssey) . create2_deployer ( create2_deployer)
34- } )
35- . spec_id ( evm_spec_id ( version. unwrap_or_default ( ) , odyssey) )
36- . build ( env, db) ,
37- } )
31+ // configures a bare version of the evm executor: no cheatcode inspector is enabled,
32+ // tracing will be enabled only for the targeted transaction
33+ let mut executor = ExecutorBuilder :: new ( )
34+ . inspectors ( |stack| {
35+ stack. trace_mode ( trace_mode) . odyssey ( odyssey) . create2_deployer ( create2_deployer)
36+ } )
37+ . spec_id ( evm_spec_id ( version. unwrap_or_default ( ) , odyssey) )
38+ . build ( env, db) ;
39+
40+ // Apply the state overrides.
41+ if let Some ( state_overrides) = state_overrides {
42+ for ( address, overrides) in state_overrides {
43+ if let Some ( balance) = overrides. balance {
44+ executor. set_balance ( address, balance) ?;
45+ }
46+ if let Some ( nonce) = overrides. nonce {
47+ executor. set_nonce ( address, nonce) ?;
48+ }
49+ if let Some ( code) = overrides. code {
50+ let bytecode = Bytecode :: new_raw_checked ( code)
51+ . wrap_err ( "invalid bytecode in state override" ) ?;
52+ executor. set_code ( address, bytecode) ?;
53+ }
54+ if let Some ( state) = overrides. state {
55+ let state: HashMap < U256 , U256 > = state
56+ . into_iter ( )
57+ . map ( |( slot, value) | ( slot. into ( ) , value. into ( ) ) )
58+ . collect ( ) ;
59+ executor. set_storage ( address, state) ?;
60+ }
61+ if let Some ( state_diff) = overrides. state_diff {
62+ for ( slot, value) in state_diff {
63+ executor. set_storage_slot ( address, slot. into ( ) , value. into ( ) ) ?;
64+ }
65+ }
66+ }
67+ }
68+
69+ Ok ( Self { executor } )
3870 }
3971
4072 /// Returns the spec id of the executor
0 commit comments