DeFiFoundry
20,000 USDC
View results
Submission Details
Severity: medium
Invalid

If the `updatePendingPoints` modifier is triggered in the `claimPoints` function before `distributePoints` has been called, users might claim points that don’t fully account for the latest distributions.

Summary

Link one
Link two
Link three

Vulnerability Details

The distributePoints function is responsible for updating the global pointsPerToken variable, which reflects the total amount of points distributed per staked token. This function ensures that the points distribution is updated according to the time elapsed and the total staked amount.

In the contract, the claimPoints function triggers the updatePendingPoints modifier to calculate the pending points for the user based on the current pointsPerToken. The modifier calculates the additional points earned since the user’s last recorded pointsPerToken:

modifier updatePendingPoints(address user) {
UserInfo storage userInfo = users[user];
uint256 owed = userInfo.stakedAmount.mul(pointsPerToken.sub(userInfo.lastPointsPerToken))
.div(PRECISION_18);
userInfo.pendingPoints = userInfo.pendingPoints.add(owed);
userInfo.lastPointsPerToken = pointsPerToken;
_;
}

If distributePoints hasn’t updated pointsPerToken, the modifier calculates the pending points using an outdated pointsPerToken.
This means the pending points might not include the most recent distributions, leading to users potentially claiming fewer points than they should.

Impact

If distributePoints has not been executed recently, the pointsPerToken used in the updatePendingPoints modifier may be outdated. This can lead to users claiming fewer points than they are actually owed, as the latest distribution adjustments have not been applied to their pending points.

Tools Used

Manual

Recommendations

Enforce a call to distributePoints before users claim points.

function claimPoints() external checkDistribution updatePendingPoints(msg.sender) {
// Ensure points are distributed before claiming
distributePoints();
UserInfo storage userInfo = users[msg.sender];
uint256 pointsToClaim = userInfo.pendingPoints;
if (pointsToClaim > 0) {
userInfo.pendingPoints = 0;
_mint(msg.sender, pointsToClaim);
emit PointsClaimed(msg.sender, pointsToClaim);
}
}
Updates

Lead Judging Commences

inallhonesty Lead Judge
11 months ago
inallhonesty Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.