mint.fast docs

Buy and sell

Exact-in buys and sells through the launchpad, plus quoter eth_call examples.

Trading always goes through MintFastLaunchpad against the coin's Uniswap v4 pool. The hook takes 2% of the ETH side on the way through.

Buy (ETH in, tokens out)

function buy(
    address token,
    uint256 minTokensOut,
    uint256 deadline
) external payable returns (uint256 tokensOut);
  • msg.value is the exact ETH you offer (fee comes out of this path via the hook)
  • unused ETH on a partial fill is refunded
  • deadline is a unix timestamp, tx reverts if mined later
  • minTokensOut is your slippage floor
await walletClient.writeContract({
  address: launchpad,
  abi: launchpadAbi,
  functionName: "buy",
  args: [token, minTokensOut, BigInt(Math.floor(Date.now() / 1000) + 120)],
  value: parseEther("0.1"),
})

Sell (tokens in, ETH out)

function sell(
    address token,
    uint256 tokenAmount,
    uint256 minEthOut,
    uint256 deadline
) external returns (uint256 ethOut);

You must approve the launchpad (or use permit) for tokenAmount first. Unsolds on a partial fill are returned. ETH proceeds are paid to msg.sender.

await walletClient.writeContract({
  address: token,
  abi: erc20Abi,
  functionName: "approve",
  args: [launchpad, tokenAmount],
})

await walletClient.writeContract({
  address: launchpad,
  abi: launchpadAbi,
  functionName: "sell",
  args: [
    token,
    tokenAmount,
    minEthOut,
    BigInt(Math.floor(Date.now() / 1000) + 120),
  ],
})

Quote before you trade

MintFastQuoter simulates a swap inside a PoolManager unlock and reverts with the deltas. You must call it via eth_call (or viem simulateContract / a custom decoder). Nothing settles.

function quoteBuy(address token, uint256 ethIn)
    external returns (uint256 ethUsed, uint256 tokensOut);

function quoteSell(address token, uint256 tokenIn)
    external returns (uint256 tokenUsed, uint256 ethOut);

Returned amounts already net the 2% hook fee. If ethUsed < ethIn (or tokenUsed < tokenIn), the quote would only partially fill the locked range.

viem sketch

import { decodeErrorResult } from "viem"

const quoterAbi = [
  {
    type: "function",
    name: "quoteBuy",
    stateMutability: "nonpayable",
    inputs: [
      { name: "token", type: "address" },
      { name: "ethIn", type: "uint256" },
    ],
    outputs: [
      { name: "ethUsed", type: "uint256" },
      { name: "tokensOut", type: "uint256" },
    ],
  },
] as const

try {
  await publicClient.simulateContract({
    address: quoter,
    abi: quoterAbi,
    functionName: "quoteBuy",
    args: [token, parseEther("0.1")],
  })
} catch (err) {
  // Depending on RPC / viem version, decode the QuoteResult revert
  // or read the structured return if your client surfaces it.
  console.error(err)
}

The quoter always reverts with a QuoteResult carrier on success. Your client should simulate the call, decode that revert, then set minTokensOut / minEthOut with a slippage buffer.

Spot price and market cap

function state(address token)
    external view
    returns (
        TokenInfo info,
        bytes32 poolId,
        uint256 spotPriceWad // ETH per token, 1e18 scale
    );

Market cap in ETH:

marketCapEth ≈ spotPriceWad * 1e9 / 1e18

(1e9 tokens of total supply, price in ETH per whole token.)

Common reverts

UnknownToken, ZeroAmount, DeadlineExpired, Slippage, PoolNotLive, TransferFailed (sell path if ETH payout rejects).