# Kaleido Tether and Mirror Pattern Implementation **Date**: 2025-12-11 **Reference**: Kaleido's cross-chain architecture patterns --- ## 📚 Understanding Kaleido's Patterns ### **Tether Contract** (State Anchoring) In Kaleido's architecture, a **Tether** contract is deployed on a public Ethereum network (e.g., Mainnet) that: - Stores signed state proofs from a private blockchain network - Creates an immutable, verifiable record of the private chain's state - Anchors the private chain's state to the public network at specific intervals - Provides security and transparency by making state proofs publicly verifiable - Prevents collusion by requiring collective signatures from all nodes **Purpose**: State anchoring and integrity verification across chains --- ### **Mirror Contract** (Address Registry) In Kaleido's architecture, a **Mirror** contract: - Maintains a registry of mirrored token/contract addresses across chains - Maps source chain addresses to destination chain addresses - Provides replay protection for cross-chain operations - Enables address resolution for cross-chain interactions **Purpose**: Address mapping and cross-chain contract resolution --- ## 🔍 Implementation in This Codebase ### 1. MirrorManager Contract ✅ **File**: `contracts/mirror/MirrorManager.sol` **Status**: ✅ Available, ❌ Not deployed to Mainnet **Functionality**: - Registry of mirrored token/contract addresses across chains - Mapping: `(sourceChain, sourceAddress) => (destChain => destAddress)` - Replay protection via `processed` mapping - Pausability for emergency stops - Admin-controlled configuration **Kaleido Pattern**: ✅ **Implements Mirror pattern** **Deployment**: ```bash forge script script/DeployMirrorManager.s.sol \ --rpc-url $ETH_MAINNET_RPC_URL \ --private-key $PRIVATE_KEY \ --broadcast \ --verify ``` **Required Environment Variables**: - `MIRROR_ADMIN` - Admin address (multisig recommended) --- ### 2. TwoWayTokenBridge (Tether-like Pattern) ✅ **Files**: - `contracts/bridge/TwoWayTokenBridgeL1.sol` (Mainnet/L1 side) - `contracts/bridge/TwoWayTokenBridgeL2.sol` (Chain-138/L2 side) **Status**: ✅ Available, ❌ Not deployed to Mainnet **Functionality**: - **L1 Side**: Locks canonical tokens and sends CCIP messages to mint on L2 - **L2 Side**: Mints mirrored tokens on inbound, burns on outbound - State synchronization via CCIP messages - Replay protection - Destination chain configuration **Kaleido Pattern**: ✅ **Implements Tether-like pattern** (state synchronization) **Deployment**: ```bash forge script script/DeployTwoWayBridge.s.sol \ --rpc-url $ETH_MAINNET_RPC_URL \ --private-key $PRIVATE_KEY \ --broadcast \ --verify ``` **Required Environment Variables**: - `CCIP_ROUTER` - CCIP router address (set) - `CCIP_FEE_TOKEN` - LINK token address (set) - `BRIDGE_L1_TOKEN` - Canonical token on Mainnet (NOT SET) - `BRIDGE_L2_TOKEN` - Mintable token on Chain-138 (NOT SET) --- ## 🔄 Relationship Between Contracts ### MirrorManager + TwoWayTokenBridge 1. **MirrorManager** maintains the address registry: - Maps Mainnet token addresses to Chain-138 addresses - Used by other contracts to resolve cross-chain addresses 2. **TwoWayTokenBridge** handles token transfers: - Uses MirrorManager to resolve destination addresses - Locks tokens on L1, mints on L2 (or vice versa) - Maintains state synchronization via CCIP ### Typical Flow: ``` User on Mainnet ↓ TwoWayTokenBridgeL1.lockAndSend() ↓ CCIP Message → Chain-138 ↓ TwoWayTokenBridgeL2.ccipReceive() ↓ MirrorManager.getMirror() → Resolve address ↓ Mint mirrored tokens on Chain-138 ``` --- ## 📋 Deployment Status ### ✅ Available Contracts | Contract | Pattern | Status | Deployment Script | |----------|---------|--------|------------------| | **MirrorManager** | Mirror | ❌ Not Deployed | `script/DeployMirrorManager.s.sol` | | **TwoWayTokenBridgeL1** | Tether-like | ❌ Not Deployed | `script/DeployTwoWayBridge.s.sol` | | **TwoWayTokenBridgeL2** | Tether-like | ❌ Not Deployed | `script/DeployTwoWayBridge.s.sol` | ### ⚠️ Missing Configuration **MirrorManager**: - `MIRROR_ADMIN` - Not set in `.env` **TwoWayTokenBridge**: - `BRIDGE_L1_TOKEN` - Not set in `.env` - `BRIDGE_L2_TOKEN` - Not set in `.env` --- ## 🚀 Deployment Plan ### Step 1: Deploy MirrorManager ```bash # Set admin address (multisig recommended) export MIRROR_ADMIN=0x... # Deploy forge script script/DeployMirrorManager.s.sol \ --rpc-url $ETH_MAINNET_RPC_URL \ --private-key $PRIVATE_KEY \ --broadcast \ --verify # Update .env echo "MIRRORMANAGER_MAINNET=" >> .env ``` ### Step 2: Deploy TwoWayTokenBridge ```bash # Set token addresses export BRIDGE_L1_TOKEN=0x... # Canonical token on Mainnet export BRIDGE_L2_TOKEN=0x... # Mintable token on Chain-138 # Deploy (deploys both L1 and L2) forge script script/DeployTwoWayBridge.s.sol \ --rpc-url $ETH_MAINNET_RPC_URL \ --private-key $PRIVATE_KEY \ --broadcast \ --verify # Update .env echo "TWOWAY_BRIDGE_L1_MAINNET=" >> .env echo "TWOWAY_BRIDGE_L2_CHAIN138=" >> .env ``` ### Step 3: Configure MirrorManager ```bash # Register bridge addresses in MirrorManager cast send $MIRRORMANAGER_MAINNET \ "setMirror(uint64,address,uint64,address)" \ 1 \ # Mainnet chain selector $TWOWAY_BRIDGE_L1_MAINNET \ 138 \ # Chain-138 selector $TWOWAY_BRIDGE_L2_CHAIN138 \ --rpc-url $ETH_MAINNET_RPC_URL \ --private-key $PRIVATE_KEY ``` ### Step 4: Configure TwoWayTokenBridge ```bash # Configure L1 bridge to point to L2 cast send $TWOWAY_BRIDGE_L1_MAINNET \ "addDestination(uint64,address)" \ 138 \ # Chain-138 selector $TWOWAY_BRIDGE_L2_CHAIN138 \ --rpc-url $ETH_MAINNET_RPC_URL \ --private-key $PRIVATE_KEY # Configure L2 bridge to point to L1 cast send $TWOWAY_BRIDGE_L2_CHAIN138 \ "addDestination(uint64,address)" \ 1 \ # Mainnet selector $TWOWAY_BRIDGE_L1_MAINNET \ --rpc-url $RPC_URL_138 \ --private-key $PRIVATE_KEY ``` --- ## 🔗 Integration with Existing Contracts ### CCIPWETH9Bridge / CCIPWETH10Bridge The existing CCIP bridges can use MirrorManager to: - Resolve destination addresses for cross-chain transfers - Verify address mappings before processing transfers - Maintain consistency across chains ### Example Integration: ```solidity // In CCIPWETH9Bridge MirrorManager mirror = MirrorManager(mirrorManagerAddress); address destBridge = mirror.getMirror( block.chainid, address(this), destChainSelector ); ``` --- ## 📊 Comparison with Kaleido | Feature | Kaleido Pattern | This Implementation | |---------|----------------|---------------------| | **State Anchoring** | Tether Contract | TwoWayTokenBridge | | **Address Registry** | Mirror Contract | MirrorManager | | **Cross-Chain Messaging** | Custom | CCIP (Chainlink) | | **Replay Protection** | ✅ | ✅ | | **Pausability** | ✅ | ✅ | | **Admin Control** | ✅ | ✅ | --- ## ⚠️ Important Notes 1. **MirrorManager** should be deployed before TwoWayTokenBridge for proper address resolution 2. **TwoWayTokenBridge** requires mintable tokens on L2 (Chain-138) 3. Both contracts should use multisig for admin addresses 4. Configure MirrorManager mappings after deployment 5. Test with small amounts before production use --- ## 📚 References - [Kaleido Tether Documentation](https://docs.kaleido.io/kaleido-services/tether/) - [Kaleido Mirror Pattern](https://docs.kaleido.io/) - [CCIP Documentation](https://docs.chain.link/ccip) --- **Last Updated**: 2025-12-11 **Status**: Documentation complete, deployment pending