# Redemption

At maturity, token holders redeem their tokens for principal repayment. Tokens are burned and the bond lifecycle completes.


# Redemption Flow

sequenceDiagram
    participant ISSUER as Issuer
    participant ML as Master Ledger
    participant HOLDER as Holder
    participant CF as Chain Fusion
    participant BANK as Settlement

    Note over ISSUER,BANK: Approaching Maturity

    ISSUER->>ML: Initiate Redemption
    ML->>ML: Set status = Maturing
    ML->>ML: Disable new mints

    ML->>HOLDER: Notify Redemption
    HOLDER->>ML: Submit Redemption Request
    ML->>ML: Lock Tokens

    ISSUER->>BANK: Fund Settlement
    BANK-->>HOLDER: Principal Paid

    HOLDER->>ML: Confirm Receipt
    ML->>CF: Burn Cross-chain Tokens
    CF->>CF: Execute Burns
    ML->>ML: Burn ICP Tokens
    ML->>ML: Set status = Redeemed

# Redemption Types

# Scheduled Maturity

Normal redemption at bond maturity date:

flowchart LR
    MATURE[Maturity Date] --> NOTICE[30-Day Notice]
    NOTICE --> REQUESTS[Collect Requests]
    REQUESTS --> SETTLE[Settlement]
    SETTLE --> BURN[Token Burn]

# Early Redemption

Issuer calls bonds before maturity (if permitted):

flowchart LR
    CALL[Issuer Call] --> NOTICE[Notice Period]
    NOTICE --> PREMIUM[Calculate Premium]
    PREMIUM --> SETTLE[Settlement]
    SETTLE --> BURN[Token Burn]

# Partial Redemption

Redeem portion of holdings (if permitted):

type PartialRedemption = record {
    holder : Principal;
    token_id : TokenId;
    amount : nat;                   // Tokens to redeem
    remaining : nat;                // Tokens to keep
};

# Maturity Process

# Timeline

gantt
    title Redemption Timeline
    dateFormat YYYY-MM-DD

    section Notice
    Maturity Announcement    :2027-01-22, 7d
    Trading Restriction      :2027-01-29, 21d

    section Collection
    Request Window           :2027-02-12, 10d
    Request Deadline         :milestone, 2027-02-22, 0d

    section Settlement
    Funding                  :2027-02-22, 3d
    Payment Processing       :2027-02-25, 5d
    Token Burn               :2027-03-02, 1d

# Phase 1: Announcement

type RedemptionAnnouncement = record {
    token_id : TokenId;
    maturity_date : Timestamp;
    redemption_price : nat;         // Per token
    currency : Text;
    request_deadline : Timestamp;
    payment_date : Timestamp;
    instructions : Text;
};

30 days before maturity:

  • Announce redemption to all holders
  • Publish redemption price
  • Open request submission window

# Phase 2: Request Collection

Holders submit redemption requests:

type RedemptionRequest = record {
    id : RequestId;
    holder : Principal;
    token_id : TokenId;
    amount : nat;
    payment_method : PaymentMethod;
    bank_details : opt BankDetails;
    wallet_address : opt Text;      // For stablecoin payment
    submitted_at : Timestamp;
    status : RequestStatus;
};

type PaymentMethod = variant {
    BankWire : BankDetails;
    Stablecoin : StablecoinDetails;
};

type BankDetails = record {
    account_holder : Text;
    iban : Text;
    swift : Text;
    bank_name : Text;
    bank_address : Text;
    reference : opt Text;
};

type StablecoinDetails = record {
    chain : Chain;
    address : Text;
    currency : Text;                // "USDC", "USDT"
};

# Phase 3: Token Locking

Upon request submission, tokens are locked:

stateDiagram-v2
    [*] --> Active: Tokens tradeable
    Active --> Locked: Redemption requested
    Locked --> Burned: Payment confirmed
    Locked --> Active: Request cancelled

    note right of Locked: Cannot transfer

# Phase 4: Settlement

sequenceDiagram
    participant ISSUER as Issuer
    participant ESCROW as Escrow
    participant HOLDER as Holder

    ISSUER->>ESCROW: Deposit Funds
    Note over ESCROW: Verify sufficient funds

    loop For Each Request
        ESCROW->>HOLDER: Process Payment
        alt Bank Wire
            ESCROW->>HOLDER: Wire Transfer
        else Stablecoin
            ESCROW->>HOLDER: On-chain Transfer
        end
    end

# Phase 5: Token Burn

After payment confirmation:

flowchart TB
    CONFIRM[Payment Confirmed] --> COLLECT[Collect Tokens]

    COLLECT --> ICP_BURN[Burn ICP Tokens]
    COLLECT --> EVM_BURN[Burn EVM Tokens]
    COLLECT --> SOL_BURN[Burn Solana Tokens]

    ICP_BURN & EVM_BURN & SOL_BURN --> VERIFY[Verify Total Burned]
    VERIFY --> COMPLETE[Mark Redeemed]

# Redemption Pricing

# At Par

Most common - tokens redeemed at face value:

Redemption Value = Token Balance × Denomination
Example: 100 tokens × $1,000 = $100,000

