Skip to content

feat(soroban-contracts): Add Merkle distributor contract for proof-based airdrops (#248) - #284

Merged
manoahLinks merged 2 commits into
crowdpass-live:mainfrom
amankoli09:feature/248-merkle-distributor
Apr 27, 2026
Merged

feat(soroban-contracts): Add Merkle distributor contract for proof-based airdrops (#248)#284
manoahLinks merged 2 commits into
crowdpass-live:mainfrom
amankoli09:feature/248-merkle-distributor

Conversation

@amankoli09

Copy link
Copy Markdown
Contributor

Summary

Implements MerkleDistributor, a Soroban smart contract that distributes
tokens to eligible recipients using Merkle proof verification — the
canonical pattern for gas-efficient, permissionless airdrops.

Closes #248


Changes

New contract: soroban-contract/contracts/merkle_distributor/

File Purpose
Cargo.toml Package manifest, links soroban-sdk + upgradeable
src/lib.rs Contract implementation
src/test.rs 17 unit tests

Modified

  • soroban-contract/Cargo.toml — registered merkle_distributor as a workspace member

How It Works

Leaf encoding

… for airdrops (crowdpass-live#248)

Implements a Soroban smart contract that distributes tokens to eligible
recipients using Merkle proof verification — the canonical pattern for
gas-efficient, permissionless airdrops.

## Contract design

- Merkle root is committed at initialization; only recipients whose
  (address, amount) pair is included in the tree can claim.
- Leaf encoding: SHA-256( sha256(address_str) ‖ amount_u64_le )
- Proof verification: sorted-pair hashing at every node, matching the
  most common off-chain Merkle tree libraries.

## Features
- Single-claim guard: each index stored in persistent storage; double
  claims are rejected with AlreadyClaimed.
- Multi-token support: any SEP-41 / Soroban token address.
- Expiry: optional UNIX timestamp; claims blocked after expiry.
- Sweep: admin can recover unclaimed tokens after expiry.
- Fund: any approved address can top-up the distributor balance.
- Checks-Effects-Interactions: claim flag set before token transfer.
- Upgradeable: inherits project-wide time-lock upgrade pattern.
- Rich events: Claimed, Swept.

## Tests (17 / 17 pass)
- Initialization: success, double-init guard
- Single-leaf tree: happy path, double-claim, invalid proof, wrong amount
- Two-leaf tree: both recipients claim, wrong-index rejection
- Four-leaf tree: all 4 recipients claim in sequence
- Expiry: claim before/after expiry, set_expiry query
- Sweep: after expiry, before expiry, no expiry configured
- Fund: balance increases correctly
- InsufficientBalance guard
- is_claimed default false

Closes crowdpass-live#248
@drips-wave

drips-wave Bot commented Apr 27, 2026

Copy link
Copy Markdown

@amankoli09 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@manoahLinks
manoahLinks merged commit aa26fa2 into crowdpass-live:main Apr 27, 2026
0 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

soroban-contracts: Add merkle distributor contract template

2 participants