# Cross-Chain Operations

Detailed technical flows for minting, burning, and transferring Tortuga tokens across chains.


# Operation Types

Operation Direction Description
Mint ICP → External Create tokens on external chain
Burn External → ICP Destroy tokens on external chain, credit ICP
Cross-chain Transfer Chain A → Chain B Move tokens between external chains

# Mint Operation

Minting creates tokens on an external chain for a KYC-verified user.

# Flow Diagram

sequenceDiagram
    participant User
    participant ML as Master Ledger
    participant KYC as KYC Registry
    participant CF as Chain Fusion
    participant EXT as External Chain

    User->>ML: request_mint(token, amount, chain, address)
    ML->>KYC: is_verified(user)
    KYC-->>ML: true

    ML->>ML: Check balance on ICP
    ML->>ML: Lock tokens
    ML->>CF: request_mint(token, amount, chain, address)

    CF->>CF: Build transaction
    CF->>CF: Request threshold signature
    Note over CF: ICP nodes sign collectively

    CF->>EXT: Submit signed transaction
    EXT-->>CF: tx_hash

    CF->>CF: Monitor for confirmation
    EXT-->>CF: Confirmed (N blocks)

    CF->>ML: confirm_mint(request_id, tx_hash)
    ML->>ML: Update balances
    ML-->>User: Success

# Request Structure

type MintRequest = record {
    token_id : TokenId;
    amount : nat;
    target_chain : Chain;
    recipient_address : Text;   // Chain-specific format
    memo : opt Text;
};

// EVM address: "0x742d35Cc6634C0532925a3b844Bc9e7595f..."
// Solana address: "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83T..."
// Cosmos address: "osmo1abc123..."

# Validation Steps

  1. KYC Check: User must be verified
  2. Balance Check: Sufficient ICP balance
  3. Address Validation: Valid format for target chain
  4. Token Status: Token must be active (not suspended/matured)
  5. Chain Status: Target chain must be active

# Burn Operation

Burning destroys tokens on an external chain and credits the user on ICP.

# Flow Diagram

sequenceDiagram
    participant User
    participant EXT as External Chain
    participant CF as Chain Fusion
    participant ML as Master Ledger
    participant KYC as KYC Registry

    User->>EXT: Call burn(amount)
    EXT->>EXT: Burn tokens
    EXT->>EXT: Emit Burn event

    Note over CF: Chain monitor detects event
    CF->>EXT: Fetch event details
    CF->>CF: Verify event authenticity
    CF->>CF: Wait for finality

    CF->>ML: report_burn(user, token, amount, tx_hash)
    ML->>KYC: is_verified(user)
    KYC-->>ML: true
    ML->>ML: Credit ICP balance
    ML-->>CF: Confirmed

    Note over User: Balance updated on ICP

# Burn Event Detection

Chain Fusion monitors external chains for burn events:

EVM Event:

event Burn(
    address indexed from,
    uint256 amount,
    bytes32 icpPrincipal
);

Event Processing:

type BurnEvent = record {
    chain : Chain;
    tx_hash : Text;
    block_number : nat64;
    log_index : nat32;
    burner : Text;              // External chain address
    amount : nat;
    icp_principal : Principal;  // Encoded in event data
};

# Finality Requirements

Chain Finality Wait Time
Ethereum 12 blocks ~2.4 minutes
Base 12 blocks ~24 seconds
Arbitrum 12 blocks ~3 seconds
Solana 32 slots ~12 seconds
Osmosis 1 block ~6 seconds

# Cross-Chain Transfer

Moving tokens from one external chain to another.

# Flow Diagram

sequenceDiagram
    participant User
    participant ChainA as Source Chain
    participant CF as Chain Fusion
    participant ML as Master Ledger
    participant ChainB as Target Chain

    User->>ChainA: burn(amount, targetChain, targetAddress)
    ChainA->>ChainA: Burn tokens

    CF->>ChainA: Detect burn event
    CF->>CF: Wait for finality
    CF->>ML: Report burn

    ML->>ML: Update balance (ChainA → pending)
    ML->>CF: Request mint on ChainB

    CF->>CF: Build transaction for ChainB
    CF->>CF: Threshold signature
    CF->>ChainB: Submit mint transaction

    ChainB-->>CF: Confirmed
    CF->>ML: Confirm mint

    ML->>ML: Update balance (pending → ChainB)

# Cross-Chain Message Format

type CrossChainMessage = record {
    source_chain : Chain;
    source_tx_hash : Text;
    target_chain : Chain;
    target_address : Text;
    token_id : TokenId;
    amount : nat;
    sender_principal : Principal;
    nonce : nat64;
};

# Transaction Building

# EVM Transaction

type EvmTransaction = record {
    chain_id : nat64;
    nonce : nat64;
    max_priority_fee_per_gas : nat64;
    max_fee_per_gas : nat64;
    gas_limit : nat64;
    to : Text;                  // Contract address
    value : nat;                // Always 0 for token ops
    data : blob;                // Encoded function call
};