# With Premium (Early Redemption)

Issuer pays premium for calling early:

Redemption Value = Token Balance × Denomination × (1 + Premium)
Example: 100 tokens × $1,000 × 1.02 = $102,000 (2% premium)

# Below Par

Rare - only in distressed situations:

Redemption Value = Token Balance × Denomination × Recovery Rate
Example: 100 tokens × $1,000 × 0.80 = $80,000 (80% recovery)

# Cross-Chain Burns

# Burn Process

sequenceDiagram
    participant ML as Master Ledger
    participant CF as Chain Fusion
    participant EVM as EVM Chain
    participant SOL as Solana

    ML->>CF: Initiate Burns
    par Burn on EVM
        CF->>EVM: Call burn()
        EVM-->>CF: TX Hash
    and Burn on Solana
        CF->>SOL: Burn instruction
        SOL-->>CF: Signature
    end

    CF->>CF: Wait for confirmations
    CF->>ML: Report Burns Complete
    ML->>ML: Update total_supply

# Burn Verification

All burns must be verified before closing:

type BurnVerification = record {
    chain : Chain;
    expected_amount : nat;
    actual_burned : nat;
    tx_hash : Text;
    block_number : nat64;
    verified : bool;
};

# Canister Interface

candid
service : {
    // Issuer operations
    initiate_redemption : (TokenId) -> (Result<RedemptionId, Error>);
    set_redemption_price : (RedemptionId, nat) -> (Result<(), Error>);
    fund_redemption : (RedemptionId) -> (Result<(), Error>);
    process_payments : (RedemptionId) -> (Result<ProcessingResult, Error>);
    finalize_redemption : (RedemptionId) -> (Result<(), Error>);

    // Holder operations
    submit_redemption_request : (SubmitRequestArgs) -> (Result<RequestId, Error>);
    update_payment_details : (RequestId, PaymentMethod) -> (Result<(), Error>);
    cancel_request : (RequestId) -> (Result<(), Error>);
    confirm_payment : (RequestId) -> (Result<(), Error>);

    // Queries
    get_redemption : (RedemptionId) -> (opt Redemption) query;
    get_my_requests : () -> (vec RedemptionRequest) query;
    get_redemption_status : (TokenId) -> (RedemptionStatus) query;
}

type SubmitRequestArgs = record {
    token_id : TokenId;
    amount : nat;
    payment_method : PaymentMethod;
};

type ProcessingResult = record {
    total_requests : nat32;
    processed : nat32;
    failed : nat32;
    total_amount : nat;
};

# Redemption States

stateDiagram-v2
    [*] --> Active: Token Active

    Active --> Announced: Maturity Approaching
    Announced --> Collecting: Request Window Open
    Collecting --> Processing: Deadline Passed
    Processing --> Settling: Payments in Progress
    Settling --> Burning: All Paid
    Burning --> Redeemed: Tokens Burned
    Redeemed --> [*]

    Processing --> Disputed: Payment Issues
    Disputed --> Settling: Resolved

# Token Status Transitions

Status Trading Minting Burning Transfers
Active
Announced
Collecting ⚠️ Limited ⚠️ Locked tokens
Processing
Settling
Burning
Redeemed

# Edge Cases

# Unreachable Holders

flowchart TB
    HOLDER[Holder Unreachable] --> ATTEMPT[Multiple Contact Attempts]
    ATTEMPT --> ESCROW[Funds in Escrow]
    ESCROW --> WAIT[Wait Period: 1 Year]
    WAIT --> CLAIM{Claimed?}
    CLAIM -->|Yes| PAY[Pay Holder]
    CLAIM -->|No| ESCHEAT[Escheat Process]

# Lost Wallet Access

type WalletRecovery = record {
    holder : Principal;
    old_address : Text;
    new_address : Text;
    kyc_verification : Text;        // Re-verify identity
    approved_by : Principal;
    approved_at : Timestamp;
};

# Disputed Payments

flowchart TB
    DISPUTE[Payment Dispute] --> REVIEW[Review Evidence]
    REVIEW --> DECISION{Valid Dispute?}
    DECISION -->|Yes| RETRY[Retry Payment]
    DECISION -->|No| CLOSE[Close Dispute]
    RETRY --> VERIFY[Verify Receipt]
    VERIFY --> PROCEED[Continue Redemption]

# Events

type RedemptionEvent = variant {
    Announced : record {
        token_id : TokenId;
        maturity_date : Timestamp;
        redemption_price : nat;
        timestamp : Timestamp;
    };
    RequestSubmitted : record {
        request_id : RequestId;
        holder : Principal;
        amount : nat;
        timestamp : Timestamp;
    };
    PaymentProcessed : record {
        request_id : RequestId;
        amount : nat;
        method : Text;
        timestamp : Timestamp;
    };
    TokensBurned : record {
        token_id : TokenId;
        chain : Chain;
        amount : nat;
        tx_hash : Text;
        timestamp : Timestamp;
    };
    Completed : record {
        token_id : TokenId;
        total_redeemed : nat;
        total_burned : nat;
        timestamp : Timestamp;
    };
};