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