Core Contracts

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

Incorrect totalsupply() in debt token.sol

Summary

The DebtToken contract contains a critical mathematical error in its total supply () calculation that fundamentally breaks the protocol's debt accounting system. The function incorrectly divides by the interest index instead of multiplying, causing exponential underreporting of total system debt as interest accrues.
This error creates an inverse relationship between interest accrual and reported debt, causing the system to report decreasing debt when it should be increasing.

Vulnerability Details

https://github.com/Cyfrin/2025-02-raac/blame/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/tokens/DebtToken.sol#L234
DebtToken.totalSupply() incorrectly calculates debt using division with the interest index instead of multiplication. This inverts the fundamental relationship between scaled balances and accrued interest.
Formula
Total Debt = Scaled Supply × Debt Index
Current Implementation

Reported Debt = Scaled Supply ÷ Debt Index

Impact on LendingPool Operations

  1. Reserve Tracking Failure

// LendingPool.sol (Reserve updates)
reserve.totalUsage = IDebtToken(reserve.reserveDebtTokenAddress).totalSupply();
  • Stores underreported debt values

  • Results in Incorrect Protocol Fee Calculations

  1. Liquidity Management Breakdown

// _ensureLiquidity() logic
availableLiquidity = reserveAsset.balanceOf(rToken)
required = amount - availableLiquidity
  • Actual Debt: $100M (Index=1.2 → $120M)

  • Reported Debt: $100M/1.2 ≈ $83.3M

  1. Interest Rate Distortion

// ReserveLibrary.sol (Rate calculation)
utilization = totalDebt / (totalLiquidity + totalDebt)
  • Actual Utilization: 120/220 = 54.5%

  • Reported Utilization: 83.3/183.3 = 45.4%

  1. Liquidation System Failure

// Health Factor Calculation
healthFactor = (collateralValue × threshold) / userDebt
  • Actual Debt: $120M → HF = (150×0.8)/120 = 1.0

  • Reported Debt: $100M → HF = 120/100 = 1.2

Recommendations

function totalSupply() public view override returns (uint256) {
return super.totalSupply().rayMul(debtIndex);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

DebtToken::totalSupply incorrectly uses rayDiv instead of rayMul, severely under-reporting total debt and causing lending protocol accounting errors

inallhonesty Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

DebtToken::totalSupply incorrectly uses rayDiv instead of rayMul, severely under-reporting total debt and causing lending protocol accounting errors

Support

FAQs

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

Give us feedback!