Sparkn

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

[M] deployProxyAndDistribute doesnt check if the contest has expired before distributing prizes

Summary

The deployProxyAndDistribute function is designed to deploy a proxy contract and distribute prizes
immediately after the contest is closed. It checks whether the contest is closed (saltToCloseTime[salt] > block.timestamp) and then proceeds to distribute the prizes.

Vulnerability Details

The distributeByOwner function is designed to allow the owner to distribute prizes on behalf of the organizer,
but only after the contest is expired. It checks whether the contest is expired (saltToCloseTime[salt] + EXPIRATION_TIME > block.timestamp) and then proceeds to distribute the prizes.

Impact

In the scenario described, if the owner calls distributeByOwner after the contest is
expired and the deployProxyAndDistribute function is called around the same time by another party
(e.g., a frontrunner), there could indeed be a possibility of duplicate distributions.

This could happen because the deployProxyAndDistribute function doesn't check if the contest is expired;
it only checks if it's closed. If someone exploits the timing,
they could execute the deployProxyAndDistribute function before the owner's distributeByOwner transaction,
resulting in duplicate distributions.

Tools Used

Manual Review

Recommendations

You could add a boolean flag to check if prizes have been distributed or not.

Alternatively, you can add a modifier to the function to check if prizes have been distributed or not.

i.e

// Define the modifier
modifier prizesDistributed(bytes32 salt) {
require(hasDistributed[salt] == false, "Prizes already distributed for this contest");
_;
hasDistributed[salt] = true; // Set the flag after successful distribution
}

And then insert the modifier into the functions' signature.

Support

FAQs

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