DeFi Security AllianceRequest an audit
Menu

Operations

DeFi Hack Post Mortem: Evidence, Recovery and Repair

A credible DeFi hack post mortem connects a verified timeline, the violated security property and evidence that the repair was checked. Recovery amounts and audit coverage need separate records; an incident archive cannot fill gaps in either.

Broken glass fragments reassembled in order along a timeline strip under a magnifier, representing a DeFi hack post mortem.

Key facts

Original measurement
191 of 197 records from 2023 had no returnedFunds value
Source-field limit
0 of 197 selected archive records had a populated source field
Accounting rule
Missing recovery data is unknown, not zero
Review boundary
Audit coverage must match the affected revision

Timeline

A transaction hash establishes an execution event. It does not establish when an engineer noticed the event, when a signer became available or when a recovery decision was approved. A credible DeFi hack post mortem keeps those clocks separate. Otherwise an apparently precise chronology can hide the delay that the next response plan actually needs to fix.

Begin with a preserved incident record. Record the chain, block number, transaction hash and observation source for every on-chain step. Operational entries need their own timestamp, time zone and provenance, such as the monitoring log or incident ticket. Normalize the displayed chronology to UTC while retaining the original timestamp in the evidence bundle. A block timestamp is useful for ordering execution; it is not a measurement of when a human read an alert.

The initial timeline can contain uncertainty. Label an approximate detection window as approximate and explain why it cannot yet be narrowed. If a monitoring provider supplies a corrected export later, revise the affected row and retain the earlier version. Silent edits make it difficult for another investigator to reproduce the sequence.

Timeline fields and the questions they answer
Event classEvidence to retainQuestion resolved
ExecutionChain identifier, block and transaction hashWhich state transition occurred?
DetectionAlert payload and delivery timestampWhen did the response channel receive a signal?
DecisionIncident ticket and approving roleWho authorized the containment action?
ContainmentSubmitted transaction and confirmation recordWhen did the control actually take effect?

A useful timeline distinguishes a failed containment attempt from a completed one. A transaction sitting in a multisig queue may show preparation, but the affected system is still exposed until the relevant action executes. Name that interval. It can reveal a signer availability problem even when the detection system worked as designed.

Keep personal contact details and credentials out of the public table. Their existence may be relevant to the private investigation, but publishing them rarely helps a reader verify the technical sequence. Preserve the original evidence under the incident team's access controls and publish a redacted reference with a stable identifier.

What the public incident archive leaves unknown

Method

Source and selection
Complete 2023 calendar-year subset of the fetched DefiLlama hacks API. Count populated source and returnedFunds fields, not verified post-mortems or recovery rates.
Retrieved
Observation
The observation unit is an archive record, including non-DeFi targets. Missing returnedFunds is not zero recovery.

Results

Recorded observations on
FieldObserved recordsDenominator
Populated source field0197 incident records from 2023
Returned-funds value present6197 incident records from 2023
Returned-funds value missing191197 incident records from 2023

Our extraction found 191 missing returned-funds values among 197 records dated in 2023. None of those records carried a populated source field in the fetched response. This is a limitation of this endpoint snapshot, not evidence that the affected teams failed to publish reports.

That distinction changes the writing workflow. An incident directory can help locate a name and date, but its empty recovery field cannot support a sentence saying funds were never recovered. The post-mortem needs its own reconciled ledger and links to the actual disclosures. A later archive refresh may change these counts without changing the historical incident.

Limits

  • The full response contained 1,255 records; 1,058 were outside the selected calendar year.
  • DefiLlama curates the archive. The subset includes centralized services and other non-DeFi targets.
  • No source URLs or recovery transactions were independently verified through these fields. The six populated recovery values are not a recovery-rate estimate.

The reproducible record is kept in the repository: seo/research/articles-32-41-2026-09-05/surveys.py and seo/research/articles-32-41-2026-09-05/survey-32.json. These file paths are not public downloads.

Root cause and class

A root cause explains why the system permitted the harmful transition. The attack class describes a broader family of behavior. Keep both. Calling an event a flash-loan attack identifies a funding mechanism, but it may leave the broken accounting rule entirely unexplained.

Euler's own retrospective describes the V1 exploit through the missing check associated with donateToReserves. It also disputes the claim that the function was unaudited. Those are statements by the affected team, and an article should attribute them accordingly. The useful editorial lesson is narrower: an audit label cannot substitute for a revision-level account of the code path that failed.

Use a causal chain the reader can inspect. State the intended invariant, the action that invalidated it and the check that should have rejected the resulting state. Then identify the reason that check did not run or did not express the intended condition. If a compiler defect changed deployed behavior, preserve the compiler version and configuration alongside the source rather than blaming the source language as a whole.

