Normal: Raffle outcomes should be unpredictable and ungameable. Players should not be able to selectively exit based on pending results.
Bug: An attacker monitoring the mempool can see a pending selectWinner() transaction, simulate its outcome locally, and front-run with a refund() if they would lose. This gives the attacker a risk-free participation: win the raffle or get a refund, never lose.
Additionally, selectWinner() uses msg.sender as a random seed — the caller can choose their own address or use a contract to influence the outcome.
Likelihood:
MEV searchers actively monitor mempools for profitable opportunities
Front-running infrastructure (Flashbots) is readily available
No special tools needed — a simple script can monitor and front-run
Impact:
Honest players always lose — attackers have an asymmetric advantage
Raffle fairness is fundamentally broken
Protocol loses credibility and users
Attack scenario:
Attacker enters raffle with N addresses
Attacker monitors mempool for selectWinner() transactions
On seeing selectWinner():
a. Simulate: winnerIndex = keccak256(msg.sender, block.timestamp, block.difficulty) % players.length
b. If players[winnerIndex] is one of attacker's addresses → let it through
c. If not → front-run with refund() on all attacker positions
Net result: attacker either wins the prize or gets a full refund. Never loses.
For the randomness, use Chainlink VRF instead of on-chain block data.
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.