# Minting

Token minting creates the on-chain ERC-3643 representation of a bond on the ICP Master Ledger, following TradFi settlement and delivery of the bond into custody. Supply is fixed and capped to the subscribed amount, linked to the specific ISIN compartment.


# Minting Flow

sequenceDiagram
    participant ISSUER as Issuer
    participant II as Issuer Interface
    participant ML as Master Ledger
    participant STORE as Metadata Store
    participant CF as Chain Fusion
    participant EVM as EVM (Plume / Base / Canton)

    ISSUER->>II: Create Token Request
    II->>II: Validate Issuer Auth
    II->>ML: create_token(params)

    ML->>ML: Validate Parameters
    ML->>ML: Generate Token ID
    ML->>STORE: Store Metadata
    ML->>ML: Mint Initial Supply
    ML->>ML: Assign to Issuer Treasury

    ML-->>II: Token Created
    II-->>ISSUER: Token ID + Details

    Note over CF,EVM: ERC-3643 contracts deployed on live chains
    ISSUER->>CF: Deploy ERC-3643 contracts
    CF->>EVM: Deploy token + Identity Registry + Compliance Module
    EVM-->>CF: Contract addresses

# Token Creation

# Create Token Request

type CreateTokenArgs = record {
    // Bond identification
    isin : Text;
    name : Text;
    symbol : Text;

    // Token parameters
    total_supply : nat;
    decimals : nat8;

    // Bond metadata
    bond_metadata : BondMetadata;

    // ERC-3643 compliance configuration
    compliance_config : ComplianceConfig;
};

type BondMetadata = record {
    issuer_name : Text;
    issuer_id : Text;
    maturity_date : Timestamp;
    coupon_rate_bps : nat16;        // Basis points (e.g., 750 = 7.5%)
    coupon_frequency : CouponFrequency;
    collateral_type : Text;
    collateral_location : Text;
    spv_compartment : Text;         // Luxembourg SPV compartment ID
    prospectus_hash : Text;
    legal_docs_hash : Text;
};

type ComplianceConfig = record {
    kyc_required : bool;
    geographic_restrictions : vec Text;  // e.g., ["US"]
    min_investment : nat;               // EUR/USD 100,000
    accreditation_required : bool;
    lock_period : opt Duration;
    max_holders : opt nat32;
};

# Token ID Generation

Token IDs are deterministically generated from the ISIN:

Token ID = SHA256(ISIN || Canister ID || Timestamp)
         = "trtg_ch1234567890_a1b2c3..."

# Token Data Model

# On-Chain Token Record

type Token = record {
    // Identity
    id : TokenId;
    isin : Text;
    name : Text;
    symbol : Text;

    // Supply
    total_supply : nat;
    circulating_supply : nat;
    decimals : nat8;

    // Metadata
    bond_metadata : BondMetadata;

    // State
    status : TokenStatus;
    created_at : Timestamp;
    created_by : Principal;

    // ERC-3643 compliance
    compliance_config : ComplianceConfig;

    // Treasury
    treasury_balance : nat;

    // Live chain deployments
    chain_deployments : vec ChainDeployment;
};

type ChainDeployment = record {
    chain : Chain;
    token_contract : Text;          // ERC-3643 token address
    identity_registry : Text;       // Identity Registry address
    compliance_module : Text;       // Compliance Module address
};

type TokenStatus = variant {
    Pending;        // Created but not yet active
    Active;         // Transfers enabled on live chains
    Suspended;      // Transfers halted
    Matured;        // Past maturity date
    Redeemed;       // Fully redeemed, tokens burned
};

# Initial State

After minting, the token is in this state:

Field Value
status Pending
total_supply As specified (capped to subscribed amount)
circulating_supply 0
treasury_balance total_supply

# ERC-3643 Contract Deployment

When a token is minted, ERC-3643 contracts are deployed on each live chain:

flowchart TB
    MINT[Token Minted on ICP] --> DEPLOY[Deploy ERC-3643 Contracts]

    DEPLOY --> PLUME_D[Plume Deployment]
    DEPLOY --> BASE_D[Base Deployment]
    DEPLOY --> CANTON_D[Canton Deployment]

    subgraph "Per-Chain Deployment"
        TOKEN[ERC-3643 Token Contract]
        IR[Identity Registry]
        CM[Compliance Module]
    end

    PLUME_D --> TOKEN
    BASE_D --> TOKEN
    CANTON_D --> TOKEN

Each deployment includes:

  • Token Contract: ERC-3643 permissioned token with fixed supply
  • Identity Registry: Wallet-to-identity bindings, synchronized from ICP KYC Registry via Chain Fusion
  • Compliance Module: Per-token rules (investor caps, geographic restrictions, lockups)

# Validation Rules

# Pre-Mint Validation

flowchart TB
    REQ[Create Token Request] --> V1{Valid ISIN?}
    V1 -->|No| E1[Error: Invalid ISIN]
    V1 -->|Yes| V2{ISIN Unique?}

    V2 -->|No| E2[Error: ISIN Exists]
    V2 -->|Yes| V3{Valid Symbol?}

    V3 -->|No| E3[Error: Invalid Symbol]
    V3 -->|Yes| V4{Valid Supply?}

    V4 -->|No| E4[Error: Invalid Supply]
    V4 -->|Yes| V5{Valid Metadata?}

    V5 -->|No| E5[Error: Invalid Metadata]
    V5 -->|Yes| MINT[Proceed with Minting]

# Validation Checks

Check Rule
ISIN Format Valid country code, 9 digits, valid check digit
ISIN Uniqueness Not already registered
Symbol 3-10 uppercase alphanumeric
Supply > 0, ≤ MAX_SUPPLY, matches subscribed amount
Decimals 0-18 (typically 0 for bonds)
Maturity Date Future date
Coupon Rate 0-10000 bps (0-100%)

# Issuer Treasury

After minting, all tokens are held in the issuer's treasury until distribution:

flowchart LR
    MINT[Mint Tokens] --> TREASURY[Issuer Treasury]
    TREASURY --> DIST1[Distribution to Investor A]
    TREASURY --> DIST2[Distribution to Investor B]
    TREASURY --> DIST3[Distribution to Investor C]

# Token Activation

After minting and ERC-3643 contract deployment, the token must be activated before transfers are enabled:

sequenceDiagram
    participant ISSUER as Issuer
    participant ML as Master Ledger

    Note over ISSUER,ML: Token in Pending state

    ISSUER->>ML: activate_token(token_id)
    ML->>ML: Verify all metadata present
    ML->>ML: Verify ERC-3643 contracts deployed on all live chains
    ML->>ML: Verify Identity Registry synchronized

    ML->>ML: Set status = Active
    ML-->>ISSUER: Token Activated

    Note over ISSUER,ML: Transfers now enabled

# Activation Checklist

Before activation:

  • All metadata fields populated
  • Document hashes verified
  • Luxembourg SPV compartment confirmed
  • ERC-3643 contracts deployed on Plume, Base, Canton
  • Identity Registry synchronized with ICP KYC Registry
  • Compliance Module configured with correct rules
  • Issuer treasury funded