Core Contracts

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

Previously deposited LPs are losing intersts on further Depositing

Summary

Vulnerability Details

To found out this Bug, Workflow is like below

  • Lp call `LendingPool :: deposit()` with amount

  • this function further call ReserveLibrary.deposit()

  • after updating Reserves interst updateReserveInterests (liquidityIndex and usagesIndex), minting of `rToken` happens

    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);
    }

here balnaceIncrease is calculated for previously deposited LPs

balanceIncrease = scaledBalance.rayMul(index) - scaledBalance.rayMul(_userState[onBehalfOf].index)

But as you can see this balanceIncreasevariable never used further in that code base, and _userState[onBehalfOf].indexis updated with current liquidity index,

That means all the Interst accured by Lp from previous liquidity index to current liquidity index will be lost.

https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/core/tokens/RToken.sol#L129-L139

Impact

Lp losing their intest on previous deposited value.

Tools Used

Manual review

Recommendations

Add balanceIncreasedwith `amountToMint` and Mint resultant amount to caller

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() + balanceIncrease);
Updates

Lead Judging Commences

inallhonesty Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

RToken::mint calculates balanceIncrease (interest accrued since last interaction) but never mints it, causing users to lose earned interest between deposits

The balanceIncrease is the interest that has already accrued on the user's existing scaledBalance since their last interaction. It's not something you mint as new tokens in the _mint function.

inallhonesty Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

RToken::mint calculates balanceIncrease (interest accrued since last interaction) but never mints it, causing users to lose earned interest between deposits

The balanceIncrease is the interest that has already accrued on the user's existing scaledBalance since their last interaction. It's not something you mint as new tokens in the _mint function.

Support

FAQs

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