github foundry-rs/foundry v1.9.0

4 hours ago

What you get:

  • SolDB debugger. --debug now runs on SolDB and debugs large tests without exhausting memory. On a 1.46M-step Aave v4 test, peak memory footprint drops from 27.6 GiB to 0.92 GiB and the session opens 5.8× sooner (6.58 s → 1.13 s).
  • Fork reuse. Creating a fork that already exists reuses it instead of reloading its cache. With a 20 MB fork cache and a local RPC, 40 suites that call createSelectFork in setUp run 26× faster (5.15 s → 0.20 s).
  • Faster invariant shrinking. The shrinker drops blocks of calls first and stops once no call can be removed. It finds the same minimal counterexample up to 35× faster (38 s → 1.1 s).
  • Immediate mining in Anvil. Anvil mines each transaction as it arrives. viem gets its receipt in 2 ms instead of waiting 4 s for its next poll.
  • Lower memory. Anvil and Cast stream RPC results without building a JSON tree, and coverage counts hits densely. cast rpc --json traces use 80% less memory, Anvil traces 52% less and coverage 34% less.
  • New tools. forge properties and forge exploit, transient-storage cheatcodes, and Tempo consensus in Anvil.
  • About 190 fixes across script recovery, cheatcodes, gas accounting, Anvil and symbolic execution.

