size.fun Open app

How it works

Quote assets

Every coin is priced in something. OKB by default — or one of six tokenised Hong Kong equities, so a coin can be denominated in Tencent rather than in the gas token.

A coin's quote asset is what buyers spend, what its price and market cap are counted in, and what its creator earns. It is fixed when the coin is created and can never be changed — it is written into the curve, or into the pool, at that moment.

The default is OKB, the chain's own gas token. Six tokenised Hong Kong equities are also approved, so a coin can be denominated in Tencent or Meituan instead.

The approved list#

AssetStockOpens atGraduates at
OKBNative gas token30 OKB75 OKB
wTCENTxTencent · HK 70061.7154.2
wSHEINxSHEIN · HK 625633.91,584.9
wHKEXCxHKEX · HK 38866.2165.4
wKUAIxKuaishou · HK 1024829.62,074.1
wMEITxMeituan · HK 3690351.4878.5
wMIXUxMixue · HK 2097135.8339.5

Every figure is denominated in the asset on its own row, and every one is pegged to roughly the same value as the OKB numbers above it — around 30 OKB to open and 75 to graduate — so a coin's economics do not change because of what it is priced in. Stock prices move, so those pegs are adjusted on chain from time to time; the launch form reads them live rather than repeating this page.

A seeded pool opens within about 1% of the same figure. Its opening price has to land on a usable Uniswap tick, and ticks are 2% apart on the tier these launch on.

Why the wrapped version#

Backed's xStocks rebase on EVM: dividends and splits are applied by moving a multiplier that rewrites balanceOf in place, without a transfer. A bonding curve reads its own quote balance as the reserve backing every seller, so a rebase would conjure reserve out of a dividend or strand it on a reverse split — the coin's price would move because the underlying stock paid a dividend, which is not a market anyone asked for.

The wrappers are ERC-4626 vaults. A share balance only moves when someone deposits or redeems, so the reserve means what the contract thinks it means. The dividend still accrues — it accrues to the vault, and therefore to the share price.

What changes for a creator#

  • Your fees arrive in that asset. A wTCENTx-quoted coin pays its creator in wTCENTx, claimable from the same escrow as everything else.
  • The launch fee is still OKB. It is charged in the gas token regardless of what the coin is quoted in, so you need OKB in the wallet either way.
  • Your own buy is unavailable on a seeded launch. It is funded with the launch transaction's own native value, and that value is OKB.
  • Your buyers need the asset. Which is the real cost — see below.

What changes for a trader#

You need the quote asset itself. There is no OKB pool for any of these stocks on X Layer — they trade against USDG on Uniswap v3, while the funded OKB market is a v4 pool — so reaching one from the gas token is three hops across two protocols.

Not yet on the site

Buying a stock-quoted coin with OKB in one click is not live here yet. The coin's market is real and public either way: a seeded one is an ordinary Uniswap v3 pool that anything holding the stock can trade, and a curve one can be traded by calling it directly with the stock. What is missing is the one-transaction path from OKB, and the trade panel says so rather than offering a form that would revert.

Launching against one#

A stock-quoted coin is a curve launch with the wrapper's address in place of OKB. The quote asset is the third argument to launchToken, and it is a constructor immutable on the curve — there is no setter, and nothing can change it afterwards.

A seeded launch picks its quote asset differently. The v3 factory's launchToken takes (params, launchConfigId, dexId, salt) — there is no quote-asset argument, because the asset is part of the launch config rather than passed alongside it. There is one config per approved asset, so the id you choose is the pairing you get:

launchConfigIdQuote assetGraduates at
0WOKB75.00
1wTCENTx154.21
2wSHEINx1,584.87
3wHKEXCx165.40
4wKUAIx2,074.10
5wMEITx878.49
6wMIXUx339.52

Read launchConfigCount() and getLaunchConfig(id) rather than trusting this table — configs are added and re-pegged on chain, and the id is the only thing your call passes. Note that a seeded launch quotes against wrapped OKB where a curve launch quotes against the native token, which is why config 0 reads WOKB and not OKB.

Two things differ from an OKB launch, and both of them revert rather than misbehave if you get them wrong. The opening buy is denominated in the stock, so LaunchAndBuy pulls it with transferFrom and needs an allowance first. And the call carries the launch fee alone as native value — the fee is always OKB, but the buy no longer is, so the familiar launchFee + quoteIn is wrong here and fails with NativeValueMismatch.

