Sparkn

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

Risk of winners losing rewards.

Summary

When checking if totalPercentage is correct in the _distribute function, the value is compared with a hardcoded value 10000. Assuming this value is the same as BASIS_POINTS, if the BASIS_POINTS and COMMISSION_FEE gets updated in the future, two things can happen:

  1. All _distribute executions get reverted due to an underflow error.

  2. Only a tenth of the rewards get distributed to the winners due to incorrect totalPercentage check.

Vulnerability Details

// check if totalPercentage is correct
// Use constant instead of hardcoded value
if (totalPercentage != (10000 - COMMISSION_FEE)) { // <- hardcoded value 10000
revert Distributor__MismatchedPercentages();
}
IERC20 erc20 = IERC20(token);
uint256 totalAmount = erc20.balanceOf(address(this));
...
for (uint256 i; i < winnersLength;) {
uint256 amount = totalAmount * percentages[i] / BASIS_POINTS; // <-- basis points used here to calculate amount.
erc20.safeTransfer(winners[i], amount);
unchecked {
++i;
}
}

Underflow Scenario

This can happen if BASIS_POINTS is set to a number such as 100_000 for higher precision and COMMISSION_FEE is set to 11000. _distribute will revert every time due to an underflow error at 10000 - COMMISSION_FEE. The calculated value can be -1000. Winners will not be able to get rewards.

Small rewards Scenario

For higher precision, let's say the BASIS_POINTS and COMMISSION_FEE gets updated to the following values:

  • COMMISSION_FEE = 5000

  • totalAmount = 100 // for simplicity

If the totalPercentage check passes where (10000 - COMMISSION_FEE) = 5000`, the winners will only a tenth of the expected rewards:

uint256 amount = totalAmount * percentages[i] / BASIS_POINTS; // amount = 100 * 1000 / 100_000 = 1 vs expected rewards = 10

The rest of the rewards will get sent to the STADIUM_ADDRESS.

// send commission fee as well as all the remaining tokens to STADIUM_ADDRESS to avoid dust remaining
_commissionTransfer(erc20);

Impact

Winners do not get the full amount or no rewards in the worst case scenario.

Tools Used

Manual Analysis

Recommendations

Use the BASIS_POINTS constant instead of a hardcoded value.

if (totalPercentage != (BASIS_POINTS - COMMISSION_FEE)) {

Support

FAQs

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