-
Notifications
You must be signed in to change notification settings - Fork 2.2k
feat(invariant): support fuzz with random msg.value #8644
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
base: master
Are you sure you want to change the base?
Conversation
CC @grandizzy @mds1 |
thanks for your PR! Generally this is recommended #8449 but will consider making it automatically (I think we want this only if fuzzed function is payable) |
Thanks for the info, handlers can help! If people don't use handlers, It would be nice if foundry could do that automatically. Yeah, we will use random values only for payable target functions. |
Hi @DaniPopes @mattsse , could you help review this PR? |
// Execute call from the randomly generated sequence without committing state. | ||
// State is committed only if call is not a magic assume. | ||
let mut call_result = current_run | ||
if current_run.executor.get_balance(tx.sender)? < tx.value { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@QiuhaoLi I am looking into integrate this approach but I am not sure we should inflate sender's balance with the fuzzed value (nor restore the balance after the call) as it could result in false positives like in forked tests / transfers, etc. Instead we could bound it in (0, current sender balance) but even so for long running campaigns the balance could get spent quickly and then the fuzzed calls will be performed with call value U256::ZERO
@0xalpharush any thoughts re how to deal with this scenario? thank you!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are the senders always the same pool of "test" addresses? If the tx.sender
is the pranked value here and not the original, it may cause issues. But if it's from the pool, I think it should be fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
makes sense, can keep a track of those addresses
Motivation
Currently, the foundry's invariant fuzz testing doesn't support txs with value > 0, which makes it unable to find sequences in some situations. For example, the Pay contract below will only set the
hacked
variable if the calls areC() --> B() --> A()
with2, msg.value>0.11 ether, 0
, but foundry can't generate such calls.Solution
When generating a tx, we set the
msg.value
as a random number (uint96) if the target function is payable. After applying this strategy, foundry can find the sequence quickly: