devoracles.

NewsData Feeds & APIs

How a Market ID Collision Enabled a $4.9M Exploit on Injective

Per on-chain analysis from Metaverse Post: 299 instant binary-options markets went live across a 19-hour window.

How a Market ID Collision Enabled a $4.9M Exploit on Injective

Settlement Logic Collapsed at the Market-ID Hash

A $4.9M drain on Injective on August 31 didn't come from price feed spoofing. It came from a market_id collision that let an attacker deploy self-controlled oracles returning nothing — and still trigger full refunds.

Each carried an oracle symbol engineered to hit the no-price refund path. Expiration and settlement timestamps sat seconds apart. The actor self-matched longs and shorts across its own subaccounts, extracted roughly 2x the deposited collateral per cycle.

One captured sequence: ~105,000 USDC deposited. Withdrawals cleared 204,000+ USDC. Zero price discovery required.

The Identifier Collision

Root cause lives in market_id generation. Injective concatenates five fields — oracleType, ticker, quoteDenom, oracleSymbol, oracleProvider — with no separators and no length prefixes.

Result: an INJ-denominated insurance fund hashed identically to a USDC-denominated binary-options market. When settlement entered the no-price refund branch, the protocol reached for the attached INJ balance to cover a USDC shortfall. Minimal INJ integer balance satisfied the coverage check. Required haircut among remaining positions was bypassed. Full withdrawal of the artificially inflated balance went through.

Oracle returned nothing. Code paid out anyway.

Chain Response — and the Open-Source Gap

Halt duration: 3h 42m. Blocks 181,027,006 → 181,027,007. Window: 16:10–19:52 UTC. Block production degraded to ~38-minute intervals before validators intervened. The final exploit attempt died only because its settlement timestamp expired in that slowed window.

Contrast point: Cronos rolled back transactions after its recent incident. Injective advanced by exactly one block across the seam. Every executed trade preserved.

Funds trail: bridged to Ethereum via CCTP, swapped to ETH on Uniswap, consolidated at 0x5a18…69ea. Balance at press time: ~1,980 ETH ($4.88M). Untouched.

What Builders and Node Operators Should Check

  • Audit any market_id hashing logic. Concatenation without length prefixes is a collision primitive.
  • Flag zero-response oracles across multiple settlement windows. Silent oracles on binary or derivatives markets = manual intervention queue.
  • Review refund-path coverage logic. Cross-denomination balance fallback (INJ covering USDC deficit) is unacceptable accounting — pin coverage to quote-denominated reserves only.
  • Track block-time deviation. The 38-minute interval preceded the final failed attempt; sustained deviation above threshold is a leading halt signal.
  • Pressure-test insurance-fund ↔ derivatives-market identifier namespaces. Shared prefixes or shared oracle provider fields need explicit collision guards.

Injective also pulled core chain repositories from GitHub earlier, citing reduced attack surface. That decision is back under review — the vulnerability surfaced only through post-hoc on-chain forensics, with no open-source diff available to spot the concatenation flaw in advance. For oracle consumers and market makers building on settlement-dependent primitives, the takeaway is sharper: verify the hash, not just the price feed.