Part 4 of "Building on Polkadot Hub: A Builder's Journal"
TL;DR
When a bonding curve fills, the token automatically graduates to PlazaSwap — our Uniswap V2 fork. 90% of the LP tokens are burned permanently. The remaining 10% are locked in a vault, and the creator receives a FeeKeyNFT representing the right to harvest yield from that locked LP position. No one can pull the liquidity. The creator can't touch the principal. They can only harvest the yield.
Why This Matters
Most launchpads have a graduation problem. The bonding curve phase is exciting — momentum, price action, community forming. Then the token "graduates" to a DEX, and... nothing. On Solana, Raydium is littered with dead pools from pump.fun graduates — $2K of liquidity that one trade punches through. The anticlimax kills momentum.
We designed graduation to be the opposite: the moment the token becomes more trustworthy, not less.
What Triggers Graduation
No button to press. No admin intervention. When the last token on the bonding curve sells — when realTokenReserve hits zero and 6,280 DOT has accumulated — the contract triggers graduation in the same transaction as the final buy.
The buyer who fills the curve pays for their trade, and the contract does the rest.
The Graduation Sequence
Four things happen atomically:
1. Create the DEX pool The GraduationManager transfers ~206.9M reserved tokens and the accumulated DOT to a PlazaSwap V2 pair. If the pair doesn't exist, it's created. If someone front-ran pair creation with a tiny amount of liquidity, the contract checks price deviation — if it's off by more than 5%, graduation reverts and retries later.
2. Burn 90% of LP tokens The minted LP tokens are split. 90% go to 0x000...dEaD. Gone. The underlying tokens and DOT backing that liquidity are locked in the pair contract forever. No one — not the creator, not us, not a governance vote — can retrieve them.
3. Lock 10% in the CreatorFeeVault The remaining 10% of LP tokens are transferred to the CreatorFeeVault. The vault records the LP's initial WDOT value as a baseline. This matters for harvesting — the creator can only claim growth above this baseline, never the principal.
4. Mint a FeeKeyNFT An ERC-721 token is minted to the creator's address. This NFT represents the permanent right to harvest LP fee growth from the locked 10% position. It's transferable — sell the NFT, sell the earnings stream.
This isn't a policy or a promise. It's math, enforced by the EVM. The burn address has no private key. The vault has no unlockLP() function. The graduation adapter has renounceOwnership disabled — it can't accidentally lose its safety properties.
Why 90% Burn?
Why not 100%? Because then creators earn nothing after graduation. The whole point of Burn & Earn is that both things happen:
- Burn — 90% of LP is destroyed, making rug pulls structurally impossible
- Earn — 10% of LP is locked in a vault, generating ongoing yield for the creator
100% burn is maximally safe but gives creators zero reason to keep building after graduation. 0% burn is a rug pull waiting to happen. 90/10 is the tradeoff: overwhelming safety (90% of liquidity is permanent) with meaningful incentive (creators can earn from the locked LP's harvestable yield).
Compare this to pump.fun, where creators earn nothing after graduation. The incentive is to pump and dump during the bonding curve phase, then walk away. Our incentive is the opposite: keep the community alive, drive trading volume, because your FeeKeyNFT keeps earning.
How Harvesting Works
The 10% locked LP earns its pro-rata LP fee share through standard Uniswap V2 mechanics. As fees accumulate, the LP position can grow in value. The delta between current value and the baseline is the harvestable profit.
A keeper (our indexer service) periodically checks each graduated token's locked LP:
- Calculate current WDOT value of the locked LP
- Subtract the baseline (set at graduation, adjusted after each harvest)
- If profit exceeds the threshold (0.1 WDOT): harvest
Harvesting removes a proportional amount of LP tokens, burns them against the pair to receive MEME + WDOT, swaps the MEME to WDOT, and deposits the total into the CreatorFeeVault as claimable fees.
The baseline updates using proportional reduction — not a reset to current value. This preserves the "proven growth trend" and makes subsequent harvests smoother. If we reset to current value after each harvest, the creator would have to wait for the full growth cycle again. With proportional reduction, residual profit remains claimable immediately.
The FeeKeyNFT holder calls claimFees() whenever they want. No vesting, no lockup.
Why We Built Our Own DEX
PlazaSwap is a Uniswap V2 fork. Zero modifications to Factory, Pair, or Router. So why not just use an existing DEX?
Graduation requires atomic control. The graduation contract needs to create a pair, add liquidity, burn LP tokens, and lock the remainder — all in one transaction. With a third-party DEX, we'd need approvals, multiple transactions, and trust that the DEX doesn't change its interface. A single revert in a multi-step graduation would leave the token in a broken state.
Precompile constraints forced our hand. On Hub, pallet_assets ERC-20 precompiles don't fully support approve() in cross-contract calls (a pallet-revive limitation we reported). Standard Uniswap V2 Router flow is: approve → addLiquidity(). That flow fails on Hub. Our DirectAdapter bypasses the Router entirely — it transfers tokens directly to the pair address and calls pair.mint(). This only works because we control the factory.
Fee collection needs integration. The treasury fee collector contract is set as the feeTo target on the PlazaSwap factory. It atomically redeems protocol LP fees, swaps meme tokens to WDOT, unwraps to native DOT, and transfers to treasury. Plugging this into a third-party DEX's fee architecture would be fragile at best.
Before and After Graduation
| Bonding Curve | PlazaSwap | |
|---|---|---|
| Fee | 1% per trade | 0.3% LP fee |
| Creator earnings | 25% of trade fees (claimable) | FeeKeyNFT harvest (LP growth) |
| Liquidity | Virtual (algorithmic) | Real (token + WDOT in pool) |
| Price discovery | Constant-product curve | Standard AMM |
| Who can LP | Nobody (curve owns all) | Anyone |
| Rug possible | No (curve controls everything) | No (90% burned, 10% locked) |
The fee drops from 1% to 0.3% at graduation. This is intentional — the bonding curve stage is the price discovery phase where higher fees are acceptable. After graduation, the token competes with the broader DeFi market, and standard DEX fees apply.
What We Learned
Atomic graduation is non-negotiable — until the platform says otherwise. Early designs had graduation as a multi-step process: admin creates pair, admin adds liquidity, admin burns LP. Every step that requires a separate transaction is a step where things can go wrong, be front-run, or get stuck. We designed graduation to be fully atomic — one transaction does everything. Then we hit a pallet_revive limitation: the full graduation flow (4+ nested calls + CREATE2 + precompile interactions) reverts via Substrate extrinsics but succeeds via EVM RPC. Our solution: async graduation — buy() marks "pending", then a permissionless executeGraduation() completes the heavy work. It adds ~3 seconds of delay but works on both EVM and Polkadot native wallets.
The DirectAdapter pattern solved our biggest blocker. When we discovered that approve() fails in cross-contract precompile calls on Hub, we thought we were stuck. The insight was that Uniswap V2 pairs accept direct token transfers + mint() — you don't need Router approval flow. This pattern might be useful for any project integrating with Uniswap V2 on Hub.
90% burn creates real trust. In testing and community feedback, the single most convincing feature was "90% of liquidity is permanently burned." Not locked. Not timelocked. Not governed. Burned. The simplicity of it — there is no key, there is no function, the liquidity is gone — communicates safety better than any audit report.
Building a launchpad forced us to build DeFi infrastructure. We didn't set out to build Hub's first DEX — we needed one for graduation. We didn't set out to build a fee distribution protocol — we needed one for creator earnings. We didn't set out to file bugs against pallet_revive — we hit them and documented them. The launchpad is the application; the DEX, fee engine, and upstream contributions are the infrastructure layer that any Hub builder can use.
Next: Part 5 — Security & Governance — real bugs, the attack surface map, and the governance architecture.
Previous: Part 3 — The Fee Engine
Follow @plaza_fun for updates. · Discord
