Pot::_transferReward calls i_token.transfer(...) and ignores the returned bool. The EIP-20 standard allows a token to return false instead of reverting when a transfer fails, and says that callers must handle it. If this happens in claimCut, the Pot has already set the player's reward to 0, reduced remainingRewards and added the player to claimants, but no tokens were sent. The player cannot claim again, so the reward is lost.
claimCut updates the state first and then calls _transferReward, which does not check the result:
If transfer returns false (for example a token that blocks some addresses or is paused, and returns false instead of reverting), claimCut does not revert. The player's reward is already set to 0, so the player cannot try again.
All token calls in the protocol ignore the returned bool:
In fundContest, a false result means the owner can believe the Pot is funded when no tokens arrived.
The README says "Standard ERC20 Tokens Only". A token that returns false on failure is still allowed by EIP-20, so the code must handle it.
Likelihood: Low
It needs a token that returns false instead of reverting when a transfer fails.
The token is chosen by the owner, and players cannot influence it.
Impact: Medium
The affected player loses the whole reward: the balance is unchanged, checkCut is 0 and the claim cannot be repeated.
The Pot keeps more tokens than remainingRewards says, so these tokens belong to nobody.
Only the money of this one contest is affected.
Add the following inside the existing TestMyCut contract in test/TestMyCut.t.sol. It uses the existing setup, imports and the mintAndApproveTokens modifier.
Run from the repository root:
Output:
vm.mockCall makes transfer(player1, 10) return false, the same as a token that returns false for a failed transfer.
Use OpenZeppelin's SafeERC20 for every token call. It reverts when a transfer fails or returns false, so the whole claimCut reverts and the player's reward stays claimable:
The PoC covers claimCut. The other calls listed in the Description ignore the returned value in the same way and need the same fix.
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.