Skip to content

feat(anvil): bypass authorization signatures for testing #11178

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion crates/anvil/src/eth/backend/cheats.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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<SignedAuthorization> {
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
Expand Down
8 changes: 8 additions & 0 deletions crates/anvil/src/eth/backend/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,14 @@ impl<DB: Db + ?Sized, V: TransactionValidator> 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());
}
Expand Down
Loading