- Introduced Aggregator.sol for Chainlink-compatible oracle functionality, including round-based updates and access control. - Added OracleWithCCIP.sol to extend Aggregator with CCIP cross-chain messaging capabilities. - Created .gitmodules to include OpenZeppelin contracts as a submodule. - Developed a comprehensive deployment guide in NEXT_STEPS_COMPLETE_GUIDE.md for Phase 2 and smart contract deployment. - Implemented Vite configuration for the orchestration portal, supporting both Vue and React frameworks. - Added server-side logic for the Multi-Cloud Orchestration Portal, including API endpoints for environment management and monitoring. - Created scripts for resource import and usage validation across non-US regions. - Added tests for CCIP error handling and integration to ensure robust functionality. - Included various new files and directories for the orchestration portal and deployment scripts.
282 lines
7.5 KiB
Markdown
282 lines
7.5 KiB
Markdown
# 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=<deployed_address>" >> .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=<l1_address>" >> .env
|
|
echo "TWOWAY_BRIDGE_L2_CHAIN138=<l2_address>" >> .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
|
|
|