Sparkn

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

Organizer has the ability to take back / steal the prizes

Summary

There is a business logic vulnerability that revolves around the contest organization process. It pertains to the actions of the Organizer who has the ability to initiate prize distribution using a smart contract function. This vulnerability potentially allows the Organizer to IGNORE the contest results and unfairly allocate prize funds to themselves, thereby compromising the integrity of the contest and/or stealing sponsor funds.

Vulnerability Details

Consider the following scenario:

  1. Alice the Organizer initiates a contest. She convinces some sponsors to finance it.
  2. Sponsors 1, 2, and 3 send 1.5 million JPYC each to the proxy address.
  3. The contest concludes, and winners are to be rewarded.
  4. Alice triggers the deployProxyAndDistribute function with the correct contest ID, implementation address, designating herself as the winner, and allocating max percentage 9500%.

In my opinion the statement We may build a reputation system in the future to handle the issue of the system being maliciously used, e.g., sybil attack. is insufficient. Alice will be the most exemplary participant, she will organize 5-10 small contests to farm that reputation, engage the community, a true saint. The moment the amount sent in by possible sponsors will reach her turning point amount, she will run with the money, causing reputational damage to the platform and loss of funds to the sponsors.

KYC won't necessarily prevent this, a reputation system will definitely not solve this, this can be fixed on-chain

Impact

The organizer can:

  1. Lie and pull back the funds they promised, by calling deployProxyAndDistribute with their address as the sole winner and 9500 as percentage, stealing the prizes of the actual winners.
  2. Steal the sponsor’s funds by calling deployProxyAndDistribute with their address as the sole winner and 9500 as percentage when they are not the one financing the contest.

Tools Used

Manual review

Recommendations

The web2 side of things is aware of the contest conditions, list of participants and their addresses, list of winners and their respective percentages. Create a new mapping that ties contestId to winners data:

mapping(bytes32 contestId => bytes data) public contestWinners;

and a function callable only by the owner or other owner controllable role that updates this mapping:

function setWinners(bytes32 contestId, bytes memory data) public onlyOwner {
contestWinners[contestId] = data;
}

after this any other function that can be called by the organizer to distribute prizes either reads that mapping automatically or accepts the input of the organizer but checks it against the data in the mapping to ensure that the actual winners are the ones who receive the prizes.

Support

FAQs

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