Foundry v1.0 migration guide

Several breaking changes were introduced in Foundry v1.0 version, which could require updates on projects using older versions. This guide documents the suggested best practices when migrating from an older version.

Solc optimizer disabled by default

Enabling optimizer by default could introduce bugs for seemingly correct code (if there are bugs in optimizer itself) - see #2486. Foundry v1.0 default settings could affect current projects by reporting higher contract sizes and / or project build failures. It is recommended to explicitly enable optimizer and their runs in foundry.toml configuration:

optimizer = true
optimizer_runs = 200

See: optimizer configuration

Expect revert cheatcode disabled on internal calls by default

When testing internal functions with vm.expectRevert cheatcode at the same call depth only the first vm.expectRevert is executed - see #3437. In Foundry v1.0 default settings this behavior is disabled by default. This could affect current projects by reporting test failures as [FAIL: call didn't revert at a lower depth than cheatcode call depth]. It is recommended to review these failing tests and either enable revert on internal calls or rewrite tests to avoid this.
For example, a test like the one below:

contract ContractTest is Test {
    error CustomError();

    function revertWithCustomError() internal {
        revert CustomError();
    }

    function testExample() public {
        vm.expectRevert();
        revertWithCustomError();
    }
}

can be changed to use a mock CustomContract that expose a public function:

contract CustomContract {
    error CustomError();

    function revertWithCustomError() external {
        revert CustomError();
    }
}

contract ContractTest is Test {
    CustomContract internal c;

    function setUp() public {
        c = new CustomContract();
    }

    function testExample() public {
        vm.expectRevert();
        c.revertWithCustomError();
    }
}

or configured to allow expect reverts:

    /// forge-config: default.allow_internal_expect_revert = true
    function testExample() public {
        vm.expectRevert();
        revertWithCustomError();
    }

See: vm.expectRevert cheatcode

Removed support for testFail tests

The testFail test prefix support is removed in Foundry v1.0 in order to prevent confusion - see #4437. This could affect existing projects by reporting test failures where they’re not expected. Existing testFail tests can be migrated for v1.0 by using vm.expectRevert() cheatcode or by using a try/catch approach and assert the failure.
For example, a test like the one below:

function testFail_IncrementAsNotOwner() public {
    vm.prank(address(0));
    upOnly.increment();
}

can be rewritten as

function test_RevertWhen_CallerIsNotOwner() public {
    vm.expectRevert(Unauthorized.selector);
    vm.prank(address(0));
    upOnly.increment();
}

Removed support for legacy console.sol signatures

Foundry v1.0 removes the support for console.sol selectors that use the faulty ABI encoding - see #8910. This could affect existing projects by producing test build failures, therefore they needs to be update accordingly. For example:

console.log("testMisc", 42);
console.log(0);

should be rewritten as

console.log("testMisc", uint256(42));
console.log(uint256(0));

Conflicting remappings are ignored

Prior Foundry v1.0, forge inferred remappings by taking into account remappings of sub-projects. When conflicting remappings were present, the longest / most specified had the priority. This was dangerous, as adding sub-projects were able to completely change the code that is executed, even if the remappings of the root project are not changed - see #8910. With v1.0, a project will fail to build if the same remapping

@openzeppelin/=lib/openzeppelin-contracts/contracts/

is defined in both root project and in an imported dependency. To fix it, the project root remapping should be added in src context:

src:@openzeppelin/=lib/openzeppelin-contracts/contracts/

Artifacts not persisted on forge coverage

In prior versions, forge coverage was changing the artifacts (which are unoptimized in order to provide accurate source hit maps) without any warnings. This was confusing and was leading to undesired situations like the one in #8840 comment. Foundry v1.0 does not generate artifacts when running coverage anymore hence projects should be aware of the change.

Other

  • FORGE_SNAPSHOT_CHECK requires boolean value. Use FORGE_SNAPSHOT_CHECK=true|false.
  • forge inspect --pretty flag was removed. Use forge inspect for table view.
  • forge bind --ethers was removed. Use forge bind (defaults to alloy).
  • forge debug subcommand was removed. Use forge test --debug and forge script --debug.
  • cast etherscan-source subcommand was replaced with cast source. Use additional explorer_url and explorer_api_url args for alternative block explorers.
  • foundryup installs stable if no version specified. Use foundryup -i nightly to install nightly versions.