Core Contracts

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

`StabilityPool::deposit` and `withdraw` can be DoSed permanently if rToken and deToken have different decimals

Summary

when depositing rToken or withdrawing deToken, the contract calculates the amount user would get for the corresponding token. but the flaw in the logic does not account if the decimals is different

Vulnerability Details

StabilityPool.sol#L54-L56

// Allow to make rToken / deToken decimals flexible
uint8 public rTokenDecimals;
uint8 public deTokenDecimals;

the code intended to allow the rToken / deToken to have flexible decimal, thus they implement the scaling factor to calculate the amount of exchange from rToken-deToken:

StabilityPool.sol#L186-L204

/**
* @notice Calculates the amount of deToken to mint for a given rToken deposit.
* @param rcrvUSDAmount Amount of rToken deposited.
* @return Amount of deToken to mint.
*/
function calculateDeCRVUSDAmount(uint256 rcrvUSDAmount) public view returns (uint256) {
@> uint256 scalingFactor = 10**(18 + deTokenDecimals - rTokenDecimals);
return (rcrvUSDAmount * scalingFactor) / getExchangeRate();
}
/**
* @notice Calculates the amount of rToken to return for a given deToken redemption.
* @param deCRVUSDAmount Amount of deToken to redeem.
* @return Amount of rToken to return.
*/
function calculateRcrvUSDAmount(uint256 deCRVUSDAmount) public view returns (uint256) {
uint256 scalingFactor = 10**(18 + rTokenDecimals - deTokenDecimals);
@> return (deCRVUSDAmount * getExchangeRate()) / scalingFactor;
}

but one of this function would be broken if the decimals is not 18.

1) if one of the token decimal is 18, and the other is 6, then one of the function would revert because of overflow

2) if two token decimals is not 18, let say 6 for both token, then the scalingFactor would result in 10**18 which is different

Impact

the above function always result in DoS, as the example above, the first one because overflow. the second one because the token amount is bigger than what it supposed to be, potentially makes the tx revert if user/pool does not have the amount or if the amount suffice then it would became loss for user or pool because the amount transferred should not that huge.

Tools Used

manual review

Recommendations

derive the decimals straight from the rToken and deToken contract, and work the scaling by checking what contract have bigger decimal than other before deducting it and then multiply it with the corresponding token.

consider to not use addition when doing the exponent, you can use multiplication for more readability.

Updates

Lead Judging Commences

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