The formulas for calculating the amount of deToken
(DeCRVUSD) to receive when sending rToken
(rcrvUSD) do not correctly account for tokens with different decimal places. From the implementation, it intends to account for tokens with different decimals. While the implementation works for tokens with the same decimals (e.g., both 18 decimals), it fails for tokens with different decimals (e.g., 6 and 18). This leads to incorrect conversions, as the scaling factor does not properly normalize the decimal differences. The current implementation attempts to handle tokens with different decimals but is flawed, resulting in inaccurate calculations. This issue also affects the withdraw
function, causing users to experience reverts due to insufficient balances when attempting to withdraw funds.
Affected Code: StabilityPool::calculateDeCRVUSDAmount
& calculateRcrvUSDAmount
The current implementation of the conversion formulas is as follows:
Incorrect Scaling Factor:
The scaling factor 10**(18 + deTokenDecimals - rTokenDecimals)
is arbitrary and does not correctly account for the difference in decimals between the two tokens.
For tokens with different decimals, this leads to incorrect conversions.
Assumption of 1:1 Conversion:
The implementation assumes a 1:1 conversion for tokens with different decimals, which is incorrect.
Impact on withdraw
Function:
The incorrect conversion formulas affect the withdraw
function, causing users to experience reverts due to insufficient balances when attempting to withdraw funds.
For example, if a user deposits rToken
and receives an incorrect amount of deToken
, they may not have enough deToken
to cover the withdrawal, leading to the InsufficientBalance
revert.
Let’s assume:
rToken
(rcrvUSD) has 6 decimals.
deToken
(DeCRVUSD) has 18 decimals.
getExchangeRate()
returns 1e18
(1:1 exchange rate in ray math).
10 rToken
(rcrvUSD) to deToken
(DeCRVUSD)Current Implementation:
scalingFactor = 10**(18 + 18 - 6) = 10**30
.
calculateDeCRVUSDAmount(10 * 1e6) = (10 * 1e6 * 1e30) / 1e18 = 10 * 1e18
.
10 deToken
(DeCRVUSD) to rToken
(rcrvUSD)Current Implementation:
scalingFactor = 10**(18 + 6 - 18) = 10**6
.
calculateRcrvUSDAmount(10 * 1e18) = (10 * 1e18 * 1e18) / 1e6 = 10 * 1e30
.
This result is incorrect because it does not account for the difference in decimals.
Incorrect Conversions: Users will receive incorrect amounts of tokens when converting between rToken
and deToken
if the tokens have different decimals.
Financial Loss: Users may lose funds due to inaccurate calculations.
Protocol Integrity: The protocol’s functionality is compromised, leading to a loss of trust among users.
Withdraw Function Reverts: Users may experience reverts due to insufficient balances when attempting to withdraw funds, as incorrect conversion formulas lead to mismatched balances.
Manual code review
To fix the issue, the scaling factor must correctly account for the difference in decimals between the two tokens. Here’s the corrected implementation:
Both tokens have 18 decimals. Info
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.