Sparkn

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

[H-02] Possible to Distribute Tokens to address(0) Leading to Loss of Sponsor Funds

Summary

Tokens could be lost if sent to address(0) when calling deployProxyAndDistribute.

Vulnerability Details

If the organizer intentionally (griefing) or unintentionally inputs address(0) as the data in the deployProxyAndDistribute function of contract ProxyFactory.sol, the tokens will be lost.

  1. Organizer comes up with a contest idea and submits it

  2. Contest is created and funded by sponsors with e.g. 1000USDT

  3. Contest concludes and organizer calls deployProxyAndDistribute with address(0) as input in the data for the winner address[]

There is no check if value 0 exists for winner address[] inside _distribute function in Distributor.sol:

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;) {
uint256 amount = totalAmount * percentages[i] / BASIS_POINTS;
erc20.safeTransfer(winners[i], amount); // @audit no checks to verify off-chain with on-chain info so we can just distribute tokens to whatever address we like (including ours)
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);
}

Impact

Loss of sponsor funds as the tokens are all lost.

Tools Used

VSCode, Manual Review

Recommendations

Incorporate checks inside the _distribute function to make sure there is no address zero inside of the winners address[]. The solution to this issue is very simple, and not gas-heavy either, thus I don't see a reason not to include it as a security measure in any case.

for (uint256 i; i < winners.length; i++) {
if (winners[i] == address(0)) {
revert;
}
}

Support

FAQs

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