Sparkn

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

After contest ends, if winners array is empty(i.e. no proposals == no winners), then tokens will be stuck in proxy address because rescue tokens function distributeByOwner() will revert

Summary

(Note: I'm aware of the non-whitelisted tokens issue that the protocol team is already aware of. This finding of mine is not related to that known issue at all. My finding considers whitelisted tokens only.)

ProxyFactory::distributeByOwner() - After contest ends, if winners array is empty(i.e. no proposals == no winners), then tokens will be stuck in proxy address because rescue tokens function distributeByOwner() will revert.

(Note: Medium risk because I assume it's unlikely that there will be zero proposals from supporters, i.e. zero winners, when the contest duration is long enough, not too short. However, it is up to the judges to decide whether this finding is actually low or high instead. I wanted to be conservative and make it medium because my related finding is already a high. It was necessary to create a separate submission for this finding because it's completely independent from the bug I discovered for my high risk finding. Related, but independent)

Vulnerability Details

If no supporters submit proposals, then once the contest ends, and after the expiry period EXPIRATION_TIME of 7 days has passed, when the owner calls the distributeByOwner() function to rescue the stuck tokens, it will revert during _distribute() call on L125 of Distributor.sol contract, because winners array will be empty.

Therefore with current protocol functionality, the tokens will be stuck in the proxy address until a working solution is implemented.

Impact

Tokens stuck in proxy address until new solution is implemented to rescue them.

Tools Used

VSC. Manual.

Recommendations

A potential solution for getting the stuck tokens out of the proxy address would be to add the STADIUM_ADDRESS to the empty winners mapping, if that was at all possible: address[] memory winners.

Then it would just be a matter of calling the relevant functions in factory contract, distributing the "winner" tokens to the only "winner"(STADIUM_ADDRESS), and then transfer the remaining funds + dust to the STADIUM_ADDRESS.

Alternatively, consider implementing such that contest cannot end until at least one proposal/solution was submitted by supporter.

Or, if contest ends and there are no winners, automatically transfer the ERC20 tokens back to the organizer.

Support

FAQs

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