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

Precision Loss in Point Distribution Due to Multiplication After Division

Summary

The distributePoints() function in the FjordPoints contract performs a multiplication on the result of a division, which can lead to a loss of precision in the calculation of points per token. This could result in inaccurate distribution of points to users over time.

Vulnerability Details

In the distributePoints() function, the following calculations are performed:

weeksPending = (block.timestamp - lastDistribution) / EPOCH_DURATION;
pointsPerToken = pointsPerToken.add(weeksPending * (pointsPerEpoch.mul(PRECISION_18).div(totalStaked)));

The issue arises because:

  1. weeksPending is calculated using integer division, which truncates any remainder.

  2. This truncated weeksPending is then multiplied by the result of another division operation.

This order of operations can lead to a loss of precision, especially when:

  • The time elapsed since the last distribution is not an exact multiple of EPOCH_DURATION

  • The totalStaked amount is large relative to pointsPerEpoch

Impact

1: Users will receive fewer points than they should due to the loss of precision, especially over longer periods.

2: The effect of this precision loss will compound over time, leading to increasingly significant discrepancies in point allocation.

Tools Used

manual review

Recommendations

1: Reorder the operations to minimize precision loss:

uint256 timeElapsed = block.timestamp - lastDistribution;
pointsPerToken = pointsPerToken.add((timeElapsed * pointsPerEpoch * PRECISION_18) / (EPOCH_DURATION * totalStaked));

2: Use a higher precision for intermediate calculations:

uint256 timeElapsed = block.timestamp - lastDistribution;
uint256 highPrecisionPoints = (timeElapsed * pointsPerEpoch * PRECISION_18 * ADDITIONAL_PRECISION) / EPOCH_DURATION;
pointsPerToken = pointsPerToken.add(highPrecisionPoints / totalStaked);
Updates

Lead Judging Commences

inallhonesty Lead Judge
10 months ago
inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

Division before multiplication

Support

FAQs

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