It is observed that a vulnerability in the StabilityPool
contract allows users to perform a flash loan attack by depositing and immediately withdrawing funds to unfairly harvest RAAC rewards. This can be exploited through multiple rapid deposit/withdraw cycles to drain RAAC rewards from the pool.
The vulnerability exists in the withdraw()
function of the StabilityPool contract that allows users to immediately withdraw their deposits while still receiving RAAC rewards. The key issues:
In withdraw()
, RAAC rewards are calculated and distributed based on the current deposit state:
contracts/core/pools/StabilityPool/StabilityPool.sol#L229
The calculateRaacRewards()
function bases rewards on the user's current deposit ratio:
contracts/core/pools/StabilityPool/StabilityPool.sol#L251C1-L259C6
There is no minimum deposit time requirement or rewards vesting period, allowing immediate withdrawals.
An attacker could:
Take a flash loan of crvUSD, deposit into lending pool and mint rTokens
Call deposit() with large amount
Call withdraw() immediately
Receive RAAC rewards proportional to the large deposit
Repay flash loan
Repeat the cycle
The impact is high as this issue:
Allows complete drain of RAAC rewards tokens
Easy to exploit to achieve the maximum impact via flash loans
Manual code review
To incentivize user to stake their asset into the StabilityPool in exchange for RAACToken rewards and ensure fair rewards distribution:
The rewards amount for users should also be proportional to their staking duration. Consider adding reward vesting or linear distribution.
Implement a minimum deposit time requirement before rewards can be claimed.
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.