-
Notifications
You must be signed in to change notification settings - Fork 11.8k
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
Add FV specification for ERC20Wrapper #4100
Conversation
🦋 Changeset detectedLatest commit: 0c57f1b The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
import "helpers.spec" | ||
import "ERC20.spec" | ||
|
||
methods { |
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.
When we specify an invariant
, is it only checked for the methods listed in this block? What happens if we add a new function in the Solidity code and we don't add it here?
I just noticed this in the docs and I find it concerning!
It is possible for a method signature to appear in the methods block but not in the contract being verified. In this case, the Prover will skip any rules that mention the missing method, rather than reporting an error.
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.
AFAIK:
- The invariant (and arbitrary methods) will check all functions in the contract's ABI, even if not here.
- Putting them here allow to mark them envfree, of set a summarize policy
- If a rule does a test on a function declared here, its absence from the contract will not break things and the tests will just be ignored.
certora/specs/ERC20Wrapper.spec
Outdated
{ | ||
preserved { | ||
requireInvariant totalSupplyIsSumOfBalances; | ||
require underlyingBalanceOf(currentContract) <= underlyingTotalSupply(); |
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.
Can't we write:
require underlyingBalanceOf(currentContract) <= underlyingTotalSupply(); | |
requireInvariant totalSupplyIsSmallerThanUnderlyingBalance; |
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.
since we are in the definition of totalSupplyIsSmallerThanUnderlyingBalance
that would be saying totalSupplyIsSmallerThanUnderlyingBalance
holds assuming totalSupplyIsSmallerThanUnderlyingBalance
. I hope the prover will reject that. It a bit like using a variable inside its own declaration.
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.
we could do
sumOfUnderlyingBalancesLowerThanUnderlyingSupply(currentContract, 0);
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.
It a bit like using a variable inside its own declaration.
No, that is not the case according to the docs on invariants. The preserve
block is included as a precondition, so by using a "recursive" requireInvariant
in its own preserve block, we're just stating that this is an inductive property.
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.
Isn't the whole point of an invariant that its a precondition of itself?
- [instace] we test that its holds a construction
- [preserve] assuming it holds, execute any function and check that it still holds.
I don't understand what requiring it adds, since its already assumed to hold before the function call
Certora specs for the ERC20 wrapper, rewritten almost from scratch