enterRaffle() checks for duplicate players with a nested loop over the entire players array — and it re-runs that full scan on every single entry (lines 85-91):
Gas cost therefore grows quadratically with the number of entrants, and there is no cap on players.length. Measured behavior: entering the 6th batch of 10 players costs ~5.6x the gas of the 1st batch (331k → 1.86M gas), and it keeps climbing. Two consequences follow:
Unfair gas burden — later entrants pay for re-scanning all earlier players; the cost of entering depends on when you enter, not what you do.
Griefing / DoS — an attacker enters many addresses (paying the entrance fees) to inflate the array until enterRaffle() becomes prohibitively expensive for honest players, or outright exceeds the block gas limit and halts the raffle entirely.
Likelihood: Medium — stuffing the array only costs entrance fees, which the attacker can partially reclaim via refund(); no privileged access needed.
Impact: Medium — honest players priced out of entry, or the raffle halted entirely once the check exceeds the block gas limit.
The Foundry test below measures the quadratic growth directly:
Enter 6 consecutive batches of 10 new players (60 total).
Record gasleft() before and after each enterRaffle() call.
Assert the 6th batch costs more than 5x the 1st batch.
Test assertions and measured result (forge test --match-test test_PoC_M2_DuplicateCheckGasGrowth):
1st batch of 10: ~331k gas,
6th batch of 10: ~1.86M gas (5.6x),
growth is unbounded as players.length increases.
Replace the O(n²) scan with a mapping(address => bool) for O(1) duplicate detection per entrant. Entry gas then stays constant no matter how large the array grows — which simultaneously removes the unfair late-entrant burden and the griefing vector, since inflating the array no longer raises anyone's entry cost.
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.