Core Contracts

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

Users Could Steal Excess Assets in the `mint` and `balanceOf` Functions of `RToken.sol` Contract

Summary

Common users can steal excess underlying asset, by depositing funds, exploiting the double interest calculation to receive more RToken, and then withdrawing immediately.

amountScaled is the minted amount calculated to maintain a 1:1 value ratio between the RToken and the UnderlyingToken, where amountScaled == amountToMint / liquidityIndex. The mint function in the RToken.sol contract should mint amountScaled RToken tokens. However, the function incorrectly mints amountToMint tokens instead. This results in new users minting more RToken tokens and earning more interest, while older users lose out on their deposit interest.

Vulnerability Details

Core Issue: Mint Incorrect Amount
The mint function in the RToken.sol contract incorrectly mints amountToMint instead of amountScaled. The function should mint amountScaled to maintain a 1:1 ratio of total value between RToken and the underlying token.

contracts/core/tokens/RToken.sol:mint#L136

function mint(
address caller,
address onBehalfOf,
uint256 amountToMint,
uint256 index
) external override onlyReservePool returns (bool, uint256, uint256, uint256) {
...
uint256 amountScaled = amountToMint.rayDiv(index); // @audit: Standardized amount
if (amountScaled == 0) revert InvalidAmount();
uint256 scaledBalance = balanceOf(onBehalfOf);
...
//@audit: Error - Minting the actual amount instead of the normalized amount, for example: mint 1000 USDC
_mint(onBehalfOf, amountToMint.toUint128());
}

However, balanceOf will be multiplied by the interest rate index again, causing the user's balance to be calculated with interest an additional time.

function balanceOf(address account) public view override(ERC20, IERC20) returns (uint256) {
uint256 scaledBalance = super.balanceOf(account);
// @audit: Error: The interest rate index is multiplied again, for example: 1000 * 1.1 = 1100 USDC
return scaledBalance.rayMul(ILendingPool(_reservePool).getNormalizedIncome());
}

Example of Double Counting Interest:

Assumptions:

  • User deposit: 1000 USDC.

  • Interest rate index: 1.1

Issues with the current implementation:

  1. Expected mint

    • Value is maintained 1:1 (not the quantity, but the value)

    • RToken amount = Deposit amount / current index = 1000 USDC / 1.1 = 909.09

  2. Actual mint:

    • 1000 USDC is minted (actual amount).

    • Stored in the ERC20 balance.

  3. When querying balanceOf:

    • Retrieve 1000 USDC, multiply by the interest rate index of 1.1.

    • Return 1100 USDC.

    • User steal 100 USDC

Incorrect Result: User steal 100 USDC
The user sees a balance that includes an additional interest calculation, leading to an inflated balance.

Attack Steps:

  • Deposit funds.

  • Exploit double interest calculation to receive more RToken.

  • Withdraw immediately to obtain excess USDC.

Impact

  • Platform funds are stolen: New users mint more RTokens than they should, causing a dilution of interest income.

  • Unfair Interest Distribution: Existing users lose a portion of their rightful interest due to incorrect balance calculations.

  • Protocol Insolvency: The protocol's liquidity pool is drained faster than it can accumulate funds, potentially causing the protocol to run out of assets.

Tools Used

Manual code review

Recommendations

It is recommended to modify mint() to correctly use amountScaled instead of amountToMint, so as to maintain the correct 1:1 peg, ensure fair interest distribution, prevent immediate arbitrage and protect platform funds.

function mint(...) {
uint256 amountScaled = amountToMint.rayDiv(index); // Standardized amount
// @audit: Correct minting of amountScaled (standardized amount)
- _mint(onBehalfOf, amountToMint.toUint128());
+ _mint(onBehalfOf, amountScaled.toUint128());
}
Updates

Lead Judging Commences

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

RToken::mint should mint the amountScaled not the amountToMint

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

RToken::mint should mint the amountScaled not the amountToMint

Support

FAQs

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