# biddin Integration Docs

> biddin is a memecoin launchpad on Arc, Circle's L1 where gas is paid in USDC.
> A launch is one contract call with no prior approval. Everything here is enforced by public
> contracts, so you can launch, trade, read and index without ever touching our site.
> Arc mainnet, chain 5042. HTML version: https://biddin.win/docs.html

## How it works

A token is sold along a bonding curve priced in USDC. When the curve has raised its threshold the
token graduates: the proceeds and the remaining supply seed a Uniswap V3 position, the position is
locked, and a slice of supply is burned. Trading continues in that pool. The creator keeps earning
from every trade, before and after graduation.

| | value | note |
|---|---|---|
| Sale supply | 1,000,000,000 | Fixed. Sold through the curve. |
| Graduation | 8,000 USDC | Raised on the curve before the pool opens. |
| Trade fee | 1.00% | Charged on the USDC leg, both directions. |
| Creator share | 70% | Of that fee — 0.70% of volume, forever. |
| Launch cost | 1.00 USDC | Flat, plus gas. Gas on Arc is USDC too. |
| Snipe tax | 99% → 0 | Decays to zero over 4 seconds. |

Every number above is read from the factory, not written here. See "Reading state" for how to fetch
them yourself, and "What cannot change" for which of them are frozen once your token exists.

## Graduation

A coin lives on its curve until the curve has taken in **8,000 USDC**. Then it graduates, in two
permissionless steps anyone can call — our keeper does it within a block or two, and if it ever
stops, anybody else can finish the job.

What happens is fixed:

- The curve closes for good. No more buying or selling against it.
- The USDC it collected and the tokens it still holds open a **Uniswap V3 pool** at the price the
  curve closed at — so there is no gap for a first buyer to arbitrage.
- About **8.16%** of the supply is burned in the same transaction.
- The pool position goes to a locker contract that **has no withdrawal function**. Not a promise not
  to pull it — there is no code path that could.

The burn is not a marketing number, it falls out of the arithmetic. The curve prices against a
phantom reserve that has no real USDC behind it, so seeding every remaining token would open the
pool cheaper than the curve closed and hand the first buyer free money, paid for by the people who
bought last. Seeding only what the collected USDC supports at the closing price leaves a surplus,
and that surplus is burned rather than kept — exactly `1 / (1 + threshold/virtualQuote)²`, which
with 8,000 over 3,200 is 8.16%. Sending it anywhere other than a burn address would make it a hidden
team allocation.

## What the creator earns

Creators get no token allocation here. What they get is **70% of the 1% trade fee** — 0.70% of every
dollar traded, in USDC, on the curve and in the pool afterwards, for as long as the coin trades. No
cliff, no vesting, no end date.

It accrues to an escrow contract and is claimed with one call. Anyone may trigger that claim, but
the money can only ever go to the recipient, never to the caller — so a front end or a relayer can
pay a creator out without ever holding their funds.

The right to those fees is movable, not welded to the wallet that launched the coin. Whoever
currently holds it can hand it to someone else — a multisig, a treasury, a co-founder — and it only
moves forwards, so the launching wallet cannot take it back. That is what makes launching from a hot
wallet safe.

A creator may also set a tax of their own, up to 10%, charged on top of the protocol fee and paid
entirely to them. Most do not, and there is a reason: a 5% tax costs someone who buys and later
sells 10% of their money, which suppresses the volume the 0.70% is calculated on.

## Buyback and burn

A creator can point their own fee stream at the coin instead of at their wallet. Switch it on and
every fee the coin earns is used to **buy the coin back and burn what it buys**, from the first
trade onwards.

It is a contract, not a policy. Turning it on at launch replaces the fee recipient with a buyback
contract deployed for that coin, so the fees never pass through a wallet at all. Nobody — not the
creator, not us — can redirect them afterwards or withdraw from it.

| Rule | Value | Why |
|---|---|---|
| Runs when it holds | 50 USDC | Below that the gas is a meaningful share of the buy |
| …or after | 3 days | Then 10 USDC is enough, so a quiet coin still gets its buybacks |
| Max spend per run | 3% of the curve | A buyback should support the price, not spike it |
| Tokens bought | all burned | Burned in the same transaction; the contract never holds the coin between runs |

Who may trigger it is deliberate. Our keeper has it to itself for the first three days after each
run, then anyone can call. That is not gatekeeping: an attacker who controls *when* a buyback fires
could buy just before it, sell into it, and use the coin's own fees as their exit liquidity. Taking
the timing away costs nothing while the keeper is alive, and the public fallback means a dead keeper
can never strand a coin's fees.

