Sparkn

CodeFox Inc.
DeFiFoundryProxy
15,000 USDC
View results
Submission Details
Severity: low
Valid

Distributor code forces unfair distributions when supporters provide equal value proportion

Summary

The check totalPercentage != (10000 - COMMISSION_FEE) can fail due to integer division precision errors when evenly distributing funds between multiple winners. This will block the distribution.

Vulnerability Details

In _distribute() it is assumed that the caller should always pass the percentages array which totals to 9500 as of this version. But it restricts organizers biased to winners when there are same value proportion made by several users of protocol. The protocol misses such cases where it leads to unfair reward distributions.

for (uint256 i; i < percentagesLength;) {
totalPercentage += percentages[i];
unchecked {
++i;
}
}
// check if totalPercentage is correct
// @audit-issue organizer can never split equal amount for odd count of winners
if (totalPercentage != (10000 - COMMISSION_FEE)) {
revert Distributor__MismatchedPercentages();
}

Proof of Concept

  1. Alice sets a contest

  2. 3 Supporter provided same value

  3. Alice wanted to allot prizes evenly among them.

  4. But the protocol forces to totalPercentages == 9500

  5. Alice can't divide 9500 among 3 as it gives each 3166.66 shares which is not possible.

  6. Protocol should allow to distribute either excess/less of expectedTotal % winners.length (9500 % 3)

  7. As it is strictly checking for 10000-COMMISSION_FEE alice should be biased or can never distribute.

Impact

Reported as high as

High likelihood: This issue occurs reliably whenever multiple winners are specified with calculated even percentage splits. This is a very common way that organizers will want to distribute funds

High Impact: Faulty percentage check results in a complete failure of the distribution

Tools Used

Manual Code Review, VSCode

Recommendations:

  1. Allow a small tolerance threshold in the totalPercentage check to account for division rounding errors.

  2. Explicitly calculate and allow the mathematical remainder that arises from precision loss.

+ uint256 expectedTotal = 10000 - COMMISSION_FEE;
+ uint256 remainder = expectedTotal % winners.length;
// this ensures fair distribution when multiple winners are listed
if (totalPercentage != expectedTotal && totalPercentage != expectedTotal - remainder) {
revert Distributor__MismatchedPercentages();
}

Support

FAQs

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

Give us feedback!