FLOOR / Technical

The contracts and the math.

01 — Overview

One program per chain, and what a launch is

Each chain runs one FLOOR. It is a market and a launchpad in one: every token it launches trades against the program from its first block. The program sells the token along a fixed schedule and buys it back from money it holds for that purpose.

Nothing outside the program sets a launch’s price. Its price, its floor and its pots are the program’s own state. The same math library runs on every chain, so a trade fills to the same base unit on Solana and on an EVM chain.

01floor_amm
FLOOR on Solana.

An Anchor program at 7TFse4fPC383KWiSTHXfdRrNBSzLWpsB8VNF9TJFLooR. Each launch is the account ["launch", base_mint], with its own token vault and quote vault owned by that account. The program’s state lives in a few more accounts: Config, one PresetRow per preset, one QuoteEntry per listed quote, and the Team Slot and referral records.

one program
a launch is a PDA
02FloorAmm.sol
FLOOR on every EVM chain, at one address.

One UUPS proxy deployed through the deterministic CREATE2 factory, so it has the same address on Ethereum, Base, BNB Chain, Arbitrum, Arc, Robinhood Chain and HyperEVM. A launch is a uint256 launchId, numbered from 1. Its token is a clone at a CREATE2 address salted by that id, and launchOf(token) maps back.

UUPS proxy
launchId from 1
03floor-math
The math, written once.

A Rust library with no dependencies: the Stack, the bid, the fees, the window, the tail and the bought-back lot. The Solana program links it directly. The EVM contracts and the SDK reproduce its published vectors bit for bit. Every rounding goes against the trader.

amounts in base units
prices Q64.64
04The token
1,000,000,000 tokens, minted once, to the program.

On Solana the token is a Token-2022 mint with no extensions and 6 decimals. Its mint authority is renounced in the same instruction that mints the supply, and it has no freeze authority. On EVM it is an ERC-20 with 18 decimals, no owner and no mint function. Holders can burn on both.

1B supply
burns are real

Where a Solana launch lives

Config            ["config"]
PresetRow         ["preset", id]
QuoteEntry        ["quote", quote_mint]
Launch            ["launch", base_mint]
TeamSlot          ["team_slot", launch]
TraderRef         ["trader_ref", trader, quote_mint]
token vault       ATA(launch, base_mint)    // Token-2022
quote vault       ATA(launch, quote_mint)   // the quote's own program

A launch’s state that matters

Fthe floor’s money, in the launch’s quote
Cthe cushion’s money, which buys above the floor
S_outthe tokens outside the program
price_x64the Stack’s price, where the next buy fills
window_left / inventorythe tokens the program still has to sell
lot / tailthe bought-back tokens, and the tail range after the Stack ends
graduated / endedthe window has sold out / the Stack has sold out

02 — Floor math

Floor = F ÷ the tokens outside the program

The floor price is the money in the launch’s F pot divided by the tokens held outside the program. A sell of any size is paid at the floor or better, less its fees. The program publishes the floor after every trade, rounded down, so F always covers it.

S_out is the live supply less every token the program holds: the window’s tokens, the inventory, the bought-back lot and the tail. A locked Team Buy counts as outside, so F holds money for it. The program reads the live supply at the start of every trade, so a burn counts at once.

S_out = live_supply − held
held  = window_left + inventory + lot_tokens + tail

// the published floor, quote per token, Q64.64
floor_x64 = ⌊F · 2^64 ÷ S_out⌋        // 0 while S_out = 0

// a holding is backed at the floor
backing(tokens) = tokens · floor_x64 ÷ 2^64

The floor does not fall while anyone outside the program holds the token. Market cap is price × total supply, and a burn lowers the total supply.

03 — The window and graduation

The opening window sells at one flat price

A launch opens with a window: its first tokens sell at one flat price. Everyone who buys in the window pays the same price, so buying in the first block gives no price advantage. When the window’s last token sells, the launch graduates and buys fill along the Stack.

The preset sets the window’s size, window_whole, and what it raises. Its price is that raise divided by the window’s tokens, converted to the quote at the price governance declares for it. Each window buy pays that price or the floor’s line, whichever is higher. The floor’s line only matters if the floor has already risen close to the window price.

p0 = ⌈raise · 2^64 ÷ window_tokens⌉    // the raise in quote units

window_price = max(p0, floor_line)
floor_line   = ⌈1.03 · f⌉                // f, the floor per token

// the buy that sells the window out graduates the launch
if window_left == 0:
  graduated = true                         // emits Graduated
  // the rest of the same buy fills along the Stack