Readable on chain: `pending()` for what is waiting, `totalBurned()` for what it has destroyed, and a
`BoughtBack` event for every run.

## Quick start — launch in one call

`launchWithNative` creates the token, opens its curve, optionally buys your own allocation and
optionally enrols the coin in buyback-and-burn — in a single transaction with **no approval step**.
Arc's gas asset is USDC and the native balance is the same money as the ERC-20, so the factory is
funded by the value you send.

```js
// client.js — npm i viem
import { createPublicClient, createWalletClient, http, defineChain } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';

export const arc = defineChain({
  id: 5042,
  name: 'Arc',
  nativeCurrency: { name: 'USDC', symbol: 'USDC', decimals: 18 },
  rpcUrls: { default: { http: ['https://rpc.arc-scan.org'] } },
});

export const account = privateKeyToAccount(process.env.PRIVATE_KEY);
export const pub = createPublicClient({ chain: arc, transport: http() });
export const wallet = createWalletClient({ account, chain: arc, transport: http() });
```

```js
// launch.js
import { parseAbi, parseEventLogs, parseUnits } from 'viem';
import { pub, wallet, account } from './client.js';

const FACTORY = '0xA5b69A713bf53C7f6f2E230428CebA62842fc9e2';

const factoryAbi = parseAbi([
  'struct Metadata { string name; string symbol; string imageUri; string description; string xUrl; string telegramUrl; string websiteUrl; }',
  'struct LaunchOptions { uint16 creatorTaxBps; address creatorFeeRecipient; uint256 devBuyQuote; uint256 devBuyMinTokensOut; bool buyback; address[] snipeTaxExemptions; }',
  'function launchWithNative(Metadata meta, LaunchOptions opts) payable returns (address token, address curve)',
  'function params() view returns (uint256 saleSupply, uint256 virtualQuote, uint256 graduationThreshold, uint256 launchFee, uint16 tradeFeeBps, uint16 creatorFeeShareBps, uint16 maxCreatorTaxBps)',
  'event Launched(address indexed token, address indexed curve, address indexed creator, string name, string symbol, uint256 saleSupply, uint16 creatorTaxBps)',
  'error WrongNativeValue(uint256 sent, uint256 needed)',
  'error CreatorTaxTooHigh()',
]);

// USDC has two faces on Arc: 6 decimals as an ERC-20, 18 as the native gas balance.
// Every AMOUNT in these structs is the 6-decimal one. Only msg.value is 18.
// parseUnits takes a STRING. Never build a money amount from a float — Math.round(n * 1e6)
// drifts, and it drifts silently.
const NATIVE_SCALE = 10n ** 12n;
const devBuy = parseUnits('50', 6);
const [, , , launchFee] = await pub.readContract({
  address: FACTORY, abi: factoryAbi, functionName: 'params',
});

const { request, result } = await pub.simulateContract({
  address: FACTORY, abi: factoryAbi, functionName: 'launchWithNative', account,
  args: [
    { name: 'Example Coin', symbol: 'EXMPL',
      imageUri: 'ipfs://bafy...', description: 'launched from code',
      xUrl: '', telegramUrl: '', websiteUrl: '' },
    { creatorTaxBps: 0,
      creatorFeeRecipient: account.address,
      devBuyQuote: devBuy,
      devBuyMinTokensOut: 0n,
      buyback: false,
      snipeTaxExemptions: [] },
  ],
  // EXACT. The factory refuses an over- or under-payment rather than keeping the difference.
  value: (launchFee + devBuy) * NATIVE_SCALE,
});

const hash = await wallet.writeContract(request);
const receipt = await pub.waitForTransactionReceipt({ hash });
const [launched] = parseEventLogs({ abi: factoryAbi, eventName: 'Launched', logs: receipt.logs });
console.log('token', launched.args.token, 'curve', launched.args.curve);
```

**Why the value must be exact.** Both over- and under-payment revert with
`WrongNativeValue(uint256 sent, uint256 needed)` — selector `0xfe018882`. Put that error in your ABI
and the revert decodes into both numbers, `sent` first. The factory refuses rather than keeping the
difference: it has no sweep and no owner withdrawal, so an over-payment left inside would be
unrecoverable. Compute `value` from `params().launchFee + devBuyQuote` at call time rather than
hardcoding it.

