Skip to content

About

No description, website, or topics provided.

Resources

Stars

166 stars

Watchers

1 watching

Forks

Repository files navigation

Pons Token Scanner

Real-time Pons token discovery and market-state indexing on Robinhood Chain.

This repository is a read-only discovery/indexing system. It does not custody funds or execute trades.

What It Does

The scanner watches the Pons launch factories on Robinhood Chain (chain id 4663). It backfills historical launches, follows new ones over WebSocket or HTTP polling, normalizes V1 and V2 into one token model, stores curve trades from the events that actually settled, and exposes that state over a REST API.

When a token matches the configured filters it is marked ELIGIBLE. That state is a record and, optionally, a webhook. The process never signs or sends a transaction.

Architecture

Robinhood Chain
      ↓
Pons Events
      ↓
Indexer
      ↓
Normalizer
      ↓
Token Registry
      ↓
Market State
      ↓
Filters
      ↓
Opportunities
      ↓
API / Alerts
                     ROBINHOOD CHAIN
                            ↓
                     PONS CONTRACTS
                            ↓
                    EVENT INGESTION
                            ↓
                ┌───────────────────────┐
                │ Protocol Adapters     │
                │                       │
                │ Pons V1               │
                │ Pons V2               │
                └───────────┬───────────┘
                            ↓
                     EVENT DECODER
                            ↓
                    TOKEN REGISTRY
                            ↓
                  METADATA ENRICHMENT
                            ↓
                   MARKET STATE ENGINE
                            ↓
                      FILTER ENGINE
                            ↓
                   OPPORTUNITY STATE
                            ↓
             ┌──────────────┼──────────────┐
             ↓              ↓              ↓
           Alerts          API         Dashboard-ready data

V1 and V2 stay behind adapters. The rest of the application uses normalized launches, phases, and trades.

Pons V1 / V2

Pons V2 is the current launch protocol: a token is created, traded on its own bonding curve, swept, and graduated into a Uniswap v4 pool. The factory used here is 0x7eD598BcEf8bd9Edd8C97A195C6d13f40801EC7e. Event and read ABIs follow the current V2 builder docs at docs.ponsfamily.com/v2. Curve trade amounts are taken from CurveBuy and CurveSell, not from the quantity a caller requested.

V2 market phase is read from getLaunchedToken on the factory:

Contract phase Scanner phase Meaning
0 NotGraduated CURVE Still trading on the bonding curve
1 Swept SWEPT Curve closed, pool not created yet
2 PoolCreated POOL Trading on the Uniswap v4 pool
3 Rescued RESCUED Recovery path

A V2 pool does not have its own contract address. The scanner stores a derived Uniswap v4 pool id when the launch record supplies fee, tick spacing, and the configured hook. quoteReserve, realQuoteReserve, tokenReserve, and sellableTokens are raw curve reads. The spot ratio is labeled display-only. It is not an executable quote and it is not a USD price.

Pons V1 is a separate factory (0xA5aAb3F0c6EeadF30Ef1D3Eb997108E976351feB). Its TokenLaunched event creates a Uniswap V3 pool immediately and does not emit V2 curve events. The V1 adapter decodes that event and reads getLaunchedToken. It does not invent curve reserves.

LaunchGraduationRescued is recognized by its verified topic so reconciliation can refresh contract state. Its argument names are not in the official V2 docs, so those fields are not decoded into domain data.

Features

  • Resumable historical backfill in configurable block chunks
  • WebSocket live listener, with HTTP polling when WS_URL is empty
  • Reconnect overlap and idempotent replay
  • V1 and V2 protocol adapters
  • Token identity as chainId + address
  • Event identity as chainId + transactionHash + logIndex
  • ERC-20 and Pons metadata, best-effort
  • V2 curve buys, sells, refunds, completion, and factory sweep/graduation events
  • Filter engine and opportunity states DETECTED, WATCHING, ELIGIBLE, REJECTED, EXPIRED
  • Optional webhook alerts
  • REST API, health, and indexer status
  • Lightweight reorg repair and recent-window reconciliation
  • Structured Pino logs and in-process counters
  • Foundry fixtures for the V2 events the TypeScript decoder understands

Tech Stack

Node.js, TypeScript, viem, PostgreSQL, Drizzle ORM, Fastify, Zod, Pino, Vitest, Foundry.

Quick Start

pnpm install
cp .env.example .env
docker compose up -d postgres
pnpm db:migrate
pnpm demo
pnpm scanner

pnpm demo only needs an RPC. It prints the chain id, checks the V2 factory code, and decodes recent TokenLaunched logs. It does not write to the database and it does not send transactions.

The public RPC in .env.example is for local development. Production should set RPC_URL and WS_URL to a dedicated provider.

Environment Variables

See .env.example.

Variable Purpose
RPC_URL HTTP RPC. Required.
WS_URL WebSocket RPC. Empty disables live push and keeps polling.
DATABASE_URL PostgreSQL connection string.
PONS_V2_FACTORY V2 factory. Invalid addresses fail startup.
PONS_V1_FACTORY / ENABLE_V1 Optional V1 factory indexing.
START_BLOCK First block for a fresh backfill. Empty skips history and starts at the head.
BACKFILL_CHUNK_SIZE Inclusive log-query window.
CONFIRMATION_BLOCKS Blocks left unindexed at the tip.
RECONNECT_BACKFILL_BLOCKS Overlap replayed after a websocket reconnect.
MODE BACKFILL, LIVE, or FULL (default).
ALERT_WEBHOOK_URL Optional. The scanner runs without it.
ALLOWED_PAIR_TOKENS, BLOCKED_DEPLOYERS, ALLOWED_DEPLOYERS, MIN_TOKEN_AGE_SECONDS Filter rules. Empty lists do not restrict.
RUN_MIGRATIONS Apply SQL migrations on startup when true.

