Users can be permanently locked out of claiming rewards via FeeCollector::claimRewards
when new veToken holders join and dilute the total voting power which causes the formula to return 0 always due to a flawed reward calculation mechanism in FeeCollector::_calculatePendingRewards
.
The _calculatePendingRewards
function calculates rewards by:
This means:
A user's share is their percentage of totalDistributed based on current voting power
This calculated share must exceed their last claimed amount (userRewards[user]
) to receive rewards
When new stakers join, the user's voting percentage drops, making their share smaller than their last claim
For example:
Initial State:
Alice stakes 100 tokens (66% of pool)
totalDistributed = 10 ETH
Alice claims her share (6.6 ETH)
userRewards[Alice] = 10 ETH
Dilution Occurs:
Bob stakes 300 tokens
Alice's voting power drops to 25%
New fees added, totalDistributed = 20 ETH
Alice's new share = (20 ETH * 25%) = 5 ETH
Since 5 ETH < 10 ETH, claim reverts
This condition can never be reversed without massive fee influx
Users who have legitimately staked and claimed rewards can be permanently locked out from claiming future rewards when large stakers join. This effectively:
Denies users access to future rewards they should be entitled to
Early stakers are punished
May force users to unstake and restake to access rewards
Foundry
Implement a reward epoch system where:
Each fee distribution creates a new epoch
User rewards are calculated based on their voting power at distribution time
Previous claims cannot be diluted by future staking activity
This matches established patterns used in major DeFi protocols for fair reward distribution.
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.