🎁Vulnerabilities Due to Insufficient Precision in Reward Calculations

In smart contracts, especially those involving token distribution or rewards, precision is critical to ensure fair and accurate operations. A common issue arises when calculations lack the necessary precision, leading to results being rounded down to zero or significantly reduced, which can prevent proper distribution of rewards or benefits to users.

In this tutorial, we’ll explore how insufficient precision in mathematical operations can lead to significant vulnerabilities, explain why it happens, and demonstrate how to mitigate this issue.

The Vulnerability: Insufficient Precision in Reward or Token Calculations

When calculating rewards or benefits for users, the contract typically multiplies and divides values representing time intervals, token amounts, or other relevant data points. If the precision of these calculations is too low, small reward increments can be rounded down to zero, especially when the total amount being divided is large. This can lead to users not receiving their entitled rewards.

Example of the Vulnerability:

Consider a contract that calculates rewards per user based on time passed and a total supply value:

contract.rewardPerShare += uint128((timeDelta * 1e18) / totalSupply);

Where:

  • timeDelta is the time since the last update.

  • totalSupply is the total amount of tokens or units being tracked.

  • rewardPerShare is the reward earned per unit over time.

If the total supply is large, the reward calculation can suffer from precision loss. For example:

  • totalSupply = 10e18 (a large value).

  • timeDelta = 1 (a small time increment).

Using the above formula:

rewardPerShare = (1 * 1e18) / 10e18 = 0.1e18 = 0 (after rounding down).

Since the calculation result is too small to be represented with the precision of 1e18, it gets rounded down to zero, effectively giving the user no reward.


Impact: Why This is a Serious Issue

  1. Zero or Incorrect Rewards: Users who expect to receive rewards based on their participation in a system may get nothing due to precision issues. This can lead to dissatisfaction and loss of trust in the platform.

  2. Fairness Issues: When some users receive their correct rewards and others don’t, the fairness and credibility of the system are compromised.

  3. Systemic Imbalances: In long-running systems, the accumulation of precision errors can lead to significant imbalances where users are not rewarded appropriately, potentially destabilizing the system.


Mitigation: Improving Precision in Calculations

To avoid these precision-related issues, the solution is to increase the precision factor in the calculations or use an alternative approach that prevents rewards from being rounded down to zero.

1. Increase Precision Factor

One simple way to resolve the issue is to use a larger precision factor in the calculations, such as 1e27 instead of 1e18. This allows even small rewards to be represented accurately without being rounded down.

Updated formula:

contract.rewardPerShare += uint128((timeDelta * 1e27) / totalSupply);

In this case:

  • totalSupply = 10e18.

  • timeDelta = 1.

The calculation now becomes:

rewardPerShare = (1 * 1e27) / 10e18 = 0.1e27 = 1e26.

This higher precision prevents the reward from being rounded to zero and ensures that users receive their correct share.

2. Use Fixed-Point Arithmetic

Another option is to use fixed-point arithmetic, which is a more reliable way to handle precision in large-scale calculations. Libraries or custom implementations can help represent small fractions more accurately and avoid rounding errors.

3. Use Accumulation Techniques

By breaking down calculations into smaller, more manageable increments and accumulating results over time, the risk of precision loss can be minimized. This ensures that even very small amounts are accounted for properly.


Conclusion

Precision is crucial when performing calculations in smart contracts, particularly in systems that distribute rewards or tokens. Insufficient precision can lead to small reward values being rounded down to zero, which unfairly penalizes users. To mitigate this issue, developers should use larger precision factors (e.g., 1e27) or fixed-point arithmetic to ensure that all participants receive their fair share.

By improving the precision in your contract calculations, you can ensure accurate rewards distribution and maintain the integrity of the system, preventing potential exploitation or unintended consequences.

Last updated