Core Contracts

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

Hardcoded Exchange Rate Leading to Incorrect Deposits and Redemptions

Summary

The StabilityPool::getExchangeRate() function is hardcoded to return a fixed value of 1e18, which assumes a static 1:1 exchange rate between rToken and deToken. This implementation does not account for real-time changes in token supply and demand. As a result, users may receive incorrect amounts when depositing or redeeming tokens, leading to potential financial imbalances and arbitrage exploits.

Vulnerability Details

function getExchangeRate() public view returns (uint256) {
// uint256 totalDeCRVUSD = deToken.totalSupply();
// uint256 totalRcrvUSD = rToken.balanceOf(address(this));
// if (totalDeCRVUSD == 0 || totalRcrvUSD == 0) return 10**18;
// uint256 scalingFactor = 10**(18 + deTokenDecimals - rTokenDecimals);
// return (totalRcrvUSD * scalingFactor) / totalDeCRVUSD;
return 1e18;
}

Issue:

  1. Static Exchange Rate:

    • The function always returns 1e18, meaning the exchange rate between rToken and deToken is assumed to be fixed at 1:1.

    • The commented-out code suggests an original intention to make the rate dynamic based on token supply but was removed.

  2. Incorrect Deposit and Redemption Calculations:

    • The deposit function (deposit()) relies on calculateDeCRVUSDAmount(), which uses getExchangeRate().

    • The redemption function (calculateRcrvUSDAmount()) also uses getExchangeRate().

    • Since getExchangeRate() is hardcoded, these calculations may not reflect real market conditions.

  3. Arbitrage Risks:

    • If the real market value of rToken fluctuates, users can deposit undervalued tokens and redeem overvalued ones, extracting unearned profits.

    • This could result in protocol insolvency if redemptions exceed available reserves.

  4. Liquidity Imbalance:

    • The total supply of deToken may become misaligned with the actual available rToken balance.

    • If too many deposits occur before an update, redemptions may fail due to insufficient reserves.

Impact

https://github.com/Cyfrin/2025-02-raac/blob/main/contracts/core/pools/StabilityPool/StabilityPool.sol#L211-L212

Real-World Impact A similar issue occurred in DeFi lending protocols, where mispriced exchange rates led to excessive borrowing and redemption exploits. A well-known case was the Iron Finance Bank Run, where an artificially pegged stablecoin lost parity, causing mass redemptions and liquidity depletion.

Tools Used

Recommendations

Replace the hardcoded 1e18 with a formula that correctly derives the rate based on deToken.totalSupply() and rToken.balanceOf(address(this)).

Updates

Lead Judging Commences

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

StabilityPool::getExchangeRate hardcodes 1:1 ratio instead of calculating real rate, enabling unlimited deToken minting against limited reserves

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

StabilityPool::getExchangeRate hardcodes 1:1 ratio instead of calculating real rate, enabling unlimited deToken minting against limited reserves

Support

FAQs

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

Give us feedback!