Core Contracts

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

Users will pay more interest when taking a second loan.

Summary

The DebtToken is minted to borrowers to track the loan + interest owed. This is done in the mint() which also has functionality to track the interest owed when users take a second loan by minting the interest owed in terms of DebtToken. However the calculation of interest owed is wrong, which causes the function to mint more DebtToken, making the users entitiled to pay more interest.

Vulnerability Details

In DebtToken.sol::mint(), the function gets the interest owed by the borrowers comparing the usageIndex at 1st borrow and 2nd borrow.

function mint(
address user,
address onBehalfOf,
uint256 amount,
uint256 index
) external override onlyReservePool returns (bool, uint256, uint256) {
....
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;
_mint(onBehalfOf, amountToMint.toUint128());

The function is supposed to get the current DebtToken of the user, rayMul() it with the last usage index and current usage index to get the interest owed by the user, which will be minted on top of the borrowing amount. However, the balanceOf() returns the borrowed + interest amount because it scales the debtToken balance with the current usage index.

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

Thus, the function scale the underlying asset amount with the last index and current index, instead of the debtToken amount, minting more debtToken to the users.

Impact

Borrowers will pay more interest than they are owed when taking out a second loan. The issue will get bigger as the usageIndex grows.

Tools Used

Manual Review

Recommendations

Use the scaledBalanceOf() to get the debtToken balance of the user, then use it to calculate the interest owed by the user.

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.