Foundry v1.9.0
- Version
v1.9.0- Repository
- foundry-rs/foundry
Release notes
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…