Core Contracts

Regnum Aurum Acquisition Corp
HardhatReal World AssetsNFT
77,280 USDC
View results
Submission Details
Severity: high
Invalid

Exponential Debt Growth Due to Residual Dust Balance

Summary

Even after a user fully repays their debt or gets liquidated, a small dust amount can remain in their scaledDebtBalance. Since debt accrues compounded interest exponentially, this dust can continue to grow unchecked over time. When the user attempts to borrow again, they may be shocked to find a significantly higher debt than anticipated. This issue can lead to unfair debt accumulation, poor user experience, and loss of trust in the protocol.

Vulnerability Details

Step 1. Dust Balance Persists After Repayment or Liquidation

scaledDebtBalance is updated when the user fully repays or gets liquidated. However, it is not explicitly reset to zero if a tiny amount remains due to rounding that can be as much as 1e6 as indicated by the code check below:

LendingPool.sol#L484

if (userDebt > DUST_THRESHOLD) revert DebtNotZero();

This means that even after full repayment or liquidation, the user's balance might still be slightly greater than zero.

Step 2. Compounded Interest Grows Unexpectedly

scaledDebtBalance is compounded based on usageIndex, which grows over time. Any nonzero balance—even an extremely small dust amount—continues to accrue interest exponentially.

If the user does not interact with the protocol for an extended period of time, their balance can become unexpectedly large.

Step 3. User Is Unaware Until They Borrow Again

When the user returns to borrow again, they inherit the exponentially grown debt they never knew existed.

LendingPool.sol#L340-L341

// Fetch user's total debt after borrowing
uint256 userTotalDebt = user.scaledDebtBalance.rayMul(reserve.usageIndex) + amount;

This can lead to confusion, financial losses, and frustration, particularly for long-term users who assume they have no outstanding debt.

Impact

  • Unexpected Debt Growth: Users may find themselves with unanticipated and compounding debt when they return to borrow.

  • Unfair Financial Burden: What was supposed to be a fully repaid or liquidated position continues to accrue interest.

  • Bad User Experience & Loss of Trust: Users may lose confidence in the protocol due to unexplained debt accumulation.

And worst of all, such losses are non-repairable and non-refundable since they will automatically be surcharged into the accounting tally on reserve and rateData via updateInterestRatesAndLiquidity() following state update:

LendingPool.sol#L362-L363

// Update liquidity and interest rates
ReserveLibrary.updateInterestRatesAndLiquidity(reserve, rateData, 0, amount);

Tools Used

Manual

Recommendations

Explicitly Reset scaledDebtBalance to Zero When Debt is Fully Paid or Liquidated

If user.scaledDebtBalance < DUST_THRESHOLD, set it to exactly zero in repay() and finalizeLiquidation().

Implement a Safety Check Before Allowing Users to Borrow Again

Before a user borrows, ensure that any leftover dust balance is cleared to prevent unexpected debt inheritance. For instance, user.nftTokenIds.length == 0 may be used as a check for this specific purpose.

Updates

Lead Judging Commences

inallhonesty Lead Judge 4 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.