Skip to content

Emergency Rescue Mechanism for Wormhole‑Stuck tBTC #883

@evandrosaturnino

Description

@evandrosaturnino

🛠️ Emergency Rescue Mechanism for Wormhole‑Stuck tBTC

(MixBytes Audit Finding 2.4‑3 – “L1 Redeemer Rescue Inoperable”)

📚 Background

The L1BTCRedeemerWormhole contract currently exposes rescueTbtc() only for tBTC that becomes trapped inside the redeemer itself.
When redemption is initiated from an L2 via Wormhole and fails permanently during on‑L1 validation (e.g., malformed payload), the tBTC remains locked in the Wormhole Token Bridge, not in the redeemer. As a result, the built‑in rescue path is ineffective and funds cannot be recovered without a contract upgrade.

Reference: MixBytes Interim Audit § 2.4 Low – “L1 Redeemer Rescue Inoperable for tBTC Stuck on Wormhole Bridge” (07 Jul 2025).

🔴 Problem Statement

  • Users whose Wormhole VAAs revert on L1 lose access to their bridged tBTC.
  • No on‑chain mechanism exists for the protocol owner or governance to pull those tokens out of the Wormhole bridge contract.
  • Situations that trigger this state include invalid payload formatting, replay attempts, or future logic changes that cause completeTransferWithPayload() to revert.

🎯 Objective

Design and implement a secure, owner‑gated emergency pull‑through rescue pathway that:

  1. Discovers stuck VAAs / token accounts held by the Wormhole Token Bridge.
  2. Claims the tokens via completeTransferWithPayload (or equivalent) without rerunning the failing validation logic.
  3. Forwards the rescued tBTC either
    • (A) into the normal requestRedemption flow or
    • (B) directly to a configurable recovery address.
  4. Emits transparent events for each rescue operation.
  5. Respects robust access‑control (multi‑sig / DAO) to prevent misuse.

📝 Proposed Approach (High‑Level)

Step Description
1. Data Collection Build helper view or script to enumerate VAAs in Wormhole storage that have tokenChain == <L2‑chain‑id> and toAddress == L1BTCRedeemerWormhole.
2. Rescue Function Add rescueStuckWormholeTbtc(bytes[] calldata vaas) callable by onlyOwner / onlyGovernance.
3. Claim & Forward For each VAA: call wormholeTokenBridge.completeTransferWithPayload(vaa) inside a try/catch; on success, route tokens according to config.
4. Safeguards * Re‑entrancy guard
* Event StuckTbtcRescued(bytes32 indexed vaaHash, uint256 amount, address indexed to)
* Time‑lock / multi‑sig on onlyGovernance function.
5. Unit Tests Simulate malformed VAA redemption, confirm rescue recovers funds, verify event data.

🗒️ Open Questions

  1. Destination strategy – forward into the standard redemption pipeline vs. direct payout?
  2. Governance layer – DAO vote, multi‑sig, or dedicated RescueRole?
  3. Batch size / gas limits – maximum VAAs per transaction?
  4. Chain coverage – single‑function for all L2 chains or per‑chain variants?

⏳ Timeline

Design draft 👉 TBD
Implementation PR 👉 TBD (after OpenZeppelin upgrade in #<next‑PR‑id>).


This issue tracks the audit‑mandated rescue functionality deferred from PR <id>.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions