A critical scaling error in RToken.burn
function prevents users from withdrawing their full deposited amounts. The vulnerability stems from comparing non-scaled withdrawal values against scaled token balances, creating an artificial cap that grows more restrictive as interest accrues. This forces liquidity providers to execute multiple transactions to recover diminishing fractions of their funds, effectively trapping capital in the protocol over time. The flaw fundamentally breaks the core withdrawal guarantee of the lending pool system, representing a high-severity economic vulnerability.
The vulnerability arises from incorrect balance scaling handling in the RToken.burn
function (RToken.sol#L164-L170). The function improperly compares a non-scaled withdrawal amount against the user's scaled token balance, leading to artificial capping of valid withdrawals.
Key issues:
Scaling Mismatch:
RToken
balances are stored in scaled form using a liquidity index
The amount
parameter represents underlying asset units while userBalance
returns scaled units
Direct comparison between scaled/non-scaled values creates mathematical inconsistency
Incorrect Withdrawal Capping:
The check if(amount > userBalance)
uses incompatible units
Should compare amount
against userBalance.rayMul(index)
to account for interest accrual
Protocol Integration Impact:
Affects core LendingPool.withdraw
functionality through ReserveLibrary interactions ReserveLibrary.withdraw
Fails to properly validate the maximum withdrawable amount when burning RTokens
This mismatch becomes progressively worse as the liquidity index increases over time, effectively creating a denial-of-service condition for liquidity providers trying to withdraw their assets.
This vulnerability creates a progressive denial-of-service for withdrawals, with demonstrated financial impact:
Exploit Example:
Initial Deposit: 100 CRVUSD (liquidityIndex = 1.0e27)
After 1 Year: Index grows to 1.1e27 (10% interest)
User Attempts Withdrawal:
Entitled Amount: 110 CRVUSD (100 * 1.1)
Actual Withdrawable: 100 CRVUSD (capped by flawed comparison)
Immediate Loss: 10 CRVUSD (9.09% of entitled funds)
Compounding Effect:
At Index 2.0e27: Users can only withdraw 50% of true balance per transaction
At Index 10.0e27: Requires 10+ transactions to fully exit position
Gas costs multiply while funds remain partially trapped
Protocol-Level Consequences:
Liquidity providers effectively subsidize the protocol with trapped funds
Violates core protocol promise of fungible liquidity positions
Creates irreversible loss vector that worsens with protocol success (higher utilization → faster index growth)
Undermines trust in withdrawal guarantees critical for DeFi lending primitives
Manual Review
Implement proper scaling conversions in RToken.burn
function with the following changes:
This approach maintains consistency with the RToken's scaling mechanism while ensuring users can withdraw their full entitled amount in a single transaction.
It's underlying vs underlying
It's underlying vs underlying
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.