Action required

  • Debugger: --debug opens SolDB. The built-in debugger and --debug-layout are removed, and --dump now writes a SolDB bundle directory instead of a JSON file (#17429).
  • Gas snapshots: regenerate them for tests that deploy contracts with new. Dynamic test linking turns new into vm.deployCode, which now charges its creation gas (#17732, #18034).
  • vm.getRecordedLogs: it no longer returns logs from calls or creations that revert or halt, including reverts expected with expectRevert (#17866).
  • CREATE2 factory: with always_use_create_2_factory = true, salted vm.deployCode deploys through the factory. The address changes, and the constructor sees the factory as msg.sender (#17471).
  • Anvil: it mines immediately, so concurrent transactions may land in separate blocks. Pass --transaction-coalescing-window 5 to restore the 1.8 behavior. Priced calls below the base fee return -32003 (#17578, #17419).
  • --resume: it fails when a sequence has a recorded revert and operations left to send, including broadcasts from older versions. Pass --broadcast --start-fresh to archive the run and broadcast again (#18031, #17736, #17851, #17964).
  • Tempo: Tempo mainnet activates T13 on 2026-11-03 at 15:00 UTC. Local Tempo nodes that follow the wall clock switch from T12 to T13 at that time (#18021).

Other behavior changes

  • Script sender: when --sender and a single --private-key are both given, the script runs as --sender. Before, msg.sender came from the key while broadcasts came from --sender (#17528).
  • Delegatecall broadcasts: a DELEGATECALL or CALLCODE at the broadcast depth is now an error instead of being recorded as a plain CALL (#17794).
  • Coverage: executed bytecode is credited only to exactly matching artifacts, so coverage of code installed with vm.etch may drop (#17520).
  • Remappings: absolute remapping aliases no longer apply inside the project root. For affected projects, bytecode metadata no longer depends on the checkout path and can differ from 1.8 builds (#17507).
  • Gas reporting: flamegraph and evm-profile gas no longer add refunds, and under Amsterdam top-level creates are charged EIP-8037 account-creation state gas (#17728, #17545).
  • Anvil: block timestamps strictly increase, so bursts of blocks can run ahead of wall-clock time. Slow pubsub clients are disconnected instead of buffered. Reversed eth_newFilter ranges, integer trace_get indices and unknown trace blocks return errors (#17373, #17909, #17681, #17308, #17777).
  • vm.writeToml: integers above i64::MAX are written as strings instead of lossy floats (#18016).
  • Rust API: callers must use DebuggerBuilder::run instead of the removed debugger API (#17429).

Features

Forge

  • SolDB debugger: --debug in forge test, forge script, cast run and cast call opens an interactive view in a terminal and a soldb> prompt otherwise. It reads sources from build info, so files rewritten by dynamic test linking show correct lines, and it restores the terminal if it panics (#17429, #18035, #17960) by @figtracer, @mablr.
  • forge properties and forge exploit: forge properties runs a swarm of agents you bring yourself, each in an isolated copy of the project, and reports the bugs they prove with failing tests. forge exploit asks a model on the Tempo Gateway to find a bug and prove it with a test. Both run generated tests in a restricted sandbox (#17259) by @figtracer.
  • Coverage and mutation testing: forge coverage --report gaps writes every uncovered item as JSON, and mutation testing can replace function bodies with constants (#17183, #17599) by @decofe, @siosw.
  • Linked libraries: setting allow_linked_libraries = false fails builds that need linked libraries (#13585) by @mgiagante.
  • Cheatcodes and state diffs: added vm.storeTransient and vm.loadTransient, and state diffs decode ERC-7201 namespaces (#17484, #17869) by @awss1i, @sakulstra.
  • Fuzzing: the fuzzer reuses whole structs from results, events and views, keeps only applicable comparison hints, and builds its dictionary deterministically (#18017, #17459, #17808, #17931) by @0xalpharush, @figtracer, @stevencartavia.
  • Fork prefetch: the opt-in fork_prefetch setting warms new fork blocks in the background with the keys earlier runs read (#17673) by @figtracer.
  • Warnings: forge script warns when a dry run uses the default sender and while it waits on a pending receipt, and it can unlock a keystore without an address to find the sender. Forge warns when an explicit network does not match a fork (#17839, #17977, #17818, #18037) by @stevencartavia, @aelmanaa, @figtracer.

Anvil

Cast and editors

  • cast: it decodes indexed event parameters, and 4byte commands check the local signatures cache (#17634, #17919) by @mattsse, @aelmanaa.
  • Editors: the VS Code extension is on the Marketplace and Open VSX, and the Zed extension downloads Forge when none is installed (#17463, #17858) by @DaniPopes.

Performance

  • Fork reuse: createFork, createSelectFork and rollFork reuse an existing fork instead of reloading its cache (#17418, #17739) by @figtracer.
  • Invariant shrinking: the shrinker drops blocks of calls first and stops once no call can be removed, instead of spending the whole shrink_run_limit. Optimization mode keeps removals that raise the score (#17742) by @figtracer.
  • Immediate mining: Anvil mines each transaction as it arrives again, so clients get receipts without waiting for a poll (#17578) by @figtracer.
  • Memory: the debugger records steps without a second copy of the trace. Anvil and Cast serialize RPC results without building a JSON tree first, and coverage counts hits densely (#17429, #17650, #17672, #17671) by @figtracer, @DaniPopes.
  • Symbolic execution: cached context classifications explore the same paths about 3× faster on Halmos Storage4 (#17701) by @mablr.
  • Build times: smaller binaries and faster builds from aligned dependency features, trimmed dependency defaults and less monomorphization (#17783, #17806, #17788, #17802, #17787, #17786, #17798) by @DaniPopes.

Bug fixes

Scripts

Cheatcodes and testing

Anvil

Cast and verification

  • cast: decode-error and decode-event --json output stays valid JSON, cached 4byte signatures with another selector are ignored, cast call --trace respects fees, and cast run warns when it skips system transactions (#17925, #17939, #17527, #17906, #17946) by @ninglinLiu, @stevencartavia.
  • Solar: Solar's experimental codegen warning is accepted, and forge verify-contract keeps Solar build metadata in the compiler version (#17903, #17890) by @figtracer, @DaniPopes.

Dependencies

New contributors

@fmterrors, @gophersg, @Lubov66, @meyer9, @mohamadhammoud, @mortezashojaei, @ninglinLiu, @Ravan002 and @Snan0M.

Don't miss a new foundry release

NewReleases is sending notifications on new releases.