Core Contracts

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

Incorrect `RToken` minting on deposit allows users to withdraw more underlying than expected

Description

The protocol incorrectly mints RTokens during deposits by using the wrong amount in the mint function. Instead of minting the scaled amount amountToMint.rayDiv(index), it mints the raw deposit amount amountToMint. This results in users receiving more RTokens than they should. The scaling mechanism is essential because it accounts for the accumulation of interest in the protocol through the liquidity index. When users deposit, their deposit amount should be divided by the current liquidity index to determine how many RTokens they receive. However, the current implementation mints RTokens 1:1 with the deposit amount, ignoring this scaling factor, minting more RTokens than expected.

Context

Impact

High. When users deposit tokens, they receive more RToken than they should due to the incorrect amount being minted. This leads to users being able to withdraw more underlying tokens than they initially deposited, and potentially withdraw other users funds.

Likelihood

High. This issue occurs on every deposit transaction due to a core calculation error in the mint function, making it consistently exploitable by any user depositing into the protocol.

Proof of Concept

scenario 1:

Deposit at time t1:
initial liquidity index : 1.01
initial deposit amount : 2000 crvUSD
amount minted expected : 2000 / 1.01 = 1980.1980198 rToken
amount minted actual : 2000 rToken
Withdraw at time t2:
final liquidity index : 1.02
amount withdrawable expected : 1980.1980198 * 1.02 = 2019.8019802
amount withdrawable actual : 2000 * 1.02 = 2040
amount withdrawable excess : 2040 - 2019.8019802 = 20.1980198

scenario 2:

Deposit at time t1:
initial liquidity index : 1.01
initial deposit amount : 2000 crvUSD
amount minted expected : 2000 / 1.01 = 1980.1980198 rToken
amount minted actual : 2000 rToken
Withdraw at time t1:
final liquidity index : 1.01
amount withdrawable expected : 1980.1980198 * 1.01 = 2000
amount withdrawable actual : 2000 * 1.01 = 2020

Recommendation

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());
+ _mint(onBehalfOf, amountScaled);
emit Mint(caller, onBehalfOf, amountToMint, index);
- return (isFirstMint, amountToMint, totalSupply(), amountScaled);
+ return (isFirstMint, amountScaled, totalSupply(), amountToMint);
}
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

RToken::mint should mint the amountScaled not the amountToMint

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

RToken::mint should mint the amountScaled not the amountToMint

Support

FAQs

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