If you would rather approve USDC first and send no value, the three `launch(...)` overloads do the
same work against an ERC-20 allowance: `launch(meta)`, `launch(meta, creatorTaxBps)`, and
`launch(meta, opts)`.

## Launch options

| Field | Type | What it does |
|---|---|---|
| `creatorTaxBps` | `uint16` | A tax you charge on every trade, on top of the 1% protocol fee, paid entirely to you. Capped at **10%** by `params().maxCreatorTaxBps`. Frozen at launch. A 5% tax costs a round-tripping buyer 10%, so it suppresses volume — price it deliberately. |
| `creatorFeeRecipient` | `address` | Where your earnings go. Zero means the launching wallet. Transferable afterwards by whoever currently holds it, one way — which is what makes launching from a hot wallet safe. |
| `devBuyQuote` | `uint256` | USDC (6 dp) spent buying your own launch in the same transaction, at the same curve price as anyone else. Exempt from the snipe tax, because it settles before the market exists. |
| `devBuyMinTokensOut` | `uint256` | Slippage floor on that buy. Zero disables the check. |
| `buyback` | `bool` | Enrol the coin in buyback-and-burn in this same transaction, so every creator fee it ever earns buys the coin back and burns it from the first trade. Enrolling later takes two more transactions and leaves a window where fees went to the wallet instead. |
| `snipeTaxExemptions` | `address[]` | Wallets that skip the snipe tax. Up to **100**. Declared at launch only — there is deliberately no way to add one later. |

### The snipe tax

For the first **4 seconds** after a curve opens, buys pay a tax on top of the normal fee. Selling is
never taxed, and the creator's launch buy is exempt because it settles before the market exists for
anyone else.

The schedule is `startBps >> ((elapsed * 14) / window)` with `elapsed` in whole seconds. Because
block timestamps have one-second resolution, the rate is a **step function, not a smooth curve** —
it changes once per second and nothing in between:

| Seconds after launch | Tax on the buy |
|---|---|
| 0 | 99.00% |
| 1 | 12.37% |
| 2 | 0.77% |
| 3 | 0.09% |
| 4 and later | 0% |

Read the live rate for a specific wallet with `curve.currentSnipeTaxBps(address)`, which returns `0`
for an exempt wallet and for everyone once the window closes. Tax plus fee together are capped so a
trade can never be charged more than 100%.

**Disclose your exemptions.** A creator may bring up to 100 wallets into the untaxed window. The tax
then protects buyers from bots *outside* that group, not from the group itself. This is a deliberate
product choice, and it is public: exemptions are readable at `curve.snipeTaxExempt(address)` and each
one emits `SnipeTaxExempted(address)` in the launch transaction. If you are building a front end or a
discover feed on top of biddin, **count those events and show the number**.

**Subtract one when you count.** Every launch emits one `SnipeTaxExempted` for the factory itself,
because the factory is what executes the creator's bundled buy and would otherwise pay its own 99%
tax. A launch declaring no exemptions at all still emits exactly one event. Verified on a real
launch: two events for one declared address.

## Metadata

`Metadata` is stored on-chain as plain strings, so there is no upload API you are required to use and
no gateway that can lose your image. Point `imageUri` at anything a browser can load — an `ipfs://`
URI, an `https://` URL, or a `data:` URI for something small.

Our own front end uploads the picture to our storage and writes that `https://` URL into `imageUri`.
That is a convenience, not a recommendation, and it is worth knowing what it costs: the bytes live
with us, so such an image lasts as long as our hosting does, and whoever controls the host can change
what sits behind the URL after people have already bought. Artwork that cannot be swapped and does
not depend on us means pinning it yourself and passing the `ipfs://` URI. The contract is indifferent
— it stores whichever string you give it.

## Trading on the curve

Before graduation a token trades against its own bonding curve, not a pool. Quote first: the curve
refunds any overshoot past the graduation threshold and charges the fee on the filled amount only, so
a large buy does not revert at the line — it fills what fits.

