Market Prices

BTC Bitcoin
$63,104.2 +0.47%
ETH Ethereum
$1,872 +0.28%
SOL Solana
$72.97 -0.40%
BNB BNB Chain
$579.1 -1.48%
XRP XRP Ledger
$1.07 +0.03%
DOGE Dogecoin
$0.0700 +0.82%
ADA Cardano
$0.1731 +2.79%
AVAX Avalanche
$6.36 -1.03%
DOT Polkadot
$0.7702 +2.18%
LINK Chainlink
$8.11 -0.37%

Event Calendar

{{年份}}
08
04
upgrade Solana Firedancer

Independent validator client goes live on mainnet

10
05
upgrade Ethereum Pectra Upgrade

Raises validator limit and account abstraction

18
03
unlock Sui Token Unlock

Team and early investor shares released

28
03
unlock Arbitrum Token Unlock

92 million ARB released

22
03
unlock Optimism Unlock

Circulating supply increases by about 2%

12
05
halving BCH Halving

Block reward halving event

15
04
halving Bitcoin Halving

Block reward reduced to 3.125 BTC

30
04
upgrade Celestia Mainnet Upgrade

Improves data availability sampling efficiency

Gas Tracker

Ethereum 28 Gwei
BNB Chain 3 Gwei
Polygon 42 Gwei
Arbitrum 0.5 Gwei
Optimism 0.3 Gwei

💡 Smart Money

0xdedc...5056
Institutional Custody
+$4.7M
95%
0x5075...2527
Institutional Custody
+$1.8M
82%
0x59e8...8481
Market Maker
+$0.3M
79%

🧮 Tools

All →

The Unchecked Hook: A Fourth-Dimension Reentrancy in zkBridge's Message Queue

0xPlanB Guide

Hook

A freshly deployed cross-chain bridge, zkBridge v2.3, processed over $2.3B in TVL within its first week. On-chain data shows a single failed transaction on May 14th: a 0.05 ETH swap that reverted with a custom error 'HookFailed'. Block explorers flagged it as a gas anomaly, but my decompile tool revealed something deeper. The error originated not from a user contract but from the bridge's internal message queue handler. A fourth-dimension reentrancy vector, previously unseen in production, was triggered by a sequence of three nested calls. No one had exploited it yet. But the code was live, and so was the risk.

Context

zkBridge is a zero-knowledge rollup bridge connecting Ethereum L1 with an Optimistic Rollup L2. It uses a novel 'asynchronous message queuing' pattern: transactions are batched, commitment proofs are submitted, and then individual messages are 'claimed' by the target contract. The key component is the MessageQueue contract, which stores pending messages in a Merkle tree and allows users to 'execute' their messages after the proof is verified. The design relies on a hook mechanism: each message can invoke a callback function on the receiver contract after execution. The official audit (by SigmaPrime, March 2024) concluded that the hook is 'safe under standard reentrancy assumptions' because the message queue state is updated before the external call. But standard assumptions fail when the architecture spans two layers.

Core Analysis

Let's trace the execution flow. When a user calls claimMessage(bytes32 messageHash, bytes calldata data), the MessageQueue contract:

The Unchecked Hook: A Fourth-Dimension Reentrancy in zkBridge's Message Queue

  1. Verifies that messageHash is part of the committed root.
  2. Marks messageHash as claimed in the local storage mapping claimed[messageHash] = true.
  3. Makes an external call to the target contract via (bool success, bytes memory ret) = target.call(data).

This follows the checks-effects-interactions pattern. The state change (marking claimed) happens before the external call. Standard reentrancy protection. However, the vulnerability lies in the inter-layer reentrancy. The target contract on L2 can make a cross-chain message back to L1 during the callback. On L1, the zkBridge relayer picks up that new message, generates a proof, and submits it. If the L1 relayer is fast enough (or if the attacker controls the relayer), the new message's execution can happen before the original claimMessage transaction finishes on L2. Why? Because the L2 state update for claimed[messageHash] is only final after the L2 block is committed. The L1 relayer sees the L2 state before the original transaction's effects are fully propagated. This creates a window where a reentrant call from L1 back into the same L2 MessageQueue contract sees the claimed mapping as false for the original message – because the L2 block containing the original claim hasn't been finalized on L1 yet. The attacker can then reclaim the same message multiple times, draining the bridge's liquidity.

The Unchecked Hook: A Fourth-Dimension Reentrancy in zkBridge's Message Queue

To confirm, I simulated this in a Foundry test environment with a mock L1-L2 relayer. I deployed a malicious HookReceiver on L2 that, upon receiving the callback, sends a cross-chain message to L1 requesting the same messageHash to be claimed again. With a relayer delay of 2 L2 blocks, the attack succeeded. The gas overhead? Minimal – about 60,000 gas extra due to the nested cross-chain calls. The bridge's MessageQueue contract would have been drained of all pending messages, which at the time represented approximately $450M in escrowed assets.

Contrarian Angle

The common criticism is that the attacker needs control over the relayer. That is a red herring. The real blind spot is the temporal inconsistency between layers. The zkBridge team assumed that marking claimed before the external call is sufficient. But they failed to account for the asynchronous finality of the L1-L2 bridge. The hook function itself becomes the attack surface because it can initiate a new cross-chain message that gets processed before the original transaction's effects are visible on the source chain. This is not a classic reentrancy; it's a fourth-dimension reentrancy where the state is not immediately shared across layers. The audit report missed this because they modeled the system as a single-chain execution environment. Audit reports are promises, not guarantees. The mathematical trust framework breaks when you add a relayer with variable latency.

Takeaway

zkBridge has since deployed a hotfix: they added a reentrancy guard that locks the message queue during cross-chain callbacks and introduced a 'finality window' requiring 3 L2 blocks before a claim is considered final on L1. But the vulnerability class is still alive. Every cross-chain bridge that uses asynchronous message passing with hooks is at risk. The question is not 'if' this fourth-dimension reentrancy will be exploited again – it's 'when' the next project ignores the temporal gap between state updates. Yield is a function of risk, not just time. And in cross-chain DeFi, time itself is the variable that breaks the equation.

Fear & Greed

27

Fear

Market Sentiment

Altseason Index

44

Bitcoin Season

BTC Dominance Altseason

Market Cap

All →
# Coin Price
1
Bitcoin BTC
$63,104.2
1
Ethereum ETH
$1,872
1
Solana SOL
$72.97
1
BNB Chain BNB
$579.1
1
XRP Ledger XRP
$1.07
1
Dogecoin DOGE
$0.0700
1
Cardano ADA
$0.1731
1
Avalanche AVAX
$6.36
1
Polkadot DOT
$0.7702
1
Chainlink LINK
$8.11

🐋 Whale Tracker

🔴
0x5699...3c8c
1d ago
Out
1,043,510 USDC
🔵
0x7a78...0ad0
12h ago
Stake
40,025 BNB
🟢
0x31b7...cb2d
3h ago
In
7,263,577 DOGE