Foreshock

Product · Radar

Who can freeze your assets right now

The durable part of Radar is not the alert. It is that you always know which party currently holds freeze authority over each asset you hold, that you hear about it the day that authority changes, and that every answer tells you where that authority is visible to us and where it is not. The live enforcement signal sits on top of that, matched against your own address book and against nothing else.

Scope
your address book
Response
match-only
Delivery
webhook · ws · email · im

Standing freeze authority

An asset you list today can be freezable by a different party tomorrow, with nothing on your side having changed and no announcement anywhere. Radar reads the control state actually in force on chain, reconciles it against what is on record, and raises an alert on any mismatch.

Who holds it
For every asset you hold, the party that can currently freeze, seize or immobilise it — read from the chain, not from documentation or from a press release.
When it moves
A change of controlling party is its own alert, separate from any enforcement event. Authority moving is information even on a day when nothing is being frozen.
One model, many mechanisms
Denylist-style blocking, freeze authorities, and permanent delegate or clawback powers are normalised into a single event model, so one alert shape covers assets whose contracts have nothing in common. Mechanisms that do not fit an existing class are marked as needing a custom adapter rather than silently approximated.
Before you list
A static authority check on an asset before you accept it — including whether a party outside your control can move it out of a wallet you hold. On Solana the unit is the token account rather than the wallet, so two accounts under one wallet are answered for separately.

Signal lifecycle

Six states. Each has a meaning for you, not only for our pipeline. Two of them are traps, and both are spelled out under the table.

State What it means for you What to do
PROPOSED A freeze has been submitted against an address and has not executed. Start refusing deposits from it now. Pre-emptive refusal is the entire purpose of this state.
CONFIRMING The submission is accumulating confirmations toward its threshold, updated as it goes. Use it to judge urgency. Do not use it to judge outcome.
EXECUTED The freeze has taken effect. The entry becomes a standing list item and the interval is recorded. Treat as a confirmed list hit from here on, and expect it in the retrospective public record.
EXPIRED The submission passed its configured window without executing. It is downweighted, not deleted. Lower the weight. Do not conclude that the intent went away.
REVOKED The submission was withdrawn and the address leaves your match set. This is not the same as no risk. Remove it locally because you received this event, never because it stopped appearing. A withdrawal can be followed by a fresh submission.
STALE We cannot currently verify this entry — a registry record lapsed, or a collector lost its connection. The data is untrustworthy, which is not the same as safe. Treat it as a blind spot and fall back to your more conservative policy for that exposure.

What a match returns

The API answers a question about your addresses. It does not answer a question about anybody else’s.

Which of your addresses
An opaque reference to an entry in your own address book. It is not a lookup key for anything outside it.
How it is related
A relation class — direct, upstream, or by path — and nothing finer.
How serious
A severity class. Not a number, not a percentage, not something you could sort a spreadsheet by and mistake for precision.
What stage, and when
The lifecycle state above, with the time it was observed, in UTC.
Where the evidence is
A content-addressed reference to the stored record the match was made against.

Delivery

Four channels. The same payload and the same ordering, different destinations.

Webhook
Signed, at-least-once, with exponential backoff and a dead-letter queue for anything still undelivered when the retry window closes. You can replay from the queue.
WebSocket
A cursor-based stream, so a reconnect resumes from where you stopped rather than replaying everything or skipping the gap.
Email
For the people who are not on call but need the record to exist in their inbox.
Chat
Routed into the channel your on-call rota actually watches, because an alert nobody reads is not an alert.

Coverage health

Every response carries a coverage health block: for each authority we are supposed to be watching, whether it was observable at that moment and how far behind the collector was. It is not a status page. It is a field in the response you are already reading.