The withdrawal calculation in StabilityPool.sol uses an inverted decimal scaling formula compared to deposits, enabling users to withdraw incorrect rToken amounts. This fundamental arithmetic error destroys the core value preservation guarantee of the StabilityPool when rToken/deToken have different decimals.
The vulnerability stems from mismatched scaling factors between deposit and withdrawal calculations:
Deposit Calculation (calculateDeCRVUSDAmount):
Withdrawal Calculation (calculateRcrvUSDAmount):
The withdrawal calculation reverses the decimal adjustment order, creating an asymmetric scaling relationship. This error persists regardless of specific decimal values when deTokenDecimals ≠ rTokenDecimals.
Let's demonstrate the issue with specific values:
deTokenDecimals = 18, rTokenDecimals = 6
User deposits 100 rTokens (100e6)
1. Deposit Flow (calculateDeCRVUSDAmount):
we mint to the user : 100e18 deTokens
2. Withdrawal Flow (calculateRcrvUSDAmount):
The Issue:
User deposited 100e6 rTokens
User received 100e18 deTokens (correct conversion)
User attempts to withdraw 100e18 deTokens
User receives 100e30 rTokens (24 orders of magnitude more!)
This happens because:
The deposit correctly scales up by multiplying with a large factor (10^30)
The withdrawal incorrectly scales down by dividing by a small factor (10^6)
The formulas should be inverses of each other, but flipping the subtraction in the exponent breaks this relationship
could lead to permanently locks funds by DoSing withdrawals, or allows complete protocol fund drainage
Foundry
Manual Review
This change aligns the withdrawal scaling with the deposit calculation, maintaining consistent decimal handling across both operations regardless of specific decimal values.
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.