-
Notifications
You must be signed in to change notification settings - Fork 587
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
Imprecision on liquidity index calculation due to reserve.accruedToTreasury
#730
Comments
As a reproduction of the problem, this is the state of the protocol when doing:
As expected, there is a diff post-second flash loan, which should not be there
|
Implementation-wise, after doing some gas profiling and evaluating the consequences of changing to mint all the time aTokens to the Collector, it seems the optimal solution is to just extend the part of the code using |
…e flash loan fee (same as bridging) imprecision
Thanks for the detailed analysis @eboadom . I agree with the chosen approach |
Fixes #730. accruedToTreasury not being properly considered together with aToken supply
Problem
Currently, the depositors on the protocol accrue yield over time via the ever-growing
liquidityIndex
multiplying their scaled balanced of aToken. This "growth" happens in 3 different places:_updateIndexes()
https://github.com/aave/aave-v3-core/blob/master/contracts/protocol/libraries/logic/ReserveLogic.sol#L295_handleFlashLoanRepayment()
https://github.com/aave/aave-v3-core/blob/master/contracts/protocol/libraries/logic/FlashLoanLogic.sol#L233executeBackUnbacked()
https://github.com/aave/aave-v3-core/blob/master/contracts/protocol/libraries/logic/BridgeLogic.sol#L127The problem is that, at the moment, the protocol is not taking into account correctly the entities with "rights to withdraw underlying" that are not aToken holders. Mainly this applies to
reserve.accruedToTreasury
, which factually should act like aToken scaled balance: not minted yet, but accruing yield like any other holder of aToken.For example in the case of flash on 2), it is relatively straightforward to see that by using the
IERC20(reserveCache.aTokenAddress).totalSupply()
(withincumulateToLiquidityIndex()
as a divisor) instead of supply +reserve.accruedToTreasury
, the effect is that the liquidity index increases on each flash loan fee by more than it should (smaller divisor, bigger result). The situation on the BridgeLogic is the same.Even if not a totally major one, this is obviously problematic, because as the non-claimed
accruedToTreasury
is bigger (if not claimed frequently), the imprecision also gets bigger; the liquidity index increases more than it should.Flash loan logic of liquidity index increment
It is important to highlight that the problem of assuming
rights to withdraw underlying == aToken.totalSupply()
instead ofrights to withdraw underlying == aToken.totalSupply() + accruedToTreasury
can potentially be affecting in other places like validations involving supply, even if at the moment we don't see any big problem.Potential solutions
Mainly 2 options here:
accruedToTreasury
in all the calculations involving rights to withdraw underlying. Probably the most realistic option, given that the pattern of having multiple sources for those rights (aToken supply, accruedToTreasury) is already in place.In addition to the fix itself, it is pretty clear that the current Certora properties are not extensive enough, as this specific case was not caught in multiple places of the codebase. So highly recommended to both add new rules and do a bigger review of all the invariants of the protocol.
The text was updated successfully, but these errors were encountered: