Core Contracts

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

Wrong amount used in `DebtToken::mint`

Summary

In DebtToken::mint, the amount minted is wrong. The amountToMint is in units of underlying assets instead of scaled units(debtToken). This leads to the wong amount of debtToken being minted, making a user to mint incorrect amount of debtToken than they should have.

Vulnerability Details

The issue arises because:

amount is in underlying asset units
balanceIncrease is calculated in underlying asset units
These unscaled values are directly used in _mint
However, _mint should receive scaled units (DebtToken units)

Impact

  • Users receive incorrect amounts of debt tokens when they mint debt tokens.

  • System accounting becomes inaccurate

  • Protocol's debt tracking becomes unreliable

  • Could lead to under-collateralization or excessive borrowing

  • Protocol's economic model becomes unstable

Tools Used

Manual Review

Recommendations

/**
* @notice Mints debt tokens to a user
* @param user The address initiating the mint
* @param onBehalfOf The recipient of the debt tokens
* @param amount The amount to mint (in underlying asset units)
* @param index The usage index at the time of minting
* @return A tuple containing:
* - bool: True if the previous balance was zero
* - uint256: The amount of scaled tokens minted
* - uint256: The new total supply after minting
*/
function mint(
address user,
address onBehalfOf,
uint256 amount,
uint256 index
) external override onlyReservePool returns (bool, uint256, uint256) {
if (user == address(0) || onBehalfOf == address(0)) revert InvalidAddress();
if (amount == 0) {
return (false, 0, totalSupply());
}
uint256 amountScaled = amount.rayDiv(index);
if (amountScaled == 0) revert InvalidAmount();
uint256 scaledBalance = balanceOf(onBehalfOf);
bool isFirstMint = scaledBalance == 0;
uint256 balanceIncrease = 0;
if (_userState[onBehalfOf].index != 0 && _userState[onBehalfOf].index < index) {
balanceIncrease = scaledBalance.rayMul(index) - scaledBalance.rayMul(_userState[onBehalfOf].index);
}
_userState[onBehalfOf].index = index.toUint128();
uint256 amountToMint = amount + balanceIncrease;
+ amountToMint = amountToMint.rayDiv(index);
_mint(onBehalfOf, amountToMint.toUint128());
emit Transfer(address(0), onBehalfOf, amountToMint);
emit Mint(user, onBehalfOf, amountToMint, balanceIncrease, index);
- return (scaledBalance == 0, amountToMint, totalSupply());
+ return (isFirstMint, amountToMint, 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!