SOCI4L

An airdrop that fits in one slot

Step 1 of 4
0 of 2 goals

Rebuild the root

The contract stores one bytes32. The list of eligible addresses lives off chain, and each claimant brings the few hashes needed to prove they were in it.

Walk the proof upward, hashing the smaller value first each time:

bytes32 hash = leaf;
for (uint256 i = 0; i < proof.length; i++) {
    hash = hash < proof[i]
        ? keccak256(abi.encodePacked(hash, proof[i]))
        : keccak256(abi.encodePacked(proof[i], hash));
}
return hash == root;

Sorting the pair is what lets the contract verify without knowing which side the leaf sat on.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

contract Airdrop {
    bytes32 public immutable root;
    uint256 public constant AMOUNT = 100;

    mapping(address => uint256) public balanceOf;
    mapping(address => bool) public claimed;

    event Claimed(address indexed who, uint256 amount);

    constructor(bytes32 merkleRoot) {
        root = merkleRoot;
    }

    // Rebuild the root from a leaf and the proof beside it.
    function verify(bytes32[] calldata proof, bytes32 leaf) public view returns (bool) {
        return false;
    }

    function claim(bytes32[] calldata proof) external {
        balanceOf[msg.sender] += AMOUNT;
        emit Claimed(msg.sender, AMOUNT);
    }
}

Goals

The contract compiles
nothing to compile yet
The proof walk is implemented
nothing hashes the proof yet

Contract storage

Write a contract and it will deploy itself here.