AirdropDistributor (VRF Winner Selection)
Uses VRF to pick N winners from a registered address pool on a fixed schedule.
Overview
AirdropDistributor is a recurring airdrop contract. Addresses register themselves into a pool, and on a fixed schedule AutoLoop uses ECVRF to pick winnersPerDraw winners via a partial Fisher-Yates shuffle. Each winner receives prizePerWinner ETH minus a protocol fee.
| Property | Value |
|---|---|
| Base contract | AutoLoopVRFCompatible |
| VRF usage | Winner selection |
| Gas per tick | ~90k + 15k per winner |
| Source | autoloop/src/agents/AirdropDistributor.sol |
| Tests | 18 passing (unit + fuzz) |
Why AutoLoop + VRF Are Structurally Required
The trigger holder knows who wins before the call. With deterministic or predictable RNG, whoever submits the draw transaction can compute all winners in advance and time the call to a favorable state. AutoLoop separates triggering from participation — the keeper has no stake in the outcome and earns a fee regardless of who wins.
ECVRF makes the outcome unguessable to participants (they don't have the keeper's private key) and cryptographically verifiable on-chain after the fact.
Keeper Trust Model
What AutoLoop guarantees: Participants cannot manipulate or predict the outcome. The keeper's private key is required to produce a valid proof, so no participant can pre-compute winners or time the trigger.
What the keeper knows: Each keeper generates the VRF proof off-chain before submitting, so it knows its own output before the transaction lands.
How collusion resistance works: AutoLoop registers multiple independent controllers per VRF contract. Each controller's VRF output is unique — it's a function of their private key applied to the same seed, producing a completely different result. They race to submit:
- A malicious controller can withhold their submission if they dislike their output
- But they cannot prevent another registered controller from submitting with a different, independent output
- Determining the final winner requires ALL registered controllers to collude on withholding — each honest controller that submits spoils the coordination
Anyone can register as an additional controller on any VRF contract via registerControllerKey(), increasing the collusion bar. This is the same trust model as Chainlink VRF's off-chain oracle network.
Mechanics
- Register/Deregister: any address calls
register()orderegister()to enter/leave the pool - shouldProgressLoop: returns true when pool size ≥ winnersPerDraw and drawInterval has elapsed
- Winner selection: Fisher-Yates partial shuffle using VRF randomness picks
winnersPerDrawnon-repeating addresses - Prize distribution:
(totalPrize * PROTOCOL_FEE_BPS) / 10000goes to protocol; remainder split equally among winners - Pool preservation: the full pool remains registered for the next draw — winners aren't removed
Revenue Model
- 2% protocol fee on total prize per draw
- AutoLoop gas fee per draw tick
Deploy
forge create src/agents/AirdropDistributor.sol:AirdropDistributor \
--constructor-args 604800 3 100000000000000000 \
--rpc-url $RPC_URL --private-key $PRIVATE_KEY --broadcastArgs: drawInterval (seconds), winnersPerDraw, prizePerWinner (wei). Fund the contract with at least winnersPerDraw × prizePerWinner ETH before draws begin.
VRF Key Registration
After deploying, each controller worker must register its ECVRF public key:
airdropDistributor.registerControllerKey(controllerAddress, pkX, pkY);The worker derives (pkX, pkY) from its secp256k1 private key. Without this step, every VRF proof submission will revert. Register all controllers before the first draw.
Use the AutoLoop worker's register-vrf-keys.js to automate this for all workers:
NETWORK=sepolia node scripts/register-vrf-keys.jsDashboard
View AirdropDistributor on the AutoLoop Dashboard.