Files
proxmox/docs/07-ccip/NON_PREFUNDED_AVAX_MIGRATION_RUNBOOK.md
defiQUG 2a6d3cfc7f
Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
Update submodule references and improve CI workflow
- Update submodule references for explorer-monorepo and smom-dbis-138 to latest commits.
- Modify CI workflow to include shellcheck installation and enforce error severity for script checks.
- Update contract addresses in configuration and documentation to reflect the new canonical addresses for CCIPWETH9Bridge and CCIP Router.
- Revise integration test documentation to align with updated contract addresses and deployment statuses.

Made-with: Cursor
2026-03-24 22:50:52 -07:00

4.2 KiB

Non-Prefunded AVAX Migration Runbook

Date: 2026-03-04
Scope: Replace inventory-backed AVAX settlement behavior with a non-prefunded bridge path for future transfers.

1. Problem Statement

Current 138 -> AVAX flow is inventory-backed:

  • Source bridge on 138 escrows WETH.
  • Destination bridge must already hold AVAX-side WETH to pay recipients.
  • If destination inventory is zero, messages remain unprocessed.

This does not satisfy the requirement "move value to AVAX without pre-funding AVAX bridge inventory."

2. Target Architecture

Use a lock/mint or burn/mint path for the bridged asset, not release-from-inventory.

Recommended implementation in this repo:

  1. Use dedicated receiver model from CW_BRIDGE_APPROACH.md (Option 2).
  2. Bridge a mintable wrapped representation (for example cW* family), not canonical AVAX-side WETH.
  3. Convert destination minted asset to required target assets through DEX routing.

Notes:

  • Canonical WETH itself cannot be minted by your bridge contracts.
  • If you require canonical WETH/AVAX output directly, you must use an external canonical bridge/protocol that supports that asset path.

3. Execution Order

Phase A: Stop Further Loss Exposure

  1. Freeze large 138 -> AVAX sends on inventory-backed bridges.
  2. Add preflight guard: block sends when destination delivery model is inventory-backed and inventory is below requested amount.
  3. Keep BSC relay running only if still needed for legacy pending messages.

Phase B: Recover Existing Stuck Message(s)

  1. Enumerate pending message IDs (processedTransfers == false) on AVAX bridge.
  2. For each pending message, either:
    • fund destination bridge inventory and relay once, or
    • implement explicit source-side refund path (if contract supports it; current WETH9 bridge does not expose one).
  3. Verify each recovered message transitions to processedTransfers == true.

Phase C: Deploy Non-Prefunded Path

  1. Deploy/verify destination mintable token(s) and grant bridge roles:
    • MINTER_ROLE and BURNER_ROLE to dedicated receiver (TwoWayTokenBridgeL2 or equivalent).
  2. Deploy sender/receiver pair:
    • L1 sender/lock bridge on 138.
    • L2 receiver/mint bridge on AVAX.
  3. Configure chain selector mapping and router support for AVAX selector 6433500567565415381.
  4. Wire fee token and fee approvals.
  5. Register token mapping in routing/config files.

Phase D: E2E Validation (Required Before Production)

  1. Test amounts: 0.01, 1, 20 units.
  2. Validate:
    • source escrow/burn,
    • destination mint,
    • no destination inventory dependency,
    • reverse path burn/send works if required.
  3. Run consistency tests for quote/fee, message replay protection, and mapping correctness.

Phase E: Cutover

  1. Mark legacy AVAX inventory-backed route as deprecated.
  2. Update all operator scripts/docs to new route.
  3. Keep monitoring and alerting on:
    • message backlog,
    • mint/burn failures,
    • fee-token depletion.

4. Acceptance Criteria

Migration is complete only when all are true:

  1. A 138 -> AVAX transfer succeeds when destination bridge token inventory is 0.
  2. No relay payout from destination inventory is required.
  3. End-to-end tests pass at small and medium sizes.
  4. Runbooks/scripts no longer route AVAX through legacy inventory-backed path by default.

5. Immediate Operator Commands (Verification)

Check legacy destination dependency:

cast call 0x24293CA562aE1100E60a4640FF49bd656cFf93B4 "processedTransfers(bytes32)(bool)" <message_id> --rpc-url https://avalanche-c-chain.publicnode.com
cast call 0xa4B9DD039565AeD9641D45b57061f99d9cA6Df08 "balanceOf(address)(uint256)" 0x24293CA562aE1100E60a4640FF49bd656cFf93B4 --rpc-url https://avalanche-c-chain.publicnode.com

Check source escrow:

cast call 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 "balanceOf(address)(uint256)" 0xcacfd227A040002e49e2e01626363071324f820a --rpc-url https://rpc-http-pub.d-bis.org
  • docs/07-ccip/CW_BRIDGE_APPROACH.md
  • docs/11-references/CCIP_138_DESTINATION_RECEIVER_BY_CHAIN_AND_TOKEN.md
  • smom-dbis-138/contracts/bridge/TwoWayTokenBridgeL1.sol
  • smom-dbis-138/contracts/bridge/TwoWayTokenBridgeL2.sol
  • smom-dbis-138/contracts/tokens/CompliantWrappedToken.sol