Core Contracts

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

Incorrect use of amountToMint instead of amountScaled in the mint function leads to incorrect minting

Summary

Incorrect use of amountToMint instead of amountScaled in the mint function leads to incorrect minting.

Vulnerability Details

uint256 amountScaled = amountToMint.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();
❌ _mint(onBehalfOf, amountToMint.toUint128());
IERC20(reserve.reserveAssetAddress).safeTransferFrom(
msg.sender, // from
reserve.reserveRTokenAddress, // to
amount // amount
);
// Mint RToken to the depositor (scaling handled inside RToken)
(bool isFirstMint, uint256 amountScaled, uint256 newTotalSupply, uint256 amountUnderlying) = IRToken(reserve.reserveRTokenAddress).mint(

amount represents the amount of reserve.reserveRTokenAddress transferred by msg.sender, and amountScaled is the amount of mint RToken, but in the RToken contract code, _mint(onBehalfOf, amountToMint.toUint128()) is incorrect.

Assume that the amount is 100e18 and the index is 1.2e27. The amountScaled is 83,33333333333334e+18.However, according to the incorrect calculation method above, amountToMint is always the number of underlying tokens 100e18.

Impact

If mint uses amountToMint directly instead of amountScaled, reserve.liquidityIndex will have no effect and the result will be wrong.

Tools Used

Manual review

Recommendations

should use amountScaled to mint tokens instead of the original amountToMint, because amountScaled is the actual amount to be minted after adjusting the liquidity index. So the correct code should be:

Considering that balanceIncrease has not been used yet, the calculation of amountToMint should be
amountToMint = amountScaled + balanceIncrease;

uint256 amountScaled = amountToMint.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();
amountScaled = amountScaled + balanceIncrease;
✅ _mint(onBehalfOf, amountScaled.toUint128());
Updates

Lead Judging Commences

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

RToken::mint should mint the amountScaled not the amountToMint

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

RToken::mint should mint the amountScaled not the amountToMint

Support

FAQs

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