DOCS
How Frostwit works
What it is
Drained on Robinhood Chain? Paste the theft transaction (or the thief's address). Frostwit follows the stolen value on-chain, shows which part still sits in assets the issuer can freeze (official Robinhood stock tokens, USDG), re-checks it while the case is open, and writes the freeze-request pack for you.
Frostwit cannot freeze or recover anything. Robinhood and Paxos decide, and they usually need a police report or a legal directive. It does show you, from the chain, that the issuer's freeze switch is real and in use: see issuer actions.
No account. No wallet to trace. Public JSON API, no key.
Paste
- Transaction hash (0x + 64 hex): the primary mode. Frostwit reads the receipt, takes the sender of the stock tokens as the victim and the receivers that are not known pools or routers as the thieves, and follows from that exact block.
- Thief's address (0x + 40 hex): Frostwit scans for official stock tokens and USDG arriving at the address in a time window, then follows them. Address mode covers the last 24 hours by default, up to 7 days (slower, queued). For anything older, paste the theft transaction.
- My address: not sure which receiver is the thief? Paste your own wallet and pick the outgoing transfer you did not authorise. Frostwit lists the candidates and asks no one to be the thief on its own.
Token contracts, pools, routers and the registry are not wallets and are refused.
How the trail is built
- Seed. A tx hash costs two calls (transaction and receipt). Every
Transferof an official token in the receipt is read; transfers of other tokens are recorded as exits. - One query covers every token. Frostwit asks the official RPC for
eth_getLogswith the addresses of all 203 freezable tokens (202 Robinhood stock tokens and USDG) and the topics[Transfer, holder]per window of 100 000 blocks (about 2.8 hours). One day is nine windows. A window that returns more than 9 000 logs is halved, up to four times; if it still overflows, the node gets a fan-out exit. - 24 hour horizon. Each holder is followed for up to nine windows after the value arrived. After that, far follow reads the holder's current balances; for every token whose balance is lower than received minus followed out, one single-token query (up to 10 million blocks) finds where the rest went.
- Swap rule. For each outgoing transfer into a pool, router or contract, Frostwit reads the receipt. A transfer of another token back to the same holder (or from the pool to a third address) is the swap output: the edge is labelled “swapped via …” and the output token is followed. If a thief swaps NVDA into USDG, Frostwit follows the USDG. The pool is never followed. Swaps into WETH or a Withdrawal event end as an ETH exit.
- Stop rules (each one is written down as an exit so the page can say why): at most 4 hops from the first address; at most 10 receivers per address, largest first, the rest as one row “+N smaller receivers, total X”; an edge under 1% of the stolen value and under 20 USD is ignored; a receiver with code that is not a known pool or router is shown and not followed; at most 25 nodes.
- Budget. At most 120 RPC calls, 40 receipts and 180 seconds per case (plus a small reserve to read balances and timestamps). Beyond that the case is partial, says why, and every unfinished address gets a “Continue from this address” button, which starts a new case from there. That is the honest way to go deeper, and it is manual by design.
One RPC lane
The official RPC rate-limits hard: a burst blocks the whole IP for about 60 seconds. Frostwit therefore sends every chain read through one queue: at most one request in flight, at least 350 ms apart (about three requests a second). On a 429 or any error that mentions a rate limit the lane pauses for 61 seconds and retries the same request. Results that cannot change (receipts, old log ranges) are cached forever. Interactive traces go first, then watch ticks, then the registry tail. One shared lane to Robinhood's RPC: traces run one request at a time, every case shows its place in the queue.
Freezable
For every address that held a freezable token during the trace, one multicall reads balanceOf (and balanceOfUI for stock tokens), the registry's isBlocked(address), USDG's isFrozen(address) and paused() per stock token touched. Rows with a balance are sorted by USD.
- Amount is the user-facing figure: for stock tokens
balanceOfUI(which includes the dividend multiplier); the rawbalanceOfis in the tooltip when they differ. - USD is the spot of the deepest Uniswap V3 pool against USDG, from
slot0, labelled “≈ USD (pool spot)”. It is not an execution price. If the pool cannot be read the cell shows “—”. - The stock tokens also expose
adminBurn(address,uint256)andpause(); the registry and Paxos are the parties who can act. Paxos freezes USDG only on a formal legal directive (court, regulator, law enforcement).
Issuer actions
The access registry 0xe10b6f6B275de231345c20D14Ab812db62151b00 emits Blocked(address) and Unblocked(address). An operator account calls blockAccounts and unblockAccounts. The registry's first batch is 244 Blocked events covering 175 addresses (blocks 43 543–44 953, 8–9 Jun 2026 UTC); every other event is listed on its own. Frostwit reads the whole event history from block 0 once and then tails the registry every five minutes; each row links its transaction. Robinhood's registry decides; Frostwit only reads the events. A Blocked event is not an accusation and says nothing about why the issuer acted. Paxos freeze history is not indexed in this version; the live USDG flag is shown.
Watch
Re-checked every 15 minutes for 7 days while the case is open. Changes are logged with the transaction that moved the value. Each check is one multicall for the case's freezable rows. If a balance went down, Frostwit follows that holder and token from the last checked block to the head and logs where the value went (“12 400 USDG moved to 0x… (tx)”). Flag flips (blocked by the registry, frozen by Paxos) are logged too.
Pack
The pack is three plain texts: one for Robinhood (support@robinhood.com or https://robinhood.com/contact, stock tokens), one for Paxos (https://support.paxos.com, USDG; it states up front that a formal legal directive is normally required), and a summary for your police report (timeline in UTC, addresses, transaction hashes, amounts, current locations, registry status). Nothing is sent for you. Generated from public chain data; not legal advice.
Data
- Chain reads come from Robinhood's official RPC, from Frostwit's own server only. No browser ever calls it.
- Blockscout is used for human links only (
/tx,/address,/token), never as a data source. - There is no indexer. A trace is a handful of targeted log queries.
- Native ETH is not traced in this version. Prices are pool spot prices.
API
No account. No wallet to trace. Public JSON API, no key. CORS is open. Responses are cached for 10 seconds.
curl -X POST https://frostwit.pro/api/case -H 'content-type: application/json' -d '{"input":"0x…"}'
curl https://frostwit.pro/api/case/<id>
curl https://frostwit.pro/api/case/<id>/pack.md
curl https://frostwit.pro/api/issuer-actions?limit=100
curl https://frostwit.pro/api/status/0x…
curl https://frostwit.pro/api/stats
curl https://frostwit.pro/api/healthPOST /api/case{input, hours?: 24|72|168, role?: "thief"|"victim"}returns201 {id, status, queue}or400 invalid_input | too_old | not_a_wallet(a repeated input returns200 {existing:true}with the same id),404 tx_not_found,429 busy {retryAfterSec},503 rpc_unavailable.GET /api/case/:id: the graph (seed, nodes, edges, freezable, exits, budget) pluschecks[],watch,queueandlinks. The case page renders this same JSON.- Limits: 10 new cases per IP per hour, 40 per hour overall, one open case per visitor.
- For AI agents: llms.txt and /api list every route.
Check approvals
Which approval did the drainer use? /check lists the spenders that still hold an allowance on your official stock tokens and USDG, including through Permit2: ERC-20 allowance and Permit2 allowance are read by multicall. With a case, the spenders come from the senders and receivers of the transactions in which your tokens left; without one, from the approvals your address emitted in the last 24 hours. Revoke sends approve(spender, 0) from your own wallet (Permit2 allowances use Permit2's approve with amount 0); Frostwit never signs and holds no key. GET /api/check/:address?case= returns the same list with the calldata of each revoke. An allowance that is not listed does not prove that no other approval exists.
Priority watch
Until $FWIT exists, priority watch is off. Once it does, holders of at least 1,000,000 $FWIT can put a case on priority watch (2-minute re-checks for 30 days, retrace on demand). That is the only token utility; everything else is open to everyone. See /token.
Privacy
Inputs and traced graphs are stored: they are public chain data. Frostwit keeps no account, cookie or wallet connection, and logs no IP address or user agent; usage is counted per day (case opened, page viewed) without any identifier. The web server's access log has no client address.
Limits
- Native ETH is not traced in this version.
- Address mode covers the last 24 hours by default, up to 7 days (slower, queued). For anything older, paste the theft transaction.
- Paxos freeze history is not indexed in this version; the live USDG flag is shown.
- Only official Robinhood stock tokens and USDG are followed. Look-alike tokens with the same name are shown as FAKE and not followed.
- A trace stops at contracts it does not know, after 4 hops, after 10 receivers per address and at its call budget. It says where and why.
- Frostwit cannot freeze or recover anything. Robinhood and Paxos decide, and they usually need a police report or a legal directive.
Not audited
Not audited. Read the limits before you trust a trace. The tracer has no contract of its own and never asks for a wallet or a signature; the only contract is the $FWIT token, whose address is posted here at launch.