Sparkn

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

Due to gas limit, it may not be possible to distribute rewards if there are many winners

Summary

If there are many winners, due to gas limit and storage-writing for loops, it may not be possible to distribute rewards.

Vulnerability Details

Let us review the _distribute() function:

uint256 totalAmount = erc20.balanceOf(address(this));
//...
uint256 winnersLength = winners.length; // cache length
for (uint256 i; i < winnersLength;) {
uint256 amount = totalAmount * percentages[i] / BASIS_POINTS;
erc20.safeTransfer(winners[i], amount);
unchecked {
++i;
}
}

This loop only transfers reward to participants. However, the act of transferring tokens itself is storage-writing, as the token's storage is written.

Let us also note that the function will attempt to distribute its entire balance. This means that, if the sponsor sends funds before the result are out (for example, for the promise of prize commitment), or sends the entire funds to the pool for any reason, then the contest admin must distribute rewards using a single function call, as 5% of the prize pool will be made into a commission.

Therefore, if there are many winners, the transaction will also have to perform numerous ERC20 transfers. If the number of winners is large, this may result in a DOS.

Impact

If the number of winner is large, it may not be possible to distribute the rewards fairly.

Tools Used

Manual review

Recommendations

There are two ways around this:

  • Consider not requiring the admin to distribute rewards fully in one function call, allowing distribution over multiple calls.

  • Consider using a Merkle root claiming setting. Admin sets a merkle root for claim, distribute the proof to the winners, and the winners should call the function to claim rewards.

Support

FAQs

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