Sparkn

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

No primary payout token leads to excess commission fees on each contest

Summary

The distribute() function in the Distributor contract charges a commission fee on each sponsored token before prizes are paid out. This occurs independently on every token, rather than based on the total value distributed. Charging commission on a per-token basis can result in disproportionately high /unfair fees for the stadium.

Vulnerability Details

The per-token commission structure can lead to disproportionate results regardless of the number of winners, as long as prizes are distributed across multiple tokens.

function _distribute(address token, address[] memory winners, uint256[] memory percentages, bytes memory data)
internal
{
...
// 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();
}
// @audit-issue No primary payout token leads to excess commission fees on single contest
IERC20 erc20 = IERC20(token);
uint256 totalAmount = erc20.balanceOf(address(this));
...
uint256 winnersLength = winners.length; // cache length
for (uint256 i; i < winnersLength;) {
uint256 amount = totalAmount * percentages[i] / BASIS_POINTS; // possible precision error
erc20.safeTransfer(winners[i], amount);
...
}
// send commission fee as well as all the remaining tokens to STADIUM_ADDRESS to avoid dust remaining
_commissionTransfer(erc20); // @audit commission on every sponsored token
}

Assume there are 2 winners and prizes are distributed evenly across 2 tokens, the stadium receives double the share of the total prize pool through commissions.

For each contest stadium may only receive 5% of the total value, but with a 5% commission on each token, the stadium receives 10% of the pool.

Proof of Concept

  1. Whitelisted tokens

    • DAI, USDC, USDT, WBTC, WETH

  2. Amy creates a contest

  3. Bob sponsors with:

    • 10 DAI

    • 10 USDC

    • 10 USDT

  4. Carol sponsors with:

    • 5 WBTC

    • 5 WETH

  5. For total 40 tokens Amy selects 2 winners:

    • Doug

    • Edward

  6. Amy calls distribute():

    • Doug gets 9.5 DAI, 9.5 USDC, 4.75 WBTC

    • Edward gets 9.5 USDT, 4.75 WETH

  7. Stadium commission is 5% per token:

    • 0.5 DAI

    • 0.5 USDC

    • 0.5 USDT

    • 0.25 WBTC

    • 0.25 WETH

Results:

  • Doug received 23.75 tokens in prizes

  • Edward received 14.25 tokens in prizes

  • Stadium received 2.5 tokens in commissions

    • This is 6.25% of the total 40 tokens

The fewer the winners, the more disproportionate the stadium commissions will be.

More the winners there is a chance where the stadium commission exceeds amount received by each winner.

Impact

It is Medium issue as it got high likelihood as the issue arise whenever multiple tokens are used for distributions, low impact as in many cases the commission is just as dust but the fairness of the resulting commission amounts should be evaluated.

Tools Used

Manual Code Review, VSCode

Recommendations

Charge commission only on a primary payout token by using exchange or explore a way to distributed commission based on total value sponsored.

Support

FAQs

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

Give us feedback!