Evidence chain for a root-cause findingA root-cause claim connects an expected property to a specific violation and a repair that has been checked.Expected propertyObserved transitionMissing enforcementVerified repair
Evidence chain for a root-cause finding. A root-cause claim connects an expected property to a specific violation and a repair that has been checked.
  1. Write the accounting or authorization property that should have held.
  2. Identify the transaction and state changes that violated that property.
  3. Locate the guard, dependency or build behavior responsible for the violation.
  4. Demonstrate that the repaired revision rejects the same failure path.

Alternative explanations deserve a recorded disposition. If the early working theory was a compromised key and the later trace showed a permissionless accounting path, explain what evidence changed the conclusion. Do not leave both theories in the finished article as though they are equally supported. The threat-modeling workflow helps express the actor's actual authority before naming the failure.

Avoid a claim about motive unless there is evidence for it. A transaction can demonstrate a transfer or call sequence; it does not by itself establish the identity of the person operating the address. Technical certainty about execution should not become certainty about attribution.

Funds flow

Build the funds table in native asset units before attaching a dollar value. Record the asset contract, amount, source address, destination address and transaction reference. A dollar estimate adds a valuation timestamp and price source. Without those fields, readers may compare amounts measured at different prices and mistake the difference for another transfer.

Separate gross extraction from retained attacker proceeds, whitehat custody and assets returned to a recovery address. A transfer into a recovery wallet is also different from a payment to an affected user. The distinction becomes especially important when recovery requires a claim process or a later governance decision.

Use a reconciliation status for each asset rather than a single dramatic loss headline. If a token rebases, charges transfer fees or represents a claim on another asset, state the conversion rule. An investigator should be able to determine whether the report counted the receipt token, the underlying asset or both.

A public reconciliation ledger should separate these quantities
QuantityUnitEvidence boundary
Gross extractionNative units per assetTransfers attributed to the affected transaction sequence
Recovered custodyNative units per assetConfirmed receipt at a designated recovery address
User reimbursementNative units or documented claim unitsDistribution execution or a clearly labeled unpaid entitlement
Dollar valuationNamed currency at a stated timePrice source and conversion method

Do not net unrelated assets against each other without showing the conversion. A returned amount can exceed the original dollar estimate because the asset price moved. It can also differ because the report measures a different collection of transactions. Resolve those possibilities before describing a recovery percentage.

When the investigation is incomplete, publish the verified asset rows and identify the unresolved balance. An explicit unknown is more useful than a neat total assembled from incompatible estimates.

What the audit covered

Retrieve the report itself. Match its repository and reviewed revision to the affected deployment, then check the scope exclusions and remediation record. A logo on a project website cannot answer any of those questions. The audit report reading guide explains the fields to inspect before interpreting the findings count.

There are several materially different situations: the vulnerable path was in scope and missed, the path changed after review, a dependency was excluded or the public record does not resolve coverage. Report the situation the evidence supports. An unavailable private report leaves coverage unknown; it does not license either an accusation or an exoneration.

Ask whether the deployed configuration was part of the engagement. A correctly implemented access check can coexist with an unsafe production role assignment. Similarly, a report can describe an implementation while leaving the proxy's initialization or upgrade authority to a different workstream. Separate those surfaces in the post-mortem.

For named firms, link to the exact report and passage rather than relying on a directory description. Our Pharos Production profile is a provider-discovery page; it is not evidence that the firm reviewed any particular incident. The wider audit company analysis hub serves the same discovery role. Incident attribution still requires the engagement artifact.

Remediation and re-audit

A patch description explains the intended fix. Acceptance evidence shows what was checked. Connect every remediation item to the failure it addresses, the changed revision and the observed result. Keep open design questions separate from completed code changes so a reader does not mistake a plan for an implemented control.

Start with a local reproduction of the documented behavior using a preserved state where appropriate. The repair should reject the original harmful transition and preserve the legitimate operation it replaced. Add adjacent cases that would bypass an overly narrow fix, such as another entry point reaching the same accounting update. Report these as executed checks only when their artifacts exist.

A regression test for the original path is necessary evidence, but a changed architecture can introduce a different failure. Re-audit scope should identify the affected interfaces and new trust assumptions. If the team changed an oracle, liquidation rule or upgrade mechanism during recovery, each change needs an explicit review decision.

Remediation acceptance record
ItemResponsible roleAcceptance evidence
Root-cause fixContract maintainerChanged revision and regression result tied to the original failure
Adjacent-path reviewSecurity reviewerNamed interfaces inspected and unresolved findings
Operational controlIncident ownerObserved alert delivery and authorized response exercise
Restart decisionDeployment authoritySigned readiness record with open risks and rollback conditions