```js
// trade-curve.js
import { parseAbi } from 'viem';
import { pub, wallet, account } from './client.js';

const curveAbi = parseAbi([
  'function previewBuyFor(uint256 quoteIn, address recipient) view returns (uint256 tokensOut, uint256 quoteSpent, uint256 refund, uint256 fee, uint256 tax, uint256 snipeTax)',
  'function previewSell(uint256 tokensIn) view returns (uint256 quoteOut, uint256 fee, uint256 tax)',
  'function buyWithNative(uint256 minTokensOut) payable returns (uint256 tokensOut, uint256 quoteSpent)',
  'function buy(uint256 quoteIn, uint256 minTokensOut) returns (uint256 tokensOut, uint256 quoteSpent)',
  'function sell(uint256 tokensIn, uint256 minQuoteOut) returns (uint256 quoteOut)',
  'function currentSnipeTaxBps(address recipient) view returns (uint256)',
  'function readyToGraduate() view returns (bool)',
]);

const CURVE = '0x…';
const NATIVE_SCALE = 10n ** 12n;
const amountIn = 10n * 10n ** 6n;              // 10 USDC, 6 decimals

// Never buy inside the snipe window unless you are exempt: at t=0 the tax is 99%.
const tax = await pub.readContract({
  address: CURVE, abi: curveAbi, functionName: 'currentSnipeTaxBps', args: [account.address],
});
if (tax > 0n) throw new Error(`snipe tax still ${Number(tax) / 100}% — wait`);

// previewBuyFor prices the snipe tax for THIS buyer; previewBuy uses msg.sender, which is
// the zero address on an eth_call and therefore never exempt. Always pass the real recipient.
const [tokensOut, , refund] = await pub.readContract({
  address: CURVE, abi: curveAbi, functionName: 'previewBuyFor', args: [amountIn, account.address],
});
if (refund > 0n) console.log('partial fill — curve is at the graduation line');

const hash = await wallet.writeContract({
  address: CURVE, abi: curveAbi, functionName: 'buyWithNative',
  args: [(tokensOut * 9750n) / 10000n], value: amountIn * NATIVE_SCALE,   // no approval needed
});
await pub.waitForTransactionReceipt({ hash });
```

Selling needs one ERC-20 approval of the curve, then `sell(tokensIn, minQuoteOut)`. There is also
`buyWithPermit` if you would rather sign an EIP-2612 permit than send a separate approval.

## After graduation

At `readyToGraduate()` the curve closes permanently and two permissionless steps run:
`drainCurve(token)` moves the proceeds into the factory, then `seedPoolV3(token)` opens the Uniswap
V3 pool, seeds it, burns the surplus and hands the position to the locker. They are two calls rather
than one so that a pool creation that fails cannot strand the drain. Anyone may call either; our
keeper does it within a block or two. See "Graduation" above for what the burn is and why.

From that point the token is an ordinary Uniswap V3 pair against Arc USDC. Trade it through any V3
router — nothing routes through us.

**Why a locked V3 position rather than a burned LP token.** Burning the LP is the usual way to prove
liquidity cannot be pulled, and it works — but a burned position stops paying anyone. Ours is held by
a contract with no withdrawal function, which is the same guarantee, except the position keeps
collecting swap fees. Those fees are what let the creator keep earning after graduation rather than
only on the curve. The token surplus is still burned, because a full-range V3 position holds the same
reserve ratio as a V2 pair and the surplus has nowhere else to go.

## Reading state

Two calls cover most integrations: `factory.params()` for the economics every new launch inherits,
and `factory.launchOf(token)` for one coin's identity. Per-coin economics live on the curve as
immutables.

```js
const factoryAbi = parseAbi([
  'function params() view returns (uint256 saleSupply, uint256 virtualQuote, uint256 graduationThreshold, uint256 launchFee, uint16 tradeFeeBps, uint16 creatorFeeShareBps, uint16 maxCreatorTaxBps)',
  'function launchOf(address token) view returns (address token_, address curve, address creator, uint64 createdAt, uint16 creatorTaxBps, bool exists)',
  'function tokenCount() view returns (uint256)',
  'function allTokens(uint256 i) view returns (address)',
  'function snipeTaxStartBps() view returns (uint16)',
  'function snipeTaxSeconds() view returns (uint32)',
]);

const curveAbi = parseAbi([
  'function quoteReserve() view returns (uint256)',
  'function graduationThreshold() view returns (uint256)',
  'function tradeFeeBps() view returns (uint16)',
  'function creatorFeeShareBps() view returns (uint16)',
  'function creatorTaxBps() view returns (uint16)',
  'function totalChargeBps() view returns (uint256)',
  'function graduated() view returns (bool)',
  'function creatorFeeRecipient() view returns (address)',
  'function snipeTaxExempt(address) view returns (bool)',
  'function factory() view returns (address)',
]);
```

**Read `totalChargeBps`, not `tradeFeeBps`.** `tradeFeeBps` is the protocol's 1%. A creator may add up
to 10% on top. `totalChargeBps()` is the sum — the number a trader actually pays. Quoting with the
protocol fee alone will overstate the output on every taxed coin.

