Core Contracts

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

Incorrect amount reported in Deposit Event due to parameter mismatch between RToken and ReserveLibrary

Summary

The ReserveLibrary's deposit function incorrectly interprets the return values from RToken's mint function, leading to wrong amounts being emitted in Deposit events. This occurs because the ReserveLibrary assumes the second return parameter from mint is the scaled amount, while RToken actually returns the scaled amount as the fourth parameter.

Vulnerability Details

The issue stems from a parameter order mismatch between what ReserveLibrary expects and what RToken returns. Let's analyze the flow:

In ReserveLibrary's deposit function:

(bool isFirstMint, uint256 amountScaled, uint256 newTotalSupply, uint256 amountUnderlying) =
IRToken(reserve.reserveRTokenAddress).mint(
address(this),
depositor,
amount,
reserve.liquidityIndex
);
amountMinted = amountScaled; // @audit This assignment is problematic
// @audit wrong amount `amountMinted` emited in event
emit Deposit(depositor, amount, amountMinted);

From analyzing the code in deposit function above, in the Deposit event amount and amountMinted will always have the same value (since amountMinted is just the same variable as amount - has essentially just been recycled through the RToken contract)

In IRToken interface,

...
* @return A tuple containing:
* - bool: True if this is the first mint for the recipient, false otherwise
@> * - uint256: The amount of scaled tokens minted
* - uint256: The new total supply after minting
@> * - uint256: The amount of underlying tokens minted
*/
function mint(address caller, address onBehalfOf, uint256 amount, uint256 index
) external returns (bool, uint256, uint256, uint256);

Notice that in the IRToken mint natspec comments, the 2nd return value The amount of scaled tokens minted and the 4th uint256: The amount of underlying tokens mintedHowever, The RToken's mint function returns values in this interchanged order:

function mint(...)
// ...
// @audit amountToMint position has been interchanged with amountScaled
return (isFirstMint, amountToMint, totalSupply(), amountScaled);

ReserveLibrary assigns the second return value (amountToMint) to amountMinted, believing it to be the scaled amount. However, amountToMint is the raw amount, while the actual scaled amount is the fourth parameter.

This matters because:

  • The scaled amount represents the token amount adjusted by the liquidity index

  • The raw amount is the direct deposit amount without scaling

  • Using the wrong value leads to incorrect event emissions and potentially misleading off-chain monitoring systems

Impact

  • Incorrect event emissions leading to wrong historical data

  • Off-chain systems monitoring deposit amounts will record incorrect scaled values

  • Potential confusion in accounting systems tracking scaled vs. unscaled amounts

Tools Used

Manual review

Recommendations

You have 2 options;

a) Modify the RToken contract to return the correct order as in IRToken interface:

function mint(...) {
// ...
return (isFirstMint, amountScaled, totalSupply(), amountToMint);
}

b) Or alternatively modify ReserveLibrary's deposit function to use the correct return parameter:

function deposit(...) {
// ... existing code ...
(bool isFirstMint, , , uint256 amountScaled) = IRToken(reserve.reserveRTokenAddress).mint(...);
amountMinted = amountScaled; // Now correctly uses the scaled amount
// ... rest of the function ...
}
Updates

Lead Judging Commences

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

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

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

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.