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

Optimize fuzzer value generation to prevent duplicate values and improve coverage #4397

Closed
wirew0lf opened this issue Feb 20, 2023 · 3 comments
Labels
T-feature Type: feature

Comments

@wirew0lf
Copy link

Component

Forge

Describe the feature you would like

After doing some testing with the basic fuzzer I've found out the fuzzer generates lots of duplicate values.

In order to test this I created the following test which generates a .csv file with both forge fuzzer ouput and bound function ouput:

function testGenerateUint(uint a) public {
  uint b = bound(a, 0, 1_000_000*10e18);
  
  string memory path = "./results/FuzzUintGenerationResults.csv"; 
  string memory line = string.concat(string.concat(vm.toString(a), ","), vm.toString(b));
  vm.writeLine(path, line);
}

Then post-processed this information and this are the results:
image

Out of 256 runs, 101 of them are duplicate runs with a value already tested, I've also tried with other type of value such as bytes32 and obtained similar results.

For example, the max value of uint256 was run 33 times, althoughI believe the number of duplicate runs may decrease in functions with more than one parameter. Focusing on numbers near 0 and near the max value for uint256 might be useful to trigger edge cases however, the fuzzer is not generating much values in mid ranges. Also, given that most deApps use 18 decimals I think it would be better to focus more on generating values in a range of for example, between 1e17 and 100_000_000e18.

I think a better approach could be:

  • 20% of values generated should be values near 0 and max uint256 including both, to trigger edge cases.
  • 60% of values between 1e17 and 1e25.
  • The remaining 20% throughout the whole uint256 range.

I could also prepare a pull request if any of the more senior contributors agrees this should be addressed.

Additional context

No response

@wirew0lf wirew0lf added the T-feature Type: feature label Feb 20, 2023
@gakonst gakonst added this to Foundry Feb 20, 2023
@github-project-automation github-project-automation bot moved this to Todo in Foundry Feb 20, 2023
@wirew0lf wirew0lf changed the title https://github.com/foundry-rs/forge-std/issues/304 Fuzzer generates duplicate values Feb 20, 2023
@wirew0lf wirew0lf changed the title Fuzzer generates duplicate values Optimize fuzzer value generation to prevent duplicate values Feb 20, 2023
@wirew0lf wirew0lf changed the title Optimize fuzzer value generation to prevent duplicate values Optimize fuzzer value generation to prevent duplicate values and improve coverage Feb 20, 2023
@KholdStare
Copy link
Contributor

Did not know that this was the case. Perhaps the random generation is biased (which it should be), but each draw is independent (it shouldn't be). Probably need some state per fuzzed input to know whether an extreme value was already tried.

How does the "OG" Quickcheck from Haskell draw random values?

@mds1
Copy link
Collaborator

mds1 commented Apr 21, 2023

IIRC the cause is due to the fact that the edge bias strategy is chosen too frequently relative to the number of values the edge bias strategy can actually generate. More info in #3521 with my proposed fix in #3521 (comment)

Draws are independent like you said, changing that is also a possible solution but requires tracking more data which increases memory usage and incurs a performance penalty, especially as number of fuzz runs grows, which is why my proposed solution avoids that by leveraging the dictionary

@wirew0lf
Copy link
Author

I'm closing the issue, let's keep the discussion on #3521

@github-project-automation github-project-automation bot moved this from Todo to Done in Foundry Apr 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-feature Type: feature
Projects
Archived in project
Development

No branches or pull requests

3 participants