Sparkn

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

Hardcoded BASIS_POINTS value in Distributor.sol::_distribute function can cause funds to stay stuck forever or miscalculate distribution of prizes

Summary

There is a hardcoded value in Distributor.sol::_distribute.

if (totalPercentage != (10000 - COMMISSION_FEE)) {
revert Distributor__MismatchedPercentages();
}

it can cause funds to stay stuck forever or miscalculate distribution of prizes (depending on the value change) if Owner changes the BASIS_POINTS value before deploying or in a future upgraded implementation and creates a new contest with the changed implementation.

Vulnerability Details

Case 1 -> funds stay stuck forever (value changed to below 10000)

lets say COMMISSION_FEE is still 500 and Owner changes the BASIS_POINTS value to 9,000 and forgets to change the hardcoded value then he creates a new contest with this new implementation. Following will happen when contest ends and organizer tries to distribute the funds.

Organizer will create the data as bellow and sets the percentage to 8500 (totalPercentage = BASIS_POINTS - COMMISSION_FEE) as there is only one winner.

function createData() public view returns (bytes memory data) {
address[] memory tokens_ = new address[](1);
tokens_[0] = jpycv2Address;
address[] memory winners = new address[](1);
winners[0] = user1;
uint256[] memory percentages_ = new uint256[](1);
percentages_[0] = 8500;
data = abi.encodeWithSelector(Distributor.distribute.selector, jpycv2Address, winners, percentages_, "");
}

But the distribute function will revert with error Distributor__MismatchedPercentages(); because 8500 != 9500.

So the only way to execute distribute function is to pass the percentage as 9500 because the if statement requires it to be (10000 - COMMISSION_FEE = 9500) which will cause the erc20.safeTransfer(winners[i], amount); function to always revert because the following formula will always calculate more amount then the balance of contest.

uint256 amount = totalAmount * percentages[i] / BASIS_POINTS;
// Lets asume contest have 100 USDT
// amount = 100 * 9500 / 9000 = 105.56
/*below line will cause revert as you are trying to transfer more amount then the contest acually have due to the miss calculation*/
erc20.safeTransfer(winners[i], amount);

Case 2 -> miscalculated distribution of prizes (value changed to above 10000)

lets say COMMISSION_FEE is still 500 and Owner changes the BASIS_POINTS value to 20,000 and forgets to change the hardcoded value then he creates a new contest with this new implementation. Following will happen when contest ends and organizer tries to distribute the funds.

Organizer will create the data as bellow and sets the percentage to 19500 as there is only one winner.

function createData() public view returns (bytes memory data) {
address[] memory tokens_ = new address[](1);
tokens_[0] = jpycv2Address;
address[] memory winners = new address[](1);
winners[0] = user1;
uint256[] memory percentages_ = new uint256[](1);
percentages_[0] = 19500;
data = abi.encodeWithSelector(Distributor.distribute.selector, jpycv2Address, winners, percentages_, "");
}

But the distribute function will revert with error Distributor__MismatchedPercentages(); because 19500 != 9500.

So the only way to execute distribute function is to pass the percentage as 9500 because the if statement requires it to be (10000 - COMMISSION_FEE = 9500) which will cause way less prize distribution to winner and way more commission distribution to protocol.

Impact

Funds can stay stuck forever or prizes and commission fee can be miscalculated.

Tools Used

Manual analysis

Recommendations

Replace the hardcoded value with BASIS_POINTS as below.

if (totalPercentage != (BASIS_POINTS - COMMISSION_FEE)) {
revert Distributor__MismatchedPercentages();
}

Support

FAQs

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