The airdrop allows a third party to claim on a receiver's behalf using the receiver's ECDSA signature over an EIP-712 digest. However, ECDSA recovery can never produce a contract address, and no EIP-1271 fallback exists, so any whitelisted address that is a contract (Safe multisig, smart wallet) can never claim its NFT allocation.
ecrecover outputs EOA keys only — there is no (v, r, s) whose recovery equals a contract address, and the function is even pure, so it cannot call isValidSignature on the receiver. A whitelisted contract's claim therefore always reverts SA__InvalidSignature. Moving the Snow to an EOA does not rescue the allocation either: the Merkle leaf binds (contractAddress, amount), so the EOA's new balance matches no leaf. The NFT allocation for that address is permanently unreachable, while the Snow principal itself stays transferable.
Likelihood:
The operator includes any contract address (multisig, smart account, DAO treasury) in the Merkle tree — a realistic inclusion for a token-distribution snapshot.
Impact:
100% of the NFT allocation of every whitelisted contract address is permanently frozen — an entire claimant class is excluded from the airdrop.
No on-chain recovery path exists; only regenerating the tree for different addresses could remediate.
Run: add the wallet contract and the test to test/TestSnowmanAirdrop.t.sol, then forge test --match-test test_PoC_ContractHolderCannotClaim -vv
Output (actual run):
The signature check runs before the Merkle check, so the revert is attributable purely to the signature scheme: no (v, r, s) exists whose ecrecover output equals a contract address.
Support EIP-1271 contract signatures alongside ECDSA recovery.
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.