claimSnowman() takes the claimer's SNOW balance and uses it directly as the number of NFTs to mint.
Snowman.mintSnowman() then mints one NFT per unit in a loop.
Snow is an 18-decimal ERC20, so one SNOW is 1e18 wei. The airdrop therefore mints one NFT per wei, not one per token or one per allocation:
A claimer holding one whole SNOW would require 1e18 loop iterations. Minting just 200 NFTs already costs 6.7M gas, so the transaction can never fit in a block and the claim reverts with out-of-gas for every such claimer.
The documented behaviour ("users receive Snowman NFTs proportional to their Snow token holdings") is unachievable: the proportional share is expressed in wei and instantly becomes a gas exhaustion condition.
The tree does not protect against this, because the leaf commits to the same wei balance that drives the loop. The current tree happens to use 1 wei per claimer, which masks the defect; any allocation expressed in real token units is unclaimable.
Likelihood: Medium. Any claimer whose leaf commits to a non-trivial amount (anything above roughly a thousand wei) can never claim. The defect is present for every allocation and only hidden by the tree currently using 1 wei values.
Impact: Medium. The claim path is permanently unusable for realistic allocations, so the airdrop cannot be run with proportional allocations at all. No attacker is required; the transaction simply reverts.
The test mints 200 NFTs directly and measures the gas, showing the loop is linear in the raw wei amount. The logged figure for a one-token balance (1e18 wei) is 3.35e22 gas, which no block can accommodate.
Decouple the NFT count from the raw wei balance. Normalise the balance to whole tokens, or lift the allocation out of the live balance entirely by passing the committed amount and minting a fixed number of NFTs per entitlement.
Additionally, cap the number of NFTs minted per claim (require(amount <= MAX_NFTS_PER_CLAIM)) so that no allocation can make the loop exceed the block gas limit.
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.