Native ETH as a quote asset is 0x0000000000000000000000000000000000000000.

PRIVATE_KEY and mnemonics are ignored. Startup logs a warning if they are present.

Running PostgreSQL

docker compose up -d postgres
pnpm db:migrate

pnpm db:generate writes Drizzle Kit review artifacts to drizzle/. The migration the app applies is src/db/migrations/0001_init.sql.

Backfilling

pnpm backfill

The worker loads its cursor, requests BACKFILL_CHUNK_SIZE blocks at a time, decodes logs, commits token state, then advances the cursor. Restarting resumes from the last committed block. A second pass over the same range does not insert duplicate events.

Backfill:
from=2100000
to=2101999
events=17
durationMs=843

Set START_BLOCK before the first run if you want history. Without it, a fresh database starts at the confirmed head.

Running Live Scanner

pnpm dev
pnpm scanner

MODE=FULL backfills through the confirmed head, then polls. If WS_URL is set, a websocket subscription wakes the poller. On disconnect the listener replays RECONNECT_BACKFILL_BLOCKS and deduplicates. If WS_URL is empty, it logs that realtime monitoring is disabled and keeps polling.

MODE=BACKFILL indexes history and serves the API. MODE=LIVE does not walk back to START_BLOCK; it follows the head and still replays the overlap window.

Shutdown on SIGINT or SIGTERM stops listeners, finishes the current transaction boundary, persists the cursor, and closes the database.

API

GET /health
GET /tokens?version=V2&phase=CURVE
GET /tokens/:address
GET /tokens/:address/trades?limit=100
GET /launches/recent
GET /opportunities?state=ELIGIBLE
GET /markets/:address
GET /indexer/status

Responses are normalized records. uint256 values are decimal strings, not JavaScript numbers.

GET /health returns 503 when the database or RPC check fails.

GET /markets/:address includes curve reserves and, when both reserves are present, an informational spot ratio labeled as display-only.

Example Output

Robinhood Chain
Chain ID: 4663

Pons Scanner
Version: V2
Factory: 0x7eD5...

Recent launches:
----------------------------------------
XYZ
Token: 0x...
Curve: 0x...
Pair: 0x...
Phase: CURVE
State: WATCHING
----------------------------------------

A launch with contract phase, metadata, and curve reserves can move to ELIGIBLE. Nothing is traded when that happens.

Testing

pnpm test
pnpm typecheck
pnpm lint
pnpm build

Vitest covers identity, ABI topic hashes, launch and trade decoding, phase mapping, filters, opportunity transitions, cursor and reconnect math, duplicate suppression, backfill resume, metadata and curve read failures, transaction rollback, and the HTTP API. Integration tests apply the SQL migration to embedded PostgreSQL (PGlite).

Solidity / Foundry Test Layer

contracts/mocks/PonsEventFixtures.sol is a test fixture. It is not the Pons protocol and must not be deployed.

forge install foundry-rs/forge-std
pnpm test:foundry

The Foundry test records TokenLaunched, CurveBuy, and CurveSell and checks their topic0 values against the same signatures the TypeScript decoder uses.

Production Considerations

  • Point RPC_URL and WS_URL at a provider with a high enough eth_getLogs range for BACKFILL_CHUNK_SIZE.
  • Leave the public RPC for local development.
  • Run one scanner writer per database. Event identity is unique, but two writers will contend.
  • CONFIRMATION_BLOCKS should stay above zero on mainnet.
  • Reconciliation rereads a configurable window of recent launches. It does not rescan the full history.
  • Metrics counters live in the process and are copied onto the indexer cursor. A Prometheus exporter is not bundled.
  • The scanner container runs as a non-root user.

Security Notes

  • no private keys required
  • read-only runtime
  • no trade execution
  • no custody
  • environment variables for credentials
  • explicit RPC configuration
  • validated contract addresses
  • database uniqueness constraints
  • idempotent event processing

There is no walletClient, writeContract, or sendTransaction on the scanner path.

Demonstrated Engineering

  • Solidity / EVM
  • Foundry testing
  • TypeScript
  • viem
  • PostgreSQL
  • Event indexing
  • Protocol adapters
  • Historical backfill
  • WebSocket monitoring
  • Idempotent event processing
  • Reconciliation
  • REST APIs
  • Structured logging

Related Projects

Related Pons Projects

Pons Sniper Bot https://github.com/0xhamssog/pons-sniper-bot

Pons Bundler https://github.com/0xhamssog/pons-bundler

Stock Token Arbitrage Bot https://github.com/0xhamssog/robinhood-stock-token-arbitrage-bot

These are related trading systems. This scanner does not import them and does not execute their strategies. It is the read-only indexing layer underneath that kind of product: launch monitoring, market phase, and opportunity state, without a wallet.

Roadmap

  • Prometheus scrape endpoint for the existing counters
  • V1 Uniswap V3 pool state, only from a documented position read
  • Decode LaunchGraduationRescued fields once parameter names are published in the official docs
  • Archive eth_getLogs pagination hints for providers that cap responses below the configured chunk size

Commands

pnpm dev
pnpm build
pnpm test
pnpm test:watch
pnpm typecheck
pnpm lint
pnpm db:migrate
pnpm db:generate
pnpm backfill
pnpm scanner
pnpm demo

About

No description, website, or topics provided.

Resources

Stars

166 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages