The vesting contract calculates vested token amounts using integer division, which truncates fractional values. Over time, these rounding errors accumulate, causing users to receive fewer tokens than entitled. For example, a user owed 100.5 tokens receives only 100, losing 0.5 tokens permanently. This violates fairness and leads to financial loss for beneficiaries.
https://github.com/Cyfrin/2025-02-raac/blob/89ccb062e2b175374d40d824263a4c0b601bcb7f/contracts/core/minters/RAACReleaseOrchestrator/RAACReleaseOrchestrator.sol#L197
Example Scenario
Vesting Schedule Setup: imagine that :
Total tokens: 1,000 RAAC
Vesting duration: 100 days
Daily Vesting Calculation:
Daily vested amount =
1,000 RAAC × 1 day ÷ 100days =10 RAAC/day
Partial Day Vesting:
After 1.5 days, entitled amount = 1.5×10=15 RAAC.
Actual Calculation:
After 0.7 days :
No Loss Here, but consider smaller values:
If total tokens = 999 RAAC
Daily vested : 900 ÷ 100 =
9.99 RAAC/day.
After 1 day: 9 RAAC (truncated from 9.99).
Loss: 0.99 RAAC per day.
Cumulative Loss: Small truncations compound over time, especially for long-duration vesting.
Unclaimed Dust: Residual tokens remain trapped in the contract.
Reputation Damage: Users perceive the protocol as unfair.
Manual review
Use scaled arithmetic to preserve precision during calculations and distribute residual amounts fairly.
Step 1: Calculate Vested Amount with Higher Precision
Multiply token amounts by a scaling factor (e.g., 1e18) during calculations:
Step 2: Track Residual Dust and Distribute Fairly
Add a residual tracker and allocate remaining tokens in the final claim:
Why This Fix Works
Scaled Precision: Intermediate calculations use 1e18 precision, minimizing truncation.
Residual Tracking: Captures fractional tokens and allocates them in the final claim.
Fair Distribution: Users receive nearly exact amounts, with dust resolved at the end.
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.