Conversation
…13743) * Update standard_json.rs * Update provider.rs * Update sourcify.rs
…send` (foundry-rs#13747) Extract `CastTxSender::print_tx_result()` to share the "print hash or wait for receipt" logic between the normal send flow and the browser wallet flow. Flatten the browser case into its own `else if` branch so `--browser` takes priority over `--unlocked` instead of being silently ignored.
foundry-rs#13736) refactor(anvil): move network-agnostic methods to impl<N> Backend<N> Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com>
foundry-rs#13752) * refactor(evm): remove unused `snap_tx_env` from `BackendStateSnapshot` The `snap_tx_env` field was stored on every state snapshot but never read back on revert — it was destructured as `_`. Remove it along with the `tx_env` parameter from `DatabaseExt::snapshot_state`, avoiding an unnecessary `TxEnv` clone on every snapshot. * style: fmt snapshot_state signatures * fix: use backend_mut in CowBackend::snapshot_state to preserve initialization Amp-Thread-ID: https://ampcode.com/threads/T-019ce8e6-b2c7-71dd-8f3e-df34110d8a20 Co-authored-by: Amp <amp@ampcode.com> --------- Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* fix: update EtherlinkTestnet -> EtherlinkShadownet for alloy-chains v0.2.31 (foundry-rs#13763) Co-authored-by: Matthias Seitz <19890894+mattsse@users.noreply.github.com> * chore(evm): make `FoundryCfg` generic over `Spec` (foundry-rs#13757) * chore(deps): weekly `cargo update` (foundry-rs#13760) Updating git repository `https://github.com/alloy-rs/alloy` Updating git repository `https://github.com/alloy-rs/evm.git` Updating git repository `https://github.com/foundry-rs/optimism` Updating git submodule `https://github.com/flashbots/op-rbuilder` Updating git submodule `https://github.com/foundry-rs/forge-std` Updating git submodule `https://github.com/runtimeverification/kontrol-cheatcodes` Updating git submodule `https://github.com/ethereum-optimism/lib-keccak` Updating git submodule `https://github.com/dapphub/ds-test` Updating git submodule `https://github.com/vectorized/solady` Updating git submodule `https://github.com/OpenZeppelin/openzeppelin-contracts` Updating git submodule `https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable` Updating git submodule `https://github.com/OpenZeppelin/openzeppelin-contracts` Updating git submodule `https://github.com/a16z/erc4626-tests.git` Updating git submodule `https://github.com/safe-global/safe-contracts` Updating git submodule `https://github.com/vectorized/solady` Updating git submodule `https://github.com/transmissions11/solmate` Updating git submodule `https://github.com/ethereum-optimism/superchain-registry` Updating git submodule `https://github.com/flashbots/rollup-boost` Updating git repository `https://github.com/foundry-rs/foundry-fork-db` Updating git repository `https://github.com/paradigmxyz/revm-inspectors.git` Updating git repository `https://github.com/rust-cli/rexpect` Updating git repository `https://github.com/paradigmxyz/solar` Skipping git submodule `https://github.com/argotorg/solidity.git` due to update strategy in .gitmodules Updating git repository `https://github.com/tempoxyz/tempo` Updating git submodule `https://github.com/foundry-rs/forge-std` Updating git submodule `https://github.com/vectorized/solady` Updating git submodule `https://github.com/tempoxyz/tempo-std` Updating git repository `https://github.com/stevencartavia/reth` Locking 31 packages to latest compatible versions Updating alloy-chains v0.2.30 -> v0.2.31 Updating alloy-trie v0.9.4 -> v0.9.5 Adding anstream v1.0.0 Unchanged anstream v0.6.21 (available: v1.0.0) Updating anstyle v1.0.13 -> v1.0.14 Updating anstyle-lossy v1.1.4 -> v1.1.5 Adding anstyle-parse v1.0.0 Updating bon v3.9.0 -> v3.9.1 Updating bon-macros v3.9.0 -> v3.9.1 Updating c-kzg v2.1.6 -> v2.1.7 Updating cc v1.2.56 -> v1.2.57 Updating clap v4.5.60 -> v4.6.0 Updating clap_builder v4.5.60 -> v4.6.0 Updating clap_complete v4.5.66 -> v4.6.0 Updating clap_complete_nushell v4.5.10 -> v4.6.0 Updating clap_derive v4.5.55 -> v4.6.0 Updating clap_lex v1.0.0 -> v1.1.0 Updating colorchoice v1.0.4 -> v1.0.5 Updating console v0.16.2 -> v0.16.3 Removing darling v0.21.3 Removing darling_core v0.21.3 Removing darling_macro v0.21.3 Updating derive-where v1.6.0 -> v1.6.1 Updating evmole v0.8.2 -> v0.8.4 Unchanged generic-array v0.14.7 (available: v0.14.9) Unchanged icu_collections v2.0.0 (available: v2.1.1) Unchanged icu_normalizer v2.0.1 (available: v2.1.1) Unchanged icu_normalizer_data v2.0.0 (available: v2.1.1) Unchanged icu_properties v2.0.2 (available: v2.1.2) Unchanged icu_properties_data v2.0.1 (available: v2.1.2) Unchanged idna_adapter v1.1.0 (available: v1.2.1) Updating kasuari v0.4.11 -> v0.4.12 Unchanged matchit v0.8.4 (available: v0.8.6) Updating once_cell v1.21.3 -> v1.21.4 Unchanged op-revm v15.0.0 (available: v17.0.0) Updating portable-atomic-util v0.2.5 -> v0.2.6 Unchanged quick-junit v0.5.2 (available: v0.6.0) Unchanged rand v0.8.5 (available: v0.10.0) Unchanged rand v0.9.2 (available: v0.10.0) Unchanged revm v34.0.0 (available: v36.0.0) Updating schannel v0.1.28 -> v0.1.29 Updating serde_with v3.17.0 -> v3.18.0 Updating serde_with_macros v3.17.0 -> v3.18.0 Unchanged snapbox v0.6.24 (available: v1.1.0) Unchanged soldeer-commands v0.10.0 (available: v0.10.1) Unchanged soldeer-core v0.10.0 (available: v0.10.1) Unchanged strum v0.27.2 (available: v0.28.0) Updating tempfile v3.26.0 -> v3.27.0 Updating tinyvec v1.10.0 -> v1.11.0 Unchanged toml v0.9.12+spec-1.1.0 (available: v1.0.6+spec-1.1.0) Unchanged toml_edit v0.24.1+spec-1.1.0 (available: v0.25.4+spec-1.1.0) Updating tracing-subscriber v0.3.22 -> v0.3.23 Updating zerocopy v0.8.41 -> v0.8.42 Updating zerocopy-derive v0.8.41 -> v0.8.42 note: to see how you depend on a package, run `cargo tree --invert <dep>@<ver>` Co-authored-by: mattsse <19890894+mattsse@users.noreply.github.com> Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de> * feat(cheatcodes): bubble-up `Network` generic to `Wallets` (foundry-rs#13768) * feat(script): generic `TxStatus` receipt type (foundry-rs#13770) feat(script): generic `TxStatus` * chore(script): idiomatic `BroadcastReader::into_tx_receipts` (foundry-rs#13771) * refactor(evm): simplify `Backend::initialize` and `CowBackend::backend_mut` (foundry-rs#13755) `initialize` now takes `(SpecId, Address, TxKind)` instead of `&Env`, since those are the only fields it reads. This removes the need for `backend_mut` to clone `EvmEnv` — it only needs `&TxEnv` now, because the `SpecId` already comes from `self.spec_id`. Moves towards aligning with alloy-evm's BlockExecutor ownership model where `EvmEnv` is block-scoped and `TxEnv` is tx-scoped. * feat(cheatcodes): make `Cheatcodes` context-generic (foundry-rs#13767) * feat(cheatcodes): make `Cheatcodes` context-generic * fix: merge conflict --------- Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * feat(cast): add `--network` flag to `cast tx` for network-specific raw encoding (foundry-rs#13745) * feat(cast): add --network flag to `cast tx` for multi-network raw encoding Replace the `FoundryNetwork`-based `transaction_raw` workaround with proper network selection via a new `--network` / `-n` CLI flag. This moves raw tx encoding back into `Cast::transaction` dispatching to the correct provider (Ethereum, Optimism, or Tempo) based on the flag. - Add `NetworkVariant` enum (Ethereum/Optimism/Tempo) in foundry-cli opts - use it w/ `--network` through CastSubcommand::Tx and provider construction - Add test for Tempo raw tx encoding (`tx_raw_tempo`) * fix: network num args * feat(cast): `block --raw` network selection (foundry-rs#13754) * rebase PR 13745 * feat(cast): `block` for multi-network raw encoding Co-authored-by: figtracer <1gusredo@gmail.com> * fix: doctest --------- Co-authored-by: figtracer <1gusredo@gmail.com> Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * refactor(anvil): make mined_receipts generic (foundry-rs#13761) * chore(evm): split `Executor::env` into `evm_env` and `tx_env` fields (foundry-rs#13773) Split the getters/setters accordingly, and update all call sites. * refactor(cheatcodes): `CheatcodesExecutor` generic (foundry-rs#13774) refactor(cheatcodes): make `CheatcodesExecutor<CTX>` use generic env types from `ContextTr` Replace concrete `EvmEnv`/`TxEnv` in `with_fresh_nested_evm` with `EvmEnv<<CTX::Cfg as Cfg>::Spec, CTX::Block>` and `CTX::Tx` to support non-Eth networks. Add `FoundryContextTr` trait as fully generic counterpart to the concrete `FoundryContextExt`. Remove unused `clone_to_cfg_env`/`apply_cfg_env` from `FoundryCfg`. * fix(anvil): flaky `test_trace_filter()` (foundry-rs#13764) fix * chore(cast): granular bounds on `Cast` (foundry-rs#13776) * refactor(evm): `FoundryContextExt` generic types (foundry-rs#13778) * fix(cheatcodes): create file in writeJson/writeToml 3-arg overload (foundry-rs#13777) Closes foundry-rs#13775 Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * refactor(anvil): make EthApi generic over `N: Network` (foundry-rs#13751) * refactor(anvil): make EthApi generic over N: Network * rm todo comments --------- Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * refactor(evm): move `CheatsCtxExt` trait to `foundry-evm-core` (foundry-rs#13781) Previously `CheatsCtxExt` was defined in `foundry-cheatcodes`. Move it to `foundry-evm-core`, and rename it to `EthCheatCtx` to make clear it pins the context to Ethereum-specific env types (`BlockEnv`/`TxEnv`/`CfgEnv`) as a temporary alias during the transition to fully generic EVM and cheatcodes. * refactor(evm): make `NestedEvm` trait generic with associated types (foundry-rs#13782) Add `Tx`, `Block`, and `Spec` associated types to `NestedEvm` so each network can specify its own environment types. The trait remains object-safe when used as `dyn NestedEvm<Tx = TxEnv, Block = BlockEnv, Spec = SpecId>`. Update `NestedEvmClosure` to pin the associated types to Eth types, and set the concrete types in the `FoundryEvm` implementation. * refactor(anvil): propagate `EthApi<N>` to all holders (foundry-rs#13783) refactor(anvil): propagate EthApi<N> to all holders * refactor(evm): rename `NestedEvmClosure` and move to `foundry-evm-core` (foundry-rs#13785) refactor(evm): rename `NestedEvmClosure` to `EthNestedEvmClosure` and move to `foundry-evm-core` * refactor(evm): remove `Env` abstraction from `Executor` impl (foundry-rs#13790) * refactor(anvil): remove redundant param (foundry-rs#13792) * refactor(cheatcodes): tighten verbose bounds to `EthCheatCtx` (foundry-rs#13791) * refactor(evm): remove `eth_*_mut()` from `FoundryContextExt` (foundry-rs#13789) * feat(script): generic `TransactionWithMetadata` + generic pprinting `TransactionMaybeSigned` (foundry-rs#13795) * refactor(evm): `DatabaseExt` generic over env types (foundry-rs#13797) refactor(evm): make DatabaseExt generic over environment types Add generic parameters with defaults to DatabaseExt: `DatabaseExt<Spec = SpecId, Block = BlockEnv, Tx = TxEnv>` This makes the trait generic over EVM environment types while remaining fully backwards-compatible — all existing code uses the defaults. Non-Ethereum networks (e.g. Tempo) can now implement DatabaseExt with their own environment types. 9 method signatures updated: snapshot_state, revert_state, create_select_fork, create_select_fork_at_transaction, select_fork, roll_fork, roll_fork_to_transaction, transact, transact_from_tx. * test(cast): mark flaky revert_reason_from and wildcard RPC-dependent tail (foundry-rs#13796) * fix(anvil): reject invalid versioned_hashes in beacon blobs endpoint (foundry-rs#13787) * fix(cheatcodes): prevent panic in expectRevert with empty bytes (foundry-rs#13769) * fix(cheatcodes): prevent panic in expectRevert with empty bytes When vm.expectRevert(bytes('')) catches a revert with non-empty data, decode_error in alloy-dyn-abi panics on the empty expected_reason (slice index out of range). Guard the decode_error call with a length check. Closes foundry-rs#13766 Co-Authored-By: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * test: add regression test for expectRevert empty bytes panic Co-Authored-By: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * test: fix snapshot for expectRevert empty bytes regression test Co-Authored-By: zerosnacks <95942363+zerosnacks@users.noreply.github.com> --------- Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * refactor(evm): add `DB` associated type to `FoundryJournalExt` (foundry-rs#13799) * refactor(evm): make DatabaseExt generic over environment types Add generic parameters with defaults to DatabaseExt: `DatabaseExt<Spec = SpecId, Block = BlockEnv, Tx = TxEnv>` This makes the trait generic over EVM environment types while remaining fully backwards-compatible — all existing code uses the defaults. Non-Ethereum networks (e.g. Tempo) can now implement DatabaseExt with their own environment types. 9 method signatures updated: snapshot_state, revert_state, create_select_fork, create_select_fork_at_transaction, select_fork, roll_fork, roll_fork_to_transaction, transact, transact_from_tx. * refactor(evm): replace dyn DatabaseExt in FoundryJournalExt with associated type Replace `&mut dyn DatabaseExt` return type in `FoundryJournalExt` with an associated type `type DB: DatabaseExt`. This removes 3 uses of `dyn DatabaseExt` while remaining backwards-compatible — `&mut DB` auto-coerces to `&mut dyn DatabaseExt` at call sites that still need it. `FoundryJournalExt` is never used as a trait object itself, so adding the associated type has no object-safety impact. --------- Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * feat(anvil): add `AnvilBlockExecutor` and `FoundryReceiptBuilder` (foundry-rs#13788) feat(anvil): add AnvilBlockExecutor and FoundryReceiptBuilder * fix(anvil): swap param order in get_next_block_blob_excess_gas to match callers (foundry-rs#13740) * feat(script): `Network`-generic `ScriptSequence<N>` (foundry-rs#13803) * fix(config): add symmetric serialization for FuzzDictionaryConfig usize fields (foundry-rs#13723) * chore(evm): remove `Env::new_with_spec_id()` method (foundry-rs#13806) * fix(install): clean up nested submodules when using --no-git (foundry-rs#13779) * fix(install): clean up nested submodules when using --no-git Fixes foundry-rs#13688 Co-Authored-By: zerosnacks <95942363+zerosnacks@users.noreply.github.com> Amp-Thread-ID: https://ampcode.com/threads/T-019cf6ab-6839-70a9-98a9-289974db717b * test: mark regression test as flaky_ instead of ignored Co-Authored-By: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * style: fix fmt Co-Authored-By: zerosnacks <95942363+zerosnacks@users.noreply.github.com> Amp-Thread-ID: https://ampcode.com/threads/T-019cf6ab-6839-70a9-98a9-289974db717b --------- Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * refactor(evm): use associated types in `with_cloned_context` (foundry-rs#13802) refactor(evm): use associated types in `with_cloned_context` closure signature * refactor(evm): propagate env types through `FoundryJournalExt` (foundry-rs#13808) * refactor(evm): simplify `FoundryCfg` to marker trait (foundry-rs#13810) * feat(anvil): add `AnvilBlockExecutorFactory` (foundry-rs#13811) * feat(script): `Network`-generic `ScriptSequenceKind<N>` (foundry-rs#13809) * feature(evm): owned `Tx`/`Evm` getters and `Evm` setter for `FoundryContextExt` (foundry-rs#13812) * chore(evm): remove `Env::{clone_evm_and_tx,apply_evm_and_tx}` methods (foundry-rs#13813) * chore(evm): rename `InspectorExt` to `EthInspectorExt` (foundry-rs#13815) * refactor(evm): add `Fork::backend()` accessor (foundry-rs#13817) * refactor(evm): remove `Env` from `commit_transaction` and `replay_until` (foundry-rs#13816) * feat(script): generic `BundledState` impl (foundry-rs#13825) * chore: bump alloy chains (foundry-rs#13827) * chore(evm): remove `Env` abstraction (foundry-rs#13826) * chore(evm): remove `Env` abstraction completely * fix: nit Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com> --------- Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * fix(macros): use correct index for tuple struct fields in ConsoleFmt (foundry-rs#13829) * chore(evm): fix stale `Env` references in doc comments (foundry-rs#13828) The combined `Env` wrapper struct was removed in foundry-rs#13826. Update remaining doc comments that still reference it to use the current `EvmEnv`/`TxEnv` names instead. * refactor(anvil): wire `AnvilBlockExecutorFactory` into `Backend::mine_block` (foundry-rs#13814) refactor(anvil): wire AnvilBlockExecutorFactory into Backend::mine_block * feat(script): generic `ScriptTransactionBuilder` (foundry-rs#13830) Remove hardcoded `Ethereum` default from `TransactionWithMetadata`, making `ScriptTransactionBuilder`, `simulate_and_fill`, and broadcast reader calls `Network`-generic. Cheatcode broadcast helpers now explicitly use Ethereum. * fix(`foundryup`): bump foundryup version (foundry-rs#13832) bump foundryup version * fix(foundryup): tempo-foundry now ships all binaries (foundry-rs#13834) nit * chore(deps): bump taiki-e/install-action from 2.68.17 to 2.68.35 (foundry-rs#13821) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump oven-sh/setup-bun from 2.1.2 to 2.2.0 (foundry-rs#13819) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump Swatinem/rust-cache from 2.8.2 to 2.9.1 (foundry-rs#13818) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump crate-ci/typos from 1.43.5 to 1.44.0 (foundry-rs#13820) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * refactor(evm): backend env helpers generic (foundry-rs#13836) Update `update_env_block` and `update_current_env_with_fork_env` to use generic `FoundryBlock`/`FoundryTransaction` bounds and `BlockHeader` trait methods via setters, replacing direct field access on `AnyRpcBlock`. * refactor(anvil): rm `TransactionExecutor`, mv revm callers to `AnvilBlockExecutorFactory` (foundry-rs#13835) refactor(anvil): rm , mv remai callers AnvilBlockExecutorFactory * refactor(script): extract `BrowserSigner` from `MultiWallet` (foundry-rs#13839) * refactor(anvil): mv `Backend` methods to generic impl, thread N through NodeConfig/spawn (foundry-rs#13840) * refactor(anvil): extract `block_env_from_header` utility (foundry-rs#13838) * chore(evm): clean-up `FoundryEvm` impl (foundry-rs#13844) * feat(cheatcodes): add `currentFilePath` cheatcode (foundry-rs#13735) * feat(cheatcodes): add `currentFilePath` cheatcode Add `vm.currentFilePath()` that returns the source file path of the currently running test or script contract, relative to the project root. This enables contracts to locate sibling files (calldata JSONs, markdown descriptions, configs) without hardcoding paths. A common pattern in proposal/script repos is overriding a `dirPath()` function with a hardcoded string — this cheatcode eliminates that boilerplate. Implementation leverages `CheatsConfig::running_artifact` which already tracks the entry-point `ArtifactId`. The `source` field is stripped of the project root prefix to return a consistent relative path. * fix: rustfmt Amp-Thread-ID: https://ampcode.com/threads/T-019cfb9f-8fce-717d-b9de-fedd8ee7d555 Co-authored-by: Amp <amp@ampcode.com> * fix: remove view from test functions, fix forge-fmt Amp-Thread-ID: https://ampcode.com/threads/T-019cfba7-4986-77c6-9630-574261e9d580 Co-authored-by: Amp <amp@ampcode.com> --------- Co-authored-by: Alex Netto <alex@blockful.io> Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com> Co-authored-by: zerosnacks <zerosnacks@protonmail.com> Co-authored-by: Amp <amp@ampcode.com> * refactor(evm): simplify nested Evm handling (foundry-rs#13846) refactor(evm): simplify nested EVM handling - Replace `to_env()` (returning cfg+block+tx tuple) with `to_evm_env()` returning only `EvmEnv` (cfg+block), since tx is not needed by callers - Remove unused `with_cloned_context` generic type parameter `R` - Drop `set_tx` call in `with_cloned_context` since nested tx modifications should not propagate back to the outer context - Remove `Evm` useless `db_mut`, `precompiles`, `precompiles_mut`, `inspector`, `inspector_mut` provideds methods reimplementations * refactor(cheatcodes): extract fork env helper to reduce duplication (foundry-rs#13848) Extract `fork_env_op` helper that handles the common pattern shared by all fork-switching cheatcodes: clone EVM/tx env → run db operation → write env back. Deduplicates 7 call sites (rollFork × 4, selectFork, createSelectFork × 2). * refactor(cheatcodes): `BroadcastableTransaction` network-agnostic (foundry-rs#13849) refactor(cheatcodes): make BroadcastableTransaction network-agnostic Remove the `Network` type parameter from `BroadcastableTransaction` by storing raw EVM data (from, to, value, input, nonce, gas) as primitive fields instead of wrapping `TransactionMaybeSigned<N>`. This prevents the `Network` generic from leaking through `Cheatcodes`, `RawCallResult`, and `ScriptResult`. The conversion to network-specific types (`TransactionMaybeSigned<Ethereum>`) now happens in the script layer (`simulate.rs`) at the point where transactions are handed off to `ScriptTransactionBuilder`. * feat(evm): generic `NestedEvmClosure` (foundry-rs#13850) refactor(evm): generalize NestedEvmClosure with generic type params Replace `EthNestedEvmClosure` (pinned to Eth types) with generic `NestedEvmClosure<Tx, Block, Spec>` to support non-Eth networks. * feat(evm): `FoundryContextExt` generic impl (foundry-rs#13857) * feat(evm): wire Inspector and DatabaseExt Context generics (foundry-rs#13856) * refactor(anvil): make `PendingTransaction` generic over tx type (foundry-rs#13854) * chore(cheatcodes): remove `Cheatcodes` context generic (foundry-rs#13861) * refactor(evm): delegate to alloy's `EthEvmFactory` in `new_evm_with_inspector` (foundry-rs#13860) * chore: add `id` attributes to issue templates (foundry-rs#13864) * chore: add `id` attributes to issue templates Co-authored-by: 0xrusowsky <90208954+0xrusowsky@users.noreply.github.com> Amp-Thread-ID: https://ampcode.com/threads/T-019d0b22-cf39-75b7-b3d7-9280780eecd5 * chore: add `id` attributes to required issue template fields only Co-authored-by: 0xrusowsky <90208954+0xrusowsky@users.noreply.github.com> Amp-Thread-ID: https://ampcode.com/threads/T-019d0b22-cf39-75b7-b3d7-9280780eecd5 --------- Co-authored-by: 0xrusowsky <90208954+0xrusowsky@users.noreply.github.com> * refactor(evm): merge `FoundryJournalExt` into `FoundryContextExt` (foundry-rs#13863) * refactor(evm): merge `FoundryJournalExt` into `FoundryContextExt` * fix: failed merge * fix(traces): fix verbosity trace mode and unify verbosity handling (foundry-rs#13859) * fix(traces): use max instead of min for verbosity trace mode Add regression tests for TraceMode::with_verbosity to ensure verbosity 5 raises the trace mode to at least Steps rather than lowering it. Co-Authored-By: zerosnacks <95942363+zerosnacks@users.noreply.github.com> Co-Authored-By: James Niken <155266991+dizer-ti@users.noreply.github.com> * fix(traces): unify verbosity handling in TraceMode with_verbosity now raises to RecordStateDiff at verbosity 5, matching the documented behavior of -vvvvv (storage changes + backtraces). This removes the separate with_state_changes(verbosity() > 4) call in trace_mode() which used the global shell verbosity instead of the local evm_opts.verbosity — these two values can diverge when --gas-report or --flamegraph bumps evm_opts.verbosity to 3. Co-Authored-By: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * fix(forge): only show backtraces at verbosity 5 Backtraces require opcode-level step recording which is expensive. Gate backtrace display at verbosity >= 5 (-vvvvv) instead of >= 3, matching the documented behavior and the step recording threshold. Co-Authored-By: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * test(traces): comprehensive unit tests for TraceMode verbosity levels Tests every verbosity level (0-5) × every TraceMode variant: - verbosity 0-2: noop across all modes - verbosity 3-4: raises to Call, never downgrades - verbosity 5: raises to RecordStateDiff, never downgrades - into_config correctness at each level (record_steps, record_state_diff) - monotonicity invariant: with_verbosity never lowers any mode Co-Authored-By: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * test(traces): add integration test for backtrace verbosity levels Runs the same failing test at verbosity 1, 3, 4, and 5 with snapshot assertions to verify backtraces only appear at -vvvvv. Removes the monotonicity unit test in favor of concrete integration coverage. Co-Authored-By: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * fix(traces): keep backtraces at verbosity >= 3, add source locations at 5 Backtraces are useful even without source locations — they show contract/function names at -vvv/-vvvv. Source file locations are only added at -vvvvv when step recording is enabled. Updates integration test to assert all three behaviors: - -vvv: backtrace with function names only - -vvvv: same, plus setup traces - -vvvvv: backtrace with source file:line:col locations Co-Authored-By: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * chore: fix rustfmt Co-Authored-By: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * fix(test): handle compiler warnings in snapshot Co-Authored-By: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * fix(test): add [staticcall] to snapshot for pure function Co-Authored-By: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * perf(traces): RecordStateDiff should not enable debug-level recording RecordStateDiff now behaves as Steps + state diff, not Debug + state diff. This avoids recording full stack snapshots (memcpy per opcode), memory snapshots, and unfiltered opcode recording at -vvvvv. Before: 50k opcodes → 50k step records with full stack copies (~16MB) After: 50k opcodes → ~500 step records (JUMP/JUMPDEST only), no copies Co-Authored-By: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * test(traces): assert Debug mode config is unchanged Locks in that Debug mode still enables full memory/stack snapshots, returndata, immediate bytes, and unfiltered opcode recording — ensuring the RecordStateDiff optimization doesn't affect the debugger or cheatcode recording paths. Co-Authored-By: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * fix(traces): state diff needs unfiltered opcodes for SLOAD/SSTORE record_state_diff captures storage changes in the step() callback, which only fires for recorded opcodes. With a JUMP/JUMPDEST filter, SSTORE steps are skipped and state diffs are lost. RecordStateDiff now disables the opcode filter (like before) but still skips memory/stack snapshots — saving the expensive per-opcode memcpy. Co-Authored-By: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * fix(test): update JSON fixture for RecordStateDiff config Stack and memory snapshots are no longer recorded at -vvvvv since RecordStateDiff now uses Steps-level config. These fields are null in the JSON output instead of populated. Full debugger-level data is still available via --debug. Co-Authored-By: zerosnacks <95942363+zerosnacks@users.noreply.github.com> --------- Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com> Co-authored-by: James Niken <155266991+dizer-ti@users.noreply.github.com> * refactor(anvil): make Block generic over tx type (foundry-rs#13865) * refactor(evm): `FoundryContextExt<Journal: JournalExt>` bound, use generic `Spec` in `EthCheatCtx` (foundry-rs#13866) * refactor(evm): use `TxEnv` directly in `DatabaseExt` instead of `TransactionRequest` (foundry-rs#13867) * chore(deps): weekly `cargo update` (foundry-rs#13878) Co-authored-by: mattsse <19890894+mattsse@users.noreply.github.com> * Update flake.lock (foundry-rs#13877) Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> * fix(deps): bump to Foundry browser wallet version 0.2.0 (foundry-rs#13890) bump to https://github.com/foundry-rs/foundry-browser-wallet/releases/tag/v0.2.0 * revert: "BroadcastableTransaction network-agnostic" (foundry-rs#13849) (foundry-rs#13891) * perf(anvil): remove redundant clone in create_access_list (foundry-rs#13887) * perf(evm): make `NestedEvm::to_evm_env` consuming to avoid useless clone (foundry-rs#13893) Change `to_evm_env(&self)` to `to_evm_env(self)` so the implementation can use `Evm::finish()` to destructure the EVM without an extra clone of `cfg_env` and `block_env`. Update `with_fresh_nested_evm` to return `EvmEnv` after consuming the EVM post-closure, so callers no longer need to capture the env inside a `NestedEvmClosure` (which only has `&mut dyn NestedEvm` and cannot call a consuming method). Fix the `sub_inner` / `sub_evm_env` ordering in `with_nested_evm` impls so the journal is cloned before `to_evm_env` consumes the EVM. * chore(common): consistency fix on `TransactionMaybeSigned::to()` (foundry-rs#13895) * feat(cheatcodes): Network/Evm generic `Cheatcodes` (foundry-rs#13894) * feat(cheatcodes): Network/Evm generic `Cheatcodes` * fix: tx create detection * fix(ci): adapt to `TransactionMaybeSigned::to()` return type change (foundry-rs#13896) * chore(cheatcodes): remove unused `cheats` param from `CheatcodesExecutor::console_log` (foundry-rs#13897) * refactor(evm): remove `tx_env` param from EVM constructor helper (foundry-rs#13903) Remove the `tx_env` parameter from `new_eth_evm_with_inspector`, `with_cloned_context`, and `with_fresh_nested_evm`. Instead of setting the transaction environment at EVM construction time (where it may become stale or be set redundantly), callers now pass the tx env directly to `evm.transact()` at execution time. This avoids some clones. * chore: remove dead code `paths_config` and `log_status` from inspector stack (foundry-rs#13905) chore: remove dead code in InspectorStackInner Remove two unused methods: - `InspectorStack::paths_config()`: zero callers across the codebase - `InspectorStackInner::log_status()`: zero callers across the codebase Also removes the now-unused `foundry_compilers::ProjectPathsConfig` import. * chore: remove no-op `spec_id` reassignment in `Executor::clone_with_backend` (foundry-rs#13906) chore: remove no-op spec_id reassignment in clone_with_backend After cloning `self.evm_env`, `evm_env.cfg_env.spec` already equals `self.spec_id()` (which simply returns `self.evm_env.cfg_env.spec`). The reassignment is a no-op. * feat(evm): `Backend` generic network (foundry-rs#13579) * feat(evm): `Backend` generic over `Network` * fix(evm): use `AnyNetwork` for fork env init to support non-standard chains When forking non-standard EVM chains (e.g. Moonbeam, Arbitrum), their block headers may lack standard Ethereum fields like `mixHash`. Using the generic `N`-typed provider (defaulting to `Ethereum`) caused deserialization failures for these chains. * feat(evm): add `TryAnyIntoTxEnv` trait for `AnyTxEnvelope` to `TxEnv` conversion Introduces TryAnyIntoTxEnv trait in foundry-evm-core to replace the TxEnv: FromRecoveredTx<N::TxEnvelope> bound on Backend<N>. This allows Backend to default to AnyNetwork: - TxEnvelope (Ethereum): delegates to FromRecoveredTx directly - AnyTxEnvelope: extracts inner TxEnvelope via as_envelope(), then delegates to FromRecoveredTx; returns error for unknown tx types Co-authored-by: Amp <amp@ampcode.com> * chore: fix `cargo deny` failure --------- Co-authored-by: Amp <amp@ampcode.com> * refactor(evm): `NestedEvm` based on revm's `Evm` instead of alloy-evm (foundry-rs#13908) * Add feature: `forge inspect <x> linearization` to see a Solidity contract's linearized inheritance (foundry-rs#13704) * feat: Tempo wallet access key support for cast (foundry-rs#13909) * refactor(script-sequence): rename misleading `opcode` field to `call_kind` (foundry-rs#13907) * fix(fmt): swap valid_before/valid_after in TempoTransaction pretty print (foundry-rs#13910) * fix(fmt): prefer header total_difficulty for totalDifficulty (foundry-rs#13919) * feat(evm): `FoundryContextExt` impls for OP (foundry-rs#13925) * refactor(evm): simplify `NestedEvm` trait by removing `Block` and `Spec` (foundry-rs#13933) * refactor(evm): make `FoundryInspectorExt` generic over `CTX` and rename traits (foundry-rs#13922) * refactor(evm): make `FoundryInspectorExt` generic over `CTX` and rename traits Restructure the inspector extension traits for clarity and genericity: - Rename FoundryInspectorExt -> InspectorExt: the context-free base trait providing Foundry-specific inspector methods (console logging, network config) without any Inspector<CTX> supertrait. - Rename EthInspectorExt -> FoundryInspectorExt<CTX>: the combined trait that unifies Inspector<CTX> + InspectorExt. Generic over any CTX that implements FoundryContextExt, rather than being hardcoded to specific BLOCK/TX/SPEC type parameters with for<'a> HRTB baked in. - Introduce EthEvmCtx<'db> type alias for the concrete Eth context (Context<BlockEnv, TxEnv, CfgEnv, &'db mut dyn DatabaseExt>), keeping usage sites concise. This makes the trait hierarchy composable for multi-network support while keeping the Eth-specific default path ergonomic via the type alias during refactor. Co-authored-by: Amp <amp@ampcode.com> * fix: use `EthEvmContext<DB>` instead of EthEvmCtx as default --------- Co-authored-by: Amp <amp@ampcode.com> * fix(evm): restore `code_size_limit` config in `CfgEnv` (foundry-rs#13912) `cfg_env()` unconditionally set `limit_contract_code_size = Some(usize::MAX)`, ignoring the user's `code_size_limit` setting from foundry.toml. Use the configured value when present, falling back to `usize::MAX` (disabled). * perf(evm): remove unnecessary clones in do_call_end/do_create_end (foundry-rs#13913) perf(evm): remove unnecessary clones in `do_call_end`/`do_create_end` Both methods returned `CallOutcome`/`CreateOutcome` but all callers discarded the return value — the outcome is already mutated in-place via `&mut`. This removes the final `outcome.clone()` and changes the early-return in the `#[ret]` macro from `then_some(outcome.clone())` to `then(|| ())`, eliminating up to 2 clones per call/create end. * fix(wallets): browser wallet CLI help heading formatting (foundry-rs#13876) fix: browser wallet CLI help heading formatting - Set proper help_heading on BrowserWalletOpts to use 'Wallet options - browser wallet' consistently - Add next_help_heading to Erc20TxOpts to prevent transaction options from leaking into the browser wallet section Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com> * feat(forge-script): Tempo access key support for forge script (foundry-rs#13917) * refactor(anvil): encapsulate per-tx inspector lifecycle in `finish_transaction` (foundry-rs#13932) * refactor(anvil): encapsulate per-tx inspector lifecycle in `finish_transaction` Extract the repeated ~20-line drain-and-reset block from 3 locations in the block mining loop into `AnvilInspector::finish_transaction()`. The method prints traces/logs, drains the tracer into `Vec<CallTraceNode>`, and reinstalls fresh tracer + log collector for the next transaction. Introduces `InspectorTxConfig` to carry the print/tracing settings, replacing direct field access into the inspector internals. * style: fix rustfmt * refactor(evm): generalize `TryAnyToTxEnv` trait over TxEnv + simplification (foundry-rs#13924) * refactor(evm): generalize `TryAnyToTxEnv` trait over TxEnv + simplification The old trait converted `TxEnvelope` (the consensus-layer type) into `TxEnv`, requiring callers to separately pass the sender address. This was a leaky abstraction: the sender is already carried by the RPC transaction wrapper (TransactionResponse::from()), so callers had to extract it themselves before calling `try_into_tx_env`. The new trait `TryAnyToTxEnv` is generic over the output TxEnv type and takes the full RPC transaction as receiver, which means: - Implementations for `alloy_rpc_types::Transaction` and `AnyRpcTransaction` can call ToTxEnv / FromRecoveredTx internally without leaking address handling to callers. - A new impl for `op_alloy_rpc_types::Transaction` produces `OpTransaction<TxEnv>`, enabling OP-stack fork replay without a separate code path. - `Backend<N>` now constrains `N::TransactionResponse: TryAnyToTxEnv<TxEnv>` instead of `N::TxEnvelope: TryAnyIntoTxEnv`, which is both more accurate and unlocks multi-network support. * fix: docs --------- Co-authored-by: zerosnacks <zerosnacks@protonmail.com> Co-authored-by: Amp <amp@ampcode.com> * refactor(evm): simplify `replay_until` to use single `ForkDB` clone (foundry-rs#13931) * refactor: simplify replay_until to use single ForkDB clone Replace the per-transaction Backend + EVM creation in replay_until with a single cloned ForkDB and one persistent EthEvm instance. Before: for each tx in the block, commit_transaction would clone Fork + JournaledState, spawn a new Backend (including MultiFork), create a new FoundryEvm, transact, then apply_state_changeset. In a block with N preceding transactions, this meant N full clones. After: clone the fork's CacheDB once (SharedBackend is Arc-backed, so only the local cache layer is duplicated), create one EthEvm via EthEvmFactory, call transact_commit for each tx, then replace the fork's DB and refresh journaled states once at the end. Also: - Remove unused tx_env parameter from replay_until - Extract Fork::refresh_journaled_states helper to deduplicate the paired update_state calls in both replay_until and apply_state_changeset - Remove unused NoOpInspector import Amp-Thread-ID: https://ampcode.com/threads/T-019d2512-8074-72ac-92d8-e8f887911219 Co-authored-by: Amp <amp@ampcode.com> * style: fix rustfmt * refactor: simplify tx collection loop and remove stale comments --------- Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: zerosnacks <zerosnacks@protonmail.com> * fix(evm): use try_any_to_tx_env in replay_until (foundry-rs#13938) The merge of foundry-rs#13931 introduced a call to the old `try_into_tx_env` method which was renamed to `try_any_to_tx_env` in foundry-rs#13924. This fixes the docs CI build. Amp-Thread-ID: https://ampcode.com/threads/T-019d2952-9ec2-76f9-8f90-b7b3735d4ce3 Co-authored-by: Amp <amp@ampcode.com> * chore(deps): bump taiki-e/install-action from 2.68.35 to 2.69.8 (foundry-rs#13915) Bumps [taiki-e/install-action](https://github.com/taiki-e/install-action) from 2.68.35 to 2.69.8. - [Release notes](https://github.com/taiki-e/install-action/releases) - [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md) - [Commits](taiki-e/install-action@94a7388...7bc99ee) --- updated-dependencies: - dependency-name: taiki-e/install-action dependency-version: 2.69.8 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump DeterminateSystems/determinate-nix-action from 3.17.0 to 3.17.1 (foundry-rs#13914) chore(deps): bump DeterminateSystems/determinate-nix-action Bumps [DeterminateSystems/determinate-nix-action](https://github.com/determinatesystems/determinate-nix-action) from 3.17.0 to 3.17.1. - [Release notes](https://github.com/determinatesystems/determinate-nix-action/releases) - [Commits](DeterminateSystems/determinate-nix-action@131015b...a18f73c) --- updated-dependencies: - dependency-name: DeterminateSystems/determinate-nix-action dependency-version: 3.17.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * refactor(evm): simplify `FoundryContextExt` spec handling (foundry-rs#13935) - Introduced `FoundryContextExt::Spec` type for convenience - Removed complex bounds on `ContextTr::Cfg` using instead the new `Spec` type - Simplified accordingly the rest of the code Co-authored-by: zerosnacks <zerosnacks@protonmail.com> Co-authored-by: Amp <amp@ampcode.com> * refactor(anvil): remove some intermediate `Env` wrappers, pass `EvmEnv` directly (foundry-rs#13941) refactor(anvil): remove some intermediate Env wrapper, pass EvmEnv directly Replace usage of the `Env` struct wrapper with direct `EvmEnv` references in `new_eth_evm_with_inspector`, `validate_pool_transaction_for`, and `validate_for`. The optimism flag is now passed explicitly as `is_optimism: bool` instead of being extracted from `env.networks`. This eliminates unnecessary `Env::new(...)` construction in several hot paths (block mining, pending block simulation, tx replay) and simplifies the function signatures. * refactor(anvil): remove Env from storage, call env, and executor APIs (foundry-rs#13942) Continue the cleanup of the Env wrapper by passing EvmEnv directly in remaining call sites: - BlockchainStorage::new / Blockchain::new: drop the redundant spec_id parameter, derive it from evm_env.spec_id() instead - build_call_env: return (EvmEnv, OpTransaction<TxEnv>) instead of Env, consumers destructure and use directly - new_eth_evm_with_inspector_ref: accept &EvmEnv instead of &Env, derive is_optimism from self.is_optimism() - build_tx_env_for_pending: take is_optimism: bool instead of NetworkConfigs + &EvmEnv - inspect_tx / replay_block_transactions_with_inspector: extract only evm_env from next_env(), avoid cloning the whole Env - api.rs: use spec_id() / chain_id() helpers instead of digging into env.evm_env.cfg_env fields directly - Various minor cleanups: inline single-use env write guards, use self.chain_id() / self.spec_id() helpers consistently --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Derek Cofausper <256792747+decofe@users.noreply.github.com> Co-authored-by: Matthias Seitz <19890894+mattsse@users.noreply.github.com> Co-authored-by: Mablr <59505383+mablr@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de> Co-authored-by: figtracer <1gusredo@gmail.com> Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com> Co-authored-by: stevencartavia <112043913+stevencartavia@users.noreply.github.com> Co-authored-by: Suuuuuuperrrrr fred <FredrikaPhililip@proton.me> Co-authored-by: Nikki <gutonosa@protonmail.com> Co-authored-by: James Niken <155266991+dizer-ti@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Alexandro T. Netto <56097505+alextnetto@users.noreply.github.com> Co-authored-by: Alex Netto <alex@blockful.io> Co-authored-by: zerosnacks <zerosnacks@protonmail.com> Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: 0xrusowsky <90208954+0xrusowsky@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Edgar Richards <eddgarrichards@gmail.com> Co-authored-by: Red Swan <jared.swan@openzeppelin.com> Co-authored-by: onbjerg <onbjerg@users.noreply.github.com> Co-authored-by: anim001k <140460766+anim001k@users.noreply.github.com>
Review or Edit in CodeSandboxOpen the branch in Web Editor • VS Code • Insiders |
There was a problem hiding this comment.
Sorry @Dargon789, your pull request is larger than the review limit of 150000 diff characters
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly refactors the codebase to improve network and transaction type genericity, particularly impacting Anvil, Cast, Cheatcodes, Forge, and Script functionalities. It introduces new traits and updates existing ones to align with the more flexible design, while also integrating enhanced support for the Tempo network and its access key mechanisms. The changes aim to streamline EVM environment management and ensure better compatibility across different blockchain networks. Highlights
Ignored Files
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces significant refactoring across the Foundry codebase, primarily focusing on enhancing network and transaction type genericity. Key changes include making many core components in Anvil, Cast, Forge, and Cheatcodes generic over Network and TxEnvelope/ReceiptEnvelope types, improving flexibility for different EVM-compatible chains like Optimism and Tempo. Explicit support for the Tempo network has been added, including handling of Tempo-specific transaction types and access keys in Cast and Script commands. The EVM environment has been refactored, removing the Env struct in favor of passing EvmEnv and TxEnv directly in many executor and backend functions. New cheatcodes like currentFilePath have been added, and existing ones have been made more robust (e.g., writeJson now creates files if they don't exist). Build system improvements include forge install --no-git now correctly cleaning up nested submodule contents, and forge inspect linearization providing detailed contract inheritance information. Numerous Rust dependencies have also been updated. A notable improvement is the addition of a expected_reason.len() >= 4 check in crates/cheatcodes/src/test/revert_handlers.rs, which prevents a potential panic when e.decode_error is called with revert data shorter than a 4-byte selector, making the cheatcode more robust against edge cases.
| // These are generated only in case of a single unnamed field, hence it is safe to | ||
| // hardcode the index to `.0`. | ||
| Member::Unnamed(_) => quote!(&self.0), | ||
| Member::Unnamed(idx) => quote!(&self.#idx), |
| if expected_reason.len() >= 4 | ||
| && let Ok(e) = get_error("Error(string)") | ||
| && let Ok(dec) = e.decode_error(expected_reason) | ||
| && let Some(DynSolValue::String(revert_str)) = dec.body.first() | ||
| && revert_str.as_str() == String::from_utf8_lossy(&actual_revert) |
There was a problem hiding this comment.
Adding the expected_reason.len() >= 4 check is a good defensive measure. It prevents a potential panic when e.decode_error is called with revert data that is shorter than a 4-byte selector, which could happen with vm.expectRevert(bytes("")) and an empty revert. This makes the cheatcode more robust against edge cases.
| _ => std::cmp::min(self, Self::Steps), | ||
| // Enable step recording and state diff recording when verbosity is 5 or higher. | ||
| // This includes backtraces (JUMP/JUMPDEST steps) and storage changes. | ||
| _ => std::cmp::max(self, Self::RecordStateDiff), |
There was a problem hiding this comment.
The updated logic for with_verbosity at level 5 and above is a significant improvement. The previous implementation could incorrectly downgrade the trace mode (e.g., from Debug to Steps). The new logic using max(self, RecordStateDiff) correctly enhances the tracing level to include state diffs for high verbosity, providing more useful information without unintended side effects.
| ); | ||
|
|
||
| let pretty = pretty_generic_header_response(block.header()); | ||
| assert!(pretty.contains("difficulty 1"), "{pretty}"); |
Check failure
Code scanning / CodeQL
Cleartext logging of sensitive information High
Copilot Autofix
AI 5 days ago
Copilot could not generate an autofix suggestion
Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.
|
|
||
| let pretty = pretty_generic_header_response(block.header()); | ||
| assert!(pretty.contains("difficulty 1"), "{pretty}"); | ||
| assert!(pretty.contains("totalDifficulty 163591"), "{pretty}"); |
Check failure
Code scanning / CodeQL
Cleartext logging of sensitive information High
Copilot Autofix
AI 5 days ago
Copilot could not generate an autofix suggestion
Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.
| } | ||
|
|
||
| fn remove_nested_git_dirs_inner(root: &Path, dir: &Path) -> Result<()> { | ||
| let entries = match std::fs::read_dir(dir) { |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 days ago
In general, to fix uncontrolled path usage you either (1) validate the path against an allowlist or ensure it is within a trusted base directory, or (2) treat the input only as a single, non-hierarchical component (e.g., a file name) and reject any separators or ... Here, the function is meant to clean nested .git artifacts only within the cloned dependency directory. The best fix while preserving behavior is to ensure the recursive traversal in remove_nested_git_dirs_inner never leaves the root directory tree, even if a malicious repository structure or symlinks attempt to redirect traversal.
Concretely, we can add a guard at the top of remove_nested_git_dirs_inner that canonicalizes both root and dir and returns early if dir is not under root. This confines std::fs::read_dir(dir) to directories that are guaranteed to be within the originally requested root, addressing the uncontrolled path issue that CodeQL flagged. Because canonicalization can fail (e.g., broken symlink), we treat such failures as non-fatal and simply stop recursing into that subtree, which maintains robustness without broadening the scope of traversal. This change is localized to remove_nested_git_dirs_inner in crates/forge/src/cmd/install.rs and requires only use std::path::Path; / PathBuf that are already in use elsewhere in the file, so no new external dependencies are needed.
| @@ -359,6 +359,20 @@ | ||
| } | ||
|
|
||
| fn remove_nested_git_dirs_inner(root: &Path, dir: &Path) -> Result<()> { | ||
| // Ensure we never recurse outside of the original root directory. | ||
| // If canonicalization fails or dir is not under root, stop recursing. | ||
| let root_canon = match root.canonicalize() { | ||
| Ok(p) => p, | ||
| Err(_) => return Ok(()), | ||
| }; | ||
| let dir_canon = match dir.canonicalize() { | ||
| Ok(p) => p, | ||
| Err(_) => return Ok(()), | ||
| }; | ||
| if !dir_canon.starts_with(&root_canon) { | ||
| return Ok(()); | ||
| } | ||
|
|
||
| let entries = match std::fs::read_dir(dir) { | ||
| Ok(entries) => entries, | ||
| Err(_) => return Ok(()), |
|
|
||
| // There should be no .git file or directory anywhere under the installed dependency. | ||
| fn assert_no_git(dir: &Path) { | ||
| for entry in fs::read_dir(dir).unwrap() { |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 5 days ago
In general, to fix uncontrolled path usage, we ensure any path derived from untrusted data is either validated/normalized (and rejected if it escapes an allowed root) or we avoid recursively following paths that might point outside an expected directory tree. For this case, the issue is in a recursive helper that walks directories; the best fix is to explicitly bind the traversal to a known root and avoid ever calling fs::read_dir on something that is not under that root.
Concretely, we can modify assert_no_git to take both the current directory and a root directory, and before recursing into path, we check that path is still within root using starts_with. We then initially call assert_no_git with root set to dep_dir, which is our safe base. This ensures we never traverse outside dep_dir even if somehow a symlink or other mechanism introduced an unexpected path component. To avoid changing existing functionality for valid trees, we simply skip recursion into any path that is not under root; in the normal test setup nothing changes, because all children of dep_dir are under that root. This change is local to the test function; no new imports are needed because we already import Path. Only the function signature, its recursive call, and the initial call site need to be updated.
Specifically:
- Change
fn assert_no_git(dir: &Path)tofn assert_no_git(dir: &Path, root: &Path). - Inside the loop, before recursing, check
if path.is_dir() && path.starts_with(root) { assert_no_git(&path, root); }. - Update the initial invocation from
assert_no_git(&dep_dir);toassert_no_git(&dep_dir, &dep_dir);.
| @@ -619,19 +619,19 @@ | ||
| } | ||
|
|
||
| // There should be no .git file or directory anywhere under the installed dependency. | ||
| fn assert_no_git(dir: &Path) { | ||
| fn assert_no_git(dir: &Path, root: &Path) { | ||
| for entry in fs::read_dir(dir).unwrap() { | ||
| let entry = entry.unwrap(); | ||
| let path = entry.path(); | ||
| if path.file_name() == Some(".git".as_ref()) { | ||
| panic!("found leftover .git at {}", path.display()); | ||
| } | ||
| if path.is_dir() { | ||
| assert_no_git(&path); | ||
| if path.is_dir() && path.starts_with(root) { | ||
| assert_no_git(&path, root); | ||
| } | ||
| } | ||
| } | ||
| assert_no_git(&dep_dir); | ||
| assert_no_git(&dep_dir, &dep_dir); | ||
| }); | ||
|
|
||
| forgetest_init!(sync_on_forge_update, |prj, cmd| { |
| if path.file_name() == Some(".git".as_ref()) { | ||
| panic!("found leftover .git at {}", path.display()); | ||
| } | ||
| if path.is_dir() { |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High test
Copilot Autofix
AI 5 days ago
Copilot could not generate an autofix suggestion
Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.
Motivation
Solution
PR Checklist