Core Contracts

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

[M] Incorrect Return Value in `mint` and `burn` Functions in `RToken`

Summary

The mint and burn functions in the RToken contract incorrectly return the amount of scaled tokens minted or burned. The functions currently return amountToMint and amount, respectively, which are not scaled.

Vulnerability Details

The mint function in the RToken contract is:

function mint(
address caller,
address onBehalfOf,
uint256 amountToMint,
uint256 index
) external override onlyReservePool returns (bool, uint256, uint256, uint256) {
if (amountToMint == 0) {
return (false, 0, 0, 0);
}
uint256 amountScaled = amountToMint.rayDiv(index);
...
_mint(onBehalfOf, amountToMint.toUint128());
emit Mint(caller, onBehalfOf, amountToMint, index);
return (isFirstMint, amountToMint, totalSupply(), amountScaled);
}

The second value in the return statement is amountToMint, which is not scaled. It should return amountScaled instead.

Similarly, the burn function in the RToken contract is:

function burn(
address from,
address receiverOfUnderlying,
uint256 amount,
uint256 index
) external override onlyReservePool returns (uint256, uint256, uint256) {
...
uint256 amountScaled = amount.rayMul(index);
_userState[from].index = index.toUint128(); //note repetitive
_burn(from, amount.toUint128());
...
emit Burn(from, receiverOfUnderlying, amount, index);
return (amount, totalSupply(), amount);
}

The first value in the return statement is amount, which is not scaled. It should return amountScaled instead.

Scaling in _update Function

The _update function in the RToken contract scales the amount by the normalized income (liquidity index) for all operations (mint, burn, transfer):

function _update(address from, address to, uint256 amount) internal override {
uint256 scaledAmount = amount.rayDiv(ILendingPool(_reservePool).getNormalizedIncome());
super._update(from, to, scaledAmount);
}

This ensures that the amount is correctly scaled by the liquidity index before any operation.
Links to the issues:

  1. https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/tokens/RToken.sol#L184

  2. https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/tokens/RToken.sol#L140

  3. https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/tokens/RToken.sol#L309

Impact

This issue can lead to incorrect reporting of the amount of scaled tokens minted or burned, potentially causing issues with token accounting and user balances.

Tools Used

Manual code review.

Recommendations

Update the return statements in the mint and burn functions to correctly return the scaled amount. The corrected functions should be:

Corrected mint Function

function mint(
address caller,
address onBehalfOf,
uint256 amountToMint,
uint256 index
) external override onlyReservePool returns (bool, uint256, uint256, uint256) {
if (amountToMint == 0) {
return (false, 0, 0, 0);
}
uint256 amountScaled = amountToMint.rayDiv(index);
...
_mint(onBehalfOf, amountToMint.toUint128());
...
return (isFirstMint, amountScaled, totalSupply(), amountScaled);
}

Corrected burn Function

function burn(
address from,
address receiverOfUnderlying,
uint256 amount,
uint256 index
) external override onlyReservePool returns (uint256, uint256, uint256) {
...
_burn(from, amount.toUint128());
...
uint256 amountScaled = amountToMint.rayDiv(index);
return (amountScaled, totalSupply(), amount);
}

This ensures that the correct scaled amount is returned by the mint and burn functions.


Updates

Lead Judging Commences

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

RToken::burn returns incorrect underlying asset amount (amount instead of amountScaled), leading to wrong interest rate calculations

RToken::mint doesn't return data in the right order, making the protocol emit wrong events

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

RToken::burn returns incorrect underlying asset amount (amount instead of amountScaled), leading to wrong interest rate calculations

RToken::mint doesn't return data in the right order, making the protocol emit wrong events

Support

FAQs

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

Give us feedback!