Files
proxmox/docs/07-ccip/CW_BRIDGE_APPROACH.md
defiQUG 4ebf2d7902
Some checks failed
Deploy to Phoenix / validate (push) Failing after 1s
Deploy to Phoenix / deploy (push) Has been skipped
Deploy to Phoenix / deploy-atomic-swap-dapp (push) Has been skipped
Deploy to Phoenix / cloudflare (push) Has been skipped
chore(repo): sync operator workspace (config, scripts, docs, multi-chain)
Add optional Cosmos/Engine-X/act-runner templates, CWUSDC/EI-matrix tooling,
non-EVM route planner in multi-chain-execution (tests passing), token list and
extraction updates, and documentation (MetaMask matrix, GRU/CWUSDC packets).

Ignore institutional evidence tarballs/sha256 under reports/status.

Validated with: bash scripts/verify/run-all-validation.sh --skip-genesis

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 16:25:08 -07:00

4.9 KiB
Raw Blame History

cW* Bridge Approach (Chosen Strategy)

Created: 2026-02-27
Status: Decided — Option 2 (dedicated cW* receiver)
Related: CW_BRIDGE_TASK_LIST.md


1. Decision (A1)

Chosen: Option 2 — Deploy dedicated cW receiver per chain.*

  • Option 1 (extend existing bridge): Would require changing CCIPWETH9Bridge / CCIPRelayBridge to accept more than WETH9 and mint cW* in ccipReceive. That mixes WETH and cW* in one contract and complicates upgrades.
  • Option 2 (dedicated receiver): Use a contract that only handles cW* mint-on-receive and burn-on-send (e.g. TwoWayTokenBridgeL2 or a minimal CCIPReceiverCW). Keeps WETH bridges unchanged; cW* flow is separate and easier to reason about.

Concrete choice: Use CWMultiTokenBridgeL1 on Chain 138 and CWMultiTokenBridgeL2 on each active public mesh chain. This is the preferred implementation because one receiver address can support the full cW* family through canonical-to-mirrored token-pair configuration. TwoWayTokenBridgeL2 remains a narrow per-token fallback. CompliantWrappedToken is extended with burnFrom so outbound burn-and-send flows work.


2. Flow 138 → chain (lock c* on 138, mint cW* on destination)

  1. User on Chain 138 locks cUSDT (or cUSDC) in a sender contract (e.g. UniversalCCIPBridge, or a dedicated c*→cW* bridge on 138).
  2. Sender sends a CCIP message to the destination chain with:
    • Receiver: Dedicated cW* receiver, preferably CWMultiTokenBridgeL2 on that chain.
    • Data: abi.encode(canonicalToken, recipient, amount).
    • Token amounts: Either none (lock-and-mint: 138 locks c*, destination mints cW*) or source token as specified by the bridge design.
  3. On destination chain, the cW receiver*s ccipReceive is called by the CCIP router. It decodes (canonicalToken, recipient, amount), resolves the configured mirrored cW* token, and mints that token to the recipient (receiver must have MINTER_ROLE on the cW* token).
  4. User on destination receives cWUSDT.

Contracts implementing receive: Dedicated cW* receiver, preferably CWMultiTokenBridgeL2 with canonical-to-mirrored token pairs configured. Not CCIPWETH9Bridge / CCIPRelayBridge (they remain WETH-only).

Contracts implementing send (138 side): CWMultiTokenBridgeL1, which locks supported canonical c* tokens on Chain 138 and sends CCIP messages to the configured CWMultiTokenBridgeL2 receiver on the target chain.


3. Flow chain → 138 (burn cW* on chain, release c* on 138)

  1. User on destination chain calls the cW receiver*s outbound function (CWMultiTokenBridgeL2.burnAndSend(mirroredToken, destSelector, recipient, amount)).
  2. Receiver burns cW* from the user (cW*.burnFrom(user, amount)) and sends a CCIP message to Chain 138 with receiver = L1 bridge and data (canonicalToken, recipient, amount).
  3. On Chain 138, the L1 bridge (or release contract) receives the message and releases cUSDT to the recipient (e.g. transfer from escrow or mint if L1 is mintable).

Contracts implementing burn-and-send: Same dedicated cW* receiver (CWMultiTokenBridgeL2) that has BURNER_ROLE on each configured cW* token and implements burnAndSend.

Contracts implementing receive on 138: CWMultiTokenBridgeL1, which verifies the configured peer and releases the locked canonical c* token to the recipient.


4. Contract summary

Role Contract(s)
cW token (destination chain)* CompliantWrappedToken (cWUSDT, cWUSDC, and broader cW* family). MINTER_ROLE and BURNER_ROLE granted to CWMultiTokenBridgeL2.
Receive on destination (mint cW)* CWMultiTokenBridgeL2. Constructor(sendRouter, receiveRouter, feeToken). Implements ccipReceive -> resolve mirrored token -> mint(recipient, amount).
Send from destination (burn cW, send CCIP)* Same CWMultiTokenBridgeL2. burnAndSend(mirroredToken, ...) -> burnFrom(user) -> ccipSend to 138.
Send from 138 (lock c, send CCIP)* CWMultiTokenBridgeL1. Receiver address = CWMultiTokenBridgeL2 on destination.
Receive on 138 (release c)* CWMultiTokenBridgeL1 releases locked canonical c* after configured peer verification.

5. References