Core Contracts

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

`DebtToken.sol` Contract Mints Actual Amount (with Interests) Leads to Users Repaying More than the Actual Debt

Summary

In the DebtToken.sol contract, the mint function mints the actual amount (including interest) and also calculates interest again in the balanceOf function using the index, results in double counting of interest due. It results in debt value to be inflated and users may end up repaying more than the actual debt.

Vulnerability Details

  • The mint function creates the debt token with the full amount (including interest) but does not normalize the debt using the appropriate scaling index.

  • The balanceOf function then further inflates the value by multiplying the actual debt by the index, leading to double-counting of the interest.

contracts/core/tokens/DebtToken.sol:#L160

function mint(
address user,
address onBehalfOf,
uint256 amount,
uint256 index
) external override onlyReservePool returns (bool, uint256, uint256) {
...
uint256 amountScaled = amount.rayDiv(index); // @auidt Standardized amount (unused)
uint256 balanceIncrease = ... // @audit Calculating historical interest
uint256 amountToMint = amount + balanceIncrease; // @audit Error: minting actual amount, not standardized
_mint(onBehalfOf, amountToMint);
}

contracts/core/tokens/DebtToken.sol:balanceOf#L225

function balanceOf(address account) public view returns (uint256) {
uint256 scaledBalance = super.balanceOf(account);
// @audit Already includes interest calculation
return scaledBalance.rayMul(ILendingPool(_reservePool).getNormalizedDebt());
}

Impact

  • User Debt Inflation: Users' debt is incorrectly inflated intermediately after deposit due to the double counting of interest.

  • Repayment Overestimation: Users may end up repaying more than the actual amount owed.

Reproduction Scenario

  1. A user borrows 100 ETH with a current index of 1.1.

  2. The mint function mints 100 ETH of DebtToken.

  3. The balanceOf function calculates the user's debt as 110 ETH (100 * 1.1), which should have been 100 ETH.

  4. User pay more Debt: 110 - 100 = 10 ETH

Tools Used

Manual Code Review

Recommendations

It is recommended to fix minting process. The mint function should mint the standardized amount (amountScaled) rather than the actual amount as shown below:

function mint(
address user,
address onBehalfOf,
uint256 amount,
uint256 index
) external override onlyReservePool returns (bool, uint256, uint256) {
...
// @audit ✅ Calculate and use the normalized amount
uint256 amountScaled = amount.rayDiv(index);
if (amountScaled == 0) revert InvalidAmount();
uint256 balanceIncrease = ... // @audit Calculating historical interest
- uint256 amountToMint = amount + balanceIncrease;
+ uint256 amountToMint = amountScaled + balanceIncrease;
// ✅ Mint the normalized amount
_mint(onBehalfOf, amountToMint.toUint128());
...
// Update the user's index
_userState[onBehalfOf].index = index.toUint128();
emit Transfer(address(0), onBehalfOf, amount);
emit Mint(user, onBehalfOf, amount, 0, index);
return (balanceOf(onBehalfOf) == 0, amount, totalSupply());
}
Updates

Lead Judging Commences

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

DebtToken::mint miscalculates debt by applying interest twice, inflating borrow amounts and risking premature liquidations

Support

FAQs

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

Give us feedback!