# CCIP Relay Architecture ## Overview The custom CCIP relay mechanism enables cross-chain message delivery from Chain 138 to Ethereum Mainnet by implementing an off-chain relay service that monitors events and delivers messages to destination chain contracts. ## System Architecture ``` ┌─────────────────┐ │ Chain 138 │ │ │ │ CCIP Router │───MessageSent Event───┐ │ (0xd49B5...) │ │ │ │ │ │ WETH9 Bridge │ │ │ (0xBBb4a...) │ │ │ │ │ │ [User sends │ │ │ 20k WETH9] │ │ └─────────────────┘ │ │ ▼ ┌───────────────────────┐ │ Relay Service │ │ (Off-chain) │ │ │ │ - Event Monitoring │ │ - Message Queue │ │ - Token Mapping │ │ - Message Relay │ └───────────────────────┘ │ │ HTTP/WebSocket │ Transaction │ ▼ ┌──────────────────────────────────────────────────────┐ │ Ethereum Mainnet │ │ │ │ ┌──────────────────┐ ┌──────────────────┐ │ │ │ Relay Router │─────▶│ Relay Bridge │ │ │ │ (Access Control) │ │ (Token Transfer) │ │ │ │ │ │ │ │ │ │ - Authorize │ │ - Receives │ │ │ │ bridges │ │ messages │ │ │ │ - Grant relayer │ │ - Transfers │ │ │ │ roles │ │ WETH9 to │ │ │ └──────────────────┘ │ recipients │ │ │ └──────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────┐ │ │ │ WETH9 Token │ │ │ │ Transfer │ │ │ └──────────────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────┐ │ │ │ Recipient │ │ │ │ Receives 20k │ │ │ │ WETH9 │ │ │ └──────────────────┘ │ └──────────────────────────────────────────────────────┘ ``` ## Components ### 1. Source Chain (Chain 138) **CCIP Router** (`0xd49B579DfC5912fA7CAa76893302c6e58f231431`) - Emits `MessageSent` events when messages are sent - Stores message metadata - Collects fees - **Note**: This is a custom router that simulates CCIP - it only emits events and does not actually relay messages cross-chain **WETH9 Bridge** (`0xBBb4a9202716eAAB3644120001cC46096913a3C8`) - Locks WETH9 tokens from users - Creates CCIP messages - Sends messages via router **WETH9 Token** (`0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2`) - Wrapped Ether token on Chain 138 ### 2. Relay Service (Off-chain) **Event Monitor** - Listens for `MessageSent` events from router - Polls for historical events as fallback - Filters messages for target destination chain (Ethereum Mainnet, chain selector: `5009297550715157269`) **Message Queue** - Queues detected messages - Manages retry logic - Tracks processed/failed messages - Prevents duplicate processing **Token Address Mapping** - Maps source chain token addresses to destination chain addresses - Ensures bridge receives correct token addresses - Currently maps WETH9 Chain 138 → WETH9 Mainnet (same address in this case) **Message Relay** - Constructs `Any2EVMMessage` format with mapped token addresses - Calls `relayMessage` on destination relay router - Handles errors and retries - Monitors transaction status ### 3. Destination Chain (Ethereum Mainnet) **Relay Router** (`0xAd9A228CcEB4cbB612cD165FFB72fE090ff10Afb`) - Receives relayed messages from off-chain service - Authorizes bridge contracts (only authorized bridges can receive messages) - Grants relayer roles (only authorized relayers can call `relayMessage`) - Forwards messages to authorized bridges using interface calls for proper ABI encoding - Emits `MessageRelayed` events **Relay Bridge** (`0xF9A32F37099c582D28b4dE7Fca6eaC1e5259f939`) - Receives messages from relay router - Validates message format - Implements replay protection (tracks processed messageIds) - Transfers WETH9 tokens to recipients - **CRITICAL**: Must be funded with WETH9 tokens to complete transfers - Emits `CrossChainTransferCompleted` events **WETH9 Token** (`0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2`) - Wrapped Ether token on Ethereum Mainnet - Bridge must hold sufficient balance for transfers ## Message Flow 1. **User initiates transfer on Chain 138** - User calls `sendCrossChain()` on bridge - Bridge locks 20,000 WETH9 from user - Bridge creates CCIP message with: - Receiver: Destination bridge address - Data: (recipient, amount, sender, nonce) - TokenAmounts: [{token: WETH9, amount: 20000e18, amountType: 0}] - Bridge calls router's `ccipSend()` - Router emits `MessageSent` event 2. **Relay service detects event** - Service monitors router for `MessageSent` events - Filters for Ethereum Mainnet destination (chain selector: `5009297550715157269`) - Adds message to queue - Logs message detection 3. **Message queued for relay** - Message stored in queue with metadata - Retry count initialized (starts at 0) - Status: pending - Queue size tracked 4. **Relay service processes message** - Service constructs `Any2EVMMessage`: - messageId: From event - sourceChainSelector: 138 (chain ID) - sender: Encoded as bytes - data: Original message data - tokenAmounts: Token addresses mapped to destination chain - Service calls `relayMessage(bridge, message)` on Relay Router (Mainnet) - Transaction sent with relayer's private key - Gas limit: 1,000,000 5. **Relay Router validates and forwards** - Checks relayer has RELAYER_ROLE (AccessControl) - Verifies bridge is authorized - Calls bridge's `ccipReceive(message)` using interface call - Interface call ensures proper ABI encoding for complex structs 6. **Relay Bridge processes message** - Validates messageId (replay protection - checks `processedTransfers`) - Marks message as processed - Validates token amounts (length > 0, token == WETH9, amount > 0) - Decodes recipient from message data - **Transfers WETH9 to recipient** (requires bridge has sufficient balance) - Emits `CrossChainTransferCompleted` event 7. **Recipient receives tokens** - WETH9 balance increased - Transfer complete ## Security Considerations ### Access Control - **Relayer Role**: Only addresses with RELAYER_ROLE can call `relayMessage` on router - **Bridge Authorization**: Only pre-authorized bridges can receive messages - **Admin Controls**: Admin can add/remove bridges and relayers via AccessControl ### Replay Protection - Message IDs tracked in bridge contract (`processedTransfers` mapping) - Each messageId can only be processed once - Prevents duplicate token transfers - Bridge checks `processedTransfers[messageId]` before processing ### Message Validation - Bridge validates token address matches WETH9 on destination chain - Bridge validates amount > 0 - Bridge validates recipient != address(0) - Bridge validates tokenAmounts array has elements ### Token Address Mapping - Source chain token addresses are mapped to destination chain addresses - Prevents invalid token transfers - Currently maps WETH9 Chain 138 → WETH9 Mainnet ### Operational Security - Private keys should be secured (hardware wallet or key management) - Service should run in secure environment - Monitor for failed relays and retry appropriately - Implement rate limiting (future improvement) ### Critical Operational Requirement **Bridge Funding**: The relay bridge MUST be funded with WETH9 tokens before it can complete any transfers. This is the most common reason for failed relays. ## Error Handling ### Relay Service Errors - **Network errors**: Retry with exponential backoff - **Transaction failures**: Log error, retry up to MAX_RETRIES (default: 3) - **Gas estimation failures**: Use fixed gas limit (1,000,000) - **Message encoding errors**: Log error, skip message ### Contract Errors - **Unauthorized relayer**: Grant RELAYER_ROLE in router - **Bridge not authorized**: Authorize bridge in router - **Duplicate message**: Message already processed (expected - skip) - **Insufficient WETH9**: Fund bridge with WETH9 tokens (CRITICAL) - **Invalid token**: Token address mismatch - check token mapping - **Invalid amount**: Amount is zero - invalid message ## Monitoring ### Key Metrics - Messages detected per hour - Messages relayed successfully - Failed relay attempts - Average relay time (from detection to completion) - Bridge WETH9 balance - Gas costs per relay - Queue size ### Alerts - Bridge WETH9 balance below threshold (CRITICAL) - High failure rate (> 5%) - Service downtime - Unprocessed messages in queue - Relayer ETH balance low ### Logging - All events logged to `relay-service.log` - Error logs include full error details - Transaction hashes logged for tracking - Message IDs logged for debugging ## Scalability ### Current Limitations - Single relay instance - Sequential message processing - No message batching - Manual bridge funding ### Future Improvements - Multiple relay instances (high availability) - Parallel message processing - Message batching to reduce gas costs - Priority queue for time-sensitive messages - Automatic bridge funding mechanism - Distributed relay network ## Current Deployment Status ### Contracts Deployed - ✅ Relay Router: `0xAd9A228CcEB4cbB612cD165FFB72fE090ff10Afb` - ✅ Relay Bridge: `0xF9A32F37099c582D28b4dE7Fca6eaC1e5259f939` - ✅ Router configured (bridge authorized, relayer role granted) - ✅ Service running and monitoring ### Operational Status - ✅ Service: Running - ✅ Monitoring: Active - ⚠️ Bridge Funding: **REQUIRED** (must have WETH9 tokens) ### Known Issues - None (all technical issues resolved) - Bridge funding is operational requirement, not a bug ## Related Documentation - [Service README](../../services/relay/README.md) - [Deployment Guide](../../services/relay/DEPLOYMENT_GUIDE.md) - [Investigation Report](INVESTIGATION_REPORT.md)