foundry-rs / foundry

Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.
https://getfoundry.sh
Apache License 2.0
7.88k stars 1.58k forks source link

Invalid Enum value when fuzzing #6623

Open ScreamingHawk opened 6 months ago

ScreamingHawk commented 6 months ago

Component

Forge

Have you ensured that all of these are up to date?

What version of Foundry are you on?

forge 0.2.0 (73fb616 2023-12-19T00:16:21.131413571Z)

What command(s) is the bug in?

forge test

Operating System

Windows

Describe the bug

When fuzzing an array of enums, forge supplies a value out of range.

Example:

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

import "forge-std/Test.sol";

contract ForgeFail is Test {

    enum EnumVal {
        VAL_0,
        VAL_1,
        VAL_2
    }

    function testForgeFail(EnumVal[] memory vals) external {
      // No content. Still fails
    }
}

Output:

Running 1 test for test/ForgeFail.t.sol:ForgeFail
[FAIL. Reason: EvmError: Revert; counterexample: calldata=0x98a2e150000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003 args=[[3]]] testForgeFail(uint8[]) (runs: 2, μ: 647, ~: 647)
Traces:
  [643] ForgeFail::testForgeFail([3])
    └─ ← EvmError: Revert

Test result: FAILED. 0 passed; 1 failed; 0 skipped; finished in 5.63ms

Ran 1 test suites: 0 tests passed, 1 failed, 0 skipped (1 total tests)

Failing tests:
Encountered 1 failing test in test/sample/endorser/ForgeFail.t.sol:ForgeFail
[FAIL. Reason: EvmError: Revert; counterexample: calldata=0x98a2e150000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003 args=[[3]]] testForgeFail(uint8[]) (runs: 2, μ: 647, ~: 647)

Encountered a total of 1 failing tests, 0 tests succeeded

The argument 3 is outside the bounds of EnumVal.

Note: I am running forge on WSL.

mds1 commented 6 months ago

Solidity's output does not return the max length of the enum, so the fuzzer can't know the max value to use. As a workaround for now you should pass a uint8, bound it, then cast to your enum. See https://github.com/foundry-rs/foundry/issues/871 for more info

I'll leave this issue open as the tracking issue better enum support as discussed in #871

Hotmanics commented 3 months ago

Solidity's output does not return the max length of the enum, so the fuzzer can't know the max value to use. As a workaround for now you should pass a uint8, bound it, then cast to your enum. See #871 for more info

I'll leave this issue open as the tracking issue better enum support as discussed in #871

What if the fuzz test has a struct parameter containing an enum? See my comment on #871 for more clarity to the problem.