-
Notifications
You must be signed in to change notification settings - Fork 36
[WIP]: fix: Liquidity growth calculation in fees logic & fee cache in transient storage #927
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
Conversation
avniculae
commented
Oct 17, 2025
- https://prover.certora.com/output/3973608/d1918d257dee446590bfd764ecd4f651/?anonymousKey=a59f76058509f8901d57a8d94830bc2aa8472ee7
Certora Run Started (Verified Rules)
Certora Run Summary
|
|
|
||
| /// @notice Accrues interest and fees for the specified asset. | ||
| function accrue(IHub.Asset storage asset) internal { | ||
| if (asset.lastUpdateTimestamp == block.timestamp) { |
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.
add comment -- this cannot be removed now
| using TransientSlot for *; | ||
|
|
||
| /// bytes32(uint256(keccak256("FEE_AMOUNT")) - 1) | ||
| TransientSlot.Uint256Slot internal constant FEE_AMOUNT_SLOT = |
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.
pack fee amount and fee shares in the same slot
| // SPDX-License-Identifier: UNLICENSED | ||
| // Copyright (c) 2025 Aave Labs | ||
| pragma solidity ^0.8.20; | ||
| pragma solidity ^0.8.28; |
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.
undo this (this was done to make certora rule compile)
| uint256 unrealized = spoke == asset.feeReceiver ? asset.unrealizedFeeShares() : 0; | ||
| return asset.toAddedAssetsDown(_spokes[assetId][spoke].addedShares + unrealized); | ||
| uint256 feeShares = spoke == asset.feeReceiver | ||
| ? asset.getUnrealizedFeeShares(asset.getUnrealizedFeeAmount(asset.getDrawnIndex())) |
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.
if this is queried after accrue but before fee shares are minted (in the same block), this will be wrong. however, I don't think this scenario exists (need to double check). If such scenario does not exist, should we fix it (by looking at the transient storage as well) just to be safer, or leave as is?
| asset.liquidity += amount.toUint128(); | ||
|
|
||
| asset.updateDrawnRate(assetId); | ||
| asset.mintFeeShares(_spokes, assetId); |
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.
is there a way to ensure we always mint fee shares at the end of actions that accrue? current impl is a bit error-prone
| } | ||
|
|
||
| /// @notice Accrues interest and fees for the specified asset. | ||
| function accrue(IHub.Asset storage asset) internal { |
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.
let's make sure to clearly document this and the need to couple this with the mintFeeShares
|
This was addressed in #933 |