Files
labrinyang d73eaf873a fix(indexer): stop a manipulated pool from minting prices
A price used to propagate from any pool with enough depth on the priced side,
which let a thin pool with one inflated side mint a price for its other token
and carry it across the graph. Depth is now measured on the side that is
already credibly priced, and a pool-priced side may claim at most 100x that
depth.

Guard rails around it, all in one place: prices travel at most 3 hops from a
GT/anchor seed, |tick| beyond 700k is a broken init rather than a market,
stored prices must land in a plausibility band, and a TVL above $1B is treated
as corrupt instead of as a whale.

Adds a log tail so pool stats follow chain events instead of polling, a
demand-gated frontpage, and a last-good fallback so a failed refresh serves
the previous stat rather than a hole.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-22 23:59:56 +08:00

28 lines
1.1 KiB
TypeScript

// Proves the event-tail signal on Robinhood Chain: one eth_getLogs over the
// last SPAN blocks surfaces every pool that traded, grouped by event.
// Run: npm run smoke:logtail
import { numberToHex } from 'viem'
import { pc } from '../indexer/rpc'
import { TOPICS } from '../indexer/logtail'
const SPAN = 1_500
const NAMES = ['v2 Sync', 'v3 Swap', 'v3 Mint', 'v3 Burn']
const head = Number(await pc.getBlockNumber())
const from = head - SPAN + 1
const logs = (await pc.request({
method: 'eth_getLogs',
params: [{ fromBlock: numberToHex(from), toBlock: numberToHex(head), topics: [TOPICS] }],
})) as { address: string; topics: string[] }[]
const pools = new Set<string>()
const byTopic = new Map<string, number>()
for (const l of logs) {
pools.add(l.address.toLowerCase())
byTopic.set(l.topics[0], (byTopic.get(l.topics[0]) ?? 0) + 1)
}
console.log(`blocks ${from}-${head} (${SPAN}): ${logs.length} logs, ${pools.size} distinct pools`)
TOPICS.forEach((t, i) => console.log(` ${NAMES[i].padEnd(8)} ${byTopic.get(t) ?? 0}`))
console.log('sample pools:', [...pools].slice(0, 8).join(' '))