Releases: foundry-rs/foundry
v1.3.0-rc3
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.
foundryup
, which avoids unnecessary downloads and verifies hashes of downloaded binaries upon install. You can update your installation by running: foundryup --update
.
Performance Improvements
- This release includes an updated
revm
(#11079) and an optimized inspector stack (#11077 #11100), which enhances Forge test performance by up to 21.50% 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 (#10496 #10838), 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 (#10405) 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
(#10190).
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 (#10190).
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.
Supported mutations:
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 (#10775), 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 (#10510).
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
- fix: use existing functions for accountinfo (#11134) by @mattsse
- fix(anvil): unwrap panic in eth/backend/mem/mod.rs (#11141) by @zerosnacks
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 (#106...
Nightly (2025-07-29)
Cast Fixes
- fix(
cast
): unknown signatures are cached as an empty string (#11127) by @zerosnacks
Forge Features
- feat(
cheatcodes
): decode and show mismatched params on expectEmit (#11098) by @yash-atreya
Other
- feat(forge): "add" alias for install subcommand (#11124) by @mablr
- chore: update package.homepage (#11131) by @DaniPopes
- fix: use existing functions for accountinfo (#11134) by @mattsse
- fix: tracy integration (#11135) by @DaniPopes
Full Changelog:
Nightly (2025-07-30)
Other
- Revert "fix(
cast
): unknown signatures are cached as an empty string" (#11140) by @zerosnacks - fix(
anvil
): unwrap panic ineth/backend/mem/mod.rs
(#11141) by @zerosnacks
Full Changelog:
Nightly
Other
- Revert "fix(
cast
): unknown signatures are cached as an empty string" (#11140) by @zerosnacks - fix(
anvil
): unwrap panic ineth/backend/mem/mod.rs
(#11141) by @zerosnacks
Full Changelog:
Nightly (2025-07-28)
Other
Full Changelog:
Nightly (2025-07-27)
Other
- chore: more StackInspector cleanups (#11105) by @DaniPopes
- chore(deps): weekly
cargo update
(#11115) by @github-actions[bot]
Full Changelog:
Nightly (2025-07-26)
Other
- Remove the --froms flag (#11099) by @CodeSandwich
- feat(forge-lint): [claude] check for unwrapped modifiers (#10967) by @0xClandestine
- perf: box inspectors in InspectorStack (#11100) by @DaniPopes
- feat(anvil): added js tracer (#11052) by @Soubhik-10
Full Changelog:
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.
foundryup
, which avoids unnecessary downloads and verifies hashes of downloaded binaries upon install. You can update your installation by running: foundryup --update
.
Performance Improvements
- This release includes an updated
revm
and an optimized inspector stack, which enhances Forge test performance by up to 21.50% 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.
Supported mutations:
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...
Nightly (2025-07-24)
Nightly (2025-07-25)
Other
- fix(
benches
): forge build benches (#11036) by @yash-atreya - chore: use alloy-evm::apply_state_overrides (#11083) by @Soubhik-10
- fix: doc comment for set_code method in Db trait (#11087) by @Galoretka
- chore(
benches
): latest benches (#11086) by @yash-atreya - fix(
forge script
): remove misleading$ETH_FROM
(#11088) by @zerosnacks - fix(cast): use all providers if local artifacts used (#11090) by @grandizzy