Event studies need a spine: what happened, when, on which chain, how big. That
list is normally rebuilt per paper from post-mortems and news.
What is in it
Three sources feed the registry on a schedule, and staff add by hand where
no machine-readable source exists (rulings, adoption).
- Exploits, imported weekly from the public DeFiLlama hacks registry: 595
events, $16.8B in recorded losses, refreshed as recoveries are reported. - Depegs, detected daily from the platform’s own hourly price bars. For
each tracked stablecoin against USDC and USDT (the pair’s consolidated
series when one exists, else its busiest pool), a run of hours in which
the close sits more than 2% from 1.0 and lasts more than six hours becomes
adepegevent. It carries the first bar’s block, the trough and the level
before, and the pools that evidenced it. USDC and USDT against each other
are judged once, as USDT priced in USDC: a bar between two stablecoins
cannot say which of them moved. Detected events are not curated until a
person links the transactions. - Governance upgrades, imported weekly from the chain itself: every
ProposalExecuteda listed Governor Bravo or OpenZeppelin Governor emitted
(Compound, Uniswap, ENS), titled from the proposal’s ownProposalCreated
text and anchored to the execution transaction. The chain is the free,
documented source here; governance aggregators and subgraphs re-index
these same logs behind an API key, and Snapshot records off-chain votes,
which are signals rather than upgrades. Governors with a different event
shape (Aave’s governance, Maker’s executive spells) need their own decoder
and are not yet listed. The list isdb/data/governors.yml; adding one is
data.
Nothing goes on the timeline unsourced. An entry needs either a source URL
or a provider reference, enforced at the model. Amounts the source doesn’t
publish are blank, never estimated by us.
Using it
- Filter by category, chain, date range, and whether the anchors have been
confirmed on chain; the recorded-loss total follows the filter. The list is
paged, newest first. - Download the filtered registry as CSV, one row per event, artifacts
pipe-joined so a hash is never split across columns. The direct download
stops at 5,000 rows; past that the page offers the same filter as a
data request, which has no cap and lands with your
other exports. - Episodes (a depeg that ran for days) carry a start and an end, so they render
as spans rather than points. - On any price chart, the Events toggle marks the events inside the plotted
window: instants as lines, episodes as bands. - Integrations can subscribe to
chain_event.createdand hear about every
new row as it lands (webhooks).
Curated entries
A curated event adds the transactions and addresses behind it, so an event can
be traced into the explorer and lined up against price windows. Re-importing
refreshes the provider’s figures (recoveries get reported months later) while
leaving a curator’s writing intact.
How bad it was
Scored events carry a severity from 1 to 5:
| 5 | Systemic — over $100M lost, or a failure that took a protocol or peg down permanently |
| 4 | Severe — $10M to $100M, or a peg broken for more than a day |
| 3 | Significant — $1M to $10M, or a peg broken for hours |
| 2 | Contained — under $1M, or fully recovered |
| 1 | Minor — no measurable loss; notable but not damaging |
The event page says which of two things the score is:
- derived from the recorded figures — computed from the loss, the share
returned and the duration. Reproducible from the row itself. - the curator’s judgement — a person’s call, with their name on it.
An event with no recorded loss and no duration is left unscored. Inventing
a number for it would put a judgement in the column that says it is not one.
Full recovery caps the score at 2: a $60M exploit returned in full is not the
same event as a $60M exploit that was not.
Anchors, and why they are checked
Most events carry a source and a figure. Some also carry the transaction
that did it, and that is what makes this a research artifact rather than a
news timeline.
Anchors are held to two rules:
- Complete, or refused. A truncated hash is rejected when the event is
saved. These are the values researchers match by eye against their own logs,
and0x5c04…9e2acannot be matched against anything while looking as though
it can. - Confirmed against the chain, not copied from a post-mortem. Post-mortems
transpose characters, quote the wrong transaction in a series, and
occasionally cite a hash that was never on mainnet. An event’s anchors are
marked confirmed on chain only when every one of them is found in the
warehouse.
You will see three states, and the middle one is the point:
- no anchor — nothing has been linked yet
- not yet checked — hashes are recorded, and nobody has confirmed them
- confirmed on chain — every hash was found
If the warehouse cannot be reached, nothing is recorded. “We could not check”
is never written down as “we checked”.
Unchecked anchors are checked every night at 05:00 UTC, newest events
first and at most 200 per run, as well as on demand from the admin page. An
event whose anchors are not found stays not yet checked and is looked at
again the next night, so a corrected hash is confirmed without anyone
re-triggering it.
Reference levels
A depeg marker on a price chart can say what the price actually was:
USDC before 1.0, trough 0.877 on 2023-03-11, recovered 0.999. Those levels
are curated per event and appear on the event page and on the charts that
mark it. A marker that only says “something happened here” is worth less.