# Redemption

At maturity, token holders redeem their tokens for USDC principal repayment. Tokens are burned on all live chains (Plume, Base, Canton) and the bond lifecycle completes. Collateral enforcement, if required, is executed through the legal and trustee framework — not by smart contract.


# Redemption Flow

sequenceDiagram
    participant ISSUER as Issuer
    participant ML as ICP Master Ledger
    participant HOLDER as Holder
    participant CF as Chain Fusion
    participant EVM as EVM (Plume / Base / Canton)

    Note over ISSUER,EVM: 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

    ISSUER->>HOLDER: USDC Principal Payment (batched transfer)

    HOLDER->>ML: Confirm Receipt
    ML->>CF: Burn tokens on all chains
    CF->>EVM: Execute burns (Plume / Base / Canton)
    EVM-->>CF: Burns confirmed
    ML->>ML: Update total_supply
    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[USDC Settlement]
    SETTLE --> BURN[Token Burn]

# Early Redemption

Issuer calls bonds before maturity (if permitted by bond documentation):

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

# Maturity Process

# Timeline

gantt
    title Redemption Timeline
    dateFormat YYYY-MM-DD

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

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

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

# Phase 1: Announcement

30 days before maturity:

  • Announce redemption to all holders
  • Publish redemption price
  • Open request submission window
type RedemptionAnnouncement = record {
    token_id : TokenId;
    maturity_date : Timestamp;
    redemption_price : nat;         // Per token, in USDC
    request_deadline : Timestamp;
    payment_date : Timestamp;
};

# Phase 2: Request Collection

Holders submit redemption requests specifying their verified wallet for USDC payment:

type RedemptionRequest = record {
    id : RequestId;
    holder : Principal;
    token_id : TokenId;
    amount : nat;
    payment_chain : Chain;          // Plume, Base, or Canton
    payment_address : Text;         // Verified wallet address
    submitted_at : Timestamp;
    status : RequestStatus;
};

# Phase 3: Token Locking

Upon request submission, tokens are locked:

stateDiagram-v2
    [*] --> Active: Tokens transferable
    Active --> Locked: Redemption requested
    Locked --> Burned: USDC payment confirmed
    Locked --> Active: Request cancelled

    note right of Locked: Cannot transfer

# Phase 4: USDC Settlement

sequenceDiagram
    participant ISSUER as Issuer
    participant DW as Distribution Wallet
    participant HOLDER as Holder

    ISSUER->>DW: Fund with USDC
    Note over DW: Verify sufficient USDC balance

    loop For Each Request
        DW->>HOLDER: Batched USDC transfer
    end

# Phase 5: Token Burn

After USDC payment confirmation, tokens are burned on all chains:

flowchart TB
    CONFIRM[USDC Payment Confirmed] --> BURN[Burn Tokens]

    BURN --> PLUME_BURN[Burn on Plume]
    BURN --> BASE_BURN[Burn on Base]
    BURN --> CANTON_BURN[Burn on Canton]

    PLUME_BURN & BASE_BURN & CANTON_BURN --> VERIFY[Verify Total Burned]
    VERIFY --> ML[Update ICP Master Ledger]
    ML --> COMPLETE[Set status = Redeemed]

# Redemption Pricing

# At Par

Most common — tokens redeemed at face value in USDC:

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

# 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 USDC (2% premium)

# Below Par

Only in distressed situations. Recovery is tied to physical collateral, not a counterparty's ability to pay. Collateral enforcement is executed through the legal and trustee framework under applicable law — not by smart contract liquidation.

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

For default and recovery scenarios, see ../product/investor-protections.md.


# Redemption States

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

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

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

# Token Status Transitions

Status Transfers Minting Burning
Active Allowed Allowed No
Announced Allowed No No
Collecting Locked tokens only No No
Processing No No No
Settling No No No
Burning No No Yes
Redeemed No No No

# Edge Cases

# Unreachable Holders

flowchart TB
    HOLDER[Holder Unreachable] --> ATTEMPT[Multiple Contact Attempts]
    ATTEMPT --> ESCROW[USDC in Escrow]
    ESCROW --> WAIT[Wait Period]
    WAIT --> CLAIM{Claimed?}
    CLAIM -->|Yes| PAY[Pay Holder in USDC]
    CLAIM -->|No| LEGAL[Legal resolution per Luxembourg law]

# Lost Wallet Access

If an investor loses wallet access, recovery follows the standard process: re-verify identity via SumSub, register new wallet in the ICP KYC Registry, Chain Fusion synchronizes to ERC-3643 Identity Registry, tokens reissued to new verified wallet.

type WalletRecovery = record {
    holder : Principal;
    old_address : Text;
    new_address : Text;
    kyc_reverification : Text;      // SumSub re-verification reference
    approved_by : Principal;
    approved_at : Timestamp;
};