diff --git a/crates/cast/bin/cmd/run.rs b/crates/cast/bin/cmd/run.rs index 4b26c848ef66..7ab5ddd511f9 100644 --- a/crates/cast/bin/cmd/run.rs +++ b/crates/cast/bin/cmd/run.rs @@ -10,7 +10,7 @@ use foundry_cli::{ opts::{EtherscanOpts, RpcOpts}, utils::{handle_traces, init_progress, TraceResult}, }; -use foundry_common::{is_impersonated_tx, is_known_system_sender, shell, SYSTEM_TRANSACTION_TYPE}; +use foundry_common::{is_known_system_sender, shell, SYSTEM_TRANSACTION_TYPE}; use foundry_compilers::artifacts::EvmVersion; use foundry_config::{ figment::{ @@ -212,12 +212,6 @@ impl RunArgs { configure_tx_env(&mut env, &tx.inner); - if is_impersonated_tx(&tx.inner.inner) { - // If the transaction is impersonated, we need to set the caller to the from - // address Ref: https://github.com/foundry-rs/foundry/issues/9541 - env.tx.caller = tx.from; - } - if let Some(to) = Transaction::to(tx) { trace!(tx=?tx.tx_hash(),?to, "executing previous call transaction"); executor.transact_with_env(env.clone()).wrap_err_with(|| { @@ -257,12 +251,6 @@ impl RunArgs { configure_tx_env(&mut env, &tx.inner); - if is_impersonated_tx(&tx.inner.inner) { - // If the transaction is impersonated, we need to set the caller to the from address - // Ref: https://github.com/foundry-rs/foundry/issues/9541 - env.tx.caller = tx.from; - } - if let Some(to) = Transaction::to(&tx) { trace!(tx=?tx.tx_hash(), to=?to, "executing call transaction"); TraceResult::try_from(executor.transact_with_env(env))? diff --git a/crates/evm/core/src/backend/mod.rs b/crates/evm/core/src/backend/mod.rs index cf6e7e8beb0b..3d162c96f46c 100644 --- a/crates/evm/core/src/backend/mod.rs +++ b/crates/evm/core/src/backend/mod.rs @@ -1281,7 +1281,7 @@ impl DatabaseExt for Backend { self.commit(journaled_state.state.clone()); let res = { - configure_tx_req_env(&mut env, tx)?; + configure_tx_req_env(&mut env, tx, None)?; let env = self.env_with_handler_cfg(env); let mut db = self.clone(); diff --git a/crates/evm/core/src/utils.rs b/crates/evm/core/src/utils.rs index 9a1dd8910c97..0f29ec2a4754 100644 --- a/crates/evm/core/src/utils.rs +++ b/crates/evm/core/src/utils.rs @@ -9,6 +9,7 @@ use alloy_network::AnyTxEnvelope; use alloy_primitives::{Address, Selector, TxKind, B256, U256}; use alloy_provider::{network::BlockResponse, Network}; use alloy_rpc_types::{Transaction, TransactionRequest}; +use foundry_common::is_impersonated_tx; use foundry_config::NamedChain; use foundry_fork_db::DatabaseError; use revm::{ @@ -88,16 +89,21 @@ pub fn get_function<'a>( } /// Configures the env for the given RPC transaction. +/// Accounts for an impersonated transaction by resetting the `env.tx.caller` field to `tx.from`. pub fn configure_tx_env(env: &mut revm::primitives::Env, tx: &Transaction) { + let impersonated_from = is_impersonated_tx(&tx.inner).then_some(tx.from); if let AnyTxEnvelope::Ethereum(tx) = &tx.inner { - configure_tx_req_env(env, &tx.clone().into()).expect("cannot fail"); + configure_tx_req_env(env, &tx.clone().into(), impersonated_from).expect("cannot fail"); } } /// Configures the env for the given RPC transaction request. +/// `impersonated_from` is the address of the impersonated account. This helps account for an +/// impersonated transaction by resetting the `env.tx.caller` field to `impersonated_from`. pub fn configure_tx_req_env( env: &mut revm::primitives::Env, tx: &TransactionRequest, + impersonated_from: Option
, ) -> eyre::Result<()> { let TransactionRequest { nonce, @@ -120,7 +126,10 @@ pub fn configure_tx_req_env( // If no `to` field then set create kind: https://eips.ethereum.org/EIPS/eip-2470#deployment-transaction env.tx.transact_to = to.unwrap_or(TxKind::Create); - env.tx.caller = from.ok_or_else(|| eyre::eyre!("missing `from` field"))?; + // If the transaction is impersonated, we need to set the caller to the from + // address Ref: https://github.com/foundry-rs/foundry/issues/9541 + env.tx.caller = + impersonated_from.unwrap_or(from.ok_or_else(|| eyre::eyre!("missing `from` field"))?); env.tx.gas_limit = gas.ok_or_else(|| eyre::eyre!("missing `gas` field"))?; env.tx.nonce = nonce; env.tx.value = value.unwrap_or_default(); diff --git a/crates/verify/src/bytecode.rs b/crates/verify/src/bytecode.rs index d3079fae72cf..01fcb488631f 100644 --- a/crates/verify/src/bytecode.rs +++ b/crates/verify/src/bytecode.rs @@ -261,7 +261,7 @@ impl VerifyBytecodeArgs { // configure_tx_rq_env(&mut env, &gen_tx); - configure_tx_req_env(&mut env, &gen_tx_req) + configure_tx_req_env(&mut env, &gen_tx_req, None) .wrap_err("Failed to configure tx request env")?; // Seed deployer account with funds @@ -478,7 +478,7 @@ impl VerifyBytecodeArgs { } // configure_req__env(&mut env, &transaction.inner); - configure_tx_req_env(&mut env, &transaction) + configure_tx_req_env(&mut env, &transaction, None) .wrap_err("Failed to configure tx request env")?; let fork_address = crate::utils::deploy_contract(