Graduatedemitted once, by the buy that sells the window out, with the price the Stack takes over at
Before graduationa window trade pays the Platform fee 0.50% and the $FLOOR fee 0.50%, flat, on top
After graduationevery fee follows its curve on market cap (09)
No windowa preset with none graduates at creation

Nothing moves to another venue at graduation. The token, the market and the pots stay in the program. There is no deadline and no minimum raise: a launch graduates only when its window sells out.

04 — The Stack and the tail

After graduation the program sells along the Stack

After graduation, the program sells its inventory along a fixed pricing curve. A buy pays the Stack’s price for each token it takes, so a larger buy pays a higher average price. When the inventory runs out, the last 1% of the supply trades as the program’s own liquidity.

The Stack’s shape is the preset’s: how the floor’s share and the cushion’s share of the price move as the market cap grows. On every row the floor’s share does not fall as the Stack sells. A buy never lowers the Stack’s price, and a sell does not move it.

01The bought-back lot
Tokens the cushion bought are resold first, cheapest first.

The program keeps the lot in bins by what each token cost. A buy takes the cheapest bin first, at its cost plus the buy’s fees, whenever that is cheaper than the Stack. The ask never goes under the live bid or the floor, and no bin is resold below what it cost.

16 bins
a log-price grid
02The end
The Stack’s price freezes when its inventory runs out.

The buy that sells the last inventory token emits ScheduleDone with the frozen price. Any inventory left unsold joins the tail. A buy larger than what is left fills along the tail in the same transaction.

ScheduleDone
03The tail POL
The last 10,000,000 tokens trade as a range to an unbounded price.

The tail is a constant-product range owned by the program, from the frozen price to an unbounded price, holding tokens and money. A buy takes tokens and the price rises along the curve. A sell returns tokens and the price falls along the same curve, down to the frozen price. Below it the cushion buys, and at the floor F does.

1% of supply
never runs out
tail::open(frozen, tail):
  L = ⌊tail · √frozen⌋                  // fixed for the launch's life
  tokens_at(p) = ⌈L ÷ √p⌉              // never reaches 0

tail::buy(money):
  to_F    = ⌈F · n ÷ S_out⌉             // the floor first, for each new token
  √p'     = √p + (kept − 1) ÷ L         // the curve moves by what the range keeps

tail::sell(tokens):
  from_F  = ⌊F · k ÷ S_out⌋             // the floor's part
  rest    = from the range's money, along the curve

Two rules keep the range from taking backing. A range buy puts the floor’s share for its new tokens into F before the range keeps anything. The curve then moves only by what the range keeps, after the fees.

Along the range the floor’s share of the price falls as the price rises. The floor itself does not fall.

05 — The bid

How a sell is filled: the cushion, then the floor

The bid is the program’s two pots. C, the cushion, buys above the floor along a stored price curve. F pays the floor for whatever C cannot take. The bid is keeperless: each sell fills against the pots in the same transaction, and nobody has to move anything first.

C has a target the preset sets, a share of the market cap. A buy fills it to that target before the rest raises the floor. The cushion’s curve is stored and walked down by each sell, so one sell split into many small sells is paid no more than the single sell.

A sell of x tokens

bid::sell(pots, S_out, x):
  // 1. the curve, from its top down to where it meets the running floor
  walk bid_sqrt_x64 down at liq while cushion lasts
  // 2. the cushion at the running floor, F ÷ (S_out − x)
  q = F · ln(S_out ÷ (S_out − x))      // while cushion holds money
  // 3. the floor pays f for the rest
  q = f · rest                           // out of F

// every token is bought; tokens C bought join the lot
// tokens F bought return to the inventory

How a buy feeds the pots

bid::credit(pay, n):                     // after fees and Milestones  pots.floor += ⌈floor_x64 · n ÷ 2^64⌉   // f for each new token outside  room = target − cushion  cushion += min(rest, room)             // C up to its target  pots.floor += rest − min(rest, room)   // the rest raises the floor  bid_sqrt_x64 rises by Δcushion ÷ liq   // the curve's top follows

The curve’s top sits at the Stack’s price times what a buy keeps, so the cushion bids just under the price. Its prices come only from the program’s own pots and schedule. A pool elsewhere cannot move them.

06 — The skim near the floor

The skim ramps over the last 1.2× above the floor

