- Config, docs, scripts, and backup manifests - Submodule refs unchanged (m = modified content in submodules) Made-with: Cursor
4.7 KiB
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 TwoWayTokenBridgeL2 (or equivalent) per (chain, token) — one deployment per chain for cWUSDT and one for cWUSDC, or a generic receiver that supports multiple cW* via message data. CompliantWrappedToken is extended with burnFrom so TwoWayTokenBridgeL2’s outbound burnFrom works (Phase C1).
2. Flow 138 → chain (lock c* on 138, mint cW* on destination)
- User on Chain 138 locks cUSDT (or cUSDC) in a sender contract (e.g. UniversalCCIPBridge, or a dedicated c*→cW* bridge on 138).
- Sender sends a CCIP message to the destination chain with:
- Receiver: Dedicated cW* receiver (e.g. TwoWayTokenBridgeL2 instance for cWUSDT on that chain).
- Data:
abi.encode(recipient, amount)(same as TwoWayTokenBridgeL2). - Token amounts: Either none (lock-and-mint: 138 locks c*, destination mints cW*) or source token as specified by the bridge design.
- On destination chain, the cW receiver*’s
ccipReceiveis called by the CCIP router. It decodes(recipient, amount)and calls cWUSDT.mint(recipient, amount) (receiver must have MINTER_ROLE on the cW* token). - User on destination receives cWUSDT.
Contracts implementing receive: Dedicated cW* receiver (e.g. TwoWayTokenBridgeL2 with mirroredToken = cWUSDT or cWUSDC). Not CCIPWETH9Bridge / CCIPRelayBridge (they remain WETH-only).
Contracts implementing send (138 side): UniversalCCIPBridge (if extended for c* and destination = cW* receiver), or a dedicated “Lock c* and send CCIP” contract that configures receiver = TwoWayTokenBridgeL2 on the target chain.
3. Flow chain → 138 (burn cW* on chain, release c* on 138)
- User on destination chain calls the cW receiver*’s outbound function (e.g. TwoWayTokenBridgeL2.burnAndSend(destSelector, recipient, amount)).
- Receiver burns cW* from the user (
cWUSDT.burnFrom(user, amount)— requires CompliantWrappedToken to implement burnFrom; see Phase C1) and sends a CCIP message to Chain 138 with receiver = L1 bridge and data(recipient, amount). - 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 (TwoWayTokenBridgeL2) that has BURNER_ROLE on the cW* token and implements burnAndSend. CompliantWrappedToken must expose burnFrom for TwoWayTokenBridgeL2.
Contracts implementing receive on 138: L1 bridge or release contract that holds or mints c* and credits the recipient.
4. Contract summary
| Role | Contract(s) |
|---|---|
| cW token (destination chain)* | CompliantWrappedToken (cWUSDT, cWUSDC). MINTER_ROLE and BURNER_ROLE granted to the dedicated receiver (e.g. TwoWayTokenBridgeL2). |
| Receive on destination (mint cW)* | TwoWayTokenBridgeL2 (or CCIPReceiverCW). Constructor(router, cWUSDT, feeToken). Implements ccipReceive → mint(recipient, amount). |
| Send from destination (burn cW, send CCIP)* | Same TwoWayTokenBridgeL2. burnAndSend → burnFrom(user) → ccipSend to 138. |
| Send from 138 (lock c, send CCIP)* | UniversalCCIPBridge (with c* and cW* receiver config) or dedicated lock-and-send contract. Receiver address = TwoWayTokenBridgeL2 on destination. |
| Receive on 138 (release c)* | L1 bridge or release contract (existing or new) that credits recipient when message received from destination chain. |
5. References
- TwoWayTokenBridgeL2.sol — Mint on receive, burnAndSend for outbound.
- CompliantWrappedToken.sol — mint, burn, burnFrom (Phase C1).
- CW_BRIDGE_TASK_LIST.md — Full task list and phases.
- CW_DEPLOY_AND_WIRE_RUNBOOK.md — Operator steps to deploy cW*, wire config, verify.