Core Contracts

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

Incorrect scalingFactor formula inside calculateRcrvUDSAmount()

Description

calculateRcrvUSDAmount() calculates & applies scalingFactor incorrectly. It should be:

File: contracts/core/pools/StabilityPool/StabilityPool.sol
186: /**
187: * @notice Calculates the amount of deToken to mint for a given rToken deposit.
188: * @param rcrvUSDAmount Amount of rToken deposited.
189: * @return Amount of deToken to mint.
190: */
191: function calculateDeCRVUSDAmount(uint256 rcrvUSDAmount) public view returns (uint256) {
192: uint256 scalingFactor = 10**(18 + deTokenDecimals - rTokenDecimals);
193: return (rcrvUSDAmount * scalingFactor) / getExchangeRate();
194: }
195:
196: /**
197: * @notice Calculates the amount of rToken to return for a given deToken redemption.
198: * @param deCRVUSDAmount Amount of deToken to redeem.
199: * @return Amount of rToken to return.
200: */
201: function calculateRcrvUSDAmount(uint256 deCRVUSDAmount) public view returns (uint256) {
- 202: uint256 scalingFactor = 10**(18 + rTokenDecimals - deTokenDecimals);
+ 202: uint256 scalingFactor = 10**(18 + deTokenDecimals - rTokenDecimals);
203: return (deCRVUSDAmount * getExchangeRate()) / scalingFactor;
204: }

Imagine:

  • deTokenDecimals = 20 and rTokenDecimals = 12

  • rTokenAmount = 100 * 1e12 ⬅️

  • Converted to deTokenAmount as per calculateDeCRVUSDAmount():

    • scalingFactor = 10**(18 + 20 - 12) = 10**26

    • deTokenAmount = (100e12 * 1e26) / 1e18 = 100e20

  • Let's convert back via calculateRcrvUSDAmount():

    • scalingFactor = 10**(18 + 12 - 20) = 10**10

    • rTokenAmount = (100e20 * 1e18) / 1e10 = 100e28 ❌

Impact

Depending on the difference between decimals of the two tokens, the value returned could be highly inflated or deflated. This will heavily effect deposit() and withdraw() functions and can cause protocol loss as they mint and burn disproportionate amount of funds.

Mitigation

As shown in the diff, use:

  • scalingFactor = 10**(18 + 20 - 12) = 10**26

  • rTokenAmount = (100e20 * 1e18) / 1e26 = 100e12 ✔️

We are assuming of course that getExchangeRate() will always be 1e18.

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.