How it works

Four steps from idea to a live, tradable coin.

  1. 1.Pick a coin you like — or launch your own in seconds

    Creating a coin is free; you only pay network gas. Name, ticker and image are locked in forever at creation.

  2. 2.Buy on the bonding curve

    Price is set by a constant-product curve with virtual reserves. Every buy moves the price up, every sell moves it down — liquidity is guaranteed by math, not market makers.

  3. 3.Sell any time

    You can exit whenever you want, locking in profits or cutting losses. There is no lockup and no counterparty to wait for.

  4. 4.Graduation

    When enough ETH accumulates on the curve (~4.5 ETH), the coin graduates automatically: liquidity moves into a Uniswap v3 pool (1% fee tier) and the LP position is locked forever. Trading continues on Uniswap — visible on aggregators like Dexscreener — and the pool's trading fees are split 65% protocol / 35% creator.

Every coin launches with a fixed 1B supply and no presale or team allocation. A 1.25% fee on every curve trade funds the protocol (1%) and the coin's creator (0.25%). At graduation a 1.5% migration fee applies and the remaining liquidity is locked forever — the pool has no owner, no admin and no withdraw function, so the rug is pulled out of rug pulls.

Build on Baaf

No API keys, no gatekeeping — the UI is optional. Every launch, trade and quote is a public contract call, so bots and integrations are first-class citizens.

Network
Robinhood Testnet
Chain ID
4663
RPC
https://rpc.mainnet.chain.robinhood.com/rpc

Each coin gets its own BondingCurve contract (second address in the CoinCreated event). Quotes are on-chain views — no off-chain oracle, what you quote is what you get.

import { createWalletClient, http, parseAbi, parseEther } from "viem";

const factoryAbi = parseAbi([
  "function createCoin(string name, string symbol, string metadataURI, bytes32 salt) payable returns (address token, address curve)",
  "function predictCoinAddress(address sender, bytes32 salt, string name, string symbol, string metadataURI) view returns (address)",
]);
const curveAbi = parseAbi([
  "function buy(uint256 minTokensOut) payable returns (uint256)",
  "function sell(uint256 tokensIn, uint256 minEthOut) returns (uint256)",
  "function quoteBuy(uint256 ethIn) view returns (uint256 tokensOut, uint256 fee)",
]);

// Launch a coin — send value > 0 to dev-buy in the same tx.
// metadataURI: "ipfs://…" or inline JSON {"description","image","socials"}
// salt: any bytes32 works; mine it so predictCoinAddress(you, salt, …)
// ends with "BAAF" to get the baaf.fun vanity suffix (~1M tries incl. EIP-55 all-caps check, a few seconds).
await wallet.writeContract({
  address: "0x91056209F7a757556f48302204ec77c2ceFebf2f",
  abi: factoryAbi,
  functionName: "createCoin",
  args: ["My Coin", "MINE", "ipfs://…", salt],
  value: parseEther("0.01"),
});