How I Won the $40,000 Chainlink Grand Prize with VMTree ๐
6 Jun 2022 ยท 5 min read ยท VMTree on Devpost โ ยท code on GitHub โ ยท the hackathon โ
One month, three strangers from the Chainlink community, my first ever web3 hackathon โ and somehow, the Chainlink Grand Prize. ๐ฅณ
In spring 2022 I signed up for the Chainlink hackathon: 1,450 hackers, a $1,067,000 prize pool, judges like Austin Griffith and Patrick Collins โ and me, with exactly zero web3 hackathon experience. I teamed up with three people I’d never met, and for a month we built VMTree.
What we built
VMTree is verifiable Merkle trees as a service โ a 10× gas optimization for on-chain privacy.
Every privacy protocol on Ethereum (think Tornado-style mixers) keeps a Merkle tree of commitments on-chain: you deposit, your commitment becomes a leaf, and later you withdraw by proving you own some leaf without revealing which one. The tree is the expensive part. It has to use SNARK-friendly hash functions like MiMC or Poseidon โ cheap inside a proof circuit, brutal inside the EVM โ so a single deposit into a depth-20 tree burned close to 1 million gas just recomputing hashes on-chain.
Our heretical idea: the chain shouldn’t compute the tree at all. It should only verify that someone else computed it correctly. A Chainlink oracle does the work off-chain and hands the contract a proof; the contract checks the proof for a (near-)constant cost. Deposits dropped to roughly 60k gas per commitment.
The math underneath
Three ideas carry the whole thing.
1. Merkle trees. A tree of hashes where each parent is H(left, right); the root is a 32-byte fingerprint of all 2²⁰ leaves. Updating one leaf means recomputing the hashes along its path โ 20 of them for depth 20:
on-chain update cost ∝ log₂(n) SNARK-unfriendly-in-EVM hashes ≈ ~1M gas
2. Computational Integrity Proofs. The clever bit. A CIP is a zk-SNARK with no secrets โ every input is public. We didn’t want privacy from the proof; we wanted verifiability. The circuit states: “given old root R and this batch of leaves, the correct new root is R′.” Groth16 verification costs the same tiny amount no matter how much computation the proof represents:
cost(verify π) ≈ constant ≪ cost(recomputing the tree in the EVM)
3. Batching. Our Poseidon circuit inserted 16 leaves per proof (the MiMC version managed 10, and Poseidon still had smaller proving keys and faster proving times). One verification, sixteen deposits โ the cost per deposit is amortized to roughly 1/16th of the proof:
cost per deposit ≈ (verify + calldata) / 16
Privacy still happens on the consumer side: a separate associate_data circuit proves membership in the tree in zero knowledge, with nullifier hashes so a commitment can’t be double-spent. Same primitive works for mixers, private voting, or airdrops.
How it worked, end to end
Four components, four repos, one pipeline:
- Users deposit; the VMTree contract queues their commitments and emits an event.
- A custom Chainlink node with its own job spec picks up the batch.
- Our external adapter computes the new tree state and generates the Groth16 proof (circom circuits).
- The node submits the proof; the contract verifies it and accepts the new root. The protocol pays the node in LINK โ users never pay for tree updates directly.
And it wasn’t vaporware โ the whole loop ran live on the Rinkeby testnet, with a real Chainlink node posting a real update transaction you could watch land on Etherscan.
What we achieved
A fully tested, top-to-bottom implementation: circuits in both MiMC and Poseidon, Solidity contracts with a gas report to back the ~10× claim, a working oracle integration, and a web admin panel โ built by four strangers arguing across timezones in Discord. It was designed as the foundation for the Twister Cash stablecoin mixer, with the Chainlink integration as the seed of a new Decentralized Oracle Network. At the closing ceremony, out of 1,450 participants, the Grand Prize had our name on it. I re-read the announcement five times.
Not bad for a first hackathon. I walked in hoping for a free t-shirt and walked out explaining to my bank why an oracle was sending me money. ๐
โ All blogs