How it works
Four steps from idea to a live, tradable coin.
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.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.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.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
- TokenFactory
- 0x91056209F7a757556f48302204ec77c2ceFebf2f
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"),
});