MyCut

First Flight #23
Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: low
Valid

Rounding errors in manager cut calculation method

Summary

The closePot() function in the Pot contract uses integer division to calculate the manager's cut of the remaining rewards. This method can lead to rounding errors, potentially resulting in the manager receiving less than the intended percentage, especially for small reward amounts.

Vulnerability Details

The vulnerable code is located in the closePot() function of the Pot contract:

uint256 managerCut = remainingRewards / managerCutPercent;

Where managerCutPercent is defined as:

uint256 private constant managerCutPercent = 10;

This calculation uses integer division, which always rounds down to the nearest integer. As a result:

  1. For remainingRewards < 10, managerCut will always be 0.

  2. For values not divisible by 10, some fraction of a token will always be lost to rounding.

Impact

The impact of this vulnerability includes:

  1. Loss of funds for the manager: For small pot sizes, the manager might receive no cut at all, despite being entitled to 10%.

  2. Inconsistent reward distribution: The actual percentage the manager receives will vary depending on the total reward amount, leading to inconsistencies across different contests.

Tools Used

Manual code review.

AI for report text and formatting.

Recommendations

To address this vulnerability, consider the following recommendations:

  1. Use percentage multiplication instead of division:

    uint256 managerCut = (remainingRewards * managerCutPercent) / 100;

    This allows for more precise percentages and minimizes rounding errors.

  2. Implement a minimum cut for the manager to ensure they always receive something:

    uint256 managerCut = max((remainingRewards * managerCutPercent) / 100, MIN_MANAGER_CUT);
  3. For high-precision tokens, consider using fixed-point arithmetic:

    uint256 managerCut = (remainingRewards * managerCutPercent) / 1e18;

    Where managerCutPercent would be represented as a percentage multiplied by 1e18 (e.g., 10% would be 1e17).

  4. Add checks to ensure the calculated cut is within expected bounds:

    uint256 managerCut = (remainingRewards * managerCutPercent) / 100;
    require(managerCut > 0, "Manager cut too small");
    require(managerCut <= remainingRewards / 10, "Manager cut too large");

By implementing these recommendations, the contract will provide a more accurate and consistent calculation of the manager's cut, reducing the potential for fund loss and manipulation.

Updates

Lead Judging Commences

equious Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Dusty Pot

Support

FAQs

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