Worked example · 2026-07
Across Protocol — a missing 8-byte Anchor discriminator check lets an attacker forge Solana deposit events that never moved funds, and the relayer fills 581 of them — Across / Risk Labs (Solana) — 2026-07-17
Summary
Across is an intents-based cross-chain bridge in which relayers front the destination-side payout to a user immediately, observing a source-chain deposit and later reclaiming from the protocol. The relayer's decision to fill therefore depends entirely on its off-chain reading of source-chain events.
Across had recently launched a Solana SpokePool. Solana has no canonical event system — events are reconstructed from transaction traces, and failed transactions still emit data. The Anchor framework addresses the resulting ambiguity by prefixing emitted event data with an 8-byte discriminator identifying the event type.
Across's off-chain relayer code did not verify that discriminator. On 2026-07-17 at approximately 05:30 UTC, an attacker exploited this by publishing transactions whose emitted data parsed as legitimate deposit events while no funds actually moved on-chain. The relayer treated them as real deposits and filled the corresponding destination-side orders.
The attacker submitted 1,627 forged deposits across 18 destination chains, totalling roughly $41.7M in face value. The relayer filled 581 of them, losing approximately $4.5M, before Solana was disabled as an origin chain.
Risk Labs disabled Solana as an origin chain, paused the Solana SpokePool on-chain, deployed a root-cause fix within approximately five hours of detection, and fully restored Solana service within roughly 12 hours using fallback CCTP routing. User funds were unaffected; all bridge transactions in flight were completed or fully refunded, and the losses were contained to the Risk Labs-operated relayer.
Timeline (UTC)
| When | Event | OAK ref |
|---|---|---|
| (standing) | Across relayers fill destination-side orders against off-chain observation of source-chain deposits; the Solana relayer path does not verify the 8-byte Anchor event discriminator | (standing T10.002 surface) |
| (standing) | Solana has no canonical event system; events are reconstructed from transaction traces, and failed transactions still emit data | (substrate condition) |
| 2026-07-17 ~05:30 | Attacker publishes transactions emitting data that parses as valid deposit events with no funds moved on-chain | T10.002 exploitation |
| same window | 1,627 forged deposits submitted across 18 destination chains, ~$41.7M face value; relayer fills 581 | T10.002 extraction |
| same day | Risk Labs disables Solana as an origin chain and pauses the Solana SpokePool on-chain; ~$4.5M relayer loss realised | (containment) |
| +~5 hours | Root-cause fix deployed | (remediation) |
| +~12 hours | Solana service fully restored using fallback CCTP routing; all in-flight transfers completed or refunded | (recovery) |
What defenders observed
- Pre-event (the off-chain observer is inside the trust boundary). Across's contracts were not defective. The authorisation decision — is this deposit real? — was made in off-chain relayer code, which means that code carried contract-grade security responsibility while receiving indexer-grade review attention. Any protocol where an off-chain component releases or fronts value should scope it into security review explicitly (M23, M35).
- Pre-event (Solana's event model is a standing hazard for every consumer). No canonical events, reconstruction from traces, and data emitted by failed transactions together mean that every Solana event consumer must validate the discriminator and the emitting program. This is not an Across-specific bug so much as an Across-specific instance of a hazard shared by every indexer, relayer, filler, and analytics pipeline reading Solana events. Teams operating such consumers can check their own code for the same omission today.
- At-event (volume anomaly across destination chains). 1,627 deposits spread over 18 destination chains inside a short window is far outside normal traffic. A rate limit on fills-per-window and a fan-out anomaly rule on destination-chain diversity would both have fired well before 581 fills accumulated (M04, M05).
- At-event (fill-versus-settlement reconciliation). The forged deposits never locked funds, so each fill created an immediate, checkable discrepancy between what the relayer fronted and what the source chain actually held. Continuous reconciliation of filled orders against confirmed source-side balances is the direct detection control for this class, and it does not require knowing anything about discriminators.
- Response (unusually good, and specific). Detection to root-cause fix in about five hours and full service restoration in about twelve, with in-flight transfers completed or refunded and a fallback routing path (CCTP) available to keep the route alive while the primary was paused. The availability of that pre-existing fallback is what allowed the operator to pause the vulnerable path without stranding users — a design decision made long before the incident that paid off during it.
- Response (loss placement was architectural, not luck). The relayer fronts its own capital ahead of settlement. That is why a parsing bug produced a $4.5M loss for Risk Labs and a $0 loss for users. Protocols should be able to state, in advance, which party's balance sheet absorbs a failure of each component — Across could.
Public references
[cryptonomistacross2026]— The Cryptonomist, "Across Solana Relayer Attack Details and Impact" (the missing 8-byte Anchor event discriminator verification in off-chain relayer code, Solana's lack of a canonical event system and data emission by failed transactions, the 1,627 forged deposits across 18 destination chains at ~$41.7M face value, 581 fills, ~$4.5M relayer loss, and the ~5-hour fix / ~12-hour restoration with fallback CCTP routing): https://en.cryptonomist.ch/2026/07/24/across-solana-relayer-attack/[cryptotimesacross2026]— The Crypto Times, "Across Protocol Reports First Attack on Solana After $34B in Bridge Volume" (the ~05:30 UTC 2026-07-17 timing, first attack since 2021, and the >$34B prior volume figure): https://www.cryptotimes.io/2026/07/17/across-protocol-reports-first-attack-on-solana-after-34b-in-bridge-volume/[cryptobriefingacross2026]— Crypto Briefing, "Across Protocol confirms Solana bridge attack, says user funds are safe" (operator confirmation, user funds unaffected, Solana deposits temporarily disabled): https://cryptobriefing.com/across-protocol-solana-bridge-attack/[cryptotimesweek0719]— The Crypto Times, "Crypto Loses Over $20M in a Week as Ostium, Across, Cascade Get Hacked" (weekly cohort placement; losses contained to Risk Labs with all in-flight Solana transfers completed or fully refunded): https://www.cryptotimes.io/2026/07/19/crypto-loses-over-20m-in-a-week-as-ostium-across-cascade-get-hacked/
Discussion
This is the most structurally novel case in OAK's July 2026 cohort, because the verification failure is entirely off-chain and the corpus's existing T10.002 anchors are all on-chain contract predicates — Wormhole's unvalidated guardian account, Nomad's 0x00 trusted root, Verus's missing source-amount conservation check. Across extends the class to the observer: the component that decides a source-chain event occurred, before any contract is asked to verify anything. The shared primitive holds — value is released against a message that should have been rejected — but the predicate lives in a Rust or TypeScript relayer rather than in deployed bytecode, and therefore in a place almost nobody audits. OAK records this as a sub-Technique candidate in TAXONOMY-GAPS.md; it needs additional anchors before promotion, and defenders should expect them, because the population of off-chain fillers, solvers, and relayers making value decisions from parsed chain events has grown very fast alongside intents-based architectures.
The Solana substrate detail deserves emphasis independent of Across. Because the chain has no canonical event log, every consumer reconstructs semantics from traces, and because failed transactions still emit data, an attacker can publish arbitrary bytes that a careless parser will treat as protocol history. The 8-byte Anchor discriminator exists to make that distinguishable, which means the entire attack reduces to one omitted comparison — and the same omission is available to any of the many teams running Solana event consumers. This is the rare finding that generalises into an immediately actionable check for third parties who were not involved in the incident.
Finally, this case is worth keeping in OAK as a contained-outcome exemplar rather than filing it away as a near-miss. The corpus is naturally biased toward total losses, which distorts what good looks like. Across pairs instructively with examples/2026-07-verus-ethereum-bridge-repeat-exploit-unfixed-import-path.md from six days later: same technique class, opposite response. Verus took 66 days to not fix a publicly root-caused defect and was drained a second time; Across fixed its root cause in about five hours, restored service in twelve, kept users whole, and absorbed the loss on the balance sheet of the party whose code was wrong. The mechanism did not determine those outcomes. The operational posture did.