# Trust: who can do what

Some parts of a Koine launch are fixed on chain at creation and Koine can't change them. Other parts (fee claims, the fee split, steward payouts, buybacks, steward checks and votes) are run by Koine's server with keys Koine holds. This page lists every key, what it can do, and what is not built or not audited.

Koine is a Solana mainnet product preparing for its public launch. None of this code has been audited.

## Which on-chain programs does a launch use?

Koine has no on-chain program of its own. A launch uses:

| Program | Used for | Address in this repo |
|---|---|---|
| SPL Token (classic, not Token-2022) | the coin | `TOKEN_PROGRAM_ID` |
| Metaplex Token Metadata | the coin's name, ticker and URI | `mpl.PROGRAM_ID` |
| Meteora DAMM v2 (cp-amm) | the pool and its locked liquidity | `cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG` |
| Meteora Alpha Vault | the presale vault | `vaU6kP7iNEGkbmPkLmZfGwiGxd4Mob24QQCie5R9kd2` |
| SPL Memo | tagging the launch-fee payment | `MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr` |
| Squads multisig | optional custody of fee rights | `@sqds/multisig` |

Koine doesn't control Meteora's or Squads' programs or their admin rights. This repo doesn't check what Meteora's own admins can change on a pool or vault.

Source: `app/server/launch.ts` (`MEMO`, `VAULT_PROGRAM`), `app/server/squads.ts`, `@meteora-ag/cp-amm-sdk` (the cp-amm program address).

## What is fixed at creation?

| Thing | How it's locked | Checked by `launch-check.ts` |
|---|---|---|
| Supply | Exactly 1,000,000,000 tokens minted, then mint authority set to none | `mint-authority`, `supply`, `supply-now` |
| Freezing | The mint is created with no freeze authority | `freeze-authority` |
| Name, ticker, metadata URI | Metaplex metadata created with `isMutable: false` | `metadata-immutable` |
| Liquidity | The pool's position is permanently locked in the creation transaction (`isLockLiquidity: true`) | `lock`, `pool-liquidity` |
| Fee schedule | 99% to about 1% over 100 s, set in the pool at creation | `fee-start`, `fee-schedule`, `fee-end` |
| Open time | The pool's activation timestamp; Meteora's program rejects swaps before it | `pool-config`, `activation` |
| Presale terms | Pro Rata vault, open to all, unlock start and end set at creation | `vault-config`, `unlock-start`, `unlock-length` |

