The StabilityPool
contract's calculateRaacRewards
function computes RAAC rewards as (totalRewards * userDeposits[user]) / deToken.totalSupply()
, using the current RAAC balance (totalRewards
) without a reward debt or snapshot mechanism. This allows users to deposit RTokens late, claim a disproportionate share of rewards accrued over time, and withdraw, exploiting the system. A test case demonstrated this vulnerability: an attacker depositing 100 RTokens after 6 days into a 7-day period received 2.354 RAACToken, exceeding User1's 2.208 RAACToken despite only 1 day of participation, contrary to the expected outcome where earlier depositors should earn more.
The vulnerability arises in the calculateRaacRewards
function, which distributes RAAC rewards proportionally to a user's current deposit (userDeposits[user]
) relative to the total DEToken supply, based on the pool's RAAC balance at the time of withdrawal. The RAACMinter
contract, integrated via the tick()
function called during deposits and withdrawals, mints RAAC tokens to the StabilityPool
based on blocks elapsed (e.g., ~1000 RAAC/day), accumulating rewards over time. However, without tracking accumulated rewards per user over the participation period (reward debt) or using snapshots, late depositors can claim rewards for the entire period’s accumulation.
The final test case illustrates this issue:
Test Results:
Execution:
User1 deposits 100 RTokens at t=0, accumulating rewards for 7 days.
After 6 days, raacMinter.tick() mints 3840277777777777764 RAACToken.
Attacker deposits 100 RTokens at t=6 days, participating for 1 day.
At t=7 days, both withdraw, claiming User1: 2208333333333333324, Attacker: 2354166666666666656.
Observation:
Attacker receives more rewards (2.354 vs. 2.208) despite only 1/7th the participation time, failing the assertion expect(reward1).to.be.gt(rewardAttacker).
Root Cause: The absence of a reward debt or snapshot mechanism in calculateRaacRewards allows late depositors to claim rewards based on the entire accumulated RAAC balance, not their time-weighted contribution.
Fairness: Early depositors earn fewer rewards than late depositors, undermining the incentive for long-term participation.
Economic: Attackers can use flash loans to deposit large amounts late, claim outsized rewards, and withdraw, potentially draining the pool’s RAAC reserves.
Trust: Unfair reward distribution risks eroding user confidence, reducing staking and protocol adoption.
Manual, Hardhat test
Track RAAC rewards per DEToken share, updating user debt on deposit/withdrawal to ensure rewards match participation duration.
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.