ts launch-paired.ts
import { erc20Abi, parseUnits, parseEventLogs } from 'viem'
import {
  publicClient, walletClient, account,
  size, factoryAbi, launchAndBuyAbi,
  STOCKS, LAUNCH_CONFIG_ID,
} from './size.js'
import { params } from './launch-params.js'

// The quote asset this coin will trade against for the rest of its life. It is
// a constructor immutable on the curve — there is no setter and no owner call
// that can change it later.
const pairToken = STOCKS.TENCENT

// Never assume. The owner can withdraw an asset at any time, and launching
// against a withdrawn one spends the launch fee on a revert.
const approved = await publicClient.readContract({
  address: size.factory,
  abi: factoryAbi,
  functionName: 'approvedPairTokens',
  args: [pairToken],
})
if (!approved) throw new Error(`${pairToken} is not an approved quote asset`)

// Both figures are denominated in the quote asset, not in OKB, and they are
// re-pegged on chain as the stock moves. Read them rather than hardcoding.
const [phantomQuote, graduationThreshold, decimals] = await publicClient.readContract({
  address: size.factory,
  abi: factoryAbi,
  functionName: 'pairTokenEconomics',
  args: [pairToken],
})
console.log({ phantomQuote, graduationThreshold, decimals })

// What you want to spend on your own coin, in the quote asset — so this is
// wTCENTx, not OKB.
const quoteIn = parseUnits('2', decimals)

const launchFee = await publicClient.readContract({
  address: size.factory,
  abi: factoryAbi,
  functionName: 'launchFee',
})

// The two things that differ from an OKB launch, and the two that catch people
// out. LaunchAndBuy pulls the quote asset with transferFrom, so it needs an
// allowance; and the call carries the launch fee ALONE as value, because the
// buy is no longer denominated in the chain's own token. Sending
// `launchFee + quoteIn` here reverts with NativeValueMismatch.
const { request: approval } = await publicClient.simulateContract({
  address: pairToken,
  abi: erc20Abi,
  functionName: 'approve',
  args: [size.launchAndBuy, quoteIn],
  account,
})
await publicClient.waitForTransactionReceipt({
  hash: await walletClient.writeContract(approval),
})

const { request, result } = await publicClient.simulateContract({
  address: size.launchAndBuy,
  abi: launchAndBuyAbi,
  functionName: 'launchAndBuy',
  args: [
    { ...params, creatorFeeRecipient: account.address },
    LAUNCH_CONFIG_ID,
    pairToken,
    quoteIn,
    0n,                 // minTokensOut — set a real floor in production
    account.address,    // who receives the opening buy
    [],                 // extra addresses exempt from the snipe tax
  ],
  value: launchFee,
  account,
})

const [token, curve, tokensOut] = result
console.log({ token, curve, tokensOut })

const receipt = await publicClient.waitForTransactionReceipt({
  hash: await walletClient.writeContract(request),
})

const [launched] = parseEventLogs({
  abi: factoryAbi,
  eventName: 'TokenLaunched',
  logs: receipt.logs,
})
// pairToken comes back on the event, so an indexer never has to guess what a
// coin's figures are denominated in.
console.log(launched.args)

Read approvedPairTokens before you rely on an asset: the owner can withdraw one, and launching against a withdrawn asset spends the launch fee on a revert. Read pairTokenEconomics rather than hardcoding the opening and graduation figures — they are denominated in the quote asset's own decimals and are re-pegged on chain as the stock moves.

Addresses#

The wrappers, on X Layer:

AssetAddress
wTCENTx0x41333Df9E7639188BBfca5522dC4844398Af9f9E
wSHEINx0xff637d2d435D6745Df3faf61272B1216e7e8b727
wHKEXCx0xDFc060b4dE44Fb88998b695aA59169643DED10ea
wKUAIx0x096369B9b197bCbF669a3bC827Aa119d80d891E4
wMEITx0xad1b65C8556957cf23d1B5e9accdc449b415fA97
wMIXUx0x1Bac76a12d8EccA6dBF4B0A146Da8870d50F04c9

Approval is a mapping on each factory with no enumeration, so this list is what has been approved rather than something readable in one call. Check any address with approvedPairTokens(address) on the curve factory, or read the seeded launcher's getLaunchConfig(id) — one config per asset, and a disabled one disappears from the launch form without a deploy.