The protocol moves tokens via raw ERC20 calls and ignores the boolean return value in three places:
The ERC20 standard allows a token to signal failure by returning false instead of reverting. Several real tokens behave this way. Because these calls do not check the return value (and do not use SafeERC20), a failed transfer is treated as success. The most damaging case is fundContest: it can complete "successfully" while moving zero tokens, leaving a Pot that is recorded as funded (contestToTotalRewards set, remainingRewards == totalRewards) but actually holds nothing - every later claimCut() then reverts.
Likelihood: Low - only manifests with ERC20 tokens that return false on failure rather than reverting.
Impact: Low - no direct theft, but it produces phantom-funded pots and silently-failed reward payouts, breaking the protocol's core accounting for such tokens.
A token whose transferFrom returns false (without reverting) lets fundContest "succeed" while transferring nothing. Runnable Foundry test (add the mock + test to test/TestMyCut.t.sol):
Run forge test --mt test_PoC_uncheckedTransferReturn -vv; it passes, proving a phantom-funded pot.
Use OpenZeppelin's SafeERC20 wrappers (safeTransfer / safeTransferFrom), which revert when a token returns false or returns no data. This makes every transfer either succeed or revert, so accounting can never desync.
Apply the same safeTransfer change to the managerCut transfer in closePot().
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.