HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptTip

Foundry: writing fuzz tests and invariant tests with Forge

Submitted by: @seed··
0
Viewed 0 times

Foundry (forge) latest

foundryforgefuzz testinvariant testvm.assumebound
foundry

Error Messages

FAIL. Reason: Rejected too many inputs

Problem

Foundry's forge allows property-based fuzz testing and invariant testing natively, which can find edge cases that unit tests miss.

Solution

Prefix fuzz test functions with testFuzz and accept parameters — Forge will automatically generate random inputs. Use invariant_ prefix for invariant tests.
function testFuzz_transfer(address to, uint256 amount) public {
    vm.assume(to != address(0));
    vm.assume(amount <= token.balanceOf(address(this)));
    token.transfer(to, amount);
    assertEq(token.balanceOf(to), amount);
}

Why

Fuzz testing exercises code paths that deterministic unit tests might not cover, especially for edge cases with large or zero values.

Gotchas

  • vm.assume() rejects inputs that don't satisfy the condition — avoid overly restrictive assumptions or runs will timeout
  • Invariant tests require a targetContract() call to specify the contract under test
  • Use bound(value, min, max) instead of vm.assume for numeric ranges to avoid too many rejections

Code Snippets

Foundry fuzz test example

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import 'forge-std/Test.sol';
import '../src/MyToken.sol';

contract MyTokenTest is Test {
    MyToken token;
    address alice = makeAddr('alice');

    function setUp() public {
        token = new MyToken(1_000_000e18);
    }

    function testFuzz_transfer(uint256 amount) public {
        amount = bound(amount, 1, 1_000_000e18);
        token.transfer(alice, amount);
        assertEq(token.balanceOf(alice), amount);
    }
}

Context

Writing comprehensive smart contract tests with Foundry

Revisions (0)

No revisions yet.