diff --git a/crates/cast/Cargo.toml b/crates/cast/Cargo.toml index 6d7b22e214b5d..6e9e55c4ae0db 100644 --- a/crates/cast/Cargo.toml +++ b/crates/cast/Cargo.toml @@ -61,7 +61,7 @@ op-alloy-consensus = { workspace = true, features = ["alloy-compat"] } chrono.workspace = true eyre.workspace = true futures.workspace = true -revm.workspace = true +revm = { workspace = true, features = ["optional_balance_check"] } rand.workspace = true rand_08.workspace = true rayon.workspace = true diff --git a/crates/cast/src/cmd/run.rs b/crates/cast/src/cmd/run.rs index 420d6960ee712..412dd970a89f1 100644 --- a/crates/cast/src/cmd/run.rs +++ b/crates/cast/src/cmd/run.rs @@ -12,7 +12,7 @@ use foundry_cli::{ opts::{EtherscanOpts, RpcOpts}, utils::{TraceResult, handle_traces, init_progress}, }; -use foundry_common::{SYSTEM_TRANSACTION_TYPE, is_known_system_sender, shell}; +use foundry_common::{SYSTEM_TRANSACTION_TYPE, is_impersonated_tx, is_known_system_sender, shell}; use foundry_compilers::artifacts::EvmVersion; use foundry_config::{ Config, @@ -232,6 +232,8 @@ impl RunArgs { configure_tx_env(&mut env.as_env_mut(), &tx.inner); + env.evm_env.cfg_env.disable_balance_check = true; + 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(|| { @@ -270,6 +272,9 @@ impl RunArgs { executor.set_trace_printer(self.trace_printer); configure_tx_env(&mut env.as_env_mut(), &tx.inner); + if is_impersonated_tx(tx.inner.inner.inner()) { + env.evm_env.cfg_env.disable_balance_check = true; + } if let Some(to) = Transaction::to(&tx) { trace!(tx=?tx.tx_hash(), to=?to, "executing call transaction"); diff --git a/crates/common/src/constants.rs b/crates/common/src/constants.rs index d127cc0548b06..4d15967fe590a 100644 --- a/crates/common/src/constants.rs +++ b/crates/common/src/constants.rs @@ -1,6 +1,8 @@ //! Commonly used constants. -use alloy_primitives::{Address, address}; +use alloy_eips::Typed2718; +use alloy_network::AnyTxEnvelope; +use alloy_primitives::{Address, B256, Signature, address}; use std::time::Duration; /// The dev chain-id, inherited from hardhat @@ -56,6 +58,24 @@ pub fn is_known_system_sender(sender: Address) -> bool { [ARBITRUM_SENDER, OPTIMISM_SYSTEM_ADDRESS, Address::ZERO].contains(&sender) } +pub fn is_impersonated_tx(tx: &AnyTxEnvelope) -> bool { + if let AnyTxEnvelope::Ethereum(tx) = tx { + return is_impersonated_sig(tx.signature(), tx.ty()); + } + false +} + +pub fn is_impersonated_sig(sig: &Signature, ty: u8) -> bool { + let impersonated_sig = + Signature::from_scalars_and_parity(B256::with_last_byte(1), B256::with_last_byte(1), false); + if ty != SYSTEM_TRANSACTION_TYPE + && (sig == &impersonated_sig || sig.r() == impersonated_sig.r()) + { + return true; + } + false +} + #[cfg(test)] mod tests { use super::*;