Deposit Signal / Locked-Value Mismatch
- Name: deposit signal / locked-value mismatch
- Category: exploit pattern / bridge security failure / source-side value-authentication failure / event ambiguity
- Summary: Some bridges treat a source-chain deposit event, handler record, or relayer-visible message as if it were proof that real value was locked or burned. The bug class appears when that signal can be emitted without the matching asset movement actually happening, or when a real message arrives from a source channel that was never entitled to claim the backing later released. Once
deposit recordeddrifts away fromassets really moved on the canonical backing path, the relayer does not need to be malicious and the destination-side contracts do not need a separate bug; they faithfully mint or release assets against fiction. - What it is:
- A bridge relies on source-chain deposit semantics as the first authenticity checkpoint.
- Relayers, listeners, or downstream proposal logic interpret a deposit event / record as proof that custody already happened.
- One reachable call path can emit or register that deposit without enforcing the expected
msg.value, token transfer, burn, or balance delta. - The bridge therefore manufactures a valid-looking cross-chain message from a false source-side fact.
- The destination side then releases custody or mints wrapped assets because it is consuming the bridge’s own poisoned deposit signal.
- Typical preconditions:
- The bridge uses trusted relayers or event listeners that treat source-chain deposit records as authoritative inputs.
- Native-asset and ERC-20 paths share handlers, sentinels, or event schemas.
- Deposit accounting is path-dependent: one entrypoint assumes a previous step already wrapped, transferred, burned, or escrowed the value.
- The implementation does not verify post-condition balance deltas for the asset supposedly being bridged.
- Operator-controlled configuration such as resource mappings, token placeholders, or handler routes can silently change what a given deposit path really means.
- Common vulnerable surfaces:
- bridges where
deposit()anddepositETH()or similar entrypoints emit the same event shape - wrapped-native convenience branches that assume the handler already received WETH / WBNB before bookkeeping runs
- resourceID or token-address mappings that alias native assets to
address(0)or another sentinel - ERC-20 helper paths that trust
safeTransferFrom()or low-level call success without proving code existence or balance movement - relayer stacks that do not distinguish
deposit log emittedfromcustody change completed - handler contracts whose bookkeeping is driven by calldata amounts rather than measured token or native-coin deltas
- bridges where
- Exploit sequence:
- The attacker finds a deposit path whose emitted bridge signal is weaker than the bridge assumes.
- They call that path with crafted calldata, wrong entrypoint selection, zero value, or a path-specific state/configuration mismatch.
- The source-side bridge still emits or records a deposit for the attacker-chosen amount.
- Relayers interpret that artifact as proof that source-chain assets were locked or burned.
- Destination-side proposal execution mints wrapped assets or releases escrowed reserves.
- The attacker cashes out the unbacked assets directly or posts them as collateral elsewhere.
- Variants:
- Ambiguous event reuse — different deposit paths emit the same log, but only one of them actually enforces custody, as in Qubit.
- Native-token sentinel aliasing —
address(0)or another placeholder is valid for one ETH path and accidentally valid for a generic token path too. - Wrapped-native shortcut — the handler skips lock/burn because it assumes wrapping already happened earlier in the call flow, as in Meter Passport.
- Silent transfer success to no-code address — the token-transfer helper reports success even though no token contract existed and no funds moved.
- Configuration drift — an owner or upgrade changes the resource mapping or handler semantics without changing the relayer’s proof model.
- Recorded amount ≠ delivered amount — the bridge stores an attacker-declared amount instead of proving that the same amount entered custody.
- Wrapper-context amount spoof — the relayer or scanner credits outer transaction shell value or wrapper context instead of the canonical router-side receipt, as in THORChain’s 2021-07-15 ETH-router exploit.
- Helper-path deposit authorship leakage — a router-adjacent refund, return, migration, or helper path can still emit a deposit-looking artifact even though it is no longer the canonical custody lane, as in THORChain’s 2021-07-22 ETH-router exploit.
- Wrong-channel deposit truth — the bridge receives a real cross-chain packet, but from a channel whose traffic was never supposed to share redeemability with the canonical escrow-backed channel, as in Secret / Axelar.
Three deposit-truth promotions reviewers should not collapse
-
Some deposit-looking artifact exists
- A log, packet, handler record, memo-bearing inbound, or relayer-visible message was emitted on the source side.
- That only means
something bridge-shaped was recorded.
-
That artifact still counts as proof that canonical backing really moved
- The harder question is whether the exact asset, amount, route, and custody mode the bridge later spends against were actually locked, burned, or escrowed on the canonical path.
- If the bridge cannot answer that precisely, the deposit artifact is already drifting away from custody truth.
-
That accepted deposit truth deserves this much redeemability authority right now
- Even a real custody event should not automatically inherit unlimited mint reach, cross-route fungibility, or immediate deep-reserve release authority.
- This is where route-local redeemability and bounded release matter.
Healthy bridge review gets materially better once teams stop flattening those three promotions into one vague moment called deposit observed.
Case splits worth preserving
- Qubit is the clean
same event, weaker pathversion:deposit()anddepositETH()shared oneDepositsurface, while the ETHresourceIDplus zero-address aliasing let the generic path emit that artifact without matching ETH custody. For the healthier design questionwhat exact post-condition should have defined ETH deposit truth?, pair this case with bridge-deposit-truth-binding. - Meter Passport is the clean
handler assumed wrapping already happenedversion: the bridge credited wrapped-native value because bookkeeping reused a path that expected earlier wrapping and transfer steps to have already completed. The healthier review question is not onlydid the event fire?butwhere exactly was the native-to-wrapper custody mutation proved?It is also a clean lifecycle case for bridge-canonical-path-exclusivity-and-stale-authoring-surface-deauthorization: oncedepositETH()existed as the intended native intake lane, the stale generic lane should have lost the right to publish equivalent wrapped-native deposit truth. - THORChain 2021-07-15 is the clean
outer transaction shell outranked router custodyversion: wrapper compatibility let Bifrost treat top-levelmsg.valueas if the router had received the same ETH. The healthier design question is whether the bridge still anchored credited amount to the router’s own custody artifact instead of to ambient transaction context. - THORChain 2021-07-22 is the clean
router-adjacent helper path still spoke with deposit authorityversion: areturnVaultAssets()-style flow could still emit a deposit-looking artifact, then ordinarybad memo -> refundlogic spent live inventory against that fake inbound. For the sharper design questionwhich exact source-side path was allowed to author inbound truth at all?, pair this case with bridge-source-provenance-bundle-and-authoring-surface-discipline. - Secret / Axelar is the clean
real packet, wrong redeemability domainversion: packets were real, but the source channel was not the one entitled to mint against Axelar-backed saToken reserves. For the healthier design questionwhy did one route inherit another route's balance sheet?, pair this case with bridge-route-local-redeemability-domain-discipline.
These cousins all belong in the same family because the bridge promoted a weaker source-side artifact into redeemable truth, but they point at different healthier follow-up questions: did value move?, who was allowed to publish deposit truth?, and which route's backing domain did that truth belong to?
- Detection heuristics:
- For every bridge deposit path, ask: what exact post-condition proves the bridge now controls the stated amount?
- Diff event schemas across native, wrapped-native, ERC-20, and burn/unlock flows; if relayers cannot distinguish them, assume danger.
- Review every sentinel asset mapping (
address(0), pseudo-WETH placeholders, special resource IDs) as part of the trust boundary, not as implementation detail. - Trace whether a deposit path measures token/native balance deltas or merely assumes a previous step succeeded.
- Treat owner-controlled resource remaps and handler reconfiguration as security-critical changes even when no verifier code changes.
- Defenses:
- Make the source-side proof-of-lock invariant explicit: emit deposit records only after measured custody change succeeds.
- Use distinct events and distinct handlers for materially different custody assumptions such as native-value wrapping versus ERC-20
transferFrom(). - Reject zero-code token addresses and sentinel aliases on generic token paths.
- Verify balance deltas or wrapped-asset mint/burn outcomes instead of trusting control-flow assumptions.
- Couple relayer logic to the stronger invariant (
value moved) rather than the weaker artifact (event emitted). - Put high-friction review around resource remaps, handler upgrades, and native-asset convenience features, because they silently redefine what a deposit record means.
What sound design looks like
- The safest bridge artifact is authored only by the canonical custody-changing path, not by helper, refund, wrapper-adjacent, migration, or compatibility flows that merely look deposit-like.
- The credited amount should come from measured custody change at the bridge core itself — native balance received, token balance delta, or canonical burn result — rather than from outer transaction context, calldata amounts, or assumptions about a previous wrapping step.
- Relayers should be able to recover emitter, asset, amount, and custody semantics from one canonical artifact without relying on operational folklore such as
this event usually means value moved. - Distinct custody semantics deserve distinct event surfaces; if materially different paths share one relay-authoritative event, the bridge is already asking listeners to guess.
- If the same nominal asset can arrive over multiple routes, channels, or peers, the bridge should keep those liabilities route-local until it has explicit proof they share the same backing bucket and redeemability semantics. Shared wrapper names or bare denoms are not enough. See bridge-route-local-redeemability-domain-discipline.
- The separate blast-radius question matters too: one bad deposit-truth event should not automatically command large immediate mint or release authority before anyone can react. For that containment layer, pair this note with bridge-bounded-release-design.
- For the positive-design companion focused on this narrower source-side question, see bridge-deposit-truth-binding.
- When the sharper question becomes
which exact source-side speaker set and handler path were allowed to author deposit truth at all?, pair this note with bridge-source-provenance-bundle-and-authoring-surface-discipline. - High-signal incidents:
- unbacked qXETH mint (2022-01-27) —
deposit()anddepositETH()shared oneDepositevent surface, the ETHresourceIDhad been remapped toaddress(0), and the generic path could emit a seemingly valid deposit withmsg.value == 0. - unbacked BNB and WETH mint (2022-02-05) — a wrapped-native handler skipped lock/burn because it assumed the native coin had already been wrapped and transferred in, but the generic deposit path could still reach that bookkeeping with attacker-chosen amounts.
- [[../../../incidents/bridges-crosschain/thorchain-eth-router-msg-value-spoof-fake-deposit-swap-refund-drain-2021-07-15|THORChain ETH Router
msg.valuespoof / fake-deposit swap+refund drain (2021-07-15)]] — a wrapper contract in front of the router let Bifrost treat outer transaction value as if the router had actually received the same ETH, so fake inbounds bought real ERC-20 inventory and later powered refunds too. - THORChain ETH Router fake-deposit refund drain (2021-07-22) — a router-adjacent
returnVaultAssets()flow could still emit a deposit-looking event with attacker-chosen memo data, so Bifrost accepted a fake inbound and THORChain’s own refund logic released real ERC-20 inventory. - unbacked saToken mint (2026-06-10) — the IBC-flavored version where the inbound packets were real, but the Secret-side bridge forgot to bind allow-listed denoms to Axelar’s canonical source channel and escrow, so a fake chain’s packets minted saTokens that the real Axelar redemption path later honored.
- unbacked qXETH mint (2022-01-27) —
Failure-prevention checklist
- Author exactly one relay-authoritative deposit artifact per custody model, and emit it only after the bridge core has measured the matching balance increase, burn, or escrow transition.
- Split native-asset, wrapped-native, ERC-20, and cross-channel receipt paths when their custody assumptions differ. Distinct invariants deserve distinct code paths, event schemas, and relayer decoders.
- Treat
address(0), pseudo-native placeholders, resource IDs, denom traces, and channel IDs as security-critical identity inputs. Generic token paths should reject sentinel values that are only meaningful in special-case branches. - Compute credited amounts from observed deltas at the custody boundary instead of from calldata, outer
msg.value, helper-return booleans, or assumptions about a prior wrapping step. - For token transfers, prove code existence and post-transfer balance movement; do not let low-level success, permissive wrappers, or non-standard token semantics stand in for
assets arrived. - Bind each redeemable asset to one canonical source route: source chain, source contract, source channel, asset identifier, and custody mode. Configuration changes to any of those fields should be high-friction, explicitly reviewed operations.
- Force relayers and proposal builders to parse the stronger fact, not the easier one. If an event does not fully encode the custody semantics needed for redemption, it is not safe to relay as bridge truth.
- Add reconciliation between destination liabilities and source-side escrow / burn totals quickly enough to catch counterfeit minting before downstream lending markets or pools absorb the loss.
- Put blast-radius limits beneath deposit truth failures: per-asset mint caps, route throttles, delayed large releases, and fast pauses on routes whose deposit semantics become suspect.
- Test convenience paths adversarially: wrappers, refunds, migration helpers, and generalized handlers should not be able to author a deposit-looking artifact unless they also satisfy the canonical lock-or-burn invariant.
Audit prompts
- For each deposit entrypoint, what exact state transition proves the bridge now controls redeemable value, and where is that fact measured?
- Can two materially different custody paths emit the same event or create the same relay-visible record? If yes, how does the relayer distinguish the stronger path from the weaker one?
- Does any bridge path credit amount from calldata, memo fields, router context, or outer transaction value instead of from measured native/token balance change at the bridge boundary?
- Which sentinel addresses, resource IDs, denom mappings, or channel identifiers are valid only in special cases, and can a generic path accidentally accept them too?
- Can a helper branch report successful custody when the token contract does not exist, the transfer returned a misleading value, or the funds landed somewhere other than canonical escrow?
- What configuration change would silently redefine what a deposit record means: token remap, handler swap, denom allow-list update, channel change, wrapper toggle, or upgrade? How is that reviewed and monitored?
- If the bridge receives a real packet or event from the wrong source contract or channel, where is redeemability denied?
- Can refunds, rollbacks, migration utilities, or router-adjacent admin flows emit artifacts that downstream relayers would mistake for fresh deposits?
- Is there a continuous supply-versus-backing reconciliation process, and does it break down by route so operators can isolate which deposit semantics have failed?
- If a counterfeit deposit lands, what control stops the next thousand: route pause, mint cap, watcher veto, relayer quarantine, or nothing?
Lessons that should already be standard
Deposit observedis not a security fact;bridge balance changed on the canonical custody pathis. Bridges that confuse the two manufacture their own forged proofs.- Shared events across different custody semantics are usually a liability, not a convenience. If listeners need folklore to know which path really moved value, the interface is already too weak.
- Native-asset convenience features are part of the trust boundary. Sentinel addresses, wrapper shortcuts, and generalized handlers routinely turn ergonomic code into counterfeit-deposit surface.
- A relayer can be perfectly honest and still mint against fiction if the protocol hands it an under-constrained artifact. Source-side semantic precision matters as much as destination-side proof verification.
- Configuration is not just operations. Resource mappings, denom/channel bindings, and handler routes often decide which source-side facts are redeemable, so they deserve verifier-grade review.
- Post-condition measurement beats control-flow confidence. The bridge should prove that value arrived, not assume some earlier branch must have made it happen.
- Counterfeit mint detection has to be route-aware and fast. Once fake assets circulate into lending venues or deep liquidity pools, the accounting bug becomes system-wide loss socialization.
- The safest bridge deposit model is boring: one canonical path, one measured custody change, one unambiguous artifact, and no helper route that can author equivalent truth on cheaper terms.
Where this pattern stops
- Use message-source-authentication-failure when the sharper lie is who authored the bridge artifact at all — wrong emitter contract, wrong helper path, wrong channel, wrong batch provenance, or forged bridge-looking message material — even if the artifact looked structurally valid once emitted.
- Stay with deposit signal / locked-value mismatch when the decisive failure is the bridge’s own source-side deposit artifact did not actually prove matching custody or burn. Qubit, Meter Passport, and THORChain’s 2021-07-15
msg.valuespoof all live here because the bridge promoted a weak or misleading custody signal into redeemable truth. - Use local-mint-authority-substitution when the source-side deposit truth may be fine or irrelevant, but a destination-side quota, allowance, signer-maintained ceiling, or fee-gated mint lane quietly becomes enough to print supply anyway, as in ChainSwap.
- Use bridge-verification-failure when the source-side deposit semantics were fine enough, but the destination-side verifier later accepted a forged root, forged signature set, poisoned registry, or other counterfeit bridge truth object.
- Pair this note with bridge-route-local-redeemability-domain-discipline when the packet or deposit is real yet still belongs to the wrong redeemability bucket. Secret / Axelar sits on that boundary: the packet was authentic IBC traffic, but the bridge forgot to keep Axelar-backed redeemability route-local.
- Pair this note with bridge-canonical-path-exclusivity-and-stale-authoring-surface-deauthorization when the technical fix is mostly about making the healthier custody lane exclusive and stripping stale generic or helper paths of the right to publish equivalent deposit truth.
Internal linkages
- Parent bridge-wide framing: bridge-verification-failure.
- Positive-design companion: bridge-deposit-truth-binding.
- Positive-design companion: bridge-source-provenance-bundle-and-authoring-surface-discipline — useful when the sharper follow-up is why stale generic routes, refund helpers, wrong channels, or non-canonical handler paths were still allowed to publish deposit authority at all.
- Positive-design companion: bridge-canonical-path-exclusivity-and-stale-authoring-surface-deauthorization — useful when the sharper follow-up is why a bridge that already knew the healthier deposit lane never made that lane exclusive.
- Positive-design companion: bridge-route-local-redeemability-domain-discipline — useful when the sharper follow-up is why multiple routes, channels, or peers were allowed to share one redeemability domain in the first place.
- Positive-design companion: bridge-bounded-release-design — useful when the sharper follow-up is why one counterfeit deposit artifact was still allowed to mint or release so much value before operators could isolate the route.
- Adjacent provenance-focused note: message-source-authentication-failure.
- Best current exemplars: qubit-finance-qbridge-zero-value-deposit-event-spoof-2022-01-27, meter-passport-wrapped-native-deposit-path-unbacked-bnb-weth-mint-2022-02-05, thorchain-eth-router-msg-value-spoof-fake-deposit-swap-refund-drain-2021-07-15, thorchain-eth-router-fake-deposit-refund-drain-2021-07-22, and secret-network-axelar-bridge-cw20-ics20-source-channel-validation-omission-unbacked-satoken-mint-2026-06-10.
Control surface
-
The leverage sits at the point where the bridge converts
user called depositintobridge now owns redeemable value. -
In this family, the destination side is often working exactly as designed. The lie is created earlier, when source-side bookkeeping claims custody that never actually happened.
-
These incidents are easy to mislabel as relayer failure. The deeper problem is semantic: the protocol gave relayers an artifact that looked like proof but was only a log of an under-constrained code path.
-
Sources:
- https://medium.com/@QubitFin/protocol-exploit-report-305c34540fa3
- https://qbt.wiki/en/incident/technical-analysis/
- https://medium.com/meter-io/post-mortem-report-meter-passport-12af6b50393d
- https://docs.meter.io/passport/technical-guideline-for-meter-passport
- https://raw.githubusercontent.com/meterio/chainbridge-solidity-v1.0.0-eth/master/contracts/handlers/ERC20Handler.sol
- https://blog.thorchain.org/post-mortem-eth-router-exploits-1-2-and-premature-return-to-trading-incident/
- https://rekt.news/thorchain-rekt2
- https://docs.thorchain.org/developers/transaction-memos
- https://forum.scrt.network/t/security-incident-axelar-secret-ibc-bridge-exploit-june-10-2026/7995
- https://www.commonprefix.com/blog/secret-network-exploit
-
Last reviewed: 2026-07-30 UTC