Core Contracts

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

Deposit event emits incorrect mintedAmount of RTokens

Summary

The RToken.mint() function is called when a user deposits reserve tokens into the protocol. However, the the amountToMint it returns and emited in Deposit event is incorrect.

Vulnerability Details

When users deposit reserve tokens via LendingPool.deposit(), they specify the amount of reserve tokens to they intend to supply.

function deposit(uint256 amount) external nonReentrant whenNotPaused onlyValidAmount(amount) {
---SNIP--
// @audit-info Expects RTokens minted
>> uint256 mintedAmount = ReserveLibrary.deposit(reserve, rateData, amount, msg.sender);
---SNIP--
// @audit-info should emit RTokens minted
>> emit Deposit(msg.sender, amount, mintedAmount);
}

It invokes ReserveLibrary.deposit() which does the following:

// @audit-info Expects correct values
>> (bool isFirstMint, uint256 amountScaled, uint256 newTotalSupply, uint256 amountUnderlying) = IRToken(reserve.reserveRTokenAddress).mint(
address(this), // caller
depositor, // onBehalfOf
amount, // amount
reserve.liquidityIndex // index
);
// @audit-info should be RTokens minted
>> amountMinted = amountScaled;
---SNIP---
// @audit-info should report RTokens minted
>> emit Deposit(depositor, amount, amountMinted);
// @audit-info should return RTokens minted
>> return amountMinted;

Now in RToken.mint(), this amount is passed down as amountToMint and now notice the values it returns and their order:

uint256 amountScaled = amountToMint.rayDiv(index);
if (amountScaled == 0) revert InvalidAmount();
---SNIP---
_mint(onBehalfOf, amountToMint.toUint128());
emit Mint(caller, onBehalfOf, amountToMint, index);
// @audit-issue Returns Incorrect number of RTokens minted
>> return (isFirstMint, amountToMint, totalSupply(), amountScaled);

Now, the amountToMint in underlying units is scaled into amountScaled. The function the calls _mint() with this value then returns the same amountToMint as the second return value. This is not right:

When _mint() is called with amountScaled, it internally calls _update() function which is overriden here as follows:

>> uint256 scaledAmount = amount.rayDiv(ILendingPool(_reservePool).getNormalizedIncome());
super._update(from, to, scaledAmount);

As seen, it first scaled the provided amount by the current liquidityIndex then mints the result to the user. So, actually the amount of RTokens minted to the user is not amountToMint but amountScaled calculated in mint() above.

Now, when mint() returns amountToMint as the second return value, this becomes amountScaled in ReserveLibrary.deposit(). The amountMinted there is then set to this amountScaled and Deposit event emited and it further returns amountToMint which is again used in LendingPool.deposit() in Deposit event.

According to the comment given:

// amountMinted The amount of RTokens minted.
Therefore, the returned value from RToken.mint() is incorrect.

Impact

External users who depend on these events receive inaccurate information about the actual amount of RTokens minted to users in exchange for their deposits.

Tools Used

Manual Review

Recommendations

Modify the RToken.mint() to return correct values:

uint256 amountScaled = amountToMint.rayDiv(index);
if (amountScaled == 0) revert InvalidAmount();
---SNIP---
_mint(onBehalfOf, amountToMint.toUint128());
emit Mint(caller, onBehalfOf, amountToMint, index);
- return (isFirstMint, amountToMint, totalSupply(), amountScaled);
+ return (isFirstMint, amountScaled, totalSupply(), amountToMint);
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!