-
Notifications
You must be signed in to change notification settings - Fork 4
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
[Certora] Check allowance to untrusted contracts are reset #217
Conversation
Note: I haven't managed to write a spec for Compound versions 2 and 3 migration adapters as it seems that we need concrete implementations that are able to resolve the underlying ERC20 contracts. Namely, in this line https://github.com/morpho-org/bundler-v3/blob/a3a2d6ccf3002bde2a654bd20a76accf40985642/certora/specs/CompoundV2Approvals.spec#L12, we do not have an implementation for a |
The Paraswap adatper verification doesn't go through since the summary in https://github.com/morpho-org/bundler-v3/blob/a3a2d6ccf3002bde2a654bd20a76accf40985642/certora/specs/ParaswapApprovals.spec#L8 doesn't seem to resolve the call to |
Signed-off-by: Colin | Morpho 🦋 <[email protected]>
I think it's completely fine to use the |
I agree that it's not sound, and probably too big of an over-approximation. This is because it makes so the call to the augustus is not changing the state, but this call is central to the adapter
We could try an intermediate solution, and add the view functions to the dispatch list. This way the call to the augustus is HAVOC_ECF and the view functions can be NONDET |
@QGarchery I think this what I did here d74106b#diff-4a5172dbceb3687fac0c19042e758db96ebfe6166c9649e2429f508ed2caf6a1R8, or am I missing something? |
Sorry @QGarchery , I wasn't completely clear. To able to use Compiling test/helpers/mocks/ERC20Mock.sol to expose internal function information and local variables...
ERROR: Failed to run Certora Prover locally. Please check the errors below for problems in the specifications (.spec files) or the prover_args defined in the .conf file.
CRITICAL: [main] ERROR ALWAYS - Found errors in certora/specs/CompoundV2Approvals.spec:
CRITICAL: [main] ERROR ALWAYS - Error in spec file (CompoundV2Approvals.spec:12:12): Did not find any contract functions that match the given name and arguments
CVL specification syntax and type check failed |
Oh right, yes you need it because you call it in the spec. Then I guess you could have a summary that depends on the |
Sorry, I don't understand why it should depend on |
It's wrong, it should not depend on e.msg.sender (I was thinking that |
I've tried this in aa18540 it looks like it's working. Only the Paraswap case is missing now! |
Note that we never allow WETH, actually And that we don't reset the allowance for the MORPHO wrapper as well |
) { | ||
require augustus != currentContract; | ||
currentContract.buy(e, augustus, callData, srcToken, destToken, newDestAmount, offsets, receiver); | ||
assert srcToken.allowance(e, currentContract, augustus) == 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.
Could we also check that there is no allowance given for the destToken ? It should hold as well, because allowances are not changed for this token. See this related thread
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.
@QGarchery should I still do this or not?
// Check that the pools's allowance is set to zero for the adapter. | ||
rule aaveV2RepayAllowanceNull(env e, address token, uint256 amount, uint256 interestRateMode, address onBehalf) { | ||
aaveV2Repay(e, token, amount, interestRateMode, onBehalf); | ||
assert token.allowance(e, currentContract, currentContract.AAVE_V2_POOL) == 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.
here, we could have messed up the token for which we are doing the verif, and actually have an error. We could have checked that for a given address, if there was a call to approve, the last one was with amount=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.
On a second thought, I'm not completely convinced of specifying things like this. I don't find it nice to read because you can't convince yourself that the approve 0 has been done on the token of interest. Also, a malicious token could make a dummy approve 0 and internally not change the allowance, here we actually check the allowance.
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.
I've pushed an alternative (much simpler specification) see #238, let me know which one you prefer.
Replaced by #238 |
This PR checks that allowances to untrusted contract are reset.
A malicious ERC20 called within a bundle could steal tokens within some transactions, for this reason we wish to check that that untrusted contracts are allowed only during the execution of some calls before resetting the allowance to zero.
We check this only for untrusted contracts (Morpho, WETH, ST_ETH) by checking that the allowance equals zero for approved untrusted contracts on entrypoints of interest.
Please ensure that: