> For the complete documentation index, see [llms.txt](https://degen-games-2.gitbook.io/degen-games-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://degen-games-2.gitbook.io/degen-games-docs/developers/reading-state.md).

# Reading State

Read a coin's launch record, phase, reserves, progress and fee rates straight from the chain.

## The launch record

The launch factory keeps one record per coin. It covers everything you need to route and label the coin: its curve, raise asset, graduation target, fee settings and current phase.

```js
import { parseAbi } from "viem";

const factory = "0xa8788400ECe2342F17Faf659E2793a06bc4ad140";

const factoryAbi = parseAbi([
  "struct LaunchedToken { address token; address curve; address deployer; address creatorFeeRecipient; address pairToken; uint256 graduationThreshold; uint24 poolFee; int24 tickSpacing; uint16 creatorTaxBps; bool buybackEnabled; uint8 phase; uint256 sweptQuote; uint256 sweptTokens; uint256 sweptAt; bool exists; }",
  "function getLaunchedToken(address token) view returns (LaunchedToken)",
]);

const launch = await client.readContract({
  address: factory,
  abi: factoryAbi,
  functionName: "getLaunchedToken",
  args: [token],
});

if (!launch.exists) throw new Error("Not a Degen Games coin");
```

`exists = false` means the factory never launched this token. That's the on-chain way to spot copycats.

## Phases

`phase` is the authoritative signal for where a coin trades. Don't infer it from balances or events.

| `phase` | Name         | Route trades to                                                                             |
| ------- | ------------ | ------------------------------------------------------------------------------------------- |
| `0`     | NotGraduated | The curve                                                                                   |
| `1`     | Swept        | Nowhere yet. The curve is closed and the pool isn't created. Usually lasts only an instant. |
| `2`     | PoolCreated  | The Uniswap v4 pool                                                                         |
| `3`     | Rescued      | Nowhere. The safety path was used. Show this explicitly.                                    |

## Curve reserves

The curve's **pricing** reserve includes the virtual (phantom) amount, so it always reads higher than what was actually raised.

| Function                | Returns                                                                       |
| ----------------------- | ----------------------------------------------------------------------------- |
| `getReserves()`         | Pricing reserves `(quoteReserve, tokenReserve)`, including the virtual amount |
| `quoteReserve()`        | Pricing quote reserve, including the virtual amount                           |
| `realQuoteReserve()`    | The raise asset actually collected and held, net of fees                      |
| `phantomQuote()`        | The virtual reserve                                                           |
| `tokenReserve()`        | Tokens the curve still holds, including the reserved share                    |
| `sellableTokens()`      | Tokens still buyable before the curve closes                                  |
| `reservedTokens()`      | Supply held back for the pool, fixed at launch                                |
| `graduationThreshold()` | The raise target                                                              |
| `readyToGraduate()`     | `true` once `sellableTokens()` hits 0                                         |
| `graduated()`           | `true` once the curve has closed                                              |
| `launchedAt()`          | Launch timestamp                                                              |

```
reserved = supply × phantomQuote ÷ (phantomQuote + graduationThreshold)
```

## Price and progress

```js
const curveAbi = parseAbi([
  "function getReserves() view returns (uint256 quoteReserve, uint256 tokenReserve)",
  "function realQuoteReserve() view returns (uint256)",
  "function graduationThreshold() view returns (uint256)",
]);

const [quoteReserve, tokenReserve] = await client.readContract({
  address: launch.curve, abi: curveAbi, functionName: "getReserves",
});

// Marginal price of one token in the raise asset (spot, display only).
// Scale by the raise asset's decimals if it isn't 18.
const price = Number(quoteReserve) / Number(tokenReserve);

const [raised, target] = await Promise.all([
  client.readContract({ address: launch.curve, abi: curveAbi, functionName: "realQuoteReserve" }),
  client.readContract({ address: launch.curve, abi: curveAbi, functionName: "graduationThreshold" }),
]);

// Road to Graduation, 0 → 1.
const progress = Number(raised) / Number(target);
```

Progress measured as quote raised ÷ target and progress measured as tokens sold ÷ sellable allocation agree by construction. Use whichever reads better.

## Fee rates

Both per-coin rates are fixed at launch and safe to cache.

```js
const feeAbi = parseAbi([
  "function feeBps() view returns (uint256)",
  "function creatorTaxBps() view returns (uint256)",
  "function buybackEnabled() view returns (bool)",
]);

// Total cost to a trader, in bps of the quote leg:
// feeBps (trading fee) + creatorTaxBps (creator tax)
```

How the trading fee is divided, and what the pool charges after graduation, comes from the snapshot taken at launch:

```js
const policyAbi = parseAbi([
  "struct FeePolicySnapshot { address protocolFeeRecipient; uint16 protocolFeeShareBps; uint16 buybackBurnBps; uint16 hookFeeBps; uint16 maxInternalPriceImpactBps; }",
  "function getLaunchFeePolicy(address token) view returns (FeePolicySnapshot)",
]);

const policy = await client.readContract({
  address: factory, abi: policyAbi, functionName: "getLaunchFeePolicy", args: [token],
});
// protocolFeeShareBps: protocol's cut of the trading fee (3000 = 30%)
// buybackBurnBps:      slice of the remainder spent on buybacks, if enabled
// hookFeeBps:          trading fee charged by the hook after graduation (100 = 1%)
```

## Platform settings

| Function (launch factory)                    | Returns                                                                    |
| -------------------------------------------- | -------------------------------------------------------------------------- |
| `launchFee()`                                | Launch fee in native wei                                                   |
| `maxCreatorTaxBps()`                         | Creator-tax cap                                                            |
| `snipeTaxSeconds()`, `snipeTaxStartBps()`    | Snipe window and starting rate for new launches                            |
| `launchConfigCount()`, `getLaunchConfig(id)` | Launch configs                                                             |
| `approvedPairTokens(asset)`                  | Whether an asset can be raised in                                          |
| `pairTokenEconomics(asset)`                  | `(phantomQuote, graduationThreshold, decimals)` for an ERC-20 raise asset  |
| `canLaunch(address)`                         | Whether an address may launch right now                                    |
| `pendingCreatorFeeRecipient(token)`          | A pending fee-recipient takeover: `(newRecipient, effectiveAt, expiresAt)` |

Each coin's curve also exposes its own `snipeTaxSeconds()`, `snipeTaxStartBps()` and `currentSnipeTaxBps(recipient)`. These are the terms that coin launched with.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://degen-games-2.gitbook.io/degen-games-docs/developers/reading-state.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