// Mint function call
// mint(address to, uint256 amount)
// Selector: 0x40c10f19

# Solana Transaction

type SolanaTransaction = record {
    recent_blockhash : Text;
    instructions : vec SolanaInstruction;
    signers : vec Text;
};

type SolanaInstruction = record {
    program_id : Text;
    accounts : vec AccountMeta;
    data : blob;
};

# Cosmos Transaction

type CosmosTransaction = record {
    chain_id : Text;
    account_number : nat64;
    sequence : nat64;
    fee : CosmosFee;
    msgs : vec CosmosMsg;
    memo : Text;
};

type CosmosMsg = variant {
    MsgExecuteContract : record {
        sender : Text;
        contract : Text;
        msg : blob;             // JSON encoded
        funds : vec Coin;
    };
};

# Signature Schemes

# ECDSA (EVM, Cosmos)

flowchart TB
    subgraph Signing Process
        TX[Transaction Hash] --> NODES[ICP Nodes]
        NODES --> SHARE1[Signature Share 1]
        NODES --> SHARE2[Signature Share 2]
        NODES --> SHARE3[Signature Share N]
        SHARE1 & SHARE2 & SHARE3 --> AGG[Aggregation]
        AGG --> SIG[ECDSA Signature]
    end

    SIG --> VERIFY[Verify on Chain]

Signature Format:

type EcdsaSignature = record {
    r : blob;   // 32 bytes
    s : blob;   // 32 bytes
    v : nat8;   // Recovery ID
};

# EdDSA (Solana)

type EddsaSignature = record {
    signature : blob;   // 64 bytes
};

# Nonce Management

# EVM Nonce Tracking

type NonceManager = record {
    chain : EvmChain;
    current_nonce : nat64;
    pending_txs : vec PendingTx;
};

type PendingTx = record {
    nonce : nat64;
    tx_hash : opt Text;
    status : TxStatus;
    created_at : Timestamp;
};

Nonce Handling:

flowchart TB
    REQ[New TX Request] --> GET[Get Current Nonce]
    GET --> INC[Increment Nonce]
    INC --> BUILD[Build TX with Nonce]
    BUILD --> SIGN[Sign TX]
    SIGN --> SUBMIT[Submit TX]

    SUBMIT --> CONFIRM{Confirmed?}
    CONFIRM -->|Yes| DONE[Done]
    CONFIRM -->|No, Timeout| REPLACE[Replace TX]
    REPLACE --> BUILD

# Error Recovery

# Stuck Transaction

flowchart TB
    STUCK[TX Stuck in Mempool] --> CHECK{Check Status}
    CHECK -->|Still Pending| WAIT{Wait Threshold?}
    WAIT -->|No| CHECK
    WAIT -->|Yes| REPLACE[Build Replacement TX]
    REPLACE --> HIGHER[Higher Gas Price]
    HIGHER --> RESIGN[Re-sign TX]
    RESIGN --> RESUBMIT[Resubmit]

    CHECK -->|Dropped| REBUILD[Rebuild TX]
    REBUILD --> RESIGN

# Failed Transaction

type TxFailure = variant {
    InsufficientGas;
    Reverted : Text;            // Revert reason
    NonceConflict;
    NetworkError : Text;
    SignatureFailed;
};

type RecoveryAction = variant {
    Retry;
    RetryWithHigherGas;
    RetryWithNewNonce;
    ManualReview;
    Abort;
};

# Rate Limiting & Batching

# Rate Limits

Chain Max TPS Batch Size
Ethereum 1 1
Base 5 10
Solana 10 20
Osmosis 3 5

# Transaction Batching

For chains that support it, multiple mints can be batched:

flowchart LR
    Q[TX Queue] --> BATCH[Batch Builder]
    BATCH --> CHECK{Batch Full?}
    CHECK -->|Yes| SIGN[Sign Batch]
    CHECK -->|No| WAIT[Wait]
    WAIT --> TIMEOUT{Timeout?}
    TIMEOUT -->|Yes| SIGN
    TIMEOUT -->|No| Q
    SIGN --> SUBMIT[Submit]

# Monitoring & Alerts

# Metrics Tracked

Metric Alert Threshold
Pending TX Age > 10 minutes
Failed TX Rate > 5% per hour
Gas Price > 200 gwei (ETH)
Signature Time > 30 seconds
Chain Sync Lag > 100 blocks

# Health Check

candid
service : {
    health_check : () -> (HealthStatus) query;
}

type HealthStatus = record {
    overall : Status;
    chains : vec ChainHealth;
    pending_txs : nat32;
    last_successful_tx : Timestamp;
};

type ChainHealth = record {
    chain : Chain;
    status : Status;
    last_block : nat64;
    pending_count : nat32;
    error_rate : float64;
};