The skim is the part of a trade that stays in F. Far from the floor it is the Backing Fee. Within 1.2 times the floor it ramps to the at-floor rate: at least 1% on a sell and 0% on a buy. The ramp is the same on every preset and every chain.

SKIM_RAMP_LOG2_X64

log2 1.2

the ramp’s width, in log price above the floor

skim_buy_at_floor_bps

0

a buy at the floor keeps no skim

skim_sell_at_floor_bps

≥ 100

a sell at the floor keeps at least 1% in F

skim_buy_far_bps

≥ 1

a buy far from the floor pays at least 0.01%

closeness = 1 − log2(price ÷ f) ÷ log2 1.2
          // 0 at 1.2 × f or more, 1 at f or below
skim = far + (at_floor − far) · closeness

// far is the Backing Fee at the launch's market cap (09)
// price is the Stack's price before the trade

A seller near the floor pays more into F, which raises the floor for the holders who stay. A buyer near the floor pays less, so buying close to the floor is cheap.

07 — Every fee

Every fee a trade pays, and where each one goes

A trade pays four fees on top, on every buy and every sell: the Backing Fee, the Team Share’s fee, the Platform fee and the $FLOOR fee. Each rate is a curve on the launch’s market cap, copied from its preset for life. The fee base is the trade’s quote amount.

Before graduation a window trade pays only the Platform fee and the $FLOOR fee, 0.50% each and flat (03). Every fee rounds up, to the smallest unit, so splitting a trade never skips a fee. A refunded part of a buy pays nothing.

A buy’s Marketcap Milestones are inside the price it pays, so they add nothing to what a trade pays on top (08). There is no LP fee, no sale fee and no sell-back fee.

08 — Marketcap Milestones

Shares of a buy that sit inside its price

A buy on the way up carries the Marketcap Milestones. They are shares of the buy that sit inside the price it pays, so the buyer pays the price shown and nothing on top. A Milestone is not a fee: only buys the window and the Stack fill pay one, and sells never do.

A Stack fill keeps u′, what is left of the buy after its fees and Milestones. The Stack’s price must still rise on every interval as it mints at that rate. The preset check proves it for a row’s whole curve before the row can be listed.

The Milestones stop when the Stack sells out. Trading in circles pays the fees, never a Milestone. A fill takes the Milestones at the market cap it ends at, so one large buy never pays less than the same money in pieces.

09 — Curves

Every rate is a curve on market cap

Each fee and each Marketcap Milestone has a start rate and an end rate. The rate moves from one to the other as the launch’s market cap grows from a start value to an end value, and stays flat outside them. Each preset row sets the points and the shape.

t    = (log2 FDV − log2 from) ÷ (log2 to − log2 from)
t    = clamp(t, 0, 1)                // flat outside the span
rate = start + (end − start) · t^n   // n, the curve's intensity

// n = 1 is a straight line in log market cap
// a rising curve: end > start; a falling one: end < start
Risingthe Backing Fee and the four Marketcap Milestones
Fallingthe Team Share’s fee, the Platform fee and the $FLOOR fee
FDVthe Stack’s price × the supply, at the declared quote price
Intensitya field per curve; it shapes the bend, never the end points

Fees on volume fall as a token grows, so trading a large token is cheap. The money that takes a token higher pays the Milestones instead. Teams earn most when their token does well, and the platform and $FLOOR earn their own Milestones on the same climb.

10 — The Team Share

The Team Slot and what its members earn

Everything a launch’s team earns is one Team Share: the Team Share’s fee on every trade and the Team Marketcap Milestone on every buy on the way up. The creator’s referrers take 10% of the whole, and the rest goes to the Team Slot’s members by their shares.

A Team Slot is free. It holds up to ten members, each with a number of share units, and a member’s part is its shares divided by all shares. Members are added with the launch and cannot be removed. While the slot has no shares, the creator receives the whole Team Share. A launch on an unlisted quote has no Team Slot.

route(team_fee, team_milestone):
  for part in [team_fee, team_milestone]:
    ref = part · [900, 90, 10] ÷ 10_000   // the creator's 3 tiers
    rest = part − Σ ref                    // an empty tier stays in rest
    if slot has shares:
      member[i] += rest · shares[i] ÷ Σ shares
    else:
      creator += rest                      // place 0

// dust from the split goes to F
team_slot_max_bpsa row field, the slot’s ceiling rate for that preset, copied at creation
init_team_slotopens the slot, free
team_slot_addadds a member’s share units; no money moves
claim bit 4a member’s Team Share

11 — Referrals and the claim

Three tiers of referrers, and one claim for everything

