claimSnowman mints the reward as a loop that runs once per unit of the recipient's raw Snow balance:
amount is the recipient's raw Snow balance. Snow is an 18-decimal ERC20, but balances are produced in raw units (buySnow does _mint(msg.sender, amount) with the raw argument), and the mint loop treats that raw number as a count of NFTs. Each _safeMint costs tens of thousands of gas, so the per-claim gas grows linearly with the balance and quickly exceeds the block gas limit, making the claim transaction revert permanently.
Likelihood: Medium â depends on the recipient's entitled Snow amount (fixed by the Merkle leaf). Any recipient whose entitlement is more than roughly a few hundred units can never successfully claim; the threshold is low enough to hit realistic distributions.
Impact: High â an affected recipient is permanently unable to claim the reward they are entitled to. The claim cannot be split (it always mints the full balance), so there is no workaround for the user.
Recipients with non-trivial entitlements are locked out of the airdrop entirely: claimSnowman reverts out of gas every time, so their owed Snowman NFTs can never be minted. This is a denial of the core protocol function for a broad class of legitimate users.
The following Foundry test passes. Minting for a modest raw amount (5000) already consumes ~165M gas â far beyond the ~30M mainnet block gas limit â so the corresponding claimSnowman would always revert:
Observed: F5: gas for minting 5000 NFTs = 165665935.
Decouple the number of NFTs from the raw token amount (mint one NFT per claim, or per whole-token unit scaled by decimals), or cap the per-call mint count:
(Choose the reward semantics intended by the protocol; the key fix is that the loop bound must not scale with an 18-decimal raw balance.)
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.