Reproduced Exploit
DIA Spectra — fee dropped during the interchain oracle callback (permanent DoS)
OracleRequestRecipient.handle() is the destination-chain entrypoint the Hyperlane relayer calls to deliver an inbound oracle request. To answer it, handle() dispatches a reply message back through the Mailbox, which charges an interchain fee. But line 76 calls OracleTrigger.dispatch(...) without {v…
Chain
Other
Category
cross-chain
Date
Mar 2025
Source
AuditVault
EVM Playground
Source-level debugger — step opcodes and Solidity in sync
The attack is replayed in an in-browser EVM preloaded with the exact dumped fork state. The execution tree shows every call; step by Solidity line or by opcode across all depths — source, Stack, Memory, Storage, Balances (native / ERC-20 / NFT), Transient storage and Return value stay in sync. Click a tree node, opcode, or source line to jump. No backend, no live RPC.
Source & credit. Reproduction of a public audit finding curated by AuditVault — the original finding: 55410-issue-with-fee-payment-during-interchain-callback-mixbytes-n. Standalone Foundry PoC and full write-up: 55410-issue-with-fee-payment-during-interchain-callback-mixbytes-n_exp in the
evm-hack-registrymirror.
Vulnerability classes: vuln/cross-chain/fee-accounting · vuln/dos/liveness · vuln/logic/missing-value-forward
Reproduction: Real audited source, deployed locally. Run forge test and inspect output.txt. The Playground bundle replays the same
55410DoS invariant against the same realOracleRequestRecipient/OracleTrigger.
Key info#
| Field | Value |
|---|---|
| Loss | The interchain oracle callback reverts on every delivery — requested prices are never dispatched back to the requesting chain (liveness DoS; fixable only by redeployment) |
| Vulnerable contract | OracleRequestRecipient.sol:76 (calls OracleTrigger.dispatch() without {value: msg.value}) |
| Protocol | DIA Spectra interoperability (cross-chain oracle) |
| Repo · commit | diadata-org/Spectra-interoperability @ ed9f1e5ff3aa6cfba02d12f0bed1e435aeec24c1 |
| Auditor · severity | MixBytes · High |
| Attacker EOA | 0x1111111111111111111111111111111111111111 (synthetic relayer) |
| Attack contract | Exploit |
| Chain · date | Local (no fork) · 2025-03 |
| Compiler | Solidity 0.8.26 |
| Bug class | vuln/cross-chain/fee-accounting · vuln/dos/liveness |
TL;DR#
OracleRequestRecipient.handle() is the destination-chain entrypoint the Hyperlane
relayer calls to deliver an inbound oracle request. To answer it, handle()
dispatches a reply message back through the Mailbox, which charges an interchain
fee. But line 76 calls OracleTrigger.dispatch(...) without {value: msg.value},
so the reply dispatch is invoked with msg.value == 0. The Mailbox's required fee hook
rejects the zero payment and the whole delivery reverts — every request is denied,
and the requesting chain never receives its price. Because it is a code bug, not a
config value, the only fix is a redeployment.
The vulnerable code#
Real audited source, vendored unchanged from the audited commit
(src/OracleRequestRecipient.sol):
// OracleRequestRecipient.handle(...) — line 76
IOracleTrigger(oracleTriggerAddress).dispatch(_origin, sender, key); // @> VULN: no {value: msg.value}
OracleTrigger.dispatch() then pays the outbound Mailbox with whatever value it
received (src/OracleTrigger.sol:230):
bytes32 messageId = IMailbox(mailBox).dispatch{value: msg.value}( // msg.value == 0 here
_destinationDomain, recipientAddress.addressToBytes32(), messageBody);
Because handle() swallowed the relayer's msg.value, dispatch() sees msg.value == 0
and the Mailbox's required fee hook (src/ProtocolFeeHook.sol,
postDispatch → require(msg.value >= requiredFee)) reverts with "Insufficient fee paid".
Root cause#
handle() receives the fee (msg.value) but forwards nothing to dispatch().
The fee is stranded in the recipient and the outbound reply is always underpaid.
Preconditions#
Standard, intended deployment: the recipient is whitelisted in Hyperlane and granted
OWNER_ROLE on the OracleTrigger so it may dispatch replies; the Mailbox charges a
non-zero required fee (production Hyperlane always does). No attacker setup and no
special state is needed — a perfectly honest, fully-funded relayer delivery is enough
to trigger the revert.
Attack walkthrough#
The PoC deploys the real audited OracleRequestRecipient, OracleTrigger, and
ProtocolFeeHook, and doubles only the opaque boundaries: the Hyperlane Mailbox
(cross-chain messenger) and the DIA oracle feed.
- The relayer calls
Mailbox.process{value: fee}(...)— the full required fee attached — which forwards the value intoOracleRequestRecipient.handle{value: fee}(...). handle()passes every check, then callsOracleTrigger.dispatch(_origin, sender, key)without the value (line 76). The fee stays in the recipient.dispatch()callsIMailbox(mailBox).dispatch{value: 0}(...); the required fee hook reverts"Insufficient fee paid". The whole delivery reverts — the reply is never sent.- The registry test repeats this three times to show the DoS is persistent, and asserts
mailbox.dispatchCount() == 0(zero replies produced). - Negative control: the same, equally-funded flow against the real one-line fix
(
dispatch{value: msg.value}, upstream commit0c4418c) succeeds and produces exactly one reply — proving the missing value forward is the sole cause.
Diagrams#
Remediation#
Forward the value (the upstream fix, commit 0c4418c):
IOracleTrigger(oracleTriggerAddress).dispatch{value: msg.value}(_origin, sender, key);
and add a mechanism to ensure the relayer supplies the required fee to
Mailbox.process() in the first place.
How to reproduce#
cd 55410-issue-with-fee-payment-during-interchain-callback-mixbytes-n_exp
forge test -vvv
The browser replay uses
scripts/poc-configs/55410-issue-with-fee-payment-during-interchain-callback-mixbytes-n.mjs
and the same real OracleRequestRecipient / OracleTrigger inlined into the Exploit.
Sources#
- AuditVault finding
- MixBytes DIA report — §3 Issue with fee payment during interchain callback
- Real audited source: diadata-org/Spectra-interoperability @ ed9f1e5f
- Forge regression: test/55410-issue-with-fee-payment-during-interchain-callback-mixbytes-n_exp.sol
Sources & further analysis#
Reproductions & code
- Standalone PoC + full trace: 55410-issue-with-fee-payment-during-interchain-callback-mixbytes-n_exp (evm-hack-registry mirror).
- AuditVault finding: 55410-issue-with-fee-payment-during-interchain-callback-mixbytes-n.
- Upstream DeFiHackLabs PoC directory: src/test.
Alerts & third-party analyses
- DeFiHackLabs incident explorer: search "DIA Spectra".
- Web3Sec X hacked database: search.
- Rekt leaderboard: search.
- Solodit incident search: search.
These dashboards index community alerts tweets, post-mortems, and independent write-ups. Reach them through the protocol name above to cross-check this reproduction against other analyses.