v1.3.0-rc2
Foundry v1.3.0
This release includes support for forge lint
, time-based campaigns and coverage-guided fuzzing for invariant tests, table tests, fork test improvements for Reth clients, and new EIP-712 features. Foundry v1.3.0 is built on top of the latest revm v27
Foundry v1.3.0 is built on top of the latest revm v27 and comes with an improved foundryup
installer.
:warning: It is highly recommended to update to latest version of foundryup
, which avoids unnecessary downloads and verifies hashes of downloaded binaries upon install.
Performance Improvements
- This release includes an updated
revm
and an optimized inspector stack, which significantly improves performance compared to previous versions
Forge Test
Repository | v1.2.3 | v1.3.0 |
---|---|---|
ithacaxyz-account | 3.69 s | 3.12 s |
solady | 2.95 s | 2.32 s |
Uniswap-v4-core | 8.03 s | 6.76 s |
sparkdotfi-spark-psm | 57.02 s | 44.76 s |
Forge Fuzz Test
Repository | v1.2.3 | v1.3.0 |
---|---|---|
ithacaxyz-account | 3.58 s | 3.39 s |
solady | 3.34 s | 2.54 s |
Uniswap-v4-core | 8.03 s | 7.46 s |
sparkdotfi-spark-psm | 3.70 s | 3.06 s |
- Forked tests using the Reth client are now faster thanks to the
eth_getAccountInfo
API, reducing account data fetching from three requests to one. Foundry detects ifeth_getAccountInfo
is available and falls back to the legacy method otherwise.
Example: Runningforge test --mt statefulFuzz_curve_test
on spark-alm-controller showed over 5 seconds in test time savings.
Provider | Response Time |
---|---|
reth-ethereum.ithaca.xyz (with eth_getAccountInfo ) | 45.21s |
reth-ethereum.ithaca.xyz (without eth_getAccountInfo ) | 50.83s |
QuickNode (Paid) | 59.66s |
Alchemy (Free Tier) | 182.12s |
Infura (Free Tier) | 176.88s |
Forge Lint
As of v1.3.0, Forge ships with a built-in linter that analyzes Solidity code for style, correctness, and best practices.
- Lint rules are configurable in the
[lint]
section offoundry.toml
and via inline comment directives. - Lints can be customized by severity or specific rule identifiers.
- By default, linting runs during
forge build
. To disable it, setlint_on_build = false
. - For more details please refer to foundry docs:
Supported lints
Linter configuration docs
How to contribute a lint rule
Invariant Test Improvements
Time-Based Campaigns
Previously, invariant tests were limited by a fixed number of runs (default: 256
, max: 4294967295
).
Now you can run them for a specific time duration by setting the timeout
value (in seconds) in the [invariant]
section of foundry.toml
.
The test progress bar shows the number of runs and the end time.
test/GuidedTest.t.sol:CounterTest
→ invariant_Puzzle5: [4360] Runs, ends at 11:03:28 2025-06-03 UTC
→ invariant_Puzzle3: [8784] Runs, ends at 14:50:08 2025-06-04 UTC
→ invariant_Puzzle6: [77762] Runs, ends at 05:56:48 2025-06-09 UTC
→ invariant_Puzzle2: [8739] Runs, ends at 12:50:08 2025-06-02 UTC
Coverage-Guided Fuzzing
Enable this mode by setting a path to corpus_dir
in your invariant config.
The coverage-Guided fuzzing mode targets a corpus_min_size
by mutating entries a number of times (default: 5), favoring those likely to uncover new paths.
splice
: Combines two sequencesinterleave
: Weaves two sequences togetherprefix
: Overwrites the beginning of a sequencesuffix
: Overwrites the end of a sequencemutate args
: Randomizes some call arguments
Additional notes:
- Entries that generate new coverage are saved to disk (default:
.gz
; setcorpus_gzip = false
to save as JSON). - On reruns, the saved corpus is loaded and reused.
- Metadata (as JSON) is persisted for evicted corpus entries. This includes a unique ID, mutation count, and coverage improvements.
- The fuzzing progress bar displays metrics for cumulative edges and features, corpus count and number of favored entries.
test/forge/invariant/StaticInvariantTest.sol:StaticInvariantTest
→ invariantHealthy: [60/2000] Runs
- cumulative edges seen: 41
- cumulative features seen: 6
- corpus count: 15
- favored items: 14
For more details please refer to invariant docs.
Table Tests
Foundry v1.3.0 comes with support for table testing, which enables the definition of a dataset (the "table") and the execution of a test function for each entry in that dataset. This approach helps ensure that certain combinations of inputs and conditions are tested.
For more details please refer to table testing foundry docs.
Improved EIP-712 support
Foundry v1.3.0 comes with additional utilities (commands and new cheatcodes) to make it easy and reliable to work with EIP-712 signatures.
For more details please refer to EIP-712 foundry guide.
Other
- new Anvil APIs including endpoints to deal and set allowance for ERC20 tokens, add balance and get blob by hash
- Vyper support for
forge verify-contract
command fail_on_revert
config for stateless fuzz tests
Anvil Features
- feat(anvil): add block context overrides for eth_call and eth_estimateGas (#10487) by @mablr
- feat: added rpc method to deal ERC20 tokens (#10495) by @Soubhik-10
- feat: implement add_balance endpoint (#10636) by @pistomat
- feat: Add anvil set erc20 allowance endpoint (#10746) by @pistomat
- feat: added eth_sendRawTransactionSync and eth_sendTransactionSync support for anvil (#10860) by @Rimeeeeee
- feat(
anvil
): reset to in-mem (#10897) by @yash-atreya - feat: added get_blob_by_hash (#10987) by @Soubhik-10
- feat: add support for passthrough of debug_codeByHash (#11053) by @cakevm
- feat(anvil): use signatures identifier for --print-traces (#11070) by @mattsse
Anvil Fixes
- fix(anvil): guard against the blockchain advancing while checking latest block (#10714) by @alexghr
- bug(anvil): incorrectly adds +1 gas when estimating transactions with explicit empty data field (#10786) by @gitToki
- fix(
anvil
): inject the P256 precompile for--odyssey
upon EVM construction and fixNotActivated
error for--optimism
(#10567) by @zerosnacks - fix(
anvil
): latest evm version should be prague (#10653) by @yash-atreya - fix: populate missing fields for eth simulate (#10682) by @mattsse
- fix: receipt conversion (#10853) by @mattsse
- fix: spawn state writer blocking (#10922) by @mattsse
- fix: dont check pool for gettransaction receipt (#10946) by @mattsse
- fix: use correct mix hash for header (#10951) by @mattsse
Cast Features
- feat: add cast da-estimate (#10588) by @mattsse
- feat(cast mktx): add support for "--ethsign" option (#10641) by @mablr
- feat(cast): add
--cost
forestimate
to return the eth cost at current gas price (#9687) by @0xvv - feat(cast): display public_key on wallet creation with "new" and "new-mnemonic" sub-commands (#10600) by @mablr
- feat(cast): Verbose signing output (#10529) by @GregTheGreek
- feat(cast):
compute_address
add support CREATE2 addresses (#10783) by @mablr - feat: added block.time and block.number override in cast (#10727) by @Soubhik-10
- feat(cast): add recover-authority for EIP7702 Authorization (#10839) by @jsvisa
- cast: Improve debugger when tracing on-chain transactions/calls (#10596) by @ngotchac
- feat(cast): print a warning on calling a contract without code (#10842) by @ryzhak
- feat(cast): add flag to disable HTTPS certificate validation for RPC (#10869) by @mablr
- feat(cast): add flag to disable alias (#10924) by @varun-doshi
- feat(cast): rpc --json should format as json (#10871) by @jsvisa
- feat(cast): add disable-labels for cast run (#10970) by @grandizzy
- feat(cast): add
--raw
option to block subcommand (#11027) by @mablr - feat(cast): add checksum address with chain id (#11043) by @KumaCrypto
Cast Fixes
- fix(
cast
): respectfull
arg incast block
(#10536) by @mattsse - fix: check for auth when deriving legacy (#10619) by @mattsse
- fix(cast): read all lines for message to hash (#10671) by @grandizzy
- fix: always update auth txenv var (#10707) by @mattsse
- fix(cast): do not use default overrides if no override arg (#10710) by @grandizzy
- fix(cast call/estimate/send): omit function selector from arguments on create calls (#10948) by @nuntax
- fix(cast): disassembler PC & end of code push padding (#10520) by @Philogy
- fix(
cast
): include zero address as known system sender in cast run (#10608) by @yash-atreya - fix: make sign and verify symmetrical (#10614) by @mattsse
- fix: check for op deposit tx when handling cast tx (#10742) by @mattsse
- fix: Respect
--override-*
flags oncast call
with--trace
flag (#10721) by @Yen - fix(cast): Always use from field of getTransaction rpc response in cast run (#10795) by @ckoopmann
- fix(
cast
): bump alloy-chains to 0.2.5 for Ethereum V2 API compatility w/cast
(#10912) by @zerosnacks - fix(cast): account state diffs overrides (#10982) by @grandizzy
Chisel Fixes
- fix(chisel): memory data location for string and bytes params (#10729) by @grandizzy
Forge Features
- feat(forge): revert diagnostic inspector (#10446) by @0xrusowsky
- feat(forge): forge lint (#10405) by @0xrusowsky
- feat(forge): eip712 cheatcodes + forge cmd (eip712 + bind-json) with solar (#10510) by @0xrusowsky
- feat(forge vb): creation code from tx trace (#10751) by @grandizzy
- feat(
dependencies
): support pinning of tags / revs when using.gitmodules
withfoundry.lock
(#9522) by @yash-atreya - feat(forge): cheatcodes to crosschain sign and attach delegation (#10518) by @grandizzy
- feat(forge inspect): Add standard-json as inspect output field (#10537) by @2xic
- feat(script): keep script / tx timestamp as milis instead seconds (#10711) by @grandizzy
- feat(
forge
): run lint on forge build (#10748) by @yash-atreya - feat(forge): table tests (#10775) by @grandizzy
- feat: add useSeed cheatcode to set RNG seed (#10698) by @Another-DevX
- feat(forge):
--exclude-tests
option from coverage (#10807) by @grandizzy - feat(forge): coverage guided fuzzing & time based campaigns for invariant mode (#10190) by @0xalpharush
- feat(fmt): dprint for toml, json, md, dockerfile, ts, & yml (#10824) by @o-az
- feat(forge lint): disable lints with inline comment (#10776) by @0xrusowsky
- feat(cheatcodes): extend usable range in
assertApproxEqRel
(#10758) by @beeb - feat(forge-lint): [claude] unchecked calls (#10810) by @0xrusowsky
- feat(forge lint): unused imports (#10662) by @0xrusowsky
- feat(forge build): cache project selectors by default (#10651) by @mablr
- feat: added disable-code-size-limit flag in forge script (#10661) by @Soubhik-10
- feat: add mesc chainid lookup (#10927) by @mattsse
- feat(forge): support vyper contract verification in
forge verify-contract
(#10864) by @Another-DevX - feat(forge): apply fail_on_revert for fuzz tests too (#10941) by @grandizzy
- feat(forge): add support for repository-path in forge doc (#10879) by @nitininhouse
- feat: fuzzer metrics (#10988) by @0xalpharush
- feat(forge-lint): new
LateLintPass
+ support code snippets (#10846) by @0xrusowsky - feat(forge fmt): Adds tab support as indent char in fmt (#10979) by @mathewmeconry
- feat(cheats): add vm.getRawBlockHeader(blockNumber) (#11082) by @0xClandestine
Forge Fixes
- fix: fix formating crash caused by non-breaking space in comment. (#10522) by @l1nxy
- fix(forge): mark prank applied on contract creation too (#10532) by @grandizzy
- fix(forge): do not revert if event with count 0 not emitted (#10534) by @grandizzy
- fix(forge): vm.cool mark cold instead storage cleaning (#10546) by @grandizzy
- fix:
vm.chainId
regression in isolation mode onnightly
postrevm
bump (#10589) by @zerosnacks - fix: eip7702 cheatcodes multiple auth (#10623) by @zjesko
- fix: adds zksync, abstract to diff gas calc (#10539) by @dutterbutter
- fix(fmt): 'at' is not a keyword (#10556) by @DaniPopes
- fix(
forge bind
): addserde
as a dependency to generatedCargo.toml
ifSerde
is being derived in bindings (#10563) by @zerosnacks - forge(fix): update persistent storage from active db (#10576) by @grandizzy
- fix(forge lint): do not flag
fn test*
andfn invariant*
(#10607) by @0xrusowsky - feat(forge/script): decode execution traces when
--json
is enabled (#10109) by @0xpanoramix - fix(bindings): ensure forge bind generates snake_case file names (#10622) by @zarkk01
- fix(fmt): 'layout' is not a keyword (#10656) by @DaniPopes
- fix(forge lint): gas lints (#10667) by @0xrusowsky
- fix(forge): Ignore file access events to prevent rebuild loop (#10763) by @joeblogg801
- fix(
forge
): don't include lib in lint runs (#10771) by @yash-atreya - show native token symbol on tx broadcast (#10770) by @ahsan-javaiid
- fix: eip712, bind-json solar cleanups (#10789) by @DaniPopes
- fix(forge): vm.getChain use config for rpc and alias (#10806) by @grandizzy
- fix(forge): filter selectors if test contract is target (#10798) by @grandizzy
- fix: forge doc panic (#10901) by @zerosnacks
- fix: update block env after tx forking (#10963) by @mattsse
- fix(forge-lint): [unused imports] check path slice (#10985) by @0xrusowsky
- fix(forge-lint): [unused imports] check doc cmnts (inheritdoc) (#11003) by @0xrusowsky
- fix(
cheatcodes
): count0
swallows non-matching reverts (#10867) by @yash-atreya - fix(invariant): apply targetSelector and excludeSelector for test contract target (#11015) by @grandizzy
- fix(forge-lint): [unused-imports] manually walk override paths (#11020) by @0xrusowsky
- fix(
cheatcodes
): load pranked caller acc in state (#11023) by @yash-atreya - fix(forge-lint): [inline-config] use relative span positions (#11022) by @0xrusowsky
- fix: ensure account is always loaded and marked as touched when pranked (#11025) by @zerosnacks
- fix(forge): show git submodule status error (#11033) by @grandizzy
Performance improvements
- fix: spawn fork backendhandler on current tokio runtime (#10923) by @mattsse
- perf: find latest block for next-base-fee. replaces #10505 (#10511) by @naps62
- perf: improve InspectorStack (#11077) by @DaniPopes
Other
- fix(
Makefile
): updatelint-foundry
target to explicitly use nightly (#10526) by @mablr - Refactor: abstract global allocator in
foundry-cli
to be used across crates (#10523) by @mablr - fix(
common
): find target by path if present (#10538) by @yash-atreya - fix: patch solang-parser (#10509) by @DaniPopes
- bump(
revm
: step 1): bumprevm
to21.0.0
release (#10183) by @zerosnacks - bump(
revm
: step 2): bumpalloy
+revm
+alloy-evm
+ other deps to latest (#10454) by @yash-atreya - feat(foundry-cli::utils): add support for mimalloc and tracy-allocator (#10545) by @mablr
- fix(
revm bump
): re-addP256
precompile injection forforge
/cast
(#10555) by @zerosnacks - chore(cast): upgrade evmole to 0.8.0 (#10585) by @cdump
- chore(ens): replacing common::ens with the alloy_ens crate. (#10584) by @l1nxy
- Force
prevrandao
on Rootstock testnet (#10603) by @ahsan-javaiid - chore(lint): correct some spans (#10610) by @DaniPopes
- chore: use dedicated accountinfo type (#10617) by @mattsse
- chore(deps): bump revm to 24.0.0 (#10601) by @zerosnacks
- chore: standardize lint help + validate docs existance (#10639) by @0xrusowsky
- chore(wallets): improve error message for signer instantiation failure (#10646) by @mablr
- chore: replaced anvil hardforks with alloy hardforks (#10612) by @Rimeeeeee
- chore: Simplifing mined_logs_for_block filter (#10572) by @Ayushdubey86
- chore: replaced anvil DepositTransaction with just op_alloy::TxDeposit (#10480) by @Rimeeeeee
- chore: fixed dead link in
ui_runner.rs
(#10645) by @cypherpepe - chore: Add unused deps lint (#10666) by @nguyenethan01
- chore: activate
prague
hardfork and Solidity version0.8.30
as default (#10565) by @zerosnacks - chore: add license to preprocessor deploy helper (#10684) by @grandizzy
- chore: add additional check for is_impersonanted (#10701) by @mattsse
- feat: add some clippy lint (#10479) by @taikoonwang
- chore(
forge bind
): pin alloy to 1.0 + e2e test (#10724) by @yash-atreya - Update README.md (#10725) by @jenpaff
- chore: update proptest to 1.7.0 (#10733) by @grandizzy
- chore: remove announcement link in
nightly
as it is unmaintained (#10745) by @zerosnacks - fix: adds remaining ZKsync chains for estimate gas checks (#10719) by @dutterbutter
- refactor: unify ERC20 storage slot discovery logic (#10749) by @mattsse
- chore: gitignore CLAUDE instructions and settings (#10750) by @yash-atreya
- fix: pin action gh release to v2.2.2 (#10752) by @grandizzy
- chore(config): enable show_metrics by default in [invariant] section (#10737) by @0xChaddB
- chore: update nix flake (#10485) by @shaunkh
- bug(
nix
): fix build in CI (#10767) by @zerosnacks - deps: bump foundry-fork-db 0.15.1 (#10778) by @onbjerg
- chore: add hash to eip-712 cmd (#10764) by @0xrusowsky
- ci: don't check all features (#10790) by @DaniPopes
- chore: pin nextest version in ci (#10800) by @grandizzy
- chore: clean up unused EOF code (#10715) by @zerosnacks
- chore: bump vyper 0.4.3 and remove previous
prague
handling (#10808) by @zerosnacks - chore: use native alloy functions for otterscan helpers (#10816) by @mattsse
- chore: reuse alloy lenient blocknumber deserializer (#10817) by @mattsse
- chore: remove HexDisplay util (#10819) by @mattsse
- chore: remove unused util (#10818) by @mattsse
- test(cast): add tests for EIP-712 type names with colons (#10772) by @mattsse
- chore: use existing minimal_tx_type fn (#10826) by @mattsse
- refactor: flatten bind_json.rs to one pass without state structs (#10791) by @DaniPopes
- chore(forge-lint): clickable links + housekeeping (#10847) by @0xrusowsky
- Fix typos in test identifiers and improve timestamp assertions (#10851) by @leopardracer
- fix: replace broken JSON-RPC error code link with EIP-1474 reference (#10717) by @MozirDmitriy
- chore: simplify tx type conversion (#10862) by @mattsse
- cast: rm expect dependency_on_unit_never_type_fallback (#10872) by @jsvisa
- chore(deps): bump alloy-trie 0.9 (#10881) by @DaniPopes
- chore(cast wallet): get public key using Alloy's helper (#10883) by @mablr
- Add more unit tests to
cast call
(#10888) by @ryzhak - chore: add trace for contract_abi error (#10898) by @mattsse
- Fix typos in Anvil module comments, docs, and test names (#10889) by @MozirDmitriy
- fix(links): update foundry book links (#10899) by @sambacha
- chore: typos (#10908) by @DaniPopes
- chore: bump to rust edition 2024 (#10802) by @zerosnacks
- chore: ignore edition 2024 bump in .git-blame-ignore-revs (#10919) by @DaniPopes
- test: check before listening (#10920) by @mattsse
- chore: bump to MSRV 1.88 (#10921) by @DaniPopes
- Fix misleading doc comment for chisel_history_file function (#10928) by @GarmashAlex
- fix(docs): correct --unlocked flag documentation for RPC transaction signing (#10929) by @CreeptoGengar
- chore: more etherescan v1 cleanup (#10956) by @grandizzy
- chore: link rustdocs in README (#10971) by @yash-atreya
- feat(
foundryup
): avoid unnecessary downloads and verify hashes of downloaded binaries upon install (#10902) by @zerosnacks - feat: benchmark suite (#10804) by @yash-atreya
- docs: Clarify comments in ChiselRunner: fix incomplete and misleading docstrings (#10931) by @GarmashAlex
- chore(deps): bump to revm 27.0.3 (#10838) by @zerosnacks
- chore: relax tracer bounds (#11024) by @mattsse
- chore: remove manual usage of solar SessionGlobals (#10980) by @DaniPopes
- docs: Fix dead links across the codebase (#11012) by @vtjl10
- chore: return reorged blocks (#11026) by @mattsse
- fix(cheatcodes): remove redundant computation in validate_private_key… (#10993) by @reject-i
- docs(lintrules): reflect latest impl changes (#11031) by @0xrusowsky
Full Changelog:
https://github.com/foundry-rs/foundry/compare/v1.2.3...v1.3.0-rc2
Previous Releases
Version | Release Date | Release Notes |
---|---|---|
v1.3.0-rc1 | July 17, 2025 | View |
v1.2.3 | June 8, 2025 | View |
v1.2.2 | May 30, 2025 | View |
v1.2.1-rc | May 21, 2025 | View |
v1.2.1 | May 26, 2025 | View |
v1.2.0-rc1 | May 19, 2025 | View |
v1.2.0-rc | May 13, 2025 | View |
v1.2.0 | May 19, 2025 | View |
v1.1.0 | April 28, 2025 | View |
v1.0.0 | February 10, 2025 | View |
This page is automatically updated with the latest release information from the Foundry GitHub repository.