Core Contracts

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

The `totalSupply()` function incorrectly uses **division** (`rayDiv`) instead of **multiplication** (`rayMul`)

Summary

The totalSupply() function incorrectly uses division (rayDiv) instead of multiplication (rayMul) to convert the stored scaled supply into the actual debt. This inverts the relationship between scaled balances and the interest index, leading to a critically understated total debt.

Vulnerability Details

/**
* @notice Returns the scaled total supply
* @return The total supply (scaled by the usage index)
*/
function totalSupply() public view override(ERC20, IERC20) returns (uint256) {
uint256 scaledSupply = super.totalSupply();
return scaledSupply.rayDiv(ILendingPool(_reservePool).getNormalizedDebt());
}

totalSupply() should equal the sum of all users' scaled balances multiplied by the current interest index. Using rayDiv violates this, leading to an understated total debt.

Debt balances are stored scaled by the interest index at the time of minting/burning.

For example:

  • If you borrow 100 units when the index is 1.1e27 (RAY), your scaled balance is stored as 100 / 1.1 = ~90.91.

To get the actual debt, the scaled balance is multiplied by the current interest index

actualDebt = scaledBalance * currentIndex / RAY

If the index rises to 1.2e27, your actual debt becomes 90.91 * 1.2 = ~109.09.

The contract’s totalSupply() function does:

return scaledSupply.rayDiv(currentIndex); // Uses division
actualTotalDebt = scaledSupply / currentIndex * RAY

With our example:

  • Scaled supply = 90.91

  • Using rayDiv: 90.91 / 1.2 = ~75.76 (total debt is understated by ~33%).

    As the interest index increases (due to accrued interest), totalSupply() decreases instead of increasing. This misrepresents the protocol’s total debt.\

Impact

The protocol relies on totalSupply() to track total outstanding debt. If it’s understated, the system may allow excessive borrowing, risking insolvency.

Lenders earn interest based on the total debt. If totalSupply() is incorrect, interest distributions will be miscalculated, shortchanging lenders.

Tools Used

Foundry

Recommendations

Replace rayDiv with rayMul in totalSupply():

function totalSupply() public view override(ERC20, IERC20) returns (uint256) {
uint256 scaledSupply = super.totalSupply();
return scaledSupply.rayMul(ILendingPool(_reservePool).getNormalizedDebt()); // Correct
}
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 month 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 about 1 month 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.