Buying and selling
Trades go to the coin's Uniswap pool. Muup.fun builds the transaction and shows you a quote; the swap itself is executed by Uniswap's router, and you sign every one.
The quote and the price you get
The “you receive” figure is a quote for the pool as it stands right now. It is not a promise. Between the moment you read it and the moment your transaction is mined, other trades can move the price — on a thin new pool, considerably.
What slippage tolerance actually does
Your slippage setting becomes a floor written into the transaction: the smallest output you will accept. If the pool moves so far that you would receive less than that, the swap reverts and you keep your funds, minus gas.
- Too tight, and ordinary price movement makes trades fail. You pay gas for nothing.
- Too loose, and you are telling the network you will accept a much worse price — which is precisely the room a sandwich attack needs.
A trade is refused when there is no quote
Why some networks ask for more signatures
On most chains a buy is a single signature. On Stable the router cannot wrap the native token for you, so you wrap, approve once, then swap. The approval is permanent, so every later trade is shorter. This is explained in full on the networks page.
You are not locked into this interface
The pool is an ordinary Uniswap pool. Any interface, aggregator or bot that supports that version of Uniswap on that network can trade the coin without going through Muup.fun at all. How you address the pool depends on which version it is, and the coin's page shows whichever applies.
V3 — the pool is a contract
A V3 pool has its own address, and reading its price takes nothing more than an RPC call:
// Current price and tick, straight from the pool.const pool = new ethers.Contract(POOL_ADDRESS, [ "function slot0() view returns (uint160 sqrtPriceX96,int24 tick,uint16,uint16,uint16,uint8,bool)", "function token0() view returns (address)",], provider);const { sqrtPriceX96, tick } = await pool.slot0();V4 — the pool has no address
Every V4 pool lives inside one PoolManager contract and is identified by a poolId — the hash of its parameters — rather than by an address of its own. There is nothing to point an ethers.Contract at, so a tool written for V3 addresses will not find it. Read the state from the manager instead:
// The pool lives inside the singleton; poolId identifies it.const manager = new ethers.Contract(POOL_MANAGER, [ "function getSlot0(bytes32 id) view returns (uint160 sqrtPriceX96,int24 tick,uint24,uint24)",], provider);const { sqrtPriceX96, tick } = await manager.getSlot0(POOL_ID);Either way, which side of the pair your coin sits on decides how that price is read, so check token0 before converting it.
