FjordPoints contract's point distribution mechanism is based on a snapshot of staked tokens at the time of distribution, rather than considering the duration of staking within each epoch. This creates an avenue for users to game the protocol by staking large amounts just before distribution and unstaking immediately after.
The distributePoints()
function updates global variables like pointsPerToken
and totalPoints
based on the current totalStaked
amount. However, it doesn't account for when users staked or unstaked within an epoch. Points are only calculated and assigned to users when they interact with the contract (stake, unstake, or claim points) using the updatePendingPoints
modifier.
This causses 2 main problems;
Users who stake just before distributePoints()
is called can receive points for the entire epoch, even if they only staked for a brief period.
Users who unstake just before distributePoints()
is called may not receive points for the period they had tokens staked.
For example:
Alice stakes 100 tokens for a full week (epoch).
Bob stakes 1000 tokens just before distribution.
After distribution, Bob would receive 10 times more points than Alice, despite only staking for a very short time which shouldnt be so.
Unfair distribution of points, not accurately reflecting users' staking commitment over time. This opens up honeypot oppportunities for malicious users who time their stakes to maximize point earnings without long-term commitment which isn't what the protocol would want and if thats the case, then there's no incentive for long-time commitment.
Manual
consider implementing a more granular point distribution system that accounts for the duration of staking within each epoch. Something like a checkpoint system that records changes in user stakes and global total stakes at each interaction and modify the point calculation logic to consider the time-weighted average of a user's staked amount over the entire epoch, rather than just the final amount at distribution time.
Another point I could think of is to distribute points more frequently, such as every block or every few blocks, rather than once per epoch. This would minimize the impact of users staking or unstaking just before the distribution. Downside of this approach is that it'll increase gas costs due to more frequent point calculations and updates.
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.