Core Contracts

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

Incorrect Scaling Factor in `calculateRcrvUSDAmount` Function

Description

The calculateRcrvUSDAmount function is designed to convert an amount of deCRVUSD (deToken) into an equivalent amount of rcrvUSD (rToken) using a scaling factor and an exchange rate. However, the scaling factor is calculated incorrectly as 10**(18 + rTokenDecimals - deTokenDecimals) instead of 10**(18 + deTokenDecimals - rTokenDecimals). This results in incorrect conversions, especially when the decimal places of the two tokens differ.

Impact

  • Incorrect Token Conversions: Users redeeming deCRVUSD for rcrvUSD will receive incorrect amounts, leading to financial losses.

  • Protocol Vulnerability: rToken balance will be drain

Root Cause

The scaling factor in calculateRcrvUSDAmount is calculated as:

https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/pools/StabilityPool/StabilityPool.sol#L202

uint256 scalingFactor = 10**(18 + rTokenDecimals - deTokenDecimals);

But in the calculateDeCRVUSDAmount the scaling factor is calculated as

https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/pools/StabilityPool/StabilityPool.sol#L192

uint256 scalingFactor = 10**(18 + deTokenDecimals - rTokenDecimals);

Proof of Concept

Setup

  1. Assume the following values for testing:

    • deTokenDecimals = 18 (e.g., deCRVUSD uses 18 decimal places, like ETH).

    • rTokenDecimals = 6 (e.g., rcrvUSD uses 6 decimal places, like USDC).

    • exchangeRate = 1e18 (1:1 exchange rate for simplicity).

  2. A user deposit 100e18 units of rToken.

deTokenAmount = 100e18 * 10**(18 + 18 - 6) / 1e18 = 100 * 10**30
deTokenAmount = 100e30
  1. User redeem his deToken

rTokenReceive = 100e30 * 1e18 / 10**(18 + 6 - 18)
rTokenReceive = 100e30 * 1e18 / 1e6
rTokenReceive = 100e30 * 1e12

This will drain rToken balance

The correct formula should be :

uint256 scalingFactor = 10**(18 + deTokenDecimals - rTokenDecimals );
return (deCRVUSDAmount * getExchangeRate()) / scalingFactor;

User would get

rTokenReceive = 100e30 * 1e18 / 10**(18 + 18 - 6)
rTokenReceive = 100e30 * 1e18 / 1e30
rTokenReceive = 100e18

Fix

Update the scaling factor calculation in calculateRcrvUSDAmount to:

uint256 scalingFactor = 10**(18 + deTokenDecimals - rTokenDecimals);
Updates

Lead Judging Commences

inallhonesty Lead Judge 5 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Incorrect scaling factor formula in StabilityPool::calculateRcrvUSDAmount function

Both tokens have 18 decimals. Info

Support

FAQs

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