Core Contracts

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

Incorrect decimal scaling in StabilityPool withdrawal calculation leading to loss of funds

Summary

The calculateRcrvUSDAmount function in StabilityPool uses an incorrect scaling factor formula which would cause users to receive much less RTokens than they should when withdrawing their DETokens, particularly when the tokens have different decimals.

Vulnerability Details

function calculateRcrvUSDAmount(uint256 deCRVUSDAmount) public view returns (uint256) {
// @audit incorrect scaling factor formula
uint256 scalingFactor = 10**(18 + rTokenDecimals - deTokenDecimals);
return (deCRVUSDAmount * getExchangeRate()) / scalingFactor;
}

The issue is that this function uses the wrong scaling factor formula compared to the deposit function:

function calculateDeCRVUSDAmount(uint256 rcrvUSDAmount) public view returns (uint256) {
uint256 scalingFactor = 10**(18 + deTokenDecimals - rTokenDecimals);
return (rcrvUSDAmount * scalingFactor) / getExchangeRate();
}

Example with DEToken (6 decimals) and RToken (18 decimals):

// Depositing 1 RToken (1e18)
calculateDeCRVUSDAmount(1e18):
scalingFactor = 10**(18 + 6 - 18) = 1e6
return (1e18 * 1e6) / 1e18 = 1e6 (1 DEToken)
// Withdrawing 1 DEToken (1e6)
calculateRcrvUSDAmount(1e6):
scalingFactor = 10**(18 + 18 - 6) = 1e30
return (1e6 * 1e18) / 1e30 = 1e-6 (0.000001 RToken)

When a user deposits 1 RToken and then withdraws their 1 DEToken, they would receive only 0.000001 RToken back instead of their original 1 RToken.

Impact

Critical. Users withdrawing from the StabilityPool would receive far less RTokens than they should, effectively losing most of their funds when the tokens have different decimals.

Recommended Mitigation

Modify calculateRcrvUSDAmount to use the correct scaling formula:

function calculateRcrvUSDAmount(uint256 deCRVUSDAmount) public view returns (uint256) {
uint256 scalingFactor = 10**(18 + deTokenDecimals - rTokenDecimals); // Same as deposit
return (deCRVUSDAmount * getExchangeRate() * scalingFactor) / 1e18;
}

Proof of Concept

  1. User deposits 1 RToken (1e18)

  2. Receives 1 DEToken (1e6)

  3. User withdraws 1 DEToken (1e6)

  4. With current code, receives 0.000001 RToken instead of 1 RToken

  5. User has lost 99.9999% of their funds

Updates

Lead Judging Commences

inallhonesty Lead Judge 7 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.

Give us feedback!