The burn function in the RToken contract incorrectly scales the amount to burn using rayMul instead of rayDiv when calculating amountScaled, leading to an inflated burn amount that does not accurately reflect the underlying asset units intended to be burned. This fully valid medium-impact, medium-likelihood vulnerability could result in excessive token burns, reducing user balances more than intended and potentially disrupting the lending protocol’s balance sheet by transferring incorrect amounts of the underlying asset.
The burn function is designed to reduce a user’s RToken balance and transfer the corresponding underlying asset amount, scaled by the liquidity index:
amount is the underlying asset amount to burn (e.g., crvUSD units).
amountScaled = amount.rayMul(index) multiplies amount by the liquidity index (e.g., 1.1e27 for 10% interest), inflating it (e.g., 1,000 * 1.1e27 = 1.1e30), which is incorrect for burning scaled tokens.
Correct scaling should use rayDiv to convert underlying units to scaled RToken units (e.g., 1,000 / 1.1e27 ≈ 909), matching Aave’s AToken pattern where _burn expects scaled amounts.
Current logic burns amount directly (_burn(from, amount.toUint128())), ignoring amountScaled, but returns amount as the scaled amount, creating inconsistency and potential future misuse.
User has 1,100 RToken (underlying value) with index = 1.1e27, scaled balance = 1,000.
burn called with amount = 1,100 (underlying units).
amountScaled = 1,100.rayMul(1.1e27) ≈ 1.21e30 (incorrectly huge), but _burn uses 1,100 directly.
Intended: amountScaled = 1,100.rayDiv(1.1e27) ≈ 1,000, burning 1,000 scaled tokens.
Transfers 1,100 crvUSD correctly but burns wrong scaled amount, misaligning balances.
The incorrect scaling in burn could over-burn RToken balances (e.g., 1,100 instead of 1,000 scaled tokens for $1,100 in a $10M pool), a medium-impact issue as it disrupts user balances and protocol accuracy without immediate fund loss. The returned amountScaled misleads external systems, potentially affecting $1M+ in downstream calculations (e.g., pool health). The medium likelihood reflects frequent burn calls in lending operations, making this a persistent risk in active use.
Manual Code Review: Confirmed burn should use rayDiv to scale underlying to scaled units, aligning with mint and balanceOf, revealing the error in logic and return values.
Correct the scaling in burn to use rayDiv and burn 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.