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
8.34k stars 1.77k forks source link

Invalid Enum value when fuzzing #6623

Open ScreamingHawk opened 11 months ago

ScreamingHawk commented 11 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 11 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

JacobHomanics commented 8 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.