Check it yourself

Every position the worm has ever held was computed from chain state at a finalized block. Nothing is sampled, smoothed, or generated. If you run the same inputs through the same engine you get the same bytes, and if you do not, we are wrong.

What determines the worm

Three things, all public:

  1. Which blocks. signalBlock = floor(finalized / 6000) * 6000. Signal blocks are a function of the block number, not of when our cron happened to fire. You can enumerate them without asking us. A late cron delays a row; it never changes which block it is.
  2. The seed. keccak256(blockHash ‖ holderSetRoot). holderSetRoot is the keccak of the holder set sorted by address, with balances at fixed width, taken over all holders with no role exclusions: a seed derived from operator config would not be derivable from chain.
  3. The signal. New holders drive chemotaxis ticks, sells into the configured liquidity pool drive nose-touch ticks, and HHI weights the left/right stimulus. All of it comes from ERC-20 Transfer logs from the mint block forward.

Two levels, and the difference matters

Level 1 takes our holder set and re-runs the simulation: root → seed → plan → trajectory, then compares. It proves we did not lie about the simulation.

It does not prove we did not lie about the data. If you take the holder set from this site, you are trusting us for it. Level 1 alone is an incomplete check, and we are not going to pretend otherwise.

Level 2 re-derives the holder set from your own RPC, from the token's mint block, and closes that gap. It is the one that actually settles the question.

Run it

git clone <repo> && cd worm
npm install
cp .env.example .env.local        # your own archive RPC + Postgres

npm run migrate
npm run add-token -- --address 0xTOKEN --mint-block N --lp 0xPOOL
npm run indexer -- --catch-up    # Transfer logs from the mint block

# Level 2: derive balances from chain, check against balanceOf
npm run reconcile -- --address 0xTOKEN

# Recompute every signal block and compare byte for byte
npm run verify-signal -- --address 0xTOKEN --limit 500

verify-signal recomputes each stored block from the indexed data and the chain, then compares the seed, the holder-set root, the 814-byte worm state, the full tick payload, and the float64 position. Any difference is reported and exits non-zero. It does not adjust anything to match: a mismatch means the derivation is wrong, and that is a finding, not something to paper over.

What you are trusting

Holder counts, HHI, Gini, and new-holder counts replay exactly from chain. The sell signal does not: it depends on which addresses are configured as liquidity pools, and that is operator config, not chain data. Every update publishes lpSetHash so the assumption is auditable rather than invisible, and you can see if the set ever changed between updates.

← back to the wormHow it works →