> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kek.pro/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Treat Solana and Robinhood Chain as separate protocol paths.
> Write for people using the KEK.PRO app.
> Treat displayed fees, limits, and availability as environment-specific unless labeled as protocol constants.

# Reading token state

> Read immutable metadata, launch records, pool identity, TGE state, permanent custody, and live fee policy directly from contracts.

Every KEK.PRO launch token exposes its metadata and canonical pool. The factory
adds launch-level state, and the locker exposes custody and fee routing.

<figure className="kek-figure kek-figure--robinhood" data-mark="READ" aria-labelledby="token-state-map-title">
  <div className="kek-figure__header">
    <span id="token-state-map-title">Direct token read / state authority map</span>
    <small>Immutable identity + mutable policy</small>
  </div>

  <div className="kek-figure__body">
    <div className="kek-figure__grid kek-figure__grid--four">
      <div className="kek-figure__cell kek-figure__cell--accent"><span>Token</span><strong>Identity + pool</strong><small>Metadata, supply, deployer, quote asset, fee tier, and pool.</small></div>
      <div className="kek-figure__cell"><span>Factory</span><strong>Launch record</strong><small>Canonical market identity, restrictions, and TGE checkpoint.</small></div>
      <div className="kek-figure__cell"><span>V3</span><strong>Pool invariants</strong><small>Token ordering, fee tier, price, ticks, and live balances.</small></div>
      <div className="kek-figure__cell"><span>Locker</span><strong>Custody + fees</strong><small>Permanent lock, recipients, allocation, and compounding policy.</small></div>
    </div>
  </div>

  <figcaption className="kek-figure__caption">Cross-check the same identity across contracts. Treat creator strings and URLs as untrusted input.</figcaption>
</figure>

## Token metadata and launch record

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
import { parseAbi } from "viem";

const tokenAbi = parseAbi([
  "function name() view returns (string)",
  "function symbol() view returns (string)",
  "function decimals() view returns (uint8)",
  "function totalSupply() view returns (uint256)",
  "function logo() view returns (string)",
  "function description() view returns (string)",
  "function socials() view returns (string twitter, string telegram, string discord, string website, string farcaster)",
  "function deployer() view returns (address)",
  "function pairToken() view returns (address)",
  "function poolFee() view returns (uint24)",
  "function liquidityPool() view returns (address)",
]);

const factoryAbi = parseAbi([
  "function getLaunchedToken(address token) view returns ((address token, address deployer, address pairedToken, address pool, address positionManager, uint256 positionId, uint256 dexId, uint256 launchConfigId, uint256 restrictionsEndBlock, uint256 launchedAt, uint256 supply, bool isToken0, uint24 poolFee, bool exists, uint256 initialBuyAmount, uint256 liquidityTokenAmount, uint256 lockedTokenDust) launched)",
  "function graduationStatus(address token) view returns (uint256 pairedPrincipal, uint256 threshold, bool liveGraduated, bool reachedEver)",
]);

const [name, symbol, decimals, totalSupply, logo, socials, pool, launched] =
  await Promise.all([
    client.readContract({ address: token, abi: tokenAbi, functionName: "name" }),
    client.readContract({ address: token, abi: tokenAbi, functionName: "symbol" }),
    client.readContract({ address: token, abi: tokenAbi, functionName: "decimals" }),
    client.readContract({ address: token, abi: tokenAbi, functionName: "totalSupply" }),
    client.readContract({ address: token, abi: tokenAbi, functionName: "logo" }),
    client.readContract({ address: token, abi: tokenAbi, functionName: "socials" }),
    client.readContract({ address: token, abi: tokenAbi, functionName: "liquidityPool" }),
    client.readContract({
      address: launchFactory,
      abi: factoryAbi,
      functionName: "getLaunchedToken",
      args: [token],
    }),
  ]);
```

Treat strings and URLs as untrusted creator input. Sanitize them before
rendering.

## Validate the canonical pool

Do not trust a pool address from a URL or indexer alone. Require:

* `launched.exists` is true;
* `launched.token` equals the requested token;
* `liquidityPool()` equals `launched.pool`;
* token getters match `launched.deployer`, `pairedToken`, and `poolFee`;
* the pool's `token0` and `token1` contain exactly the launch and quote tokens;
* the pool's `fee` equals `launched.poolFee`;
* `launched.isToken0` matches address ordering.

The launch record snapshots token-specific values. A later update to a factory
launch or DEX configuration does not rewrite an existing token.

## Read custody and fee policy

```ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
const lockerAbi = parseAbi([
  "function isLocked(address token) view returns (bool)",
  "function creatorFeeRecipients(address token) view returns (address recipient)",
  "function feeAllocation() view returns (uint16 teamBps, uint16 reserveBps, uint16 feeRightsBps, uint16 compoundBps)",
  "function teamRecipient() view returns (address)",
  "function buybackRecipient() view returns (address)",
  "function compoundRecipient() view returns (address)",
  "function pendingCompoundFees(address token, address asset) view returns (uint256)",
]);

const [locked, creatorRecipient, allocation] = await Promise.all([
  client.readContract({
    address: locker,
    abi: lockerAbi,
    functionName: "isLocked",
    args: [token],
  }),
  client.readContract({
    address: locker,
    abi: lockerAbi,
    functionName: "creatorFeeRecipients",
    args: [token],
  }),
  client.readContract({
    address: locker,
    abi: lockerAbi,
    functionName: "feeAllocation",
  }),
]);
```

`feeAllocation` is global and owner-updateable. It applies when fees are
collected. It is not snapshotted per token and does not switch automatically at
TGE.

The original deployer may update that token's creator fee recipient. The
current contracts do not implement an administrative community-takeover flow.

## Read mutable configuration

Read `launchFee`, `getLaunchConfig`, `getDexConfig`, and locker or compounder
policy immediately before constructing a write. Use the approved manifest to
choose configuration IDs, then verify every returned dependency.

Keep immutable launch facts separate from mutable global policy in your cache.
