diff --git a/crates/anvil/src/eth/backend/cheats.rs b/crates/anvil/src/eth/backend/cheats.rs index c7f5f3b71a7ce..d364359ba8e33 100644 --- a/crates/anvil/src/eth/backend/cheats.rs +++ b/crates/anvil/src/eth/backend/cheats.rs @@ -1,10 +1,12 @@ //! Support for "cheat codes" / bypass functions +use alloy_eips::eip7702::SignedAuthorization; use alloy_evm::precompiles::{Precompile, PrecompileInput}; use alloy_primitives::{ - Address, Bytes, + Address, Bytes, U256, map::{AddressHashSet, foldhash::HashMap}, }; +use alloy_rpc_types::Authorization; use parking_lot::RwLock; use revm::precompile::{ PrecompileError, PrecompileOutput, PrecompileResult, secp256k1::ec_recover_run, @@ -84,6 +86,38 @@ impl CheatsManager { pub fn has_recover_overrides(&self) -> bool { !self.state.read().signature_overrides.is_empty() } + + /// Creates authorization entries for impersonated accounts with signature overrides. + /// This allows impersonated accounts to be used in EIP-7702 transactions. + pub fn create_impersonated_authorizations( + &self, + authorizations: &[SignedAuthorization], + chain_id: u64, + ) -> Vec { + let mut authorization_list = authorizations.to_vec(); + for addr in self.impersonated_accounts() { + let auth = Authorization { chain_id: U256::from(chain_id), address: addr, nonce: 0 }; + + let signed_auth = SignedAuthorization::new_unchecked( + auth, + 0, // y_parity + U256::from(1), // r + U256::from(1), // s + ); + + let mut sig_bytes = [0u8; 65]; + let r_bytes = signed_auth.r().to_be_bytes::<32>(); + let s_bytes = signed_auth.s().to_be_bytes::<32>(); + sig_bytes[..32].copy_from_slice(&r_bytes); + sig_bytes[32..64].copy_from_slice(&s_bytes); + sig_bytes[64] = signed_auth.y_parity(); + let sig = Bytes::copy_from_slice(&sig_bytes); + + self.add_recover_override(sig, addr); + authorization_list.push(signed_auth); + } + authorization_list + } } /// Container type for all the state variables diff --git a/crates/anvil/src/eth/backend/executor.rs b/crates/anvil/src/eth/backend/executor.rs index 55214afc45817..1aac2292efe14 100644 --- a/crates/anvil/src/eth/backend/executor.rs +++ b/crates/anvil/src/eth/backend/executor.rs @@ -268,6 +268,14 @@ impl TransactionExecutor<'_, DB, V> { fn env_for(&self, tx: &PendingTransaction) -> Env { let mut tx_env = tx.to_revm_tx_env(); + if let TypedTransaction::EIP7702(tx_7702) = &tx.transaction.transaction { + let authorization_list = self.cheats.create_impersonated_authorizations( + &tx_7702.tx().authorization_list, + self.cfg_env.chain_id, + ); + tx_env.base.set_signed_authorization(authorization_list); + } + if self.optimism { tx_env.enveloped_tx = Some(alloy_rlp::encode(&tx.transaction.transaction).into()); }