From 69b520d3c6cf7460296dd90e371b11cfa6ae17f2 Mon Sep 17 00:00:00 2001 From: Derek Cofausper <256792747+decofe@users.noreply.github.com> Date: Thu, 9 Apr 2026 07:50:39 +0000 Subject: [PATCH] fix(cast): detect OP Stack chains early in `cast run` `cast run` on OP Stack chains (Base, Optimism) fails with: `data did not match any variant of untagged enum BlockTransactions` Root cause: the generic `FoundryEvmNetwork` refactor (PR #14121) changed `cast run` from using `AnyNetwork` to dispatching via `FEN::Network`. Non-Tempo chains use `EthEvmNetwork` whose `Network = Ethereum`, which cannot deserialize OP deposit transactions (type 0x7e). Fix: decouple the RPC provider network type from the EVM factory by making `run_with_provider` generic over both `FEN` (EVM factory) and `N` (provider network). The dispatch in `run()` now detects OP Stack chains early via `is_optimism()` and uses `FoundryNetwork` as the provider network, which supports all transaction types including OP deposits. Co-Authored-By: zerosnacks <95942363+zerosnacks@users.noreply.github.com> --- Cargo.lock | 1 + crates/cast/Cargo.toml | 1 + crates/cast/src/cmd/run.rs | 26 ++++++++++++++++++++------ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f66ee73901ee1..44399c5eddb6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2703,6 +2703,7 @@ dependencies = [ "foundry-config", "foundry-debugger", "foundry-evm", + "foundry-primitives", "foundry-test-utils", "foundry-wallets", "futures", diff --git a/crates/cast/Cargo.toml b/crates/cast/Cargo.toml index 16a23081c87c1..9db50ce9640cd 100644 --- a/crates/cast/Cargo.toml +++ b/crates/cast/Cargo.toml @@ -28,6 +28,7 @@ foundry-compilers.workspace = true foundry-config.workspace = true foundry-debugger.workspace = true foundry-evm.workspace = true +foundry-primitives.workspace = true foundry-wallets.workspace = true forge-fmt.workspace = true diff --git a/crates/cast/src/cmd/run.rs b/crates/cast/src/cmd/run.rs index 19b3b0daf0566..9006c3daee326 100644 --- a/crates/cast/src/cmd/run.rs +++ b/crates/cast/src/cmd/run.rs @@ -5,7 +5,7 @@ use crate::{ use alloy_consensus::{BlockHeader, Transaction, transaction::SignerRecoverable}; use alloy_evm::FromRecoveredTx; -use alloy_network::{BlockResponse, TransactionResponse}; +use alloy_network::{BlockResponse, Network, TransactionResponse}; use alloy_primitives::{ Address, Bytes, U256, map::{AddressSet, HashMap}, @@ -38,6 +38,7 @@ use foundry_evm::{ opts::EvmOpts, traces::{InternalTraceMode, TraceMode, Traces}, }; +use foundry_primitives::FoundryNetwork; use futures::TryFutureExt; use revm::{DatabaseRef, context::Block}; @@ -138,13 +139,26 @@ impl RunArgs { evm_opts.infer_network_from_fork().await; if evm_opts.networks.is_tempo() { - self.run_with_evm::().await + self.run_with_provider::::Network>().await + } else if evm_opts.networks.is_optimism() { + // OP Stack chains include deposit transactions (type 0x7e) that the + // `Ethereum` network type cannot deserialize. Use `FoundryNetwork` as the + // provider network, which supports all transaction types. + self.run_with_provider::().await } else { - self.run_with_evm::().await + self.run_with_provider::::Network>().await } } - async fn run_with_evm(self) -> Result<()> { + async fn run_with_provider(self) -> Result<()> + where + FEN: FoundryEvmNetwork, + N: Network, + N::TransactionResponse: TransactionResponse + AsRef, + N::TxEnvelope: SignerRecoverable, + N::BlockResponse: BlockResponse, + TxEnvFor: FromRecoveredTx, + { let figment = self.rpc.clone().into_figment(self.with_local_artifacts).merge(&self); let evm_opts = figment.extract::()?; let mut config = Config::from_provider(figment)?.sanitized(); @@ -157,7 +171,7 @@ impl RunArgs { let compute_units_per_second = if self.no_rate_limit { Some(u64::MAX) } else { self.compute_units_per_second }; - let provider = ProviderBuilder::::from_config(&config)? + let provider = ProviderBuilder::::from_config(&config)? .compute_units_per_second_opt(compute_units_per_second) .build()?; @@ -217,7 +231,7 @@ impl RunArgs { evm_version = Some(EvmVersion::Prague); } } - apply_chain_and_block_specific_env_changes::( + apply_chain_and_block_specific_env_changes::( &mut evm_env, block, config.networks,