Protocol documentation

QPL Factory

A fair-launch launchpad on Solana where every token runs under a post-quantum signature scheme (WOTS) and every ticker is decided by an open race, not an allocation.

Post-quantumImmutableRace-basedPhantom-ready
01

What is QPL Factory

QPL Factory is a launchpad for memecoins on Solana where every token is protected by post-quantum signatures and every launch is a race, not a presale. There is no allocation, no reserved supply for the team, and no upgrade authority. The program is immutable once deployed.

Anyone can submit a candidate under a ticker. Users pick a winner by minting into the candidate they like. The first token to reach the race target wins the ticker forever, graduates to an on-chain AMM, and all other candidates refund their minters automatically.

Why it exists
  • • No team allocation, no VC bags, no hidden unlocks
  • • Quantum-resistant by construction, not retrofitted
  • • Fair discovery: the market picks the winner, not a launchpad admin
  • • Losers are not stuck. Every non-winning candidate becomes refundable
02

The Race System

A ticker is a short symbol (up to 8 characters) like $PEPE. Multiple wallets can each submit a candidate token under the same ticker. Each candidate has its own mint pool and its own holders. They are racing head-to-head for the ticker.

Whoever reaches 50 SOL raised first wins the ticker. At that moment, the winning candidate graduates:

  1. 1. The ticker is locked to the winner forever. No other candidate can be submitted under it again.
  2. 2. The winner's race pool seeds a bonding-curve AMM and a launch reserve that fuels the tri-crank flywheel (see §6 and §7).
  3. 3. Every competing (losing) candidate enters the REFUNDING state.
  4. 4. Minters of the losing candidates can claim their SOL back at any time. No deadline, no slashing.

Race state is visible in the scanner: New Race is any ticker with open candidates, Near To Win flags the ones above 80% progress, and Winners shows graduated tokens live on the AMM.

Token states
RACING
Accepts mints, competes for the ticker.
WINNER
Ticker locked. AMM live.
REFUNDING
Lost the race. Minters can claim SOL back.
CLOSED
Refunds drained. Account closed.
03

Quantum Resistance & WOTS

Every holder-facing operation in QPL Factory is signed with WOTS(Winternitz One-Time Signatures), a hash-based signature scheme that does not rely on elliptic-curve crypto. Shor's algorithm does not break it. A cryptographically relevant quantum computer cannot forge a WOTS signature the way it could forge an Ed25519 one.

Every token position is protected by its own chain of WOTS keys. Every signed operation reveals the current key, and simultaneously commits to the hash of the next key in the chain. Re-using a key is cryptographically impossible. The chain only moves forward.

What is protected
  • • Mint / withdraw
  • • Buy / sell on the AMM
  • • Transfers between users
  • • Refund claims
  • • Key chain continuity
What is not protected
  • • Solana base-layer Ed25519 (gas wallet)
  • • External tools (Phantom, Backpack, etc.)
  • • Off-chain key custody if you export the seed
