Skip to content

deal() performance #674

@frontier159

Description

@frontier159

I've noticed the performance of StdCheats::deal() is orders of magnitude slower than if there were a mint function directly on the ERC20.

This is particularly exposed within invariant tests which had a large speedup after I updated mock tokens to add a direct mint() function on it. This wouldn't always be possible however, I think it could be a good hunting ground for performance for various projects.

Example fuzz test below:

pragma solidity ^0.8.19;
// SPDX-License-Identifier: UNLICENSED

import {Test} from "forge-std/Test.sol";
import {MockERC20} from "forge-std/mocks/MockERC20.sol";

contract MintableERC20 is MockERC20 {   
    function mint(address to, uint256 amount) external {
        _mint(to, amount);
    }
}

contract DealPerformanceTest is Test {
    MintableERC20 internal token;

    function setUp() public {
        token = new MintableERC20();
        token.initialize("TOKEN", "TOKEN", 18);
    }

    /// forge-config: default.fuzz.runs = 100000
    function test_mint(address to, uint256 amount) public {
        token.mint(to, amount);
    }

    /// forge-config: default.fuzz.runs = 100000
    function test_deal(address to, uint256 amount) public {
        deal(address(token), to, amount, true);
    }
}
Ran 1 test for test/foundry/unit/DealPerformance.t.sol:DealPerformanceTest
[PASS] test_deal(address,uint256) (runs: 100000, μ: 297655, ~: 297734)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 47.83s (47.82s CPU time)

Ran 1 test for test/foundry/unit/DealPerformance.t.sol:DealPerformanceTest
[PASS] test_mint(address,uint256) (runs: 100000, μ: 51723, ~: 52197)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 2.23s (2.22s CPU time)

So mint is > 20x faster

$ forge --version
forge Version: 1.0.0-nightly
Commit SHA: 8da73730b4033553589aa67ef404e527149c2e92
Build Timestamp: 2025-04-02T06:02:24.621284000Z (1743573744)
Build Profile: maxperf

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions