Root Cause
NEAR Intents' cross-chain vault on BNB Chain processed signed withdrawal messages originating from the Omni bridge infrastructure. A bug in the deposit notification pathway allowed failed deposit transactions to nonetheless credit balances in the off-chain intent settlement layer. The vault then paid out real USDT against these phantom credits.
// BridgeVault.sol (conceptual reconstruction — not verified source)
function processDeposit(address user, uint256 amount, bytes calldata omniSig) external {
// BUG: balance credited before on-chain deposit confirmation
pendingBalances[user] += amount; // credited even on failed token transfers
emit DepositNotified(user, amount);
// actual token transfer verified async / off critical path
}
function withdraw(address user, uint256 amount, bytes calldata sig) external {
require(verifyOmniSignature(sig), "bad sig");
require(pendingBalances[user] >= amount, "insufficient");
pendingBalances[user] -= amount;
IERC20(USDT).transfer(user, amount); // real funds drained against ghost balance
}
The off-chain Omni intent layer credited balances upon receiving a deposit notification event, without waiting for finality confirmation. The attacker submitted 23 deposit transactions that failed at the token-transfer step but still triggered the credit event, inflating their withdrawable balance with no real collateral.
Attack Steps
| Step | Action | Detail |
|---|---|---|
| 1 | Setup | Fund attacker wallet on BNB Chain with minimal capital |
| 2 | Ghost deposits | Submit 23 deposit transactions; token transfers fail but DepositNotified event fires |
| 3 | Balance inflation | Off-chain intent layer credits uncollateralized USDT balance |
| 4 | Signed withdrawals | Request withdrawals using valid Omni bridge message format against inflated balance |
| 5 | Drain vault | BNB Chain HOT Bridge vault pays out real USDT; ~$3.87M removed |
| 6 | Exit | Funds moved to KuCoin, then converted to Bitcoin |
Impact
- Chain: BNB Smart Chain
- Protocol: NEAR Intents (HOT Bridge vault)
- Asset drained: USDT (~$3.87M)
- Exploit window: September 29 – October 1, 2026 (overnight hours)
- Unaffected: NEAR Protocol chain, NEAR token, all other ecosystem applications
- Outcome: Attacker returned full funds by October 2, 2026 after a 48-hour public ultimatum; investigation closed October 4. NEAR Intents subsequently removed the deposit notification feature, added monitoring, and implemented an automatic pause on anomalous withdrawal volume.
Lessons for Auditors
- Never credit optimistically. Any system crediting a balance before atomically confirming the corresponding on-chain token transfer is vulnerable to ghost-balance attacks. Deposits and credits must be coupled atomically or via a cryptographically verified, finality-guaranteed confirmation mechanism.
- Cross-chain state is not atomic. Authorization logic spanning two chains (BNB Chain vault + NEAR Omni layer) must explicitly handle partial-failure states. Assume any off-chain notification can misrepresent deposit finality.
- Signed withdrawal messages need tight domain separation. If a withdrawal message format is structurally similar to other system messages, replay or message-crafting attacks can authorize illegitimate payouts. Use EIP-712-style typed, domain-separated signatures.
- Circuit-breakers and volume limits save funds. NEAR Intents paused services within ~1 hour of detection. Automated anomalous-withdrawal monitors can further shrink the exposure window before a manual response.