track 05 · Technical research

Merkle claim: an ERC-1155 airdrop that stores one hash

An ERC-1155 token contract that mints only to addresses proven to be on an allow-list, using a Merkle proof. The contract stores a single 32-byte root; the list lives off-chain and each claimant supplies their own proof.

PrototypeSolidityMerkle treesERC-1155FoundryHardhatTypeScript

The question

An airdrop to hundreds of addresses is too expensive to store on-chain. The question was how to let each person claim exactly their own allocation, safely, while the contract holds almost no data.

What it does

  • The contract (Solidity, built on solmate's ERC-1155 and MerkleProofLib): it takes the Merkle root in its constructor, and claim(address, id, amount, proof) rebuilds the leaf as keccak256(address, id, amount), verifies it against the root, then mints that exact amount of that token id.
  • A hasClaimed guard so an address cannot claim twice.
  • Off-chain tooling in TypeScript: a script that generates 500 random addresses with token ids and amounts as CSV, and a script that builds the tree with merkletreejs (keccak256, sorted pairs), writes each address's leaf and proof to JSON, and prints the root to deploy with.
  • Foundry and Hardhat project setup, with a test file for the contract.

What broke, and what is still wrong

  • The trade-off is storage for client-side work: the contract holds one hash, but whoever claims needs the published list (or a proof service) to build a proof of about nine hashes for a 500-entry tree.
  • Design notes worth a second pass: the claim is keyed by address, so one address gets one claim across all token ids, and anyone can submit a claim on another address's behalf (tokens still go to the claimant).

Caveat. A small April 2024 study. The README describes a wider airdrop design, including ERC-998 token airdrops, than this contract implements: only address claims are implemented here.