Simple summary
Introducing Aave v3.5, an upgrade to improve the mathematical precision of the Aave v3 protocol by defining more explicit rounding directions on user actions.
The codebase of Aave v3.5 can be found HERE, with a high-level description of what’s included in the release HERE.
Aave v3.5 changes were originally included in the previously applied v3.4, but to reduce the complexity of the v3.4 upgrade and to review/audit them independently, we decided to split the originally proposed v3.4 into v3.4 and v3.5. With the original v3.4 already passed ARFC and the reduced v3.4 active in production, it is reasonable to proceed with Direct-to-AIP on the newly named v3.5.
Motivation
Due to aspects like using rebasing tokens (a/v Tokens) on the accounting layer, Aave v3 has had well-known inherent mathematical imprecision on the lowest order of magnitudes. But even if this imprecision is highly frequently unavoidable, in the case of Aave v3, it has a kind of “chaotic” direction. This is different from standards like 4626, where the rounding is directionally explicit, consequently simpler to understand and reason about.
Even though this has not created major problems historically, we believe it is essential to enhance these mathematical mechanisms in a protocol as significant and widely adopted as Aave v3.
Specification
As previously commented, v3.5 is focused on mathematical improvements of the Aave v3 accounting layer, mainly related to rounding strategies and precision.
The following is an exhaustive list of the high-level changes included:
1. Addition of directional rounding
The Aave protocol handles balances and yield by storing a scaledBalance
and a liquidityIndex
. Then, the actual balance seen by users (growing over time) is derived by multiplying the scaledBalance
by the liquidityIndex
, or on inflows, dividing the amount
by the current liquidityIndex
.
Until v3.5, the protocol has used half-up rounding (bankers rounding) operations. In practice, that means that when, e.g., depositing 1e18 of an asset, your balance might be 1e18 or +/- 1.
The rounding depends on time & index accrual, so it’s difficult to exactly predict the outcome, hence it has a “chaotic” outcome.
On v3.5, rounding operations have been made directionally explicit, as follows:
- Rounding down on minting aTokens (supply flows).
- Rounding up on burning aTokens (applicable for withdrawal flow, repayment with aToken, or liquidation with aTokens).
- Rounding down on aToken balance reading (applicable for balanceOf()).
- Rounding up when minting vTokens (applicable, for example, for borrowing).
- Rounding down when burning vTokens (applicable for repayment or liquidations).
- Rounding up on aToken transfers (the recipient receives at least the input amount).
- Rounding down on the collateral value (USD).
- Rounding up on the debt value (USD).
A full specification can be found on the high-level description HERE or on the system’s properties HERE.
2. Improved internal usage of scaled accounting
In previous versions of the protocol, a source of precision loss was having multiple conversions back and forth from unscaled to scaled units of accounting.
Even if this only affects non-critical flows like caps calculations, or minting aTokens to the Aave treasury, on Aave v3.5, we have improved it by adding a scaled amount input to the internal mint
and burn
functions, this way avoiding repeated conversions, and as a positive side effect, reducing gas consumption across the protocol.
3. Improved flags handling
To enable validations of conditions like a user using an asset as collateral or borrowing, the Aave protocol uses a system of flags. Historically, validations for enabling/disabling these flags were handled with a mixture of scaled/unscaled balances (a/v tokens), which is not optimal.
On v3.4, we increased the robustness of the flag logic for borrow operations by switching validations from unscaled to scaled comparisons to checks against the actual balance.
In v3.5, we decided to double down on these robustness improvements by using scaled accounting on repayWithAToken
and withdraw
, on the collateral side.
4. Miscellaneous
- The allowance accounting of a/v tokens has been improved to be more precise (historically, it was imprecise due to rebasing tokens).
- The
eliminateReserveDeficit
function has been updated to return theuint256
amount of deficit that was covered, to allow for optimizations on the Aave Umbrella system. - In v3.5, the
value
emitted inMint
andBurn
events now always accurately reflects the difference between the previous upscaled balance and the new upscaled balance. ForAToken
transfers, theTransfer
event emits the input amount, while theBalanceTransfer
event emits the precise scaled amount being transferred. Due to the new rounding logic, the actual change in unscaled balance might differ slightly from the input amount. repayWithAToken
validations are now more restrictive.- The control flow of
borrow
has been altered. While in previous versions of the protocol, theborrow
would first check theHF
limitations, from v3.5.0, the health factor check is performed at the end. Moving the check allows for the de-duplication of the health factor-related calculations and avoids issues due to non-equivalence in some edge cases.
Changelog
An extensive Changelog of all components of the protocol affected in the upgrade can be found HERE.
Security procedures
The security procedures performed in the codebase have been the following:
- All our (BGD) internal testing and evaluation, including making the Aave v3 fuzz suite compatible with v3.5.
- Adapted Certora formal verification suite.
- Security review by StErMi.
- Security review by Certora.
- Security review by MixBytes.
- Security review by ABDK.
The governance proposal will include a refund to BGD Labs of the audit costs incurred of $96’050.
Next steps
- Keep this thread open on the forum for some days, for the community to comment.
- In parallel, finish the preparations for the on-chain proposal (AIP).
- Create the on-chain AIP, upgrading the protocol (v3.4) to v3.5.