Core Contracts

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

balanceIncrease is not correctly calculated when mint DebtToken

Summary

balanceIncrease is not correctly calculated when mint DebtToken.

Vulnerability Details

DebtToken balance represents user's debt, when mint DebtToken tokens, if _userState[onBehalfOf].index is less than the usage index at the time of minting, balanceIncrease is computed to reflect the accrued debt.

DebtToken.sol::mint()

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;

The problem is that balanceIncrease is incorrectly calculated, DebtToken overrides ERC20's _update() and balanceOf().

In _update(), user balance is stored as amount / index in _balances[user].

DebtToken.sol::_update()

function _update(address from, address to, uint256 amount) internal virtual override {
if (from != address(0) && to != address(0)) {
revert TransfersNotAllowed(); // Only allow minting and burning
}
uint256 scaledAmount = amount.rayDiv(ILendingPool(_reservePool).getNormalizedDebt());
super._update(from, to, scaledAmount);
emit Transfer(from, to, amount);
}

In balanceOf(), user balance is returned as _balances[user] * index.

DebtToken.sol::balanceOf()

function balanceOf(address account) public view override(ERC20, IERC20) returns (uint256) {
uint256 scaledBalance = super.balanceOf(account);
return scaledBalance.rayMul(ILendingPool(_reservePool).getNormalizedDebt());
}

Therefore, in mint(), balanceIncrease is actually computed as amount / index0 * index1 * index1 - amount / index0 * index1 * index0, that is, the value is wrongly multiplied by index.

Impact

balanceIncrease is wrongly calculated, user will bear more debt than expected.

Tools Used

Manual Review

Recommendations

The correct calculation should be:

- balanceIncrease = scaledBalance.rayMul(index) - scaledBalance.rayMul(_userState[onBehalfOf].index);
+ balanceIncrease = scaledBalance - scaledBalance.rayDiv(index).rayMul(_userState[onBehalfOf].index);
Updates

Lead Judging Commences

inallhonesty Lead Judge 5 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.