Sparkn

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

Missing zero check can DOS _distribute function

Summary

Missing zero check for winners addresses could potentially lead to DOS _ditribute function. Certain tokens, such as OpenZeppelin's implementation, revert when attempting to transfer tokens to the zero address. This could disrupt the _distribute function, resulting in locked tokens within the contract.

Vulnerability Details

The vulnerability occurs when the organizator mistakenly passes a zero address as a winner's address. If this happens, the _distribute function will attempt to transfer tokens to the zero address, causing the token transfer to revert and potentially locking the tokens within the contract indefinitely.

Impact

DOS _distribute function and possibly locked tokens in contract forever

Tools Used

Manual Review

Recommendations

To mitigate this vulnerability adding zero check for winners addresses.

function _distribute(address token, address[] memory winners, uint256[] memory percentages, bytes memory data)
internal
{
// token address input check
if (token == address(0)) revert Distributor__NoZeroAddress();
if (!_isWhiteListed(token)) {
revert Distributor__InvalidTokenAddress();
}
// winners and percentages input check
if (winners.length == 0 || winners.length != percentages.length) revert Distributor__MismatchedArrays();
uint256 percentagesLength = percentages.length;
uint256 totalPercentage;
for (uint256 i; i < percentagesLength;) {
totalPercentage += percentages[i];
unchecked {
++i;
}
}
// check if totalPercentage is correct
if (totalPercentage != (10000 - COMMISSION_FEE)) {
revert Distributor__MismatchedPercentages();
}
IERC20 erc20 = IERC20(token);
uint256 totalAmount = erc20.balanceOf(address(this));
// if there is no token to distribute, then revert
if (totalAmount == 0) revert Distributor__NoTokenToDistribute();
uint256 winnersLength = winners.length; // cache length
for (uint256 i; i < winnersLength;) {
+ if (winners[i] == address(0)) revert Distributor__NoZeroAddress();
uint256 amount = totalAmount * percentages[i] / BASIS_POINTS;
erc20.safeTransfer(winners[i], amount);
unchecked {
++i;
}
}
// send commission fee as well as all the remaining tokens to STADIUM_ADDRESS to avoid dust remaining
_commissionTransfer(erc20);
emit Distributed(token, winners, percentages, data);
}

Support

FAQs

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