Core Contracts

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

Lack of Exchange Rate Validation

Summary

The getExchangeRate() function in the StabilityPool contract hardcodes a 1e18 exchange rate, ignoring the actual balance or market value ratio between rToken and deToken. This high-impact, high-likelihood flaw risks over-issuing deToken when rToken’s value drops, leading to significant protocol losses during liquidations or redemptions by failing to reflect economic reality.

Vulnerability Details

The function returns a fixed 1e18, assuming a 1:1 value ratio between rToken and deToken (assumed tied to crvUSD). If rToken’s market value falls, this doesn’t adjust. Example:

rToken drops to 0.5 crvUSD, while deToken remains 1 crvUSD.
Attacker deposits 1000 rToken (500 crvUSD worth) via deposit().
Receives 1000 deToken (1e18 rate, scalingFactor = 1e18, decimals equal).
Uses 1000 deToken in a LendingPool liquidation to offset 1000 crvUSD debt, profiting 500 crvUSD.
The protocol loses 500 crvUSD due to unbacked deToken issuance.

Impact

The protocol faces severe losses (e.g., 500 crvUSD per exploit), a high-impact issue as over-issued deToken undermines stability. The high likelihood stems from rToken price volatility being common, making this a critical flaw that could drain reserves and erode trust.

Tools Used

Manual Code Review: To identify the fixed rate’s economic issue.

Recommendations

Calculate a dynamic exchange rate using WadRayMath:

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

Lead Judging Commences

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