Closed github-actions[bot] closed 1 year ago
Deposits are stored as unscaled values in the Fenwick tree, but are used to track values including the scale factor. Either scaled or unscaled values can be used as long as the appropriate factor are included in the exchange rates to translate to LPs. In some cases, it's more convenient to work with unscaled values for rounding purposes. The code appears to correctly use the scaled/unscaled deposits and exchange rates where cited.
Closing based on Sponsor comment
Jeiwan
medium
Unscaled value of collateral causes invalid LP price when taking and removing liquidity
Summary
When rewarding a taker or calculating the amount of deposit to withdraw and LP tokens to redeem, bucket collateral value is reduced due to unscaling. As a result: the price of an LP token will be reduced; taker will be rewarded with more LP tokens; removing quote tokens will result in a wrong amount of LP tokens burned and a wrong amount of quote tokens redeemed.
Vulnerability Detail
The pools are designed to hold two types of collateral:
The collateral of the first type is also counted in LP price calculation (Buckets.sol#L150): it's priced in terms of the quote token, and the value is added to the total amount of quote token deposits of the bucket.
The amount of total bucket deposits can be scaled and unscaled: since quote token deposits accrue borrower interest, the total price of deposits increases with time. Scaled deposits include the accrued interest, unscaled deposits don't. The amount of the collateral of the first type, while contributing to the price of an LP token, doesn't scale because it doesn't accrue interest. However, there are cases when collateral value is downscaled:
In both of these situations, an LP token exchange rate will be calculated incorrectly due to downscaling of collateral value: one LP token will cost less quote tokens than expected.
Impact
Code Snippet
Buckets.sol#L162-L173 Auctions.sol#L1335 LenderActions.sol#L651
Tool used
Manual Review
Recommendation
Consider using the
Buckets.getExchangeRate
function to calculated exchange rate with unscaled bucket deposits.