NIST's incident-response guidance treats improvement as part of continuing risk management. Apply that idea to the operational findings as well as the contract patch. A signer escalation path, a broken alert route or an unavailable dependency owner can materially affect the next response even though none appears in a Solidity diff.

A patch is not the whole recovery record

Consider a hypothetical incident in which a team pauses a vulnerable market, deploys a correction and later enables withdrawals. Those are separate events. The post-mortem should identify which action stopped the original path, which change corrected the cause and which check supported reopening. A successful patch test does not by itself establish that every user balance was reconciled or that every dependent integration resumed safely.

Give each event its own evidence reference. The pause can point to a transaction and the authority that executed it. The correction can point to a source revision and review result. Reopening needs the relevant deployment and operational acceptance record. If an action occurred off-chain, name the retained record without presenting an unavailable transaction as proof.

When a correction changes an economic rule, explain the remaining tradeoff. A tighter limit might block the exploit while restricting a legitimate workflow. The affected team should describe that consequence and its decision owner. The report reader then understands both the security repair and the operating behavior that users encounter afterward.

A later correction to the post-mortem should preserve the earlier statement and explain the evidence that changed it. Quietly replacing an uncertain loss estimate with a final figure makes the history difficult to reconstruct. Use a dated correction note and keep gross outflow, returned assets and outstanding claims separately labeled. This is a proposed reporting discipline; it does not imply that every historical source in our sample provides such a record.

Publishing and disclosure timing

Publish a short verified status update while the investigation continues, then release the technical account when the evidence and remediation state support it. Name the affected service, the current user action and the limits of what is known. A status update should not promise a recovery date simply because stakeholders want one.

Detailed exploit information may affect another deployment that shares the vulnerable component. Coordinate the technical release with the relevant maintainers through authorized disclosure channels. Keep the public report's timing explanation concrete: identify that related systems required notification or that a repair still awaited validation, without exposing private contact records.

Use the incident response workflow to coordinate the open operational work while preparing the public account.

Assign an editor who can reconcile technical findings with the legal and operational record. The editor should preserve distinctions such as confirmed transfer, suspected attribution and proposed reimbursement. Those are different claims even when they appear in the same paragraph.

  1. Freeze the evidence bundle and assign stable identifiers to its public references.
  2. Have the technical owner verify the chronology and causal chain against the retained artifacts.
  3. Confirm that recovery figures use the same asset units and valuation basis throughout the report.
  4. Publish with a revision date and a change log; later corrections should identify the claim that changed.

The accountable output is a maintained record. If a transaction, repayment plan or compiler advisory changes the conclusion later, the post-mortem needs a visible update rather than a new social post that leaves the original page wrong.

Examples

Euler's retrospective and the LlamaRisk account of the Curve pool incident illustrate different evidence problems. Euler combines technical explanation with a first-person recovery narrative. The Curve account distinguishes affected pools and the compiler behavior involved. Neither should be compressed into a generic sentence claiming that every audited protocol shares the same exposure.

Examples and the document-reading lesson
AccountWhat it establishes as a sourceWhat needs separate evidence
Euler V1 retrospectiveThe affected team describes its exploit and recovery processIndependent verification of individual recovery transfers or claims about audit coverage
Curve pool post-mortem by LlamaRiskThe account identifies affected configurations and a reentrancy-lock failureApplicability to another pool, compiler build or later deployment
DefiLlama 2023 archive subsetThe fetched endpoint exposes incident-record fieldsA primary incident narrative and a reconciled recovery ledger

A practical editorial check is to read the report with every adjective removed. The chronology should still identify the delay, the root-cause section should still identify the violated property and the remediation table should still identify the proof of repair. If those connections disappear, the text is describing the incident without explaining it.

Finish with the next unresolved evidence item and its owner when one remains. A credible post-mortem can be incomplete. It cannot hide that incompleteness behind a final claim that the protocol is now secure.

Frequently asked questions

Should an unsuccessful attack attempt have a post-mortem?

Yes, when it exposes a control or response weakness worth correcting. Separate attempted impact from executed state changes and avoid recording an unrealized loss as funds stolen.

Can a report be updated after a recovery dispute?

Yes. Preserve the prior version and identify which verified fact or decision changed. A reimbursement proposal should remain labeled as a proposal until the relevant approval and execution occur.

Should private chat screenshots be attached?

Only publish material the team is authorized to disclose and that is necessary to substantiate the public account. Redacted references and a retained private evidence bundle often support verification without publishing personal information.