The StabilityPool::withdraw() function calculates RAAC rewards based on current deposits rather than time-weighted deposits, allowing users to steal rewards through flash deposits.
The StabilityPool
contract incorrectly calculates RAAC rewards in calculateRaacRewards based on the current deposit balance and total supply at the time of withdrawal, rather than tracking time-weighted deposits. This allows users to temporarily inflate their share of rewards through flash deposits.
The key issue is in StabilityPool::calculateRaacRewards():
This calculation is flawed because:
It uses current deposits rather than time-weighted deposits
Rewards are only distributed on withdrawal
There is no minimum deposit time requirement
Add the following test to the StabilityPool.test.js file:
Legitimate long-term depositors can have their rewards stolen by attackers using flash deposits
The reward distribution mechanism fails to incentivize long-term deposits
Attackers can repeatedly execute this attack to drain accumulated rewards
Implement one of the following:
Implement time-weighted deposits
Add minimum deposit lockup period
Implement continuous reward distribution using reward per share mechanism
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.