> For the complete documentation index, see [llms.txt](https://docs.unstable.run/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.unstable.run/on-chain-reference/events.md).

# Events & indexing

Three event streams cover every meaningful thing that happens on Unstable. Subscribe to them and you can rebuild the state of the entire launcher without a single non-event RPC call.

## `TokenLaunched` — on the factory

Fires once per successful `launchToken(...)`. Carries the **full metadata bundle** so an indexer can populate a token record in a single write.

```solidity
event TokenLaunched(
    address indexed token,
    address indexed creator,
    address indexed feeRecipient,
    string name,
    string symbol,
    string logo,
    string description,
    Socials socials,             // (twitter, telegram, website)
    uint256 positionId,
    int24 startingTick,
    bool tokenIsToken0,
    uint256 timestamp
);
```

Topic hash (`keccak256(signature)`):

```
0x4179c724ff1310239e8ce80782e741c3f2843415b5f219c59623b56af9f69dfe
```

Emitted by: `UnstableFactory` at `0x4865b8974C1a8309E8791443577E3385c80436FB`.

**Use cases**

* Populate a token registry (name, symbol, logo, socials).
* Trigger auto-verify pipelines (all tokens share bytecode).
* Kick off downstream indexers for the token's pool.

## `Swap` — on each token's Uniswap V3 pool

Standard Uniswap V3 event. Fires on every trade. Unstable's charts, trades panel, and volume metrics all come from this stream.

```solidity
event Swap(
    address indexed sender,
    address indexed recipient,
    int256 amount0,
    int256 amount1,
    uint160 sqrtPriceX96,
    uint128 liquidity,
    int24 tick
);
```

Topic hash:

```
0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67
```

Emitted by: each token's pool. To find the pool address:

```solidity
IUniswapV3Factory(0x88F0a512eF09175D456bc9547f914f48C013E4aA)
    .getPool(token, USDT0, 10000);
```

**Decoding the swap direction**

Whether the swap is a buy or sell depends on which side USDT0 sits on:

```typescript
const usdtIsToken0 = USDT.toLowerCase() < token.toLowerCase();
const usdtIn = usdtIsToken0 ? log.args.amount0 : log.args.amount1;
const isBuy = usdtIn > 0n;   // USDT flowed INTO the pool = buyer
```

**Use cases**

* OHLCV candles per timeframe (bucket by `blockTimestamp`, take last `tick` per bucket).
* Recent trades feed (BUY / SELL, USDT amount, wallet, tx hash).
* 24h volume (`sum(|usdtAmount|)` over the last 24h).

## `Transfer` — on each token

Standard ERC-20 event. Fires on every mint / burn / transfer. Unstable's holders count reads this stream.

```solidity
event Transfer(address indexed from, address indexed to, uint256 value);
```

Topic hash:

```
0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
```

Emitted by: the launched token contract itself.

**Use cases**

* Holder counting (dedupe `to` addresses, filter by current non-zero balance).
* Transfer graph analysis.
* Distribution snapshots.

## `FeesCollected` — on the LP Locker

Fires whenever anyone calls `collectFees(token)`. Useful for tracking creator earnings.

```solidity
event FeesCollected(
    address indexed token,
    uint256 usdtAmount,
    uint256 tokenAmount,
    uint256 creatorUsdt,
    uint256 creatorToken
);
```

Emitted by: `UnstableLPLocker` at `0xbB027B8210E98a19d7B90929B8baA77Ec09F0f96`.

Note that the event fields carry the **total** collected on each side plus the creator's cut. The treasury share is the remainder:

```
treasuryUsdt  = usdtAmount  - creatorUsdt
treasuryToken = tokenAmount - creatorToken
```

## Recommended indexing stacks

Any of these work well:

| Stack                            | Notes                                                                                                                                                               |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Ponder**                       | TypeScript, Postgres, self-host anywhere. Great DX. Fits Unstable's event surface exactly.                                                                          |
| **Envio**                        | Managed hosted indexer. Very fast indexing. Small monthly cost.                                                                                                     |
| **The Graph (subgraph)**         | Standard schema, GraphQL API. If Stable isn't on The Graph's hosted service yet, self-hosting is trivial.                                                           |
| **Custom \`eth\_getLogs\` loop** | Fine for prototypes — Unstable's built-in frontend uses exactly this pattern (chunked over 500-block windows for the public RPC, or 10k-block windows for Alchemy). |

## Next

* [Contract addresses](/on-chain-reference/contracts.md) — the surface area you're subscribing to
* [Verification](/on-chain-reference/verification.md) — how the auto-verify flow works for tokens


---

# 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://docs.unstable.run/on-chain-reference/events.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.
