The LendingPool's deposit function mints RTokens using the raw deposit amount instead of the scaled amount adjusted by the liquidity index. This causes users to receive more RTokens than they should, leading to protocol insolvency as users can withdraw more underlying assets than they originally deposited.
The issue lies in the core deposit flow where RTokens are minted to represent users' deposits. The protocol is designed to use a liquidity index to track the accumulation of interest over time, similar to Aave's aToken mechanism.
Before I explain the issue more, here is a short recap on the lender flows;
deposit: LendingPool.deposit(asset) -> ReserveLibrary.deposit -> RToken.mint -> lender has rTokens
withdraw: LendingPool.withdraw(rTokens) -> ReserveLibrary.withdraw -> RToken.burn -> lender has asset
When a user deposits crvUSD, the amount should be scaled down by dividing it by the current liquidity index before minting RTokens. This ensures that as the liquidity index increases over time (representing earned interest), the same number of RTokens will be worth more underlying crvUSD.
However, in the current implementation in RToken::mint:
The protocol calculates the correct scaled amount but then incorrectly uses the unscaled amountToMint when minting RTokens.
To understand why this is problematic:
The liquidity index starts at RAY (1e27) and increases over time
If a user deposits 100 crvUSD when the liquidity index is 1.1 * RAY:
Correct scaled amount: 100 / 1.1 ≈ 90.90 RTokens
Current implementation: Mints 100 RTokens
Later when the user withdraws and the liquidity index is 1.2 * RAY:
Correct: 90.90 * 1.2 = 109.08 crvUSD (representing principal + interest)
Current: 100 * 1.2 = 120 crvUSD (incorrectly high amount)
On the other hand when withdrawing, RToken::burn is called which uses balanceOf function which correctly scales up the balance using the current liquidity index, This means users will be able to withdraw more crvUSD than they should be entitled to, as their incorrectly high RToken balance gets scaled up by the liquidity index.
Alice deposits 100 crvUSD when liquidity index = 1.1 * RAY
Protocol incorrectly mints 100 RTokens instead of 90.90 RTokens
Time passes, liquidity index increases to 1.2 * RAY
Alice withdraws with 100 RTokens
Alice receives 120 crvUSD instead of the correct 109.08 crvUSD
Protocol loses 10.92 crvUSD to Alice due to incorrect minting
Protocol becomes insolvent as users can withdraw more assets than they deposited plus legitimate interest.
Manual code review
Correct the minting in RToken to use the scaled amount:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.