foundry icon indicating copy to clipboard operation
foundry copied to clipboard

False negatives in property-based tests

Open pcaversaccio opened this issue 2 years ago • 6 comments

Component

Forge

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

  • [X] Foundry
  • [X] Foundryup

What version of Foundry are you on?

forge 0.2.0 (b454567 2023-02-06T00:29:35.2383332Z)

What command(s) is the bug in?

forge test

Operating System

Linux

Describe the bug

I realised that within a forge test run, sometimes addresses are fuzzed which are very unfortunate choices and it's getting complicated to always assume the right params. In order to reproduce what I exactly mean, let's have a look at the following run: https://github.com/pcaversaccio/snekmate/actions/runs/4134068222/jobs/7144742870

This one fails with the following error:

[FAIL. Reason: Call did not revert as expected Counterexample: calldata=0xa32994070000000000000000000000002e234dae75c793f67a35089c9d99245e1c58470b00000000000000000000000000000000000000000000000000000000000041600000000000000000000000000000000000000000000000000000000000001e190000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000009c9, args=[0x2e234DAe75C793f67A35089C9d99245E1C58470b, 0x0000000000000000000000000000000000004160, 0x0000000000000000000000000000000000001e19, 0x00000000000000000000000000000000000000000000000000000000000009c9]] testFuzzSafeTransferFromWithData(address,address,address,bytes) (runs: 58, μ: 1456762, ~: 1457262)

So the problem here is the input address 0x2e234DAe75C793f67A35089C9d99245E1C58470b is unfortunately the same as the erc721ReceiverMock I create in the test:

ERC721ReceiverMock erc721ReceiverMock = new ERC721ReceiverMock(
    receiverMagicValue,
    ERC721ReceiverMock.Error.None
);

After re-running the test everything passes as intended: https://github.com/pcaversaccio/snekmate/actions/runs/4134068222.

Also, I started using things like the following since sometimes it fuzzes also the test contracts etc.:

vm.assume(account.code.length == 0);

My question I would like to discuss is, whether other face similar problems & what can be done to fine-tune it. For instance, having a sort of modifier that ensures that any fuzzed addresses within a test function should not equal any created contract addresses within the test function would already help a lot.

pcaversaccio avatar Feb 09 '23 17:02 pcaversaccio

Came across this issue, by deafault I've seen foundry tends to use addresses of contracts defined in the setUp() function as msg.sender in invariant testing. As a workaround I've been excluding them with the excludeSender() function.

wirew0lf avatar Mar 27 '23 18:03 wirew0lf

+1 on this issue.

alexroan avatar Apr 18 '23 09:04 alexroan

For the sake of history, our recent Twitter discussion about this issue (check the different threads).

pcaversaccio avatar Apr 18 '23 16:04 pcaversaccio

@pcaversaccio there is a fix in that could help https://github.com/foundry-rs/foundry/pull/7595 basically if you use targetContract and targetSender to mark the contract to be fuzzed / sender's, there should be no exception from. Would that help in your scenario above? Thank you!

grandizzy avatar Apr 29 '24 12:04 grandizzy

@pcaversaccio there is a fix in that could help #7595 basically if you use targetContract and targetSender to mark the contract to be fuzzed / sender's, there should be no exception from. Would that help in your scenario above? Thank you!

Yup, that helps indeed. I recently get a lot of CreateCollision collisions in my tests (example CI: https://github.com/pcaversaccio/createx/actions/runs/8869059876/job/24349330795#step:16:257)

image

Any Idea how to prevent this in a smart way (usually rerunning fixes it, but it's annoying tbh)

pcaversaccio avatar Apr 29 '24 12:04 pcaversaccio

yeah, is same issue with failures described in https://github.com/foundry-rs/foundry/issues/7497#issuecomment-2082643806 I managed to reproduce locally by creating a failures file with the counterexample from GH action log you pointed (that is containing single line cc ce87454cc0ca562369e13d0e7219ae6deb1133b8d919db8f5b058f670f243f93), will make a fix for forge clean

grandizzy avatar Apr 29 '24 14:04 grandizzy

@pcaversaccio can this one be closed now?

grandizzy avatar May 22 '24 06:05 grandizzy

Yes.

pcaversaccio avatar May 22 '24 07:05 pcaversaccio