Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

condition not caught by invariant/fuzzer #2851

Closed
2 tasks
mattsse opened this issue Aug 19, 2022 · 10 comments
Closed
2 tasks

condition not caught by invariant/fuzzer #2851

mattsse opened this issue Aug 19, 2022 · 10 comments
Labels
A-testing Area: testing C-forge Command: forge Cmd-forge-test Command: forge test T-bug Type: bug

Comments

@mattsse
Copy link
Member

mattsse commented Aug 19, 2022

Component

Forge

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

  • Foundry
  • Foundryup

What version of Foundry are you on?

No response

What command(s) is the bug in?

No response

Operating System

No response

Describe the bug

telegram-cloud-photo-size-2-5188374473173220884-y

@mattsse mattsse added the T-bug Type: bug label Aug 19, 2022
@gakonst gakonst added this to Foundry Aug 19, 2022
@gakonst gakonst moved this to Todo in Foundry Aug 19, 2022
@joshieDo
Copy link
Collaborator

joshieDo commented Aug 19, 2022

I'm not sure invariant testing is the best for this kind of scenario. We have x on the dictionary, but we need x+1, so we're stuck on somehow getting x+1 in the middle of the uint256 space.

Also, does normal fuzzing even reach number = 0 ?

--

If we wanted to reach this, we could probably come up with a strategy that adds x - n, x + n to the dictionary... but that seems too niche.

@rkrasiuk rkrasiuk added A-testing Area: testing C-forge Command: forge labels Aug 19, 2022
@mds1
Copy link
Collaborator

mds1 commented Aug 19, 2022

Just curious, where is this example from? I'm inclined to say we shouldn't worry too much about trying to tune the fuzzer to find this particular example—it's a bit contrived and I haven't seen much solidity code with similar logic, so you could argue it's is more of an academic issue than a practical issue.

I think a more worthwhile (but also bigger) effort is ensuring foundry can match echidna's performance, which we haven't demonstrated yet. The echidna readme has a "Trophies" section showing real issues it's found, and a "Research" section reproducing examples from papers. Some of those research examples are similar to the above, but I think simpler in that there's not the - 1 and therefore collecting PUSH bytes should solve it.

All of the echidna test cases (excluding "trophies", including "research" and other tests) can be found here: https://github.com/crytic/echidna/tree/master/tests/solidity

It would be great if we setup all of those test cases as part of foundry CI and make sure fuzz/invariant tests can reliably catch those

@mattsse
Copy link
Member Author

mattsse commented Aug 19, 2022

@gakonst can probably provide some context and the expectations here

@onbjerg
Copy link
Member

onbjerg commented Aug 19, 2022

Imo this kind of test case is what symbolic execution is more geared for. The kind of fuzzer we have is borderline a blackbox fuzzer, so it's essentially just bruteforcing its way there. We have a dictionary as well but the chance of hitting that particular number is still very low.

@grandizzy
Copy link
Collaborator

Awesome write-up analysing this issue here https://hackmd.io/@SaferMaker/EVM-Sym-Exec

@brockelmore
Copy link
Member

Screenshot 2024-06-06 at 10 35 16 AM

By the way this is caught by the fuzzer now. should probably close this

@grandizzy
Copy link
Collaborator

Screenshot 2024-06-06 at 10 35 16 AM

By the way this is caught by the fuzzer now. should probably close this

Awesome! Do you have the test handy to share, would love to have it as a regression test. Also planning to create a benchmark project (smth similar with https://github.com/grandizzy/fuzz-benchmarks/) and run daily checks. thank you!

@brockelmore
Copy link
Member

// SPDX-License-Identifier: MIT OR Apache-2.0
import "forge-std/Test.sol";
pragma solidity ^0.8.1;

contract Backdoor {
    uint public number = 1;
    function backdoor(uint256 newNumber) payable public {
        uint x = newNumber - 1;
        if (x == 6912213124124531) {
            number = 0;
        }
    }
}

contract BackdoorTest is Test {
    Backdoor back;

    function setUp() public {
        back = new Backdoor();
    }


    function invariantNotZero() public {
        assertEq(back.number(), 1);
    }
}

@grandizzy
Copy link
Collaborator

thank you! confirm it is caught with fuzzer default settings 🎉

@brockelmore
Copy link
Member

Closing

grandizzy added a commit that referenced this issue Jun 7, 2024
chore: add test for 2851
@jenpaff jenpaff moved this from Todo to Completed in Foundry Sep 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-testing Area: testing C-forge Command: forge Cmd-forge-test Command: forge test T-bug Type: bug
Projects
Archived in project
Development

No branches or pull requests

7 participants