Anyone can run that script on any Koine coin; see [verify.md](https://docs.koine.markets/launchpad/verify).

The token's own keypair (the address ending in `koin`) has no power after creation. The mint has no authorities left.

One limit: the metadata URI points to Koine's server (`<site>/meta/<mint>.json`). The on-chain name, ticker and URI can't change, but the JSON at that URI (description, image link) is served from Koine's database. Koine could change it, or it could go offline.

Source: `app/server/launch.ts` (`createLaunch`), `app/server/http.ts` (`/meta/<mint>.json`), `app/scripts/launch-check.ts`.

## What keys does Koine hold?

| Key or address | Set by | What it does | What it could do if misused |
|---|---|---|---|
| **Keeper** (`KEEPER_KEY`) | Koine | Pays for and creates every launch. Briefly holds mint authority (then revokes it) and the full supply (then puts all of it in the pool). Owns each pool's position NFT, which is the right to claim the position's fees. Runs the vault buy. Creates Squads proposals when custody is on. | Without Squads: claim a coin's fees to any account. It can't remove liquidity, mint, freeze, trade before open or touch presale deposits. |
| **Buyback wallet** (`BUYBACK_KEY`) | Koine | Receives claimed fees, pays the steward and the treasury, buys the coin and burns it. Pays the network fees for claims, payouts and buybacks (with Squads on, the keeper pays for claims into the multisig and moves out of it). | Keep or send elsewhere any SOL it holds, including unpaid steward shares and buyback budget. |
| **Treasury** (`TREASURY`) | Koine | Receives launch fees, the platform's 25% of spike fees and its 40% of later fees. Koine's 1% on trades goes to the fee wallet (`FEE_WALLET`), which can be the same address. If `TREASURY` isn't set, it is the keeper's address (or the Squads vault when custody is on). | The code only sends to it. Whoever holds its key controls what it has received. |
| **Squads multisig** (`SQUADS_MULTISIG`) | Koine, optional | Holds position NFTs after the spike claim, when custody is on. | Depends on its signers. |
| **Mint keypairs** (`data/vanity/`) | Ground on the server | Sign once to create each mint, then are deleted from disk. | Nothing after creation. |

Source: `app/server/config.ts` (`KEEPER`, `BUYBACK`, `SQUADS`, `TREASURY`), `app/server/launch.ts`, `app/server/keeper.ts`, `app/server/vanity.ts` (`take`).

## What can the keeper not do?

Koine's code sets these at creation, and Meteora's programs enforce them afterwards, for the keeper as for anyone:

- remove liquidity from a pool (the position is locked in the creation transaction);
- swap before open, even after the vault buy (the pool's activation time);
- change the vault's cap or unlock times (set when the vault is created);
- deposit or withdraw for anyone after the presale (the vault's deposit window);
- let depositors claim before the unlock starts (the vault's unlock start).

It also never holds presale SOL. Deposits sit in the Alpha Vault until its one buy sends them into the pool, where they become locked liquidity.

Source: `app/server/launch.ts` (`createLaunch`: `isLockLiquidity`, `activationPoint`, vault creation), `app/scripts/launch-check.ts`.

## What runs off-chain?

These run on Koine's server and depend on Koine running it honestly:

- **The fee split** (spike fees 75% buyback / 25% platform; later fees 40% steward / 20% buyback / 40% platform). The keeper claims the fees into the buyback wallet and does the split in its own records. No on-chain program enforces it.
- **Steward payouts.** Plain SOL transfers from the buyback wallet, when the steward claims, or on a handover or vote.
- **Buybacks and burns.** Swaps and burns from the buyback wallet, on the keeper's schedule.
- **Steward checks, flags and votes.** Stored in the server's SQLite database. The server reads balances from the chain and posts from the coin's page, but decides the outcome itself. Who is acting is the signed-in account (its Koine wallet), which the server reads from the session; a handover also needs a fresh sign-in.
- **Duplicate rules** for tickers, names, tweets and websites.
- **Transactions for your Koine wallet** (trades, presale deposits, withdrawals, claims, refunds and the launch fee). The trading service signs them within your wallet's signing rules at Privy, which allow a launch fee only as exactly the fee to the treasury (see [Security](https://docs.koine.markets/terminal/security#signing-rules)).
- **The settings.** The split, steward rules, launch fee and the unlock length for new launches all come from `app/server/config.ts` and environment variables. Changes to the split and the steward rules apply to coins already trading.

Every claim, split, payout, buyback and burn is logged on the coin's page with its transaction, so you can check them against the chain. The log keeps every entry (`GET /api/launches/<mint>/log`).

Source: `app/server/keeper.ts`, `app/server/steward.ts`, `app/server/store.ts` (`appendLog`), `app/server/config.ts`, `app/server/tx.ts`.

## What could Koine still do to users?

Being plain about it:

- **Keep or redirect trading fees.** Without Squads, the keeper key can claim a coin's fees anywhere, and the buyback wallet can send what it holds anywhere. That covers the spike fees, the steward's 40% and the buyback 20%. Squads custody starts only after the spike claim, so the spike fees depend on these two keys either way.
- **Change the split or the steward rules** for every coin, by changing the server settings.
- **Stop running the keeper.** Fees then stay in the pool unclaimed (they aren't lost), buybacks stop and votes don't close. Anyone can still run the vault buy, and depositors can refund if it's missed.
- **Change a coin's description or image** served at its metadata URI, or take it offline.
- **Sign a bad trade from your Koine wallet** within its signing rules. Swaps set a minimum output, but the server chooses it. Your wallet's policy limits what can leave it: swaps, Koine's fee, tips, presales, the launch fee to the treasury, and withdrawals only to your saved address.
- **Run code other than this repo.** Nobody can verify from outside which code the server runs. The on-chain facts above can be checked directly.

Koine can't mint more of a coin, freeze it, change its name or ticker, pull its liquidity, trade before open, or take presale deposits.

Source: `app/server/keeper.ts` (`claimToBuyback`, `payOut`), `app/server/tx.ts` (`swapTx`), `app/server/config.ts`, `app/server/http.ts`.

## What is Squads custody?

An option that moves each coin's fee rights from the keeper's single key into a Squads multisig. **It is off unless the operator sets both `SQUADS_MULTISIG` and `SQUADS_SPENDING_LIMIT`.** With it off, the keeper keeps every position NFT.

When it's on, after the spike claim the keeper:

1. gives itself permission to claim fees to the position's owner only;
2. moves the position NFT to the multisig's vault;
3. proposes that the vault approve the keeper as a delegate with a 0 allowance.

Signers then approve and execute that proposal in Squads. Until they do, hourly fees wait in the pool, and the operator gets an alert after 26 hours. After it, the keeper's claims can only land in the multisig vault. The platform's 40% stays there. The other 60% moves to the buyback wallet through a Squads spending limit, which the keeper uses alone.

The code expects, but doesn't check, that the keeper is a multisig member with the Initiate permission only, and that the spending limit is in wrapped SOL, with the keeper as its only member and the buyback wallet as its only destination. That is Squads configuration, set by the signers.

There is no recorded run of a full launch through the keeper loop with Squads on.

Even with Squads on, the 70% that reaches the buyback wallet is again held by a single Koine key until it is paid out or spent.

Source: `app/server/config.ts` (`SQUADS`), `app/server/squads.ts`, `app/server/keeper.ts` (`custody`, `claimFees`, `drainMultisig`), `app/README.md` ("Squads custody").

## What is not built, not tested or not audited?

- **Not audited.** No part of Koine's code has had a security audit.
- **Not open yet.** Koine is preparing for its public launch on mainnet, so there are no public launches to check yet.
- **Not built** (per `app/README.md`): image upload, a portfolio page, a wired-up alert webhook and uptime monitor.
- **Not tested:** a real Privy sign-in in the browser, a launch paid from a Koine wallet on chain, a refund after the wrapped-SOL fix, the 99% confirmation from the live UI, and a full launch through the keeper with Squads on.
- **Not on chain:** the split, payouts, steward rules and votes (above).

Source: `app/README.md` ("Not verified yet", "Not built yet"), `app/server/config.ts` (`CLUSTER`).
