-
Notifications
You must be signed in to change notification settings - Fork 30
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
Invariant decorator option to revert state changes to the blockchain #266
base: main
Are you sure you want to change the base?
Conversation
…checking an invariant.
… after checking an invariant.
Hey @khegeman , thank for the Pr!
|
ok. I also think it should be False by default, but I didn't want to introduce a breaking change for any existing tests so I defaulted to the existing behavior. |
Rename the option to commit_changes.
Hey @khegeman, thank you for this pull request! I agree with the comments from @hacker-DOM with the only exception that If we decide to go with the default |
I am still learning woke. Found this decorator in the docs today for snapshot and revert, adding this to an invariant does the same thing as my code change. In further testing, I have noticed some unexpected side effects of using snapshot / revert with invariants, for instance tx_callback triggers for the invariant tx. In addition, I believe there are some issues with block.timestamp and anvil when using the snapshot /revert. I was noticing that inside my flows I was seeing that block.timestamp for flow n + 1 <= block.timestamp for flow n . This is with both my proposed change and with the decorator. Both exhibit the same behaviors.
A better solution for some of my invariants was to use a gas estimate, something like this:
This will revert if it's not possible to execute withdraw and cause the invariant to fail. But does not commit changes to the block. In conclusion, you might not want to merge this change. |
Yes, this decorator already exists and can also be used as a context manager: with default_chain.snapshot_and_revert():
tx = foo.bar() Still, adding an easier way to revert all chain changes caused by transactions in an invariant may be reasonable. Regarding the issue with timestamps, you are right. It seems that Anvil does not increase the timestamp of the next block right after a snapshot revert. I think this can be considered an issue in Anvil, I will communicate it with the Foundry team. You may try |
When developing stateful fuzz tests, I have had a few scenarios where I want to run a transaction to check that a condition holds, but I do not want that change commit those changes to the blockchain.
Here is an example of how I use this change in practice to verify that a user is able to can withdraw funds after a flow occurs, this should always be possible and I use the invariant to verify that.