Executive Summary
On 29-30 May 2026, Gravity Bridge sustained a $5.4M loss via cross-layer registry corruption. The attack exploited a missing validation in deployERC20() — a permissionless function in Gravity.sol — to poison the bridge's denom mapping registry. No signing key was compromised. The attack is classified FC-CLASS-001 (Cross-Chain State Validation Failure).
The attack originated on Cosmos: the attacker minted a fabricated token via Osmosis tokenfactory, constructing its denom string to embed a real Ethereum ERC20 custody address. A permissionless call to deployERC20() on the Ethereum side triggered handleErc20Deployed to write the poisoned denom→ERC20 mapping to the registry without checking for an existing ERC20 entry at that address. Validators subsequently signed withdrawal batches against the corrupted registry state — operating correctly per protocol rules, with no visibility into the poisoning. On-chain capital required by the attacker was approximately zero. No official Gravity Bridge post-mortem has been published as of 2026-06-25.
As of 2026-05-31, 2102 ETH (~$4.23M) was confirmed in the attacker's wallet. By 2026-06-04, CertiK documented 2,020 ETH (~$4.12M) routed to Tornado Cash across multiple transactions — rendering these funds structurally unrecoverable absent attacker cooperation or exchange-level KYC intercept. The remaining ~$1.17M is unaccounted for in primary sources. The bridge was halted with no announced reopening date.
Methodology & Sources
Analysis derived from the Forensic Capital signal database (passive_monitor_log, fc_incidents — FC-005 row), on-chain transaction data for gravitybridge.net, and two primary sources: rekt.news/gravity-bridge-rekt (2026-06-04) and quillaudits.com/blog/hack-analysis/gravity-bridge-demon-mapping-poisoning. The mechanism — cross-layer registry corruption via deployERC20() — is confirmed in both primary sources.
Where figures are unconfirmed or sourced from a single outlet, this is labelled explicitly. Unverified items appear in Open Questions rather than being omitted. No official Gravity Bridge incident report or post-mortem existed at publication date.
Timeline
- Pre-2026-05-29 · date inconnueL'attaquant enregistre un validateur minimal julia666 sur Gravity Chain avec 80 GRAV (~$2–5 USD). Condition nécessaire pour que deployERC20() déclenche handleErc20Deployed.
- Pre-2026-05-30 · date unknownPoisoning transaction submitted to
deployERC20()on Gravity.sol. Exact date unconfirmed — only the exploitation date (2026-05-30) is in the FC-005 record. Bridge continues operating — registry corruption is not detectable on-chain without specific denom mapping inspection. - 2026-05-29/30 · incident dateAttacker exploits poisoned registry to initiate batch withdrawals. All transactions pass cryptographic validation — validators sign based on registry state, with no visibility into the poisoning. The bridge contract correctly processes every withdrawal.
- 2026-05-30 · post-drainBridge halted. $5.4M total loss confirmed in FC-005 record. No reopening date announced.
- 2026-05-31 · observation date2102 ETH (~$4.23M at observation) confirmed in attacker wallet. Remaining ~$1.17M disposition unknown — potentially moved, exchanged, or distributed across additional wallets.
- 2026-06-25 · publication dateNo Gravity Bridge post-mortem published. Bridge remains halted. Incident classified ACTIVE in FC database.
Fonds partiellement routés via Binance et ChangeNow (BTC conversion) avant dépôt Tornado Cash — source : PeckShield 2026-05-30, Bitcoin.com 2026-05-29.
Analysis — Registry State Corruption
The vulnerability consists of two connected gaps in the registry write path. First: deployERC20() in Gravity.sol is permissionless — any caller can invoke it with any _cosmosDenom string, with no validation that the string corresponds to a legitimate Cosmos asset. Second: handleErc20Deployed, the Gravity chain handler triggered in response, writes the new denom→ERC20 mapping to the registry without checking whether an ERC20 contract at that address was already registered under a different denom. A collision check existed elsewhere in the same codebase — it was never applied in this execution path. Sources: rekt.news/gravity-bridge-rekt (2026-06-04); quillaudits.com/blog/hack-analysis/gravity-bridge-demon-mapping-poisoning.
The attack requires three sequential preconditions: (1) validator registration on Gravity Chain (julia666, 80 GRAV), (2) tokenfactory mint on Osmosis with fabricated denom embedding a real ERC20 custody address, (3) permissionless call to deployERC20() on Ethereum. The attack originates on Cosmos. The attacker used Osmosis tokenfactory to mint a fabricated token whose denom string was constructed to embed the address of a real Ethereum ERC20 custody contract. A call to deployERC20() on the Ethereum side — which accepts any caller — triggered handleErc20Deployed to write this poisoned denom→ERC20 mapping to the registry. Validators then signed withdrawal batches against the corrupted registry state. Every signature was cryptographically legitimate. No signing key was compromised. No validator acted outside protocol rules. The poisoning of the registry state preceded and enabled the withdrawals.
The critical classification distinction from FC-CLASS-002 (Privileged Key Compromise): the off-chain key management layer was never touched. The attack is entirely on-chain, deterministic, and reproducible from the Gravity.sol source. The architectural failure is the absence of authorization and input validation on a function with direct write access to the cross-chain state registry. Any actor with access to IBC tokenfactory — permissionless by design on Osmosis — could construct the poisoning transaction.
The defensibility score of 6/10 reflects that the fix is a targeted code change in a known path, not an architectural overhaul. The severity score of 9/10 reflects that once the registry is poisoned, withdrawals are indistinguishable from legitimate operations at the signing layer.
GitHub signal 1 — Audit status undischarged. The Gravity Bridge README states: "will be undergoing audits soon" — a statement present in the repository since at least the December 2021 mainnet launch, 4.5 years before the May 2026 exploit. No audit report link appears in the repository as of publication date. Source: github.com/Gravity-Bridge/Gravity-Bridge
GitHub signal 2 — 14 months without a release, 8 watchers. Last published release: v1.12.3, March 2025 — 14 months elapsed before the May 2026 exploit with no subsequent release. At time of incident the repository carried 8 watchers on a bridge holding $5.4M in assets. Source: GitHub releases — github.com/Gravity-Bridge/Gravity-Bridge/releases
GitHub signal 3 — No input validation on cross-chain state transition. The README Operational parameters section states: "events accepted based purely on signatures of the current validator set". The registry write path — deployERC20() → handleErc20Deployed — requires neither caller authorization nor _cosmosDenom input validation. Any actor on Cosmos can trigger a registry update on Ethereum with an arbitrary denom string. Source: Gravity.sol — github.com/Gravity-Bridge/Gravity-Bridge
GitHub signal 4 — Business Wire 2022 launch claim. Business Wire dated 2022-01-19 described the Gravity Bridge mainnet launch of December 2021 as "Never Hacked". The bridge was exploited 4.5 years later, in May 2026. Source: Business Wire 2022-01-19.
Perimeter signal — gravitybridge.net security hygiene. The Forensic Capital passive monitor recorded two perimeter deficiencies on gravitybridge.net at observation date: SPF absent (dns_spf_absent) and HSTS missing (http_hsts_missing_financial). These are not causal to this incident but indicate security hygiene posture consistent with a bridge operating without routine perimeter monitoring. Source: Forensic Capital passive_monitor_log.
Media misclassification signal. Multiple outlets initially classified this incident as a signing key compromise (Yahoo Finance 2026-05-30; Zealynx 2026-06-02). This classification is factually incorrect. No signing key was compromised. Validators operated correctly per protocol rules throughout. The misclassification reflects the difficulty of distinguishing registry-level state corruption from key compromise at the validator layer — both produce cryptographically valid signatures on malicious state. The distinction is material: key compromise is remediable by key rotation; registry corruption requires code-level validation enforcement.
The registry was poisoned. The validators signed what they were given.
Confidence Mapping
Three-tier classification of findings by evidentiary basis. ESTABLISHED requires on-chain or primary-source confirmation. INFERRED requires logical elimination from confirmed data. UNVERIFIED identifies open questions without confirmed answers in primary sources.
Recovery Status
FC-005 recovery probability: 2/10 — reflecting the absence of KYC-linked exchange transactions in available evidence and no publicly reported bounty negotiation. As of 2026-05-31, 2102 ETH (~$4.23M) was confirmed in the attacker's wallet. By 2026-06-04, CertiK documented 2,020 ETH (~$4.12M) routed to Tornado Cash across multiple transactions — rendering these funds structurally unrecoverable absent attacker cooperation or exchange-level KYC intercept.
The remaining ~$1.17M between the $5.4M total loss and the identified 2102 ETH is unaccounted for in primary sources. It may have been bridged, exchanged via DEX, or distributed across additional wallets prior to the 2026-05-31 observation date.
In an environment of concentrated law enforcement attention on bridge exploits, asset tracing is active but fund recovery without attacker cooperation remains structurally unlikely given the absence of KYC-linked exchange transactions in available evidence.
Open Questions & Unverified
- Exact fabricated denom string — the Cosmos denom value used in the poisoning transaction has not been published in available primary sources.
- Exploit preparation date — only the exploitation date (2026-05-30) is confirmed. The date when the poisoning transaction was submitted to
deployERC20()is not confirmed in available sources. - Additional poisoned registry entries — whether the attacker poisoned one or multiple denom→ERC20 mappings is not confirmed in available primary sources.
- Disposition of ~$1.17M not present in the identified 2102 ETH attacker wallet — no primary source confirms movement to exchange, mixer, or secondary wallet.
- No official Gravity Bridge post-mortem published as of 2026-06-25. This report relies on the FC-005 database record, on-chain observation, and two external primary sources.
- Bridge reopening timeline: not announced. Source: FC-005 vector field ("Bridge halted — no reopening date").
About this report
Forensic Capital produces independent, source-traceable forensic analysis of DeFi incidents. This report is public.
forensic-capital.com · Ω
Sources
- Forensic Capital database — FC-005 record,
fc_incidentstable,data/forensic_capital.sqlite - On-chain transaction data —
gravitybridge.netbridge contract, attacker wallet0x7B582033061b96cC3F9421e73a749ED7C62da1F9, observation 2026-05-31. Drain transactions: USDC0xfce883…b5044· USDT0x469274…1281d· WETH0x59e523…eb84b· PAXG0xd3cdfa…f9ef0 - Forensic Capital passive monitor —
passive_monitor_log, signaldns_spf_absentandhttp_hsts_missing_financialongravitybridge.net - rekt.news/gravity-bridge-rekt — primary incident report (2026-06-04)
- quillaudits.com/blog/hack-analysis/gravity-bridge-demon-mapping-poisoning — technical analysis, collision check absence (2026-06-04)
No official post-mortem published — see Methodology and Open Questions.
This hash fixes the published version at the stated date. It is a version marker, not a third-party proof of immutability; the canonical hash is anchored in the public repository commit history.