Signing flow (per op)
  1. 1. Fetch your current user PDA → read key_index.
  2. 2. Derive WOTS key #key_index from the token master secret.
  3. 3. Sign the op payload.
  4. 4. Commit hash(key #key_index+1) on-chain as the next expected hash.
  5. 5. The program verifies signature + advances key_index by one. Replay is impossible.
04

Wallet (Local or Phantom)

QPL Factory supports two signer modes. You can use the built-in local wallet (a 24-word seed stored in your browser), or you can connect an external Phantom wallet. Both paths feed the same WOTS signing layer, so the quantum-resistant guarantees are identical.

Local wallet
A 24-word seed generated on first load, encrypted in your browser with a password. It drives the Ed25519 gas wallet (for Solana fees) and every WOTS key chain used by your positions. Import / export compatible with any BIP44 Solana wallet.
Phantom connect
Your SOL stays in Phantom and pays gas as usual. The quantum-resistant WOTS master is derived locally from a deterministic signMessage challenge, so no seed is exported and no extra backup is needed. Same master on every device that connects the same Phantom.
Seed / key hierarchy
Local wallet                  Phantom connect
────────────                  ───────────────
24-word seed (BIP44)          Phantom signs gas txs
 ├── ed25519 keypair → gas    sha256(signMessage challenge)
 └── WOTS master               └── WOTS master
      └── per-token master          └── per-token master
           = HKDF(master, tokenPda)      = HKDF(master, tokenPda)
            └── WOTS key #0, #1, …          └── WOTS key #0, #1, …

The local seed is stored encrypted in your browser and never touches any server. Phantom connect derives the WOTS master from a fixed challenge, so re-connecting on another device yields the same QPL positions without any import step.

What a wallet holds on-chain
  • • SOL balance (for gas)
  • • One user PDA per token you ever touched
  • • Each PDA stores your balance, current WOTS key index, and next key hash
05

Mint & Mint Batch

During the race phase, the only way to acquire a candidate is to mint. Minting is a fixed-price operation: you send SOL, you receive tokens at a known rate. The rate is the same for everyone, from the first mint to the one that triggers the graduation.

Mint price
0.01 SOL
Tokens / mint
100,000
Race target
50 SOL
Per-slot cap
unlimited

To keep race sprints fair, the program enforces a per-slot mint cooldown and rejects mints once supply is exhausted. You can also withdraw (undo a mint) while the candidate is still racing. Useful if you change your mind before graduation.

Mint batch
The UI bundles N mints into a single transaction when you ask for a larger buy (e.g. “0.5 SOL”). The program still enforces the per-slot cap, so batches are capped accordingly. A batch that would exceed supply or the cap reverts atomically. You never get a partial fill.
06

Winner Phase & AMM v2

When a candidate crosses the race target, graduation is atomic: the ticker is locked, the winner's race pool is split between a bonding-curve AMM and a two-bucket launch reserve, and the token transitions to the WINNER state in a single instruction.

Graduation split (both sides of the pool)
Trading pool
80%
SOL and tokens that seed the constant-product AMM users can buy/sell against.
Launch reserve
20%
Split across two buckets (SOL + token) that fuel the tri-crank flywheel.

At graduation the program also snapshots the graduation price as par and seeds the EMA at the same value. The reserved tokens stay inside the token PDA as a separate bucket (they are not burned at graduation), ready to be consumed by the BURN and ADD_LP crank actions over time.

The trading pool is a Uniswap-v2-style x * y = k constant-product market. Every trade pays a fee split three ways (see §9): part stays in the curve (benefits every holder as an implicit LP), part is routed to the protocol treasury, and a third slice is siphoned into the launch reserve so the tri-crank keeps firing forever. No single trade can drain more than 99% of either reserve.

Prices you see on a winner page
  • spot: solReserve / tokenReserve, what the next 1-token trade pays.
  • par: the price at which the race graduated. The anchor the crank defends.
  • ema: an on-chain exponential moving average of spot, used for smoothing and P&L.
07

Tri-Crank Flywheel

The launch reserve is not a team allocation. It is a programmatic flywheel that any wallet can turn. Three separate permissionless instructions drain the reserve over time and feed value back into the AMM. Each crank call pays a tiny tip to whoever submitted the transaction, so the three actions compete for attention on their own economic incentives with zero off-chain automation required.

Two buckets fuel three actions
  • launch_reserve: the SOL-side bucket. Seeded at graduation and continuously topped up by a slice of every AMM trade fee (see §9).
  • launch_reserve_token: the token-side bucket. Seeded at graduation with the reserved share of total supply and topped up by BUY cranks that park their purchased tokens here.
BUY
disc 12
LP depth grows
Drains a slice of launch_reserve and swaps it through the AMM at zero fee. The tokens that come off the curve are parked in launch_reserve_token, ready for a later BURN or ADD_LP. Net effect: LP depth grows, price ticks up slightly.
BURN
disc 16
Supply compresses
Drains a slice of launch_reserve_token and removes those tokens from pool.token_reserve, permanently reducing fully-diluted supply. SOL side unchanged, so spot price moves up. The aggressive supply compression action.
ADD_LP
disc 17
Spread tightens
Pairs SOL and tokens from both buckets at the current AMM ratio and deposits the pair into the pool, growing LP depth without shifting spot. The spread-stabilising action.
Shared cooldown, independent vesting

The program stores three per-action anchors on the token PDA: last_buy_slot, last_burn_slot, last_addlp_slot. Any crank is rate-limited by a global cooldown measured against the max of all three, so you cannot spam the flywheel by alternating actions.

  • • Global cooldown (max of all 3 anchors): 50 slots, ~20 seconds.
  • • Per-action drain rate: 1 bps per slot since that action's own anchor.
  • • Per-call cap: 500 bps (5%) of the bucket, independent of wait time.
  • • Cranker tip: 10 bps (0.1%) of the crank's payload, paid in SOL (BUY/ADD_LP) or token units (BURN).

Each action reads its own anchor for drain sizing, so a burst of BUY cranks leaves the BURN and ADD_LP vesting windows untouched. The next BURN fired after that streak still drains a fully-matured slice. This asymmetry rewards crankers who pick the under-used action.

Perpetual flywheel
A slice of every AMM buy and sell is siphoned back into launch_reserve as it happens (see §9). That means the reserve never runs dry as long as the token has trading volume: the crank keeps firing for the full life of the token, not just until the graduation seed is exhausted. The fee lamports physically stay inside the pool PDA so they keep earning AMM fees until a BUY crank rebuckets them.
08

Refunds

Once a race graduates, every losing candidate enters the REFUNDING state. The losing pools are not confiscated, burned, or redistributed: they are held in their original PDA and redeemable pro-rata by the original minters.

How to claim
  1. 1. Go to /refund/ALL or open the scanner.
  2. 2. Every token you hold that is refunding shows up with a Claim button.
  3. 3. Claiming burns your candidate tokens and sends the corresponding SOL share back to your gas wallet.
What you get
  • Fixed-rate refund. Same rate as your original mint, minus the protocol's per-mint fee.
  • No deadline. A refunding token stays refundable until every holder has claimed. The account only closes when the last SOL is out.
  • No auction. No bonding curve on the refund. The formula is deterministic and identical for every holder.
09

Fees

Fees exist to fund the protocol treasury, keep the pool safe from zero-value spam, and feed the tri-crank flywheel. All fees are visible on-chain and enforced by the program. They cannot be raised, waived, or redirected after deploy.

Token creation fee
0.01 SOL
Paid once by the candidate creator. Prevents ticker spam, routed to protocol treasury.
User registration fee
0.001 SOL
One-time per user PDA, routed to protocol treasury. Covers rent and anti-sybil.
Mint
0%
Fixed-price mint during the race phase. Same rate for everyone.
Withdraw (undo mint)
1%
Protocol fee on race-phase withdraws, routed to treasury. The rest is returned at mint rate.
AMM pool fee
30 bps
Stays inside the bonding curve, inflates k. Every holder is effectively an LP.
AMM protocol fee
40 bps
Routed to the protocol treasury on every buy/sell.
AMM buyback siphon
30 bps
Parked in launch_reserve on every buy/sell. Fuels the tri-crank forever.
Cranker tip
10 bps
Paid to whoever submits a successful crank instruction. Covers gas + incentive.
Refund claim
0%
Losing-race refunds pass the full pro-rata SOL back.
10

Security Model

Immutable contract
There is no upgrade authority. The program deployed on mainnet can never be replaced, paused, or migrated by the team. What you see in the source is what runs, forever.
Per-creator uniqueness
One wallet can only enter one candidate per ticker. The token PDA is derived from (ticker, creator), so sybil-stacking a race with duplicates is physically impossible.
Anti-replay via WOTS chain
Every op advances the user's key_index. A replayed transaction references an old key and is rejected on signature verify.
Overflow protection
All pool math is checked arithmetic in BigInt space. The program rejects any trade that would underflow a reserve, cross a zero-liquidity state, or exceed the 99% max-trade ratio.
Rent-exempt floor
No instruction can drain a pool below its rent-exempt minimum. Pools physically cannot be emptied to zero. They retain the rent floor forever.
On-chain-only state
There is no backend. No API key, no centralized indexer, no off-chain admin action. The frontend is a pure read/write client talking to Solana RPC.
11

FAQ

Do I need Phantom or any external wallet?
No, but you can use one if you prefer. QPL Factory ships with a built-in 24-word wallet that signs locally in your browser, and it also accepts Phantom connect as an alternative signer. Either way the WOTS layer is identical.
How does Phantom derive my quantum-safe keys?
On first connect, Phantom signs a fixed challenge message. QPL hashes that signature into a WOTS master secret. Since Phantom's ed25519 signatures are deterministic for the same message, the same Phantom account always produces the same QPL positions on any device. No seed is ever exported.
Can the team upgrade the program?
No. The program is deployed without an upgrade authority and is fully immutable.
Can the team rug the pool?
No. There is no admin key on any pool. All pool accounts are PDAs controlled by the program itself. Withdraws are gated by WOTS signatures from individual holders.
What happens if nobody ever finishes a race?
Nothing. The candidates stay in the RACING state until someone does. There is no time-based expiry, because a timer would create an attackable “grief the last minter” vector.
Why three buyback actions instead of one?
Splitting the flywheel into BUY, BURN and ADD_LP lets the reserve move LP depth, fully-diluted supply, and spread independently. One unified action would have to pick one tradeoff up front and live with it forever. With three, the market decides which lever is most valuable right now by paying the cranker who picks the right one.
How does the crank stay funded long-term?
Every trade on the winning token pays a small slice of its fee into launch_reserve. As long as the token has volume, the reserve keeps accruing, so the flywheel keeps firing. Volume dies, the flywheel naturally slows down. Nothing extra to maintain.
Why multiple candidates per ticker?
Because one-candidate-per-ticker lets the first creator snipe every ticker. With the race model, the market picks which candidate under a ticker actually deserves the name.
What happens to the losing candidates' SOL?
It is locked in the losing candidate's PDA and is redeemable pro-rata by the original minters via claim_refund. No SOL is burned, no SOL is redirected.
Is WOTS actually quantum-safe?
WOTS is hash-based and its security relies only on the preimage and second-preimage resistance of the underlying hash function. Shor's algorithm does not apply. Grover's algorithm gives at most a quadratic speedup, which is addressed by picking a large enough hash output.
How do I export my seed to another device?
If you use the local wallet, open the wallet page, unlock it, and use the Export seed action to read the 24 words. Paste them into Restore from seedon the new device. If you use Phantom connect, you don't need to export anything: connecting the same Phantom on another device rebuilds the same QPL positions automatically.
Ready to race?
Pick a ticker, launch a candidate, or just mint the one you believe in. Post-quantum by default, race-decided by construction.
QPL Factory · immutable · on-chain · quantum-resistant