## Events

Six events cover the lifecycle. The curve events are emitted by each coin's own curve, so filter them
by topic0 alone (or by the curve address if you already know it); the factory events are worth
filtering by the factory address as well.

| Event | Emitted by | topic0 |
|---|---|---|
| `Launched(address,address,address,string,string,uint256,uint16)` | Factory | `0xd3908bba65accd90a4c5d3d668306b13dfb4d28f31ad27405142cbc149364f88` |
| `CreatorBought(address,address,uint256,uint256)` | Factory | `0x5772767e7b2a80bb7caf31ec477440a12dec4d0c71f0388af6dd6ec5234a0f38` |
| `PoolSeeded(address,address,uint256,uint256,uint256)` | Factory | `0x5d70d05a0cfd1a00cf62cd97af9b9ca9787a8d02f6acb398437ab82ee88e527e` |
| `Bought(address,uint256,uint256,uint256,uint256,uint256,uint256)` | Curve | `0x15053609d51f61ee8a7b1c2250290b901d8ef6cb2afec5d8987f3d8cafa06c4f` |
| `Sold(address,uint256,uint256,uint256,uint256,uint256)` | Curve | `0x917d0fe1b6c3328f12a0177d25bf1b7d9e963116addad0bfc06b0cdcb6427603` |
| `SnipeTaxExempted(address)` | Curve | `0xe4b7e48fbd47c2f602bacadee76ad33b16542ddb4997cfc0de04c311adcfa8c7` |

`Launched` carries the token, curve and creator as indexed topics, so you can build a complete coin
list from that one filter without a single extra call. `CreatorBought` appears in the same transaction
when the creator bundled a dev buy — its absence is itself information worth surfacing.

## Fees

Every trade pays **1.00%** on the USDC leg, in both directions, on the curve and in the pool after
graduation. It splits **70% to the creator, 30% to the protocol**. A creator tax, if the creator set
one, is charged on top and goes entirely to the creator.

| Stage | Protocol fee | Creator | Protocol | Creator tax |
|---|---|---|---|---|
| On the curve | 1.00% | 0.70% | 0.30% | 0–10%, set at launch |
| After graduation | 1.00% | 0.70% | 0.30% | — |

Creator earnings accrue in USDC to an escrow and are pulled with `claim(token, recipient)`. Anyone may
trigger a claim; the money only ever goes to the recipient, never to the caller, so a relayer or a
front end can pay a creator out without ever holding their funds.

Launching costs a flat **1.00 USDC**. There is no listing fee, no revenue share agreement and no
allowlist — the contracts do not know who you are.

## Addresses

Arc mainnet, chain **5042**. These are final — safe to compile in.

| Contract | Address |
|---|---|
| Launch factory | `0xA5b69A713bf53C7f6f2E230428CebA62842fc9e2` |
| Fee escrow | `0xcC7F665d28247155a48d359A281761A397E75DF7` |
| V3 liquidity locker | `0x8C6B6A4Cc7E8B6D3715BcB0be0fD677bF8cb3Ead` |
| Buyback factory | `0x203343182aD32A66d53355a64Bc71baaC6DC5E40` |
| Quote asset (Arc USDC) | `0x3600000000000000000000000000000000000000` |
| Owner (2-of-3 Safe) | `0xA4F1883D025E12e760124A9701704133A6FB6D1e` |

### Check you are talking to the real one

The factory is **not** a proxy — deliberately, so that nobody can swap the logic under a coin that
already exists. Nothing about the address above can change, and it holds no admin key over your coin
once launched. Four reads confirm it, and they cost nothing:

```js
const abi = parseAbi([
  'function owner() view returns (address)',
  'function pendingOwner() view returns (address)',
  'function quote() view returns (address)',
  'function feeEscrow() view returns (address)',
]);
// owner        == 0xA4F1883D025E12e760124A9701704133A6FB6D1e   the 2-of-3 Safe
// pendingOwner == 0x0000000000000000000000000000000000000000   handover completed
// quote        == 0x3600000000000000000000000000000000000000   Arc USDC, not a lookalike
// feeEscrow    == 0xcC7F665d28247155a48d359A281761A397E75DF7
```

A zero `pendingOwner` matters: it means the ownership handover to the Safe completed, rather than
sitting half-done with a deploy key still able to claim it back.

Going the other way, any token's curve exposes `factory()`. A coin whose `factory()` is not the
address above was not launched here, whatever its name and image claim.

