Core Contracts

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

Deposit event in ReserveLibrary doesn't emit correct value due to dismatch of params

Summary

According to the event definition, the Deposit event is supposed to emit liquidityMinted, but it currently emits amount due to dismatch of params in IRToken.mint().

Vulnerability Details

event Deposit(address indexed user, uint256 amount, uint256 liquidityMinted);

The order of return values of IRToken.mint() and the order of retrieved values of deposit is not same. The order of amountScaled and amountUnderlying is replaced.

function deposit(ReserveData storage reserve,ReserveRateData storage rateData,uint256 amount,address depositor) internal returns (uint256 amountMinted) {
...
// Mint RToken to the depositor (scaling handled inside RToken)
@> (bool isFirstMint, uint256 amountScaled, uint256 newTotalSupply, uint256 amountUnderlying) = IRToken(reserve.reserveRTokenAddress).mint(
address(this), // caller
depositor, // onBehalfOf
amount, // amount
reserve.liquidityIndex // index
);
amountMinted = amountScaled;
// Update the total liquidity and interest rates
updateInterestRatesAndLiquidity(reserve, rateData, amount, 0);
@> emit Deposit(depositor, amount, amountMinted);
return amountMinted;
}
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);
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());
emit Mint(caller, onBehalfOf, amountToMint, index);
@> return (isFirstMint, amountToMint, totalSupply(), amountScaled);
}

Impact

Loss of Trust and Transparency

One of the key purposes of emitting events in smart contracts is to provide transparency and ensure all actions within the contract can be tracked and verified by external observers (like users or dApps). If the wrong event is emitted:

  • Users will be misled, which could result in a lack of trust in the contract or the dApp.

  • The emitted logs may show inaccurate or incorrect information, damaging the overall reliability of the system.

Tools Used

Manual Review

Recommendations

function deposit(ReserveData storage reserve,ReserveRateData storage rateData,uint256 amount,address depositor) internal returns (uint256 amountMinted) {
...
// Mint RToken to the depositor (scaling handled inside RToken)
- (bool isFirstMint, uint256 amountScaled, uint256 newTotalSupply, uint256 amountUnderlying) = IRToken(reserve.reserveRTokenAddress).mint(
+ (bool isFirstMint, uint256 amountUnderlying, uint256 newTotalSupply, uint256 amountScaled) = IRToken(reserve.reserveRTokenAddress).mint(
address(this), // caller
depositor, // onBehalfOf
amount, // amount
reserve.liquidityIndex // index
);
amountMinted = amountScaled;
// Update the total liquidity and interest rates
updateInterestRatesAndLiquidity(reserve, rateData, amount, 0);
emit Deposit(depositor, amount, amountMinted);
return amountMinted;
}
Updates

Lead Judging Commences

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

Give us feedback!