@@ -11,10 +11,12 @@ use alloy_primitives::{Address, Bytes, TxKind, U256, hex};
1111use alloy_provider:: {
1212 Provider ,
1313 ext:: TraceApi ,
14- network:: { AnyTxEnvelope , TransactionBuilder } ,
14+ network:: {
15+ AnyTxEnvelope , TransactionBuilder , TransactionResponse , primitives:: BlockTransactions ,
16+ } ,
1517} ;
1618use alloy_rpc_types:: {
17- BlockId , BlockNumberOrTag , TransactionInput , TransactionRequest ,
19+ BlockId , BlockNumberOrTag , TransactionInput , TransactionRequest , TransactionTrait ,
1820 trace:: parity:: { Action , CreateAction , CreateOutput , TraceOutput } ,
1921} ;
2022use clap:: { Parser , ValueHint } ;
@@ -23,11 +25,14 @@ use foundry_cli::{
2325 opts:: EtherscanOpts ,
2426 utils:: { self , LoadConfig , read_constructor_args_file} ,
2527} ;
26- use foundry_common:: shell;
28+ use foundry_common:: { SYSTEM_TRANSACTION_TYPE , is_known_system_sender , shell} ;
2729use foundry_compilers:: { artifacts:: EvmVersion , info:: ContractInfo } ;
2830use foundry_config:: { Config , figment, impl_figment_convert} ;
2931use foundry_evm:: {
30- constants:: DEFAULT_CREATE2_DEPLOYER , core:: AsEnvMut , utils:: configure_tx_req_env,
32+ constants:: DEFAULT_CREATE2_DEPLOYER ,
33+ core:: AsEnvMut ,
34+ executors:: EvmError ,
35+ utils:: { configure_tx_env, configure_tx_req_env} ,
3136} ;
3237use revm:: state:: AccountInfo ;
3338use std:: path:: PathBuf ;
@@ -323,6 +328,7 @@ impl VerifyBytecodeArgs {
323328 . ok_or_else ( || {
324329 eyre:: eyre!( "Transaction not found for hash {}" , creation_data. transaction_hash)
325330 } ) ?;
331+ let tx_hash = transaction. tx_hash ( ) ;
326332 let receipt = provider
327333 . get_transaction_receipt ( creation_data. transaction_hash )
328334 . await
@@ -478,7 +484,50 @@ impl VerifyBytecodeArgs {
478484 transaction. set_nonce ( prev_block_nonce) ;
479485
480486 if let Some ( ref block) = block {
481- configure_env_block ( & mut env. as_env_mut ( ) , block)
487+ configure_env_block ( & mut env. as_env_mut ( ) , block) ;
488+
489+ let BlockTransactions :: Full ( ref txs) = block. transactions else {
490+ return Err ( eyre:: eyre!( "Could not get block txs" ) ) ;
491+ } ;
492+
493+ // Replay txes in block until the contract creation one.
494+ for tx in txs {
495+ trace ! ( "replay tx::: {}" , tx. tx_hash( ) ) ;
496+ if is_known_system_sender ( tx. from ( ) )
497+ || tx. transaction_type ( ) == Some ( SYSTEM_TRANSACTION_TYPE )
498+ {
499+ continue ;
500+ }
501+ if tx. tx_hash ( ) == tx_hash {
502+ break ;
503+ }
504+
505+ configure_tx_env ( & mut env. as_env_mut ( ) , & tx. inner ) ;
506+
507+ if let TxKind :: Call ( _) = tx. inner . kind ( ) {
508+ executor. transact_with_env ( env. clone ( ) ) . wrap_err_with ( || {
509+ format ! (
510+ "Failed to execute transaction: {:?} in block {}" ,
511+ tx. tx_hash( ) ,
512+ env. evm_env. block_env. number
513+ )
514+ } ) ?;
515+ } else if let Err ( error) = executor. deploy_with_env ( env. clone ( ) , None ) {
516+ match error {
517+ // Reverted transactions should be skipped
518+ EvmError :: Execution ( _) => ( ) ,
519+ error => {
520+ return Err ( error) . wrap_err_with ( || {
521+ format ! (
522+ "Failed to deploy transaction: {:?} in block {}" ,
523+ tx. tx_hash( ) ,
524+ env. evm_env. block_env. number
525+ )
526+ } ) ;
527+ }
528+ }
529+ }
530+ }
482531 }
483532
484533 // Replace the `input` with local creation code in the creation tx.
0 commit comments