## What cannot change

The Safe that owns the factory can change what *future* launches inherit: `setParams`, the snipe-tax
knobs, the protocol fee recipient, the pool venue. It has no function that can reach a coin that
already exists. That is not a policy, it is the storage layout — every economic term is declared
`immutable` on the curve at construction:

| Frozen at launch | Meaning |
|---|---|
| `tradeFeeBps` | The 1% protocol fee your coin pays, forever |
| `creatorFeeShareBps` | Your 70% share of it |
| `creatorTaxBps` | The tax you chose, if any |
| `snipeTaxStartBps` / `snipeTaxSeconds` | The anti-snipe schedule |
| `graduationThreshold` / `virtualQuote` | The curve shape and the finish line |
| `protocolFeeRecipient` | Where our 30% goes, for this coin |
| `saleSupply` / `quote` / `token` | Supply and the asset it trades against |

Verify it yourself: read any of these off a live curve, then read the same field off the factory. If
the Safe ever changes the factory's value, the curve's will not move.

Two more properties worth checking rather than trusting:

- The factory has **no sweep, no withdraw and no owner-controlled token transfer**. The single
  exception is `rescueStuckGraduation`, which is owner-only, requires the graduation to have been
  stuck for **7 days**, and reverts outright if the normal seeding path would still work.
- The graduated liquidity position is held by a locker contract with no withdrawal function. Not a
  pledge — there is no code path.

## Known traps on Arc

These are the things that have actually cost us time. None are biddin-specific; all of them will bite
any integrator on this chain.

**USDC has two decimal counts.** The native balance — what you send as `msg.value` and what pays gas —
is **18 decimals**. The ERC-20 at `0x3600…0000` is the same money at **6 decimals**. Every amount in
our structs and quotes is the 6-decimal one; only `msg.value` is 18. Scale by `1e12` when you cross. A
bot that reuses one number on both sides is wrong by six orders of magnitude, and the failure is a
silent under-payment rather than a revert.

**`eth_call` with a gas field but no `from` returns 503.** Arc's RPC answers `503`, not a JSON-RPC
error. It reads exactly like an outage. Send both or neither.

**Public nodes drop `eth_call` under load.** We have measured the free public endpoint refusing every
`eth_call` for minutes at a time while `eth_blockNumber` answered instantly. If your health check only
pings `eth_blockNumber` it will report green through an outage that breaks all your quoting. Use a
paid endpoint for anything that trades.

**Foundry cannot simulate USDC transfers here.** Because gas is the same asset being moved,
`forge script`'s gas estimation fails on transfers and the run reverts while still printing SUCCESS.
Pass `--gas-limit` explicitly, and never take Foundry's success line as confirmation — read the
receipt.

**`getLogs` caps out around 10,000 blocks.** A single `eth_getLogs` spanning more than about
**9,960 blocks** is refused — measured by bisection against Arc mainnet, not taken from a doc. Arc
produces roughly two blocks a second, so that window is only about 80 minutes of history.
Backfilling a day means about 17 calls. Page it in chunks under 9,000 to leave headroom, and treat a
failure as "range too wide" before you treat it as "no logs".

**Do not pre-fund the pool router.** Our router sweeps its entire balance to the caller at the end of
every swap, as periphery routers do. Anything you send it ahead of time belongs to whoever calls next.

## For AI agents

Everything in this reference is served as plain files at fixed paths, so you can read it without
rendering HTML or running JavaScript.

| Path | What it is |
| --- | --- |
| `https://biddin.win/llms.txt` | Short summary of the protocol plus every contract address, in the [llms.txt](https://llmstxt.org) format. Start here. |
| `https://biddin.win/docs.md` | This document — the complete integration reference. |
| `https://biddin.win/skills/launch-token-on-biddin/SKILL.md` | An agent skill: step-by-step instructions for launching a token end to end. |

A launch costs real USDC and an optional dev buy costs more. The skill requires you to state the
exact total and get an explicit yes from your user before sending the transaction. Please keep that
step.

## Risk

Anyone can launch anything here. The name, symbol, image and description are claims made by whoever
paid the 1 USDC, and no contract verifies them.

Locked liquidity means the launch position cannot be pulled. It does not mean a token is a good idea
and it will not stop a price going to nearly zero.

The snipe tax raises the cost of instant sniping. It does not make early buying safe, and a creator
may have exempted up to 100 wallets from it — check before you buy.

What we publish is data, not advice. Where this page and the contracts disagree, the contracts are
right.