A trader’s referrers are paid from the Platform fee of each trade: 30%, 20% and 10% across three tiers. A creator’s referrers are paid from the Team Share: 10%, split 90 / 9 / 1. One claim instruction pays a wallet everything it is owed.

The one claim · claim(wallet, types, launches)

bit   1   the creator's Team Share (no Team Slot)
bit   2   creator referrals
bit   4   a Team Slot member's Team Share
bit   8   trader referrals
bit  32   extra fee legs
bit  64   a payout that failed (EVM)
bit 128   an unlocked Team Buy, in the base token

// anyone may send; it pays only `wallet`
// each balance is paid once; nothing owed succeeds and does nothing

On EVM every balance is kept per wallet and per quote, so one claim makes one transfer per quote however many launches it covers. On Solana each launch keeps its own quote vault, and a claim lists the launches it collects from.

A trade with no referral record pays its referrer slices to the platform bucket. Holder money is never claimed: it waits in the holder bucket for governance to send it to the holder address.

12 — Presets

Presets are data, copied into a launch for life

A preset is a row of launch settings that governance writes: the window, the Stack’s shape, the cushion’s target and every fee and Milestone curve. A launch copies its row when it is created and keeps that copy for life. The site offers two rows, WAGMI and Moonshot.

A row’s floor share never falls as the Stack sells, and the preset check refuses any row whose share could. A row is listed in two steps: written, then checked against reference quotes, and only a checked row can be enabled.

Preset ids are append-only. A deleted row stays, so its id is never used again. A later change to a row reaches only launches created after it.

13 — Creating a launch

One transaction creates the token and opens the market

A creator picks a preset and a quote, names the token and sends one transaction. That transaction creates the token, mints the whole supply to the program, makes the Team Buy and opens the market. The Team Slot can be opened in the same transaction.

create_launch(name, symbol, creator_buy):
  mint 1B to the program; renounce the mint
  metadata uri = metadata_base / mint .json
  pay the create fee                     // to the platform bucket
  team_buy = window · creator_buy_max_bps ÷ 10_000
  buy team_buy at p0, before anyone      // locked 1 day
  copy the preset row into the launch
Create feeabout $10, set by governance per quote in that quote’s units
Team Buythe row’s share of the window, at most 50%, filled first at the window price
The lock1 day, then split to the Team Slot’s members by their shares
Addressevery site launch’s token address ends in B1D

Where a preset sets a Team Buy share, the create must buy all of it. A row with no share takes none. The locked tokens count as outside the program, so F holds money for them like any other tokens.

14 — Quotes and governance

The quote registry, and what governance can change

Each launch trades against one quote. Governance keeps a registry of quotes on every chain and can add one without redeploying the program. Governance runs the registries and the platform bucket. It cannot stop trading or reach a launch’s pots.

01Listed quotes
A registry entry per quote, with its create fee and USD price.

A price updater role writes each quote’s USD price, which sizes later launches on it. A live launch keeps the price it copied. Tokens launched on FLOOR can be quotes. On EVM the native coin is a quote, paid as the transaction’s value.

QuoteEntry
02Unlisted quotes
Any other token, with a USD price its creator declares.

An unlisted launch trades like any other and has no Team Slot. Its create fee is paid in the chain’s native coin. The site shows it with a not on FLOOR list mark and leaves it out of Trending, points and leaderboards.

listed = false
03No internal swap
A wallet holding another asset reaches a launch through a router.

The FLOOR site and app route the swap, and so do aggregators. buy_from_balance spends everything above a set amount, so a router can chain a swap into a buy in one transaction.

buy_from_balance

15 — Solvency

What the program checks after every instruction

After every instruction that moves money, the program checks that its vaults hold everything it owes. A check that fails undoes the instruction. These are the reads an integrator can use to watch a launch.

quote_vault ≥ F + C + tail_money + Σ owed
// owed: platform, creator, Team Slot, referrals, extra legs, holder

token_vault ≥ window_left + inventory + lot + tail + locked_team_buy

S_out = live_supply − held           // never negative

Every buy and sell emits Trade, with the money, the tokens, the fee split, the price before and after, the floor after, both pots and the tokens outside. LaunchCreated, Graduated, ScheduleDone, PotsMoved, PotsSwept and Claimed cover the rest of a launch’s life.

Source: FLOOR on Solana and EVM, and floor-math, its shared math library.

Verify

Read it on-chain.


The floor, the pots and the price are public on every launch. Check them yourself.
Browse launches →