Skip to content

How an investigation runs

An investigation starts from one question. The assistant calls the tools that answer it, reads each answer, and uses what it finds to choose the next call. Every answer also states what it covers and how sure it is, and a conclusion rests on those statements.

Question: what did the wallet behind the 22 May 2025 Cetus CLMM exploit take? Every value below can be checked on chain.

get_transaction_history on the attacker wallet, oldest transactions first:

{ "address": "0xe28b50cef1d633ea43d3296a3f6b67ff0312a5f1a99f0af753c85b8b5de8ff06", "order": "oldest", "limit": 5 }
{ "digest": "EKHNUkpyzuzBg85rFXxpvXiR4kYU9quRXDCZNUmqYnuh", "status": "success",
"subject_flow": [ { "formatted": "9.98065224 SUI", … } ], … },
{ "digest": "BTMCNZd2kt6b1ALvntNC99GGo1nancJtJHAbxi5SnCpR", "status": "failure", … },
{ "digest": "DVMG3B2kocLEnVMDuQzTYRgjwuuFSfciawPvXXheB3x", "timestamp": "2025-05-22T10:30:50.476Z",
"status": "success", … },
…

The wallet was funded once, failed one transaction, and first succeeded at 10:30:50 UTC. Cetus’s incident report dates the exploit from that time.

analyze_attack_tx on that transaction:

{ "digest": "DVMG3B2kocLEnVMDuQzTYRgjwuuFSfciawPvXXheB3x" }
"profit": { "gains": [ { "symbol": "haSUI", "amount": "10024321275017081", … },
{ "symbol": "SUI", "amount": "5765124463062928", … } ], … },
"swaps": [ { "pool": "0x871d8a227114f375170f149f7e9d45be822dd003eba225e83c05ac80828596bc",
"price_change_pct": -99.999906, … } ],
"anomalies": [ { "code": "outsized-mint", "severity": "high", … }, … ]

The transaction moved the haSUI/SUI pool’s price by -99.9999% and left the attacker 10,024,321.28 haSUI and 5,765,124.46 SUI. outsized-mint flags a position credited more liquidity than its amounts can buy, which points at the pool’s liquidity math.

The Cetus exploit example continues from here: it totals the whole run, finds where the proceeds left Sui, and checks who funded the wallet.

  • truncated and omitted: a display limit or scan budget left rows out. Follow the reported next_call; a paginated result can have more pages even without truncated. See Truncated lists.
  • complete: true: the scan reached the end of its window. Check separate unread-data and pricing warnings before drawing conclusions.
  • totals.partial or totals_usd.partial: USD excludes unpriced coin legs or unread or unpriced objects. Missing debits can raise a net, so a partial total is not a lower bound. usd_basis reports pricing coverage, and unpriced_remainder lists unpriced coins in incident totals. USD values are estimates from provider quotes; see How USD values are calculated.
  • coin_verified and verified: whether a coin is the one its symbol suggests or an imitator. See Coin identity and scale.
  • Leads and facts: amounts, digests, signers and timestamps are read from the chain. Anomaly flags, clusters and deposit-address verdicts are leads that say where to look next. A check that did not match clears nothing. A saved finding records which kind it is in evidence_tier: chain-derived, indexer-attested or heuristic.

How to read results covers the marks specific to coins, transactions, fund flows, funders and packages.