From 2f606b13d5e6362a848c91827dda6e87852a2f29 Mon Sep 17 00:00:00 2001 From: Ozgun Ozerk Date: Wed, 26 Nov 2025 11:51:03 +0300 Subject: [PATCH 1/8] rwa-sep --- ecosystem/sep-0057.md | 1216 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1216 insertions(+) create mode 100644 ecosystem/sep-0057.md diff --git a/ecosystem/sep-0057.md b/ecosystem/sep-0057.md new file mode 100644 index 000000000..1380c23f1 --- /dev/null +++ b/ecosystem/sep-0057.md @@ -0,0 +1,1216 @@ + +## Preamble +``` +SEP: 0057 +Title: T-REX (Token for Regulated EXchanges) +Author: OpenZeppelin, Boyan Barakov <@brozorec>, Özgün Özerk <@ozgunozerk> +Status: Draft +Created: 2025-11-26 +Updated: 2025-11-26 +Version: 0.1.0 +Discussion: https://github.com/orgs/stellar/discussions/1814 +``` + +## Summary +This proposal defines a standard contract interface for T-REX (Token for Regulated EXchanges) - colloquially known as RWA token - on Stellar. T-REX tokens represent tokenized real-world assets such as securities, bonds, real estate, or other regulated financial instruments that require compliance with regulatory frameworks. T-REX tokens are **permissioned tokens**, ensuring that only eligible investors can hold and transfer these tokens. + +This standard is based on the T-REX (Token for Regulated Exchanges) framework, as implemented in ERC-3643 (https://github.com/ERC-3643/ERC-3643), but introduces significant architectural improvements for flexibility and modularity. + +## Motivation +Real World Assets (RWAs) represent a significant opportunity for blockchain adoption, enabling the tokenization of traditional financial instruments and physical assets. However, unlike standard fungible tokens, RWAs must comply with complex regulatory requirements including but not limited to: + +- **Know Your Customer (KYC) and Anti-Money Laundering (AML)** compliance +- **Identity verification** and investor accreditation +- **Freezing capabilities** for regulatory enforcement +- **Recovery mechanisms** for lost or compromised wallets +- **Compliance hooks** for regulatory reporting + +The T-REX standard provides a comprehensive framework for compliant security tokens. This SEP adapts T-REX to the Stellar ecosystem, enabling: + +- **Modular hook-based compliance framework** with pluggable compliance rules +- **Flexible identity verification** supporting multiple approaches (claim-based, Merkle tree, zero-knowledge, etc.) +- **Sophisticated freezing mechanisms** at both address and token levels +- **Administrative controls** with role-based access control (RBAC) + +## Architecture Overview + +This RWA standard introduces an approach built around **loose coupling** and **implementation abstraction**. + +### Core Design Principles + +1. **Separation of Concerns**: Core token functionality is cleanly separated from compliance and identity verification +2. **Implementation Flexibility**: Compliance and identity systems are treated as pluggable implementation details +3. **Shared Infrastructure**: Components can be shared across multiple token contracts to reduce deployment and management costs +4. **Regulatory Adaptability**: The system can adapt to different regulatory frameworks without core changes + +### Component Architecture + +The Stellar T-REX consists of several interconnected but loosely coupled components: + +``` +┌─────────────────┐ ┌──────────────────┐ ┌─────────────────────┐ +│ RWA Token │───▶│ Compliance │───▶│ Compliance Modules │ +│ (Core) │ │ │ │ (Pluggable Rules) │ +└─────────────────┘ └──────────────────┘ └─────────────────────┘ + │ + ▼ +┌─────────────────┐ ┌──────────────────┐ ┌──────────────────┐ +│ Identity │───▶│ Claim Topics & │ │ Identity Registry│ +│ Verifier │ │ Issuers │───▶│ │ +└─────────────────┘ └──────────────────┘ └──────────────────┘ +``` + +This design enables the same core RWA token interface to work with vastly different regulatory and technical requirements for identity verification, such as Merkle trees, Zero-Knowledge proofs, claim-based systems, and others. Furthermore, the modular hook-based system supports diverse regulatory requirements through pluggable compliance rules. + +## Interface + +The RWA token interface extends the **fungible token** ([SEP-41](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0041.md)) with regulatory required features: freezing, pausing and recovery. + +### Architecture Overview + +The RWA token contract requires only **two external functions** to operate: + +```rust +// Compliance validation - returns true if transfer is allowed +fn can_transfer(e: &Env, from: Address, to: Address, amount: i128) -> bool; + +// Identity verification - panics if user is not verified +fn verify_identity(e: &Env, user_address: &Address); +``` + +- `can_transfer()` is expected to be exposed from a "Compliance" contract. +- `verify_identity()` is expected to be exposed from an "Identity Verifier" contract. + +These functions are **deliberately abstracted** as implementation details, enabling: +- **Regulatory Flexibility**: Different jurisdictions can implement different compliance logic +- **Technical Flexibility**: Various identity verification approaches (ZK, Merkle trees, claims) +- **Cost Optimization**: Shared contracts across multiple tokens +- **Future-Proofing**: New compliance approaches without interface changes + +In other words, the only thing required by this RWA token design, is that the RWA token should be able to call these expected functions made available by the compliance and identity verification contracts. + +### Contract Connection Interface + +The RWA token provides simple setter/getter functions for external contracts: + +```rust +// Compliance Contract Management +fn set_compliance(e: &Env, compliance: Address, operator: Address); +fn compliance(e: &Env) -> Address; + +// Identity Verifier Contract Management +fn set_identity_verifier(e: &Env, identity_verifier: Address, operator: Address); +fn identity_verifier(e: &Env) -> Address; +``` + +### Integration Pattern + +To deploy a compliant RWA token and make it functional: + +1. **Deploy Core RWA Token** +2. **Deploy/Connect Compliance Contract** +3. **Deploy/Connect Identity Verifier** +4. **Configure Connections**: Link the RWA token to its compliance and identity verifier contracts using `set_compliance()` and `set_identity_verifier()`. Additionally, configure internal connections within the compliance stack (e.g., linking compliance contract to compliance modules) and identity stack (e.g., linking identity verifier to claim topics/issuers or custom registries) as needed for your implementation. + +```rust +use soroban_sdk::{Address, Env, String}; +use stellar_contract_utils::pausable::Pausable; +use crate::fungible::FungibleToken; + +/// Real World Asset Token Trait +/// +/// The `RWAToken` trait defines the core functionality for Real World Asset +/// tokens, implementing the T-REX standard for regulated securities. It +/// provides a comprehensive interface for managing compliant token transfers, +/// identity verification, compliance rules, and administrative controls. +/// +/// This trait extends basic fungible token functionality with regulatory +/// features required for security tokens. +pub trait RWAToken: TokenInterface { + // ################## CORE TOKEN FUNCTIONS ################## + + /// Returns the total amount of tokens in circulation. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + fn total_supply(e: &Env) -> i128; + + /// Forces a transfer of tokens between two whitelisted wallets. + /// This function can only be called by the operator with necessary + /// privileges. RBAC checks are expected to be enforced on the + /// `operator`. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + /// * `from` - The address of the sender. + /// * `to` - The address of the receiver. + /// * `amount` - The number of tokens to transfer. + /// * `operator` - The address of the operator. + /// + /// # Events + /// + /// * topics - `["transfer", from: Address, to: Address]` + /// * data - `[amount: i128]` + fn forced_transfer(e: &Env, from: Address, to: Address, amount: i128, operator: Address); + + /// Mints tokens to a wallet. Tokens can only be minted to verified + /// addresses. This function can only be called by the operator with + /// necessary privileges. RBAC checks are expected to be enforced on the + /// `operator`. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + /// * `to` - Address to mint the tokens to. + /// * `amount` - Amount of tokens to mint. + /// * `operator` - The address of the operator. + /// + /// # Events + /// + /// * topics - `["mint", to: Address]` + /// * data - `[amount: i128]` + fn mint(e: &Env, to: Address, amount: i128, operator: Address); + + /// Burns tokens from a wallet. + /// This function can only be called by the operator with necessary + /// privileges. RBAC checks are expected to be enforced on the + /// `operator`. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + /// * `user_address` - Address to burn the tokens from. + /// * `amount` - Amount of tokens to burn. + /// * `operator` - The address of the operator. + /// + /// # Events + /// + /// * topics - `["burn", user_address: Address]` + /// * data - `[amount: i128]` + fn burn(e: &Env, user_address: Address, amount: i128, operator: Address); + + /// Recovery function used to force transfer tokens from a old account + /// to a new account for an investor. + /// This function can only be called by the operator with necessary + /// privileges. RBAC checks are expected to be enforced on the + /// `operator`. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + /// * `old_account` - The wallet that the investor lost. + /// * `new_account` - The newly provided wallet for token transfer. + /// * `operator` - The address of the operator. + /// + /// # Events + /// + /// * topics - `["transfer", old_account: Address, new_account: Address]` + /// * data - `[amount: i128]` + /// * topics - `["recovery", old_account: Address, new_account: Address]` + /// * data - `[]` + fn recover_balance( + e: &Env, + old_account: Address, + new_account: Address, + operator: Address, + ) -> bool; + + /// Sets the frozen status for an address. Frozen addresses cannot send or + /// receive tokens. This function can only be called by the operator + /// with necessary privileges. RBAC checks are expected to be enforced + /// on the `operator`. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + /// * `user_address` - The address for which to update frozen status. + /// * `freeze` - Frozen status of the address. + /// * `operator` - The address of the operator. + /// + /// # Events + /// + /// * topics - `["address_frozen", user_address: Address, is_frozen: bool, + /// operator: Address]` + /// * data - `[]` + fn set_address_frozen(e: &Env, user_address: Address, freeze: bool, operator: Address); + + /// Freezes a specified amount of tokens for a given address. + /// This function can only be called by the operator with necessary + /// privileges. RBAC checks are expected to be enforced on the + /// `operator`. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + /// * `user_address` - The address for which to freeze tokens. + /// * `amount` - Amount of tokens to be frozen. + /// * `operator` - The address of the operator. + /// + /// # Events + /// + /// * topics - `["tokens_frozen", user_address: Address]` + /// * data - `[amount: i128]` + fn freeze_partial_tokens(e: &Env, user_address: Address, amount: i128, operator: Address); + + /// Unfreezes a specified amount of tokens for a given address. + /// This function can only be called by the operator with necessary + /// privileges. RBAC checks are expected to be enforced on the + /// `operator`. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + /// * `user_address` - The address for which to unfreeze tokens. + /// * `amount` - Amount of tokens to be unfrozen. + /// * `operator` - The address of the operator. + /// + /// # Events + /// + /// * topics - `["tokens_unfrozen", user_address: Address]` + /// * data - `[amount: i128]` + fn unfreeze_partial_tokens(e: &Env, user_address: Address, amount: i128, operator: Address); + + /// Returns the freezing status of a wallet. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + /// * `user_address` - The address of the wallet to check. + fn is_frozen(e: &Env, user_address: Address) -> bool; + + /// Returns the amount of tokens that are partially frozen on a wallet. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + /// * `user_address` - The address of the wallet to check. + fn get_frozen_tokens(e: &Env, user_address: Address) -> i128; + + // ################## METADATA FUNCTIONS ################## + + /// Returns the version of the token (T-REX version). + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + fn version(e: &Env) -> String; + + /// Returns the address of the onchain ID of the token. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + fn onchain_id(e: &Env) -> Address; + + // ################## COMPLIANCE AND IDENTITY FUNCTIONS ################## + + /// Sets the compliance contract of the token. + /// This function can only be called by the operator with necessary + /// privileges. RBAC checks are expected to be enforced on the + /// `operator`. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + /// * `compliance` - The address of the compliance contract to set. + /// * `operator` - The address of the operator. + /// + /// # Events + /// + /// * topics - `["compliance_set", compliance: Address]` + /// * data - `[]` + fn set_compliance(e: &Env, compliance: Address, operator: Address); + + /// Sets the identity verifier contract of the token. + /// + /// This function can only be called by the operator with necessary + /// privileges. RBAC checks are expected to be enforced on the + /// `operator`. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + /// * `identity_verifier` - The address of the identity verifier contract to + /// set. + /// * `operator` - The address of the operator. + /// + /// # Events + /// + /// * topics - `["identity_verifier_set", identity_verifier: Address]` + /// * data - `[]` + fn set_identity_verifier(e: &Env, identity_verifier: Address, operator: Address); + + /// Returns the Compliance contract linked to the token. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + fn compliance(e: &Env) -> Address; + + /// Returns the Identity Verifier contract linked to the token. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + fn identity_verifier(e: &Env) -> Address; + + // ################## PAUSABLE FUNCTIONS ################## + + /// Returns true if the contract is paused, and false otherwise. + /// + /// # Arguments + /// + /// * `e` - Access to Soroban environment. + /// * `caller` - The address of the caller. + fn pause(e: &Env, caller: Address); + + /// Triggers `Unpaused` state. + /// + /// # Arguments + /// + /// * `e` - Access to Soroban environment. + /// * `caller` - The address of the caller. + fn unpause(e: &Env, caller: Address); + +} +``` + +## Events + +### Transfer Event + +The transfer event is emitted when RWA tokens are transferred from one address to another, including forced transfers and recovery operations. + +```rust +#[contractevent] +pub struct Transfer { + /// The address holding the tokens that were transferred + #[topic] + pub from: Address, + /// The address that received the tokens + #[topic] + pub to: Address, + /// The amount of tokens transferred + pub amount: i128, +} +``` + +### Mint Event + +The mint event is emitted when RWA tokens are minted to a verified address. + +```rust +#[contractevent] +pub struct Mint { + /// The address receiving the newly minted tokens + #[topic] + pub to: Address, + /// The amount of tokens minted + pub amount: i128, +} +``` + +### Burn Event + +The burn event is emitted when RWA tokens are burned from an address. + +```rust +#[contractevent] +pub struct Burn { + /// The address from which tokens were burned + #[topic] + pub from: Address, + /// The amount of tokens burned + pub amount: i128, +} +``` + +### Recovery Event + +The recovery event is emitted when tokens are successfully recovered from a lost wallet to a new wallet. + +```rust +#[contractevent] +pub struct Recovery { + /// The old account address from which tokens were recovered + #[topic] + pub old_account: Address, + /// The new account address that received the recovered tokens + #[topic] + pub new_account: Address, +} +``` + +### Address Frozen Event + +The address frozen event is emitted when an address is frozen or unfrozen. + +```rust +#[contractevent] +pub struct AddressFrozen { + /// The address that was frozen/unfrozen + #[topic] + pub user_address: Address, + /// The frozen status (true for frozen, false for unfrozen) + #[topic] + pub is_frozen: bool, + /// The operator who performed the action + #[topic] + pub operator: Address, +} +``` + +### Tokens Frozen Event + +The tokens frozen event is emitted when a specific amount of tokens is frozen for an address. + +```rust +#[contractevent] +pub struct TokensFrozen { + /// The address for which tokens were frozen + #[topic] + pub user_address: Address, + /// The amount of tokens frozen + pub amount: i128, +} +``` + +### Tokens Unfrozen Event + +The tokens unfrozen event is emitted when a specific amount of tokens is unfrozen for an address. + +```rust +#[contractevent] +pub struct TokensUnfrozen { + /// The address for which tokens were unfrozen + #[topic] + pub user_address: Address, + /// The amount of tokens unfrozen + pub amount: i128, +} +``` + +### Compliance Set Event + +The compliance set event is emitted when the compliance contract is updated. + +```rust +#[contractevent] +pub struct ComplianceSet { + /// The address of the new compliance contract + #[topic] + pub compliance: Address, +} +``` + +### Identity Verifier Set Event + +The identity verifier set event is emitted when the identity verifier contract is updated. + +```rust +#[contractevent] +pub struct IdentityVerifierSet { + /// The address of the new identity verifier contract + #[topic] + pub identity_verifier: Address, +} +``` + +## Reference Implementation: Component Deep Dive + +### 1. Identity Verification System + +**Philosophy**: The entire identity stack is treated as an implementation detail, enabling maximum regulatory and technical flexibility. + +#### The IdentityVerifier Trait + +```rust +pub trait IdentityVerifier { + /// Core verification function - panics if user is not verified + fn verify_identity(e: &Env, user_address: &Address); + + // Setters and getters for the claim topics and issuers contract + fn set_claim_topics_and_issuers(e: &Env, contract: Address, operator: Address); + fn claim_topics_and_issuers(e: &Env) -> Address; +} +``` + +#### Implementation Strategies + +Different regulatory environments may require different approaches. Here are some examples: + +**1. Claim-Based Verification (Reference Implementation)** +- **Use Case**: Traditional KYC/AML with trusted issuers +- **Components**: ClaimTopicsAndIssuers + IdentityRegistryStorage + IdentityClaims + ClaimIssuer +- **Benefits**: Familiar to regulators, rich metadata support + +**2. Merkle Tree Verification** +- **Use Case**: Privacy-focused compliance with efficient proofs +- **Components**: ClaimTopicsAndIssuers + Merkle root storage + proof validation +- **Benefits**: Minimal storage, efficient verification + +**3. Zero-Knowledge Verification** +- **Use Case**: Privacy-preserving compliance +- **Components**: ClaimTopicsAndIssuers + ZK circuit + proof verification +- **Benefits**: Maximum privacy, selective disclosure + +**4. Custom Approaches** +- **Use Case**: Jurisdiction-specific requirements +- **Components**: ClaimTopicsAndIssuers + Custom verification logic +- **Benefits**: Tailored to specific regulatory needs + +#### Reference Implementation Architecture + +The claim-based reference implementation demonstrates the full complexity of traditional RWA compliance: + +``` +┌─────────────────────┐ +│ Identity Verifier │ +│ (Orchestrator) │ +│ │ +└─────────────────────┘ + │ + ├────▶┌───────────────────────────┐ + │ │ Claim Topics & Issuers │ + │ │ (Shared Registry) │ + │ └───────────────────────────┘ + │ + ├────▶┌───────────────────────────┐ + │ │ Identity Registry Storage │ + │ │ (Investor Profiles) │ + │ └───────────────────────────┘ + │ + ├────▶┌───────────────────────────┐ + │ │ Identity Claims │ + │ │ (Investor Claims Storage) │ + │ └───────────────────────────┘ + │ + └────▶┌───────────────────────────┐ + │ Claim Issuer │ + │ (Claims Validation) │ + └───────────────────────────┘ +``` + +**Key Components:** + +- **ClaimTopicsAndIssuers**: Registry contract managing both trusted issuers and required claim types (KYC=1, AML=2, etc.). +- **IdentityRegistryStorage**: Component storing investors identity profiles with country relations and metadata. +- **IdentityClaims**: Required for every investor as a separate contract or as an extension to existing identity management systems. Its goal is to store cryptographic claims issued to that investor by trusted claim issuers. This component is under investor's control. Its structure mirrors the evolving OnchainID specification (https://github.com/ERC-3643/ERCs/blob/erc-oid/ERCS/erc-xxxx.md). +- **ClaimIssuer**: Contracts belonging to trusted 3rd parties to validate cryptographic claims about investors' attributes by using multiple signature schemes (Ed25519, Secp256k1, Secp256r1). + +Note that, Claim-Based Identity Verification is a reference implementation, it is not a part of the specification. For detailed interface specifications of these components, see the [Appendix: Claim-Based Identity Verification Reference Implementation](#appendix-claim-based-identity-verification-reference-implementation) section. + +### 2. Compliance System + +Modular hook-based architecture supporting diverse regulatory requirements through pluggable compliance modules. + +#### The Compliance Trait + +```rust +pub trait Compliance { + // Module management + fn add_module_to(e: &Env, hook: ComplianceHook, module: Address, operator: Address); + fn remove_module_from(e: &Env, hook: ComplianceHook, module: Address, operator: Address); + + // Validation hooks (READ-only) + fn can_transfer(e: &Env, from: Address, to: Address, amount: i128) -> bool; + fn can_create(e: &Env, to: Address, amount: i128) -> bool; + + // State update hooks (called after successful operations) + fn transferred(e: &Env, from: Address, to: Address, amount: i128); + fn created(e: &Env, to: Address, amount: i128); + fn destroyed(e: &Env, from: Address, amount: i128); +} +``` + +#### Hook-Based Architecture + +The compliance system uses a sophisticated hook mechanism: + +```rust +pub enum ComplianceHook { + CanTransfer, // Pre-validation: Check if transfer meets compliance rules + CanCreate, // Pre-validation: Check if mint operation is compliant + Transferred, // Post-event: Update state after successful transfer + Created, // Post-event: Update state after successful mint + Destroyed, // Post-event: Update state after successful burn +} +``` + +#### Compliance Module Examples + +**Transfer Limits Module**: +- Hook: `CanTransfer` + `Transferred` +- Logic: Enforce daily/monthly transfer limits per user + +**Jurisdiction Restrictions Module**: +- Hook: `CanTransfer` +- Logic: Restrict transfers to blocked jurisdictions + +**Holding Period Module**: +- Hook: `CanTransfer` + `Created` +- Logic: Enforce minimum holding periods for newly minted tokens + +**Investor Accreditation Module**: +- Hook: `CanCreate` +- Logic: Verify investor accreditation before minting + +#### Shared Compliance Infrastructure + +Compliance contracts are designed to be **shared across multiple RWA tokens**, reducing deployment costs and ensuring consistent regulatory enforcement: + +``` +┌─────────────┐ ┌─────────────────────┐ ┌──────────────────┐ +│ RWA Token A │───▶│ │───▶│ Transfer Limits │ +├─────────────┤ │ Shared Compliance │ │ Module │ +│ RWA Token B │───▶│ Contract │───▶├──────────────────┤ +├─────────────┤ │ │ │ Jurisdiction │ +│ RWA Token C │───▶│ │ │ Module │ +└─────────────┘ └─────────────────────┘ └──────────────────┘ +``` + + +### 3. Advanced Token Controls + +#### Freezing Mechanisms + +The system supports multiple freezing strategies to accommodate for different regulatory requirements: + +**Address-Level Freezing**: +```rust +fn set_address_frozen(e: &Env, user_address: Address, freeze: bool, operator: Address); +fn is_frozen(e: &Env, user_address: Address) -> bool; +``` +- **Use Case**: Complete account suspension for regulatory investigations +- **Effect**: Prevents all token operations (send/receive) + +**Partial Token Freezing**: +```rust +fn freeze_partial_tokens(e: &Env, user_address: Address, amount: i128, operator: Address); +fn unfreeze_partial_tokens(e: &Env, user_address: Address, amount: i128, operator: Address); +fn get_frozen_tokens(e: &Env, user_address: Address) -> i128; +``` +- **Use Case**: Escrow scenarios, disputed transactions +- **Effect**: Freezes specific token amounts while allowing operations on remaining balance + +#### Recovery System + +Two distinct recovery flows are supported: + +1. Identity Recovery: Managed in the Identity Stack (Identity Registry Storage), transfers the identity contract reference and profile (including country data) from old account to new account, and creates a recovery mapping. + +```rust +fn recover_identity(e: &Env, old_account: Address, new_account: Address, operator: Address); +``` + +2. Balance Recovery: Managed by the RWA token, transfers tokens from old to new account after verifying the identity recovery mapping exists + +```rust +fn recover_balance(e: &Env, old_account: Address, new_account: Address, operator: Address) -> bool; +``` + +#### Forced Transfers + +For regulatory compliance (court orders, sanctions): + +```rust +fn forced_transfer(e: &Env, from: Address, to: Address, amount: i128, operator: Address); +``` + +- **Use Case**: Court-ordered asset transfers, regulatory seizures +- **Authorization**: Requires operator with forced transfer permissions +- **Compliance**: Bypasses normal compliance validation checks (operator responsibility) + +### 4. Access Control & Governance + +RWA tokens require proper access control to ensure that sensitive operations are only performed by authorized entities: + +- **Operator Authorization**: All administrative functions require `operator` authorization +- **Flexible Access Control**: While the RWA interface itself doesn't prescribe a specific access control model, implementations can integrate with external access control systems as needed +- **Compliance Integration**: Access control permissions should be integrated with compliance rules to ensure regulatory requirements are met + +## Extensions + +The RWA token standard can be extended with additional functionality beyond the core specification. Extensions are optional modules that add specialized features while maintaining compatibility with the base RWA interface. + +### Document Manager (ERC-1643) + +The Document Manager extension provides document management capabilities for RWA tokens, following the ERC-1643 standard. This is particularly useful for attaching legal documents, prospectuses, or regulatory disclosures to token contracts. + +**Key Features:** +- Attach documents with URI, hash, and timestamp +- Update existing document metadata +- Remove documents from the contract +- Retrieve individual or all documents + +**Use Cases:** +- Legal agreements and terms of service +- Offering memorandums and prospectuses +- Regulatory compliance documents +- Audit reports and certifications + +### Custom Extensions + +Implementers are free to create custom extensions tailored to their specific requirements. + +## Deviations from ERC-3643 + +Several limitations in the original ERC-3643 standard and its reference implementation were identified and respectively addressed: + +**1. Tight Coupling Issues** +- **Problem**: ERC-3643 tightly couples identity verification with specific contract structures +- **Solution**: Abstract identity verification as pluggable implementation detail + +**2. Inflexible Identity Models** +- **Problem**: Hardcoded ERC-734/735 identity contracts don't translate to all blockchain architectures +- **Solution**: Support multiple identity verification approaches (Merkle, ZK, claims, custom) + +**3. Redundant Contract Hierarchies** +- **Problem**: Complex IdentityRegistry ↔ IdentityRegistryStorage relationships +- **Solution**: Direct access patterns + +**4. Limited Compliance Flexibility** +- **Problem**: Monolithic compliance validation +- **Solution**: Modular hook-based compliance system + +## Upgrade and Migration Strategies + +**Compliance Evolution**: +- Modular compliance system supports rule updates without token redeployment +- New compliance modules can be added for evolving regulations + +**Identity System Migration**: +- Abstract identity verification enables migration between verification approaches +- Gradual migration strategies for existing user bases + +For general contract upgrade patterns and best practices, refer to [SEP-49: Upgradeable Contracts](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0049.md). + +--- + +## Appendix: Claim-Based Identity Verification Reference Implementation + +> **IMPORTANT NOTICE**: This appendix describes a **reference implementation** and is **NOT a part of the RWA token specification**. The RWA standard only requires that an `IdentityVerifier` contract exposing a `verify_identity()` function. The claim-based approach described here is one possible implementation among many (others include Merkle tree verification, zero-knowledge proofs, or custom approaches). This section is provided for informational purposes to demonstrate a complete, production-ready implementation that follows traditional KYC/AML compliance patterns. + +### Overview + +The claim-based approach uses cryptographic claims issued by trusted authorities (KYC providers, compliance firms) to verify investor identities. This implementation consists of four main components that work together: + +1. **ClaimTopicsAndIssuers**: Trust registry defining required claim types and authorized issuers +2. **IdentityRegistryStorage**: Storage for investor identity profiles and country relations +3. **IdentityClaims**: Per-investor contract storing cryptographic claims +4. **ClaimIssuer**: Validator contracts operated by trusted third parties + +### ClaimTopicsAndIssuers Interface + +The `ClaimTopicsAndIssuers` contract acts as the trust registry, defining which claim topics are required for token participation and which issuers are authorized to provide those claims. + +**Purpose:** +- Maintains a registry of trusted claim issuers (e.g., KYC providers, compliance firms) +- Defines which types of claims are required (e.g., KYC=1, AML=2, Accredited Investor=3) +- Maps each trusted issuer to the specific claim topics they are authorized to issue +- Can be shared across multiple RWA tokens to reduce deployment costs + +**Interface:** + +```rust +pub trait ClaimTopicsAndIssuers { + // ################## CLAIM TOPICS ################## + + /// Adds a claim topic (for example: KYC=1, AML=2). + /// + /// Only an operator with sufficient permissions should be able to call this + /// function. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + /// * `claim_topic` - The claim topic index. + /// + /// # Events + /// + /// * topics - `["claim_added", claim_topic: u32]` + /// * data - `[]` + fn add_claim_topic(e: &Env, claim_topic: u32, operator: Address); + + /// Removes a claim topic (for example: KYC=1, AML=2). + /// + /// Only an operator with sufficient permissions should be able to call this + /// function. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + /// * `claim_topic` - The claim topic index. + /// + /// # Events + /// + /// * topics - `["claim_removed", claim_topic: u32]` + /// * data - `[]` + fn remove_claim_topic(e: &Env, claim_topic: u32, operator: Address); + + /// Returns the claim topics for the security token. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + fn get_claim_topics(e: &Env) -> Vec; + + // ################## TRUSTED ISSUERS ################## + + /// Registers a claim issuer contract as trusted claim issuer. + /// + /// Only an operator with sufficient permissions should be able to call this + /// function. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + /// * `trusted_issuer` - The claim issuer contract address of the trusted + /// claim issuer. + /// * `claim_topics` - The set of claim topics that the trusted issuer is + /// allowed to emit. + /// + /// # Events + /// + /// * topics - `["issuer_added", trusted_issuer: Address]` + /// * data - `[claim_topics: Vec]` + fn add_trusted_issuer( + e: &Env, + trusted_issuer: Address, + claim_topics: Vec, + operator: Address, + ); + + /// Removes the claim issuer contract of a trusted claim issuer. + /// + /// Only an operator with sufficient permissions should be able to call this + /// function. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + /// * `trusted_issuer` - The claim issuer to remove. + /// + /// # Events + /// + /// * topics - `["issuer_removed", trusted_issuer: Address]` + /// * data - `[]` + fn remove_trusted_issuer(e: &Env, trusted_issuer: Address, operator: Address); + + /// Updates the set of claim topics that a trusted issuer is allowed to + /// emit. + /// + /// Only an operator with sufficient permissions should be able to call this + /// function. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + /// * `trusted_issuer` - The claim issuer to update. + /// * `claim_topics` - The set of claim topics that the trusted issuer is + /// allowed to emit. + /// + /// # Events + /// + /// * topics - `["topics_updated", trusted_issuer: Address]` + /// * data - `[claim_topics: Vec]` + fn update_issuer_claim_topics( + e: &Env, + trusted_issuer: Address, + claim_topics: Vec, + operator: Address, + ); + + /// Returns all the trusted claim issuers stored. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + fn get_trusted_issuers(e: &Env) -> Vec
; + + /// Returns all the trusted issuers allowed for a given claim topic. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + /// * `claim_topic` - The claim topic to get the trusted issuers for. + fn get_claim_topic_issuers(e: &Env, claim_topic: u32) -> Vec
; + + /// Returns all the claim topics and their corresponding trusted issuers as + /// a Mapping. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + fn get_claim_topics_and_issuers(e: &Env) -> Map>; + + /// Checks if the claim issuer contract is trusted. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + /// * `issuer` - The address of the claim issuer contract. + fn is_trusted_issuer(e: &Env, issuer: Address) -> bool; + + /// Returns all the claim topics of trusted claim issuer. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + /// * `trusted_issuer` - The trusted issuer concerned. + fn get_trusted_issuer_claim_topics(e: &Env, trusted_issuer: Address) -> Vec; + + /// Checks if the trusted claim issuer is allowed to emit a certain claim + /// topic. + /// + /// # Arguments + /// + /// * `e` - Access to the Soroban environment. + /// * `issuer` - The address of the trusted issuer's claim issuer contract. + /// * `claim_topic` - The claim topic that has to be checked to know if the + /// issuer is allowed to emit it. + fn has_claim_topic(e: &Env, issuer: Address, claim_topic: u32) -> bool; +} +``` +### IdentityRegistryStorage Interface + +The `IdentityRegistryStorage` contract stores identity information for verified investors, including their identity contract references and country relations. + +**Purpose:** +- Maps wallet addresses to their onchain identity contracts +- Stores country information for regulatory compliance +- Supports both individual and organizational identities +- Manages recovery account mappings for lost wallet scenarios + +**Interface:** + +```rust +pub trait IdentityRegistryStorage: TokenBinder { + /// The specific type used for country data in this implementation. + type CountryData: FromVal; + + /// Stores a new identity with a set of country data entries. + /// + /// # Arguments + /// + /// * `e` - The Soroban environment. + /// * `account` - The account address to associate with the identity. + /// * `identity` - The identity address to store. + /// * `country_data_list` - A vector of initial country data entries. + /// * `operator` - The address authorizing the invocation. + /// + /// # Events + /// + /// * topics - `["identity_stored", account: Address, identity: Address]` + /// * data - `[]` + fn add_identity( + e: &Env, + account: Address, + identity: Address, + country_data_list: Vec, + operator: Address, + ); + + /// Removes an identity and all associated country data entries. + /// + /// # Arguments + /// + /// * `e` - The Soroban environment. + /// * `account` - The account address whose identity is being removed. + /// * `operator` - The address authorizing the invocation. + /// + /// # Events + /// + /// * topics - `["identity_unstored", account: Address, identity: Address]` + /// * data - `[]` + /// + /// Emits for each country data removed: + /// * topics - `["country_removed", account: Address, country_data: + /// CountryData]` + /// * data - `[]` + fn remove_identity(e: &Env, account: Address, operator: Address); + + /// Modifies an existing identity. + /// + /// # Arguments + /// + /// * `e` - The Soroban environment. + /// * `account` - The account address whose identity is being modified. + /// * `new_identity` - The new identity address. + /// * `operator` - The address authorizing the invocation. + /// + /// # Events + /// + /// * topics - `["identity_modified", old_identity: Address, new_identity: + /// Address]` + /// * data - `[]` + fn modify_identity(e: &Env, account: Address, identity: Address, operator: Address); + + /// Recovers an identity by transferring it from an old account to a new + /// account. + /// + /// # Arguments + /// + /// * `e` - The Soroban environment. + /// * `old_account` - The account address from which to recover the + /// identity. + /// * `new_account` - The account address to which the identity will be + /// transferred. + /// * `operator` - The address authorizing the invocation. + /// + /// # Events + /// + /// * topics - `["identity_recovered", old_account: Address, new_account: + /// Address]` + /// * data - `[]` + fn recover_identity(e: &Env, old_account: Address, new_account: Address, operator: Address); + + /// Retrieves the stored identity for a given account. + /// + /// # Arguments + /// + /// * `e` - The Soroban environment. + /// * `account` - The account address to query. + fn stored_identity(e: &Env, account: Address) -> Address; + + /// Retrieves the recovery target address for a recovered account. + /// + /// Returns `Some(new_account)` if the account has been recovered to a new + /// account, or `None` if the account has not been recovered. + /// + /// # Arguments + /// + /// * `e` - The Soroban environment. + /// * `old_account` - The old account address to check. + fn get_recovered_to(e: &Env, old_account: Address) -> Option
; +} +``` + +### IdentityClaims Interface + +The `IdentityClaims` contract manages on-chain identity claims with cryptographic signatures. This contract is controlled by the investor and stores claims issued by trusted authorities. + +**Purpose:** +- Store cryptographic claims issued to an investor +- Manage claim lifecycle (add, retrieve, remove) +- Support multiple claims per topic from different issuers +- Enable claim-based identity verification + +**Interface:** + +```rust +pub trait IdentityClaims { + /// Adds a new claim to the identity or updates an existing one. + /// + /// # Arguments + /// + /// * `e` - The Soroban environment. + /// * `topic` - The claim topic (u32 identifier). + /// * `scheme` - The signature scheme used. + /// * `issuer` - The address of the claim issuer. + /// * `signature` - The cryptographic signature of the claim. + /// * `data` - The claim data. + /// * `uri` - Optional URI for additional claim information. + /// + /// # Events + /// + /// * topics - `["claim_added", claim_id: BytesN<32>, topic: u32]` + /// * data - `[]` + /// + /// OR (for updates): + /// + /// * topics - `["claim_changed", claim_id: BytesN<32>, topic: u32]` + /// * data - `[]` + fn add_claim( + e: &Env, + topic: u32, + scheme: u32, + issuer: Address, + signature: Bytes, + data: Bytes, + uri: String, + ) -> BytesN<32>; + + /// Retrieves a claim by its ID. + /// + /// # Arguments + /// + /// * `e` - The Soroban environment. + /// * `claim_id` - The unique claim identifier. + fn get_claim(e: &Env, claim_id: BytesN<32>) -> Claim; + + /// Retrieves all claim IDs for a specific topic. + /// + /// # Arguments + /// + /// * `e` - The Soroban environment. + /// * `topic` - The claim topic to filter by. + fn get_claim_ids_by_topic(e: &Env, topic: u32) -> Vec>; +} +``` + +**Claim Structure:** + +Each claim contains: +- **Topic**: Numeric identifier (e.g., KYC=1, AML=2) +- **Scheme**: Signature algorithm identifier +- **Issuer**: Address of the claim issuer contract +- **Signature**: Cryptographic signature +- **Data**: Claim information (can include expiration, metadata) +- **URI**: Optional URI for additional information + +### ClaimIssuer Interface + +The `ClaimIssuer` contract validates cryptographic claims about investors. These contracts are operated by trusted third parties (KYC providers, compliance firms). + +**Purpose:** +- Validate cryptographic signatures on claims +- Support multiple signature schemes (Ed25519, Secp256k1, Secp256r1) +- Manage claim revocation and expiration +- Provide key management for signing authorities + +**Interface:** + +```rust +pub trait ClaimIssuer { + /// Validates whether a claim is valid for a given identity. Panics if claim + /// is invalid. + /// + /// # Arguments + /// + /// * `e` - The Soroban environment. + /// * `identity` - The identity address the claim is about. + /// * `claim_topic` - The topic of the claim to validate. + /// * `scheme` - The signature scheme used. + /// * `sig_data` - The signature data as bytes: public key, signature and + /// other data required by the concrete signature scheme. + /// * `claim_data` - The claim data to validate. + fn is_claim_valid( + e: &Env, + identity: Address, + claim_topic: u32, + scheme: u32, + sig_data: Bytes, + claim_data: Bytes, + ); +} +``` + +### Verification Flow + +The following describes how these components work together during token operations: + +1. **Off-chain**: Investor submits identity documents to KYC Provider +2. **Off-chain**: KYC Provider verifies identity and signs claim with private key +3. **On-chain**: Signed claim is stored in investor's IdentityClaims contract +4. **On-chain**: During token operations (transfer/mint), the RWA Token: + - Calls IdentityVerifier's `verify_identity()` + - Required claim topics from ClaimTopicsAndIssuers is retrieved + - Claims from investor's IdentityClaims contract are fetched + - ClaimIssuer is called to validate signatures + - Revocation status is checked + - Issuer trust is verified via ClaimTopicsAndIssuers + +**Note**: The KYC Provider and Claim Issuer are the same entity. Signing happens off-chain; only the signed claim and revocation data are stored on-chain. From d66869e980b2cb3c938deab7e80aacd0dbbcf0d6 Mon Sep 17 00:00:00 2001 From: Ozgun Ozerk Date: Tue, 2 Dec 2025 15:00:45 +0300 Subject: [PATCH 2/8] prettier fix --- ecosystem/sep-0057.md | 286 +++++++++++++++++++++++++++++++----------- 1 file changed, 213 insertions(+), 73 deletions(-) diff --git a/ecosystem/sep-0057.md b/ecosystem/sep-0057.md index 1380c23f1..c1e2dc91a 100644 --- a/ecosystem/sep-0057.md +++ b/ecosystem/sep-0057.md @@ -1,5 +1,5 @@ - ## Preamble + ``` SEP: 0057 Title: T-REX (Token for Regulated EXchanges) @@ -12,12 +12,25 @@ Discussion: https://github.com/orgs/stellar/discussions/1814 ``` ## Summary -This proposal defines a standard contract interface for T-REX (Token for Regulated EXchanges) - colloquially known as RWA token - on Stellar. T-REX tokens represent tokenized real-world assets such as securities, bonds, real estate, or other regulated financial instruments that require compliance with regulatory frameworks. T-REX tokens are **permissioned tokens**, ensuring that only eligible investors can hold and transfer these tokens. -This standard is based on the T-REX (Token for Regulated Exchanges) framework, as implemented in ERC-3643 (https://github.com/ERC-3643/ERC-3643), but introduces significant architectural improvements for flexibility and modularity. +This proposal defines a standard contract interface for T-REX (Token for +Regulated EXchanges) - colloquially known as RWA token - on Stellar. T-REX +tokens represent tokenized real-world assets such as securities, bonds, real +estate, or other regulated financial instruments that require compliance with +regulatory frameworks. T-REX tokens are **permissioned tokens**, ensuring that +only eligible investors can hold and transfer these tokens. + +This standard is based on the T-REX (Token for Regulated Exchanges) framework, +as implemented in ERC-3643 (https://github.com/ERC-3643/ERC-3643), but +introduces significant architectural improvements for flexibility and +modularity. ## Motivation -Real World Assets (RWAs) represent a significant opportunity for blockchain adoption, enabling the tokenization of traditional financial instruments and physical assets. However, unlike standard fungible tokens, RWAs must comply with complex regulatory requirements including but not limited to: + +Real World Assets (RWAs) represent a significant opportunity for blockchain +adoption, enabling the tokenization of traditional financial instruments and +physical assets. However, unlike standard fungible tokens, RWAs must comply +with complex regulatory requirements including but not limited to: - **Know Your Customer (KYC) and Anti-Money Laundering (AML)** compliance - **Identity verification** and investor accreditation @@ -25,27 +38,35 @@ Real World Assets (RWAs) represent a significant opportunity for blockchain adop - **Recovery mechanisms** for lost or compromised wallets - **Compliance hooks** for regulatory reporting -The T-REX standard provides a comprehensive framework for compliant security tokens. This SEP adapts T-REX to the Stellar ecosystem, enabling: +The T-REX standard provides a comprehensive framework for compliant security +tokens. This SEP adapts T-REX to the Stellar ecosystem, enabling: - **Modular hook-based compliance framework** with pluggable compliance rules -- **Flexible identity verification** supporting multiple approaches (claim-based, Merkle tree, zero-knowledge, etc.) +- **Flexible identity verification** supporting multiple approaches + (claim-based, Merkle tree, zero-knowledge, etc.) - **Sophisticated freezing mechanisms** at both address and token levels - **Administrative controls** with role-based access control (RBAC) ## Architecture Overview -This RWA standard introduces an approach built around **loose coupling** and **implementation abstraction**. +This RWA standard introduces an approach built around **loose coupling** and +**implementation abstraction**. ### Core Design Principles -1. **Separation of Concerns**: Core token functionality is cleanly separated from compliance and identity verification -2. **Implementation Flexibility**: Compliance and identity systems are treated as pluggable implementation details -3. **Shared Infrastructure**: Components can be shared across multiple token contracts to reduce deployment and management costs -4. **Regulatory Adaptability**: The system can adapt to different regulatory frameworks without core changes +1. **Separation of Concerns**: Core token functionality is cleanly separated + from compliance and identity verification +2. **Implementation Flexibility**: Compliance and identity systems are treated + as pluggable implementation details +3. **Shared Infrastructure**: Components can be shared across multiple token + contracts to reduce deployment and management costs +4. **Regulatory Adaptability**: The system can adapt to different regulatory + frameworks without core changes ### Component Architecture -The Stellar T-REX consists of several interconnected but loosely coupled components: +The Stellar T-REX consists of several interconnected but loosely coupled +components: ``` ┌─────────────────┐ ┌──────────────────┐ ┌─────────────────────┐ @@ -60,11 +81,17 @@ The Stellar T-REX consists of several interconnected but loosely coupled compone └─────────────────┘ └──────────────────┘ └──────────────────┘ ``` -This design enables the same core RWA token interface to work with vastly different regulatory and technical requirements for identity verification, such as Merkle trees, Zero-Knowledge proofs, claim-based systems, and others. Furthermore, the modular hook-based system supports diverse regulatory requirements through pluggable compliance rules. +This design enables the same core RWA token interface to work with vastly +different regulatory and technical requirements for identity verification, such +as Merkle trees, Zero-Knowledge proofs, claim-based systems, and others. +Furthermore, the modular hook-based system supports diverse regulatory +requirements through pluggable compliance rules. ## Interface -The RWA token interface extends the **fungible token** ([SEP-41](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0041.md)) with regulatory required features: freezing, pausing and recovery. +The RWA token interface extends the **fungible token** +([SEP-41](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0041.md)) +with regulatory required features: freezing, pausing and recovery. ### Architecture Overview @@ -79,15 +106,22 @@ fn verify_identity(e: &Env, user_address: &Address); ``` - `can_transfer()` is expected to be exposed from a "Compliance" contract. -- `verify_identity()` is expected to be exposed from an "Identity Verifier" contract. +- `verify_identity()` is expected to be exposed from an "Identity Verifier" + contract. + +These functions are **deliberately abstracted** as implementation details, +enabling: -These functions are **deliberately abstracted** as implementation details, enabling: -- **Regulatory Flexibility**: Different jurisdictions can implement different compliance logic -- **Technical Flexibility**: Various identity verification approaches (ZK, Merkle trees, claims) +- **Regulatory Flexibility**: Different jurisdictions can implement different + compliance logic +- **Technical Flexibility**: Various identity verification approaches (ZK, + Merkle trees, claims) - **Cost Optimization**: Shared contracts across multiple tokens - **Future-Proofing**: New compliance approaches without interface changes -In other words, the only thing required by this RWA token design, is that the RWA token should be able to call these expected functions made available by the compliance and identity verification contracts. +In other words, the only thing required by this RWA token design, is that the +RWA token should be able to call these expected functions made available by the +compliance and identity verification contracts. ### Contract Connection Interface @@ -110,7 +144,12 @@ To deploy a compliant RWA token and make it functional: 1. **Deploy Core RWA Token** 2. **Deploy/Connect Compliance Contract** 3. **Deploy/Connect Identity Verifier** -4. **Configure Connections**: Link the RWA token to its compliance and identity verifier contracts using `set_compliance()` and `set_identity_verifier()`. Additionally, configure internal connections within the compliance stack (e.g., linking compliance contract to compliance modules) and identity stack (e.g., linking identity verifier to claim topics/issuers or custom registries) as needed for your implementation. +4. **Configure Connections**: Link the RWA token to its compliance and identity + verifier contracts using `set_compliance()` and `set_identity_verifier()`. + Additionally, configure internal connections within the compliance stack + (e.g., linking compliance contract to compliance modules) and identity stack + (e.g., linking identity verifier to claim topics/issuers or custom + registries) as needed for your implementation. ```rust use soroban_sdk::{Address, Env, String}; @@ -381,7 +420,8 @@ pub trait RWAToken: TokenInterface { ### Transfer Event -The transfer event is emitted when RWA tokens are transferred from one address to another, including forced transfers and recovery operations. +The transfer event is emitted when RWA tokens are transferred from one address +to another, including forced transfers and recovery operations. ```rust #[contractevent] @@ -429,7 +469,8 @@ pub struct Burn { ### Recovery Event -The recovery event is emitted when tokens are successfully recovered from a lost wallet to a new wallet. +The recovery event is emitted when tokens are successfully recovered from a +lost wallet to a new wallet. ```rust #[contractevent] @@ -464,7 +505,8 @@ pub struct AddressFrozen { ### Tokens Frozen Event -The tokens frozen event is emitted when a specific amount of tokens is frozen for an address. +The tokens frozen event is emitted when a specific amount of tokens is frozen +for an address. ```rust #[contractevent] @@ -479,7 +521,8 @@ pub struct TokensFrozen { ### Tokens Unfrozen Event -The tokens unfrozen event is emitted when a specific amount of tokens is unfrozen for an address. +The tokens unfrozen event is emitted when a specific amount of tokens is +unfrozen for an address. ```rust #[contractevent] @@ -507,7 +550,8 @@ pub struct ComplianceSet { ### Identity Verifier Set Event -The identity verifier set event is emitted when the identity verifier contract is updated. +The identity verifier set event is emitted when the identity verifier contract +is updated. ```rust #[contractevent] @@ -522,7 +566,8 @@ pub struct IdentityVerifierSet { ### 1. Identity Verification System -**Philosophy**: The entire identity stack is treated as an implementation detail, enabling maximum regulatory and technical flexibility. +**Philosophy**: The entire identity stack is treated as an implementation +detail, enabling maximum regulatory and technical flexibility. #### The IdentityVerifier Trait @@ -539,31 +584,39 @@ pub trait IdentityVerifier { #### Implementation Strategies -Different regulatory environments may require different approaches. Here are some examples: +Different regulatory environments may require different approaches. Here are +some examples: **1. Claim-Based Verification (Reference Implementation)** + - **Use Case**: Traditional KYC/AML with trusted issuers -- **Components**: ClaimTopicsAndIssuers + IdentityRegistryStorage + IdentityClaims + ClaimIssuer +- **Components**: ClaimTopicsAndIssuers + IdentityRegistryStorage + + IdentityClaims + ClaimIssuer - **Benefits**: Familiar to regulators, rich metadata support **2. Merkle Tree Verification** + - **Use Case**: Privacy-focused compliance with efficient proofs -- **Components**: ClaimTopicsAndIssuers + Merkle root storage + proof validation +- **Components**: ClaimTopicsAndIssuers + Merkle root storage + proof + validation - **Benefits**: Minimal storage, efficient verification **3. Zero-Knowledge Verification** + - **Use Case**: Privacy-preserving compliance - **Components**: ClaimTopicsAndIssuers + ZK circuit + proof verification - **Benefits**: Maximum privacy, selective disclosure **4. Custom Approaches** + - **Use Case**: Jurisdiction-specific requirements - **Components**: ClaimTopicsAndIssuers + Custom verification logic - **Benefits**: Tailored to specific regulatory needs #### Reference Implementation Architecture -The claim-based reference implementation demonstrates the full complexity of traditional RWA compliance: +The claim-based reference implementation demonstrates the full complexity of +traditional RWA compliance: ``` ┌─────────────────────┐ @@ -595,16 +648,30 @@ The claim-based reference implementation demonstrates the full complexity of tra **Key Components:** -- **ClaimTopicsAndIssuers**: Registry contract managing both trusted issuers and required claim types (KYC=1, AML=2, etc.). -- **IdentityRegistryStorage**: Component storing investors identity profiles with country relations and metadata. -- **IdentityClaims**: Required for every investor as a separate contract or as an extension to existing identity management systems. Its goal is to store cryptographic claims issued to that investor by trusted claim issuers. This component is under investor's control. Its structure mirrors the evolving OnchainID specification (https://github.com/ERC-3643/ERCs/blob/erc-oid/ERCS/erc-xxxx.md). -- **ClaimIssuer**: Contracts belonging to trusted 3rd parties to validate cryptographic claims about investors' attributes by using multiple signature schemes (Ed25519, Secp256k1, Secp256r1). - -Note that, Claim-Based Identity Verification is a reference implementation, it is not a part of the specification. For detailed interface specifications of these components, see the [Appendix: Claim-Based Identity Verification Reference Implementation](#appendix-claim-based-identity-verification-reference-implementation) section. +- **ClaimTopicsAndIssuers**: Registry contract managing both trusted issuers + and required claim types (KYC=1, AML=2, etc.). +- **IdentityRegistryStorage**: Component storing investors identity profiles + with country relations and metadata. +- **IdentityClaims**: Required for every investor as a separate contract or as + an extension to existing identity management systems. Its goal is to store + cryptographic claims issued to that investor by trusted claim issuers. This + component is under investor's control. Its structure mirrors the evolving + OnchainID specification + (https://github.com/ERC-3643/ERCs/blob/erc-oid/ERCS/erc-xxxx.md). +- **ClaimIssuer**: Contracts belonging to trusted 3rd parties to validate + cryptographic claims about investors' attributes by using multiple signature + schemes (Ed25519, Secp256k1, Secp256r1). + +Note that, Claim-Based Identity Verification is a reference implementation, it +is not a part of the specification. For detailed interface specifications of +these components, see the +[Appendix: Claim-Based Identity Verification Reference Implementation](#appendix-claim-based-identity-verification-reference-implementation) +section. ### 2. Compliance System -Modular hook-based architecture supporting diverse regulatory requirements through pluggable compliance modules. +Modular hook-based architecture supporting diverse regulatory requirements +through pluggable compliance modules. #### The Compliance Trait @@ -642,24 +709,29 @@ pub enum ComplianceHook { #### Compliance Module Examples **Transfer Limits Module**: + - Hook: `CanTransfer` + `Transferred` - Logic: Enforce daily/monthly transfer limits per user **Jurisdiction Restrictions Module**: + - Hook: `CanTransfer` - Logic: Restrict transfers to blocked jurisdictions **Holding Period Module**: + - Hook: `CanTransfer` + `Created` - Logic: Enforce minimum holding periods for newly minted tokens **Investor Accreditation Module**: + - Hook: `CanCreate` - Logic: Verify investor accreditation before minting #### Shared Compliance Infrastructure -Compliance contracts are designed to be **shared across multiple RWA tokens**, reducing deployment costs and ensuring consistent regulatory enforcement: +Compliance contracts are designed to be **shared across multiple RWA tokens**, +reducing deployment costs and ensuring consistent regulatory enforcement: ``` ┌─────────────┐ ┌─────────────────────┐ ┌──────────────────┐ @@ -671,41 +743,50 @@ Compliance contracts are designed to be **shared across multiple RWA tokens**, r └─────────────┘ └─────────────────────┘ └──────────────────┘ ``` - ### 3. Advanced Token Controls #### Freezing Mechanisms -The system supports multiple freezing strategies to accommodate for different regulatory requirements: +The system supports multiple freezing strategies to accommodate for different +regulatory requirements: **Address-Level Freezing**: + ```rust fn set_address_frozen(e: &Env, user_address: Address, freeze: bool, operator: Address); fn is_frozen(e: &Env, user_address: Address) -> bool; ``` + - **Use Case**: Complete account suspension for regulatory investigations - **Effect**: Prevents all token operations (send/receive) **Partial Token Freezing**: + ```rust fn freeze_partial_tokens(e: &Env, user_address: Address, amount: i128, operator: Address); fn unfreeze_partial_tokens(e: &Env, user_address: Address, amount: i128, operator: Address); fn get_frozen_tokens(e: &Env, user_address: Address) -> i128; ``` + - **Use Case**: Escrow scenarios, disputed transactions -- **Effect**: Freezes specific token amounts while allowing operations on remaining balance +- **Effect**: Freezes specific token amounts while allowing operations on + remaining balance #### Recovery System Two distinct recovery flows are supported: -1. Identity Recovery: Managed in the Identity Stack (Identity Registry Storage), transfers the identity contract reference and profile (including country data) from old account to new account, and creates a recovery mapping. +1. Identity Recovery: Managed in the Identity Stack (Identity Registry + Storage), transfers the identity contract reference and profile (including + country data) from old account to new account, and creates a recovery + mapping. ```rust fn recover_identity(e: &Env, old_account: Address, new_account: Address, operator: Address); ``` -2. Balance Recovery: Managed by the RWA token, transfers tokens from old to new account after verifying the identity recovery mapping exists +2. Balance Recovery: Managed by the RWA token, transfers tokens from old to new + account after verifying the identity recovery mapping exists ```rust fn recover_balance(e: &Env, old_account: Address, new_account: Address, operator: Address) -> bool; @@ -721,31 +802,44 @@ fn forced_transfer(e: &Env, from: Address, to: Address, amount: i128, operator: - **Use Case**: Court-ordered asset transfers, regulatory seizures - **Authorization**: Requires operator with forced transfer permissions -- **Compliance**: Bypasses normal compliance validation checks (operator responsibility) +- **Compliance**: Bypasses normal compliance validation checks (operator + responsibility) ### 4. Access Control & Governance -RWA tokens require proper access control to ensure that sensitive operations are only performed by authorized entities: +RWA tokens require proper access control to ensure that sensitive operations +are only performed by authorized entities: -- **Operator Authorization**: All administrative functions require `operator` authorization -- **Flexible Access Control**: While the RWA interface itself doesn't prescribe a specific access control model, implementations can integrate with external access control systems as needed -- **Compliance Integration**: Access control permissions should be integrated with compliance rules to ensure regulatory requirements are met +- **Operator Authorization**: All administrative functions require `operator` + authorization +- **Flexible Access Control**: While the RWA interface itself doesn't prescribe + a specific access control model, implementations can integrate with external + access control systems as needed +- **Compliance Integration**: Access control permissions should be integrated + with compliance rules to ensure regulatory requirements are met ## Extensions -The RWA token standard can be extended with additional functionality beyond the core specification. Extensions are optional modules that add specialized features while maintaining compatibility with the base RWA interface. +The RWA token standard can be extended with additional functionality beyond the +core specification. Extensions are optional modules that add specialized +features while maintaining compatibility with the base RWA interface. ### Document Manager (ERC-1643) -The Document Manager extension provides document management capabilities for RWA tokens, following the ERC-1643 standard. This is particularly useful for attaching legal documents, prospectuses, or regulatory disclosures to token contracts. +The Document Manager extension provides document management capabilities for +RWA tokens, following the ERC-1643 standard. This is particularly useful for +attaching legal documents, prospectuses, or regulatory disclosures to token +contracts. **Key Features:** + - Attach documents with URI, hash, and timestamp - Update existing document metadata - Remove documents from the contract - Retrieve individual or all documents **Use Cases:** + - Legal agreements and terms of service - Offering memorandums and prospectuses - Regulatory compliance documents @@ -753,63 +847,95 @@ The Document Manager extension provides document management capabilities for RWA ### Custom Extensions -Implementers are free to create custom extensions tailored to their specific requirements. +Implementers are free to create custom extensions tailored to their specific +requirements. ## Deviations from ERC-3643 -Several limitations in the original ERC-3643 standard and its reference implementation were identified and respectively addressed: +Several limitations in the original ERC-3643 standard and its reference +implementation were identified and respectively addressed: **1. Tight Coupling Issues** -- **Problem**: ERC-3643 tightly couples identity verification with specific contract structures -- **Solution**: Abstract identity verification as pluggable implementation detail + +- **Problem**: ERC-3643 tightly couples identity verification with specific + contract structures +- **Solution**: Abstract identity verification as pluggable implementation + detail **2. Inflexible Identity Models** -- **Problem**: Hardcoded ERC-734/735 identity contracts don't translate to all blockchain architectures -- **Solution**: Support multiple identity verification approaches (Merkle, ZK, claims, custom) + +- **Problem**: Hardcoded ERC-734/735 identity contracts don't translate to all + blockchain architectures +- **Solution**: Support multiple identity verification approaches (Merkle, ZK, + claims, custom) **3. Redundant Contract Hierarchies** -- **Problem**: Complex IdentityRegistry ↔ IdentityRegistryStorage relationships + +- **Problem**: Complex IdentityRegistry ↔ IdentityRegistryStorage + relationships - **Solution**: Direct access patterns **4. Limited Compliance Flexibility** + - **Problem**: Monolithic compliance validation - **Solution**: Modular hook-based compliance system ## Upgrade and Migration Strategies **Compliance Evolution**: + - Modular compliance system supports rule updates without token redeployment - New compliance modules can be added for evolving regulations **Identity System Migration**: -- Abstract identity verification enables migration between verification approaches + +- Abstract identity verification enables migration between verification + approaches - Gradual migration strategies for existing user bases -For general contract upgrade patterns and best practices, refer to [SEP-49: Upgradeable Contracts](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0049.md). +For general contract upgrade patterns and best practices, refer to +[SEP-49: Upgradeable Contracts](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0049.md). --- ## Appendix: Claim-Based Identity Verification Reference Implementation -> **IMPORTANT NOTICE**: This appendix describes a **reference implementation** and is **NOT a part of the RWA token specification**. The RWA standard only requires that an `IdentityVerifier` contract exposing a `verify_identity()` function. The claim-based approach described here is one possible implementation among many (others include Merkle tree verification, zero-knowledge proofs, or custom approaches). This section is provided for informational purposes to demonstrate a complete, production-ready implementation that follows traditional KYC/AML compliance patterns. +> **IMPORTANT NOTICE**: This appendix describes a **reference implementation** +> and is **NOT a part of the RWA token specification**. The RWA standard only +> requires that an `IdentityVerifier` contract exposing a `verify_identity()` +> function. The claim-based approach described here is one possible +> implementation among many (others include Merkle tree verification, +> zero-knowledge proofs, or custom approaches). This section is provided for +> informational purposes to demonstrate a complete, production-ready +> implementation that follows traditional KYC/AML compliance patterns. ### Overview -The claim-based approach uses cryptographic claims issued by trusted authorities (KYC providers, compliance firms) to verify investor identities. This implementation consists of four main components that work together: +The claim-based approach uses cryptographic claims issued by trusted +authorities (KYC providers, compliance firms) to verify investor identities. +This implementation consists of four main components that work together: -1. **ClaimTopicsAndIssuers**: Trust registry defining required claim types and authorized issuers -2. **IdentityRegistryStorage**: Storage for investor identity profiles and country relations +1. **ClaimTopicsAndIssuers**: Trust registry defining required claim types and + authorized issuers +2. **IdentityRegistryStorage**: Storage for investor identity profiles and + country relations 3. **IdentityClaims**: Per-investor contract storing cryptographic claims 4. **ClaimIssuer**: Validator contracts operated by trusted third parties ### ClaimTopicsAndIssuers Interface -The `ClaimTopicsAndIssuers` contract acts as the trust registry, defining which claim topics are required for token participation and which issuers are authorized to provide those claims. +The `ClaimTopicsAndIssuers` contract acts as the trust registry, defining which +claim topics are required for token participation and which issuers are +authorized to provide those claims. **Purpose:** -- Maintains a registry of trusted claim issuers (e.g., KYC providers, compliance firms) -- Defines which types of claims are required (e.g., KYC=1, AML=2, Accredited Investor=3) -- Maps each trusted issuer to the specific claim topics they are authorized to issue + +- Maintains a registry of trusted claim issuers (e.g., KYC providers, + compliance firms) +- Defines which types of claims are required (e.g., KYC=1, AML=2, Accredited + Investor=3) +- Maps each trusted issuer to the specific claim topics they are authorized to + issue - Can be shared across multiple RWA tokens to reduce deployment costs **Interface:** @@ -974,11 +1100,14 @@ pub trait ClaimTopicsAndIssuers { fn has_claim_topic(e: &Env, issuer: Address, claim_topic: u32) -> bool; } ``` + ### IdentityRegistryStorage Interface -The `IdentityRegistryStorage` contract stores identity information for verified investors, including their identity contract references and country relations. +The `IdentityRegistryStorage` contract stores identity information for verified +investors, including their identity contract references and country relations. **Purpose:** + - Maps wallet addresses to their onchain identity contracts - Stores country information for regulatory compliance - Supports both individual and organizational identities @@ -1090,9 +1219,12 @@ pub trait IdentityRegistryStorage: TokenBinder { ### IdentityClaims Interface -The `IdentityClaims` contract manages on-chain identity claims with cryptographic signatures. This contract is controlled by the investor and stores claims issued by trusted authorities. +The `IdentityClaims` contract manages on-chain identity claims with +cryptographic signatures. This contract is controlled by the investor and +stores claims issued by trusted authorities. **Purpose:** + - Store cryptographic claims issued to an investor - Manage claim lifecycle (add, retrieve, remove) - Support multiple claims per topic from different issuers @@ -1154,6 +1286,7 @@ pub trait IdentityClaims { **Claim Structure:** Each claim contains: + - **Topic**: Numeric identifier (e.g., KYC=1, AML=2) - **Scheme**: Signature algorithm identifier - **Issuer**: Address of the claim issuer contract @@ -1163,9 +1296,12 @@ Each claim contains: ### ClaimIssuer Interface -The `ClaimIssuer` contract validates cryptographic claims about investors. These contracts are operated by trusted third parties (KYC providers, compliance firms). +The `ClaimIssuer` contract validates cryptographic claims about investors. +These contracts are operated by trusted third parties (KYC providers, +compliance firms). **Purpose:** + - Validate cryptographic signatures on claims - Support multiple signature schemes (Ed25519, Secp256k1, Secp256r1) - Manage claim revocation and expiration @@ -1200,10 +1336,12 @@ pub trait ClaimIssuer { ### Verification Flow -The following describes how these components work together during token operations: +The following describes how these components work together during token +operations: 1. **Off-chain**: Investor submits identity documents to KYC Provider -2. **Off-chain**: KYC Provider verifies identity and signs claim with private key +2. **Off-chain**: KYC Provider verifies identity and signs claim with private + key 3. **On-chain**: Signed claim is stored in investor's IdentityClaims contract 4. **On-chain**: During token operations (transfer/mint), the RWA Token: - Calls IdentityVerifier's `verify_identity()` @@ -1213,4 +1351,6 @@ The following describes how these components work together during token operatio - Revocation status is checked - Issuer trust is verified via ClaimTopicsAndIssuers -**Note**: The KYC Provider and Claim Issuer are the same entity. Signing happens off-chain; only the signed claim and revocation data are stored on-chain. +**Note**: The KYC Provider and Claim Issuer are the same entity. Signing +happens off-chain; only the signed claim and revocation data are stored +on-chain. From ec6d96ddd27ed47bee55d984d023d865107d8771 Mon Sep 17 00:00:00 2001 From: Ozgun Ozerk Date: Wed, 3 Dec 2025 16:59:39 +0300 Subject: [PATCH 3/8] add dennis as an author --- ecosystem/sep-0057.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ecosystem/sep-0057.md b/ecosystem/sep-0057.md index c1e2dc91a..0bcbe0e8f 100644 --- a/ecosystem/sep-0057.md +++ b/ecosystem/sep-0057.md @@ -3,7 +3,7 @@ ``` SEP: 0057 Title: T-REX (Token for Regulated EXchanges) -Author: OpenZeppelin, Boyan Barakov <@brozorec>, Özgün Özerk <@ozgunozerk> +Author: OpenZeppelin, Boyan Barakov <@brozorec>, Özgün Özerk <@ozgunozerk>, Dennis O'Connell <@droconnel22> Status: Draft Created: 2025-11-26 Updated: 2025-11-26 From ad38ab5f93956d28b0cc1cac63b5b3e89c34da95 Mon Sep 17 00:00:00 2001 From: Ozgun Ozerk Date: Mon, 8 Dec 2025 13:18:04 +0300 Subject: [PATCH 4/8] suggestions --- ecosystem/sep-0057.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/ecosystem/sep-0057.md b/ecosystem/sep-0057.md index 0bcbe0e8f..5480e2575 100644 --- a/ecosystem/sep-0057.md +++ b/ecosystem/sep-0057.md @@ -13,12 +13,13 @@ Discussion: https://github.com/orgs/stellar/discussions/1814 ## Summary -This proposal defines a standard contract interface for T-REX (Token for -Regulated EXchanges) - colloquially known as RWA token - on Stellar. T-REX -tokens represent tokenized real-world assets such as securities, bonds, real -estate, or other regulated financial instruments that require compliance with -regulatory frameworks. T-REX tokens are **permissioned tokens**, ensuring that -only eligible investors can hold and transfer these tokens. +This proposal defines a comprehensive suite of smart contracts for T-REX (Token +for Regulated EXchanges) - colloquially known as RWA token - on Stellar. T-REX +tokens represent tokenized real-world assets such as securities, real estate, +or other regulated financial instruments that require compliance with +regulatory frameworks. T-REX tokens are **permissioned tokens**, ensuring +secure and compliant transactions for all parties involved in the token +transfer. This standard is based on the T-REX (Token for Regulated Exchanges) framework, as implemented in ERC-3643 (https://github.com/ERC-3643/ERC-3643), but @@ -49,7 +50,7 @@ tokens. This SEP adapts T-REX to the Stellar ecosystem, enabling: ## Architecture Overview -This RWA standard introduces an approach built around **loose coupling** and +This T-REX standard introduces an approach built around **loose coupling** and **implementation abstraction**. ### Core Design Principles From 896ba1d5f95701d5e23e975c895a902c4f2903c8 Mon Sep 17 00:00:00 2001 From: Jane Wang Date: Mon, 15 Dec 2025 22:23:13 -0500 Subject: [PATCH 5/8] Rename RWA to T-REX --- ecosystem/sep-0057.md | 64 +++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/ecosystem/sep-0057.md b/ecosystem/sep-0057.md index 5480e2575..f756b6bed 100644 --- a/ecosystem/sep-0057.md +++ b/ecosystem/sep-0057.md @@ -6,7 +6,7 @@ Title: T-REX (Token for Regulated EXchanges) Author: OpenZeppelin, Boyan Barakov <@brozorec>, Özgün Özerk <@ozgunozerk>, Dennis O'Connell <@droconnel22> Status: Draft Created: 2025-11-26 -Updated: 2025-11-26 +Updated: 2025-12-15 Version: 0.1.0 Discussion: https://github.com/orgs/stellar/discussions/1814 ``` @@ -71,18 +71,18 @@ components: ``` ┌─────────────────┐ ┌──────────────────┐ ┌─────────────────────┐ -│ RWA Token │───▶│ Compliance │───▶│ Compliance Modules │ +│ T-REX │───▶│ Compliance │───▶│ Compliance Modules │ │ (Core) │ │ │ │ (Pluggable Rules) │ └─────────────────┘ └──────────────────┘ └─────────────────────┘ │ ▼ -┌─────────────────┐ ┌──────────────────┐ ┌──────────────────┐ -│ Identity │───▶│ Claim Topics & │ │ Identity Registry│ -│ Verifier │ │ Issuers │───▶│ │ -└─────────────────┘ └──────────────────┘ └──────────────────┘ +┌─────────────────┐ ┌──────────────────┐ ┌─────────────────-─┐ +│ Identity │───▶│ Claim Topics & │ │ Identity Registry │ +│ Verifier │ │ Issuers │───▶│ │ +└─────────────────┘ └──────────────────┘ └─────────────────-─┘ ``` -This design enables the same core RWA token interface to work with vastly +This design enables the same core T-REX interface to work with vastly different regulatory and technical requirements for identity verification, such as Merkle trees, Zero-Knowledge proofs, claim-based systems, and others. Furthermore, the modular hook-based system supports diverse regulatory @@ -90,13 +90,13 @@ requirements through pluggable compliance rules. ## Interface -The RWA token interface extends the **fungible token** +The T-REX interface extends the **fungible token** ([SEP-41](https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0041.md)) with regulatory required features: freezing, pausing and recovery. ### Architecture Overview -The RWA token contract requires only **two external functions** to operate: +The T-REX token contract requires only **two external functions** to operate: ```rust // Compliance validation - returns true if transfer is allowed @@ -120,13 +120,13 @@ enabling: - **Cost Optimization**: Shared contracts across multiple tokens - **Future-Proofing**: New compliance approaches without interface changes -In other words, the only thing required by this RWA token design, is that the -RWA token should be able to call these expected functions made available by the +In other words, the only thing required by this T-REX design, is that the token +should be able to call these expected functions made available by the compliance and identity verification contracts. ### Contract Connection Interface -The RWA token provides simple setter/getter functions for external contracts: +The token contract provides simple setter/getter functions for external contracts: ```rust // Compliance Contract Management @@ -140,12 +140,12 @@ fn identity_verifier(e: &Env) -> Address; ### Integration Pattern -To deploy a compliant RWA token and make it functional: +To deploy a compliant T-REX token and make it functional: -1. **Deploy Core RWA Token** +1. **Deploy Core Token Contract** 2. **Deploy/Connect Compliance Contract** 3. **Deploy/Connect Identity Verifier** -4. **Configure Connections**: Link the RWA token to its compliance and identity +4. **Configure Connections**: Link the T-REX token to its compliance and identity verifier contracts using `set_compliance()` and `set_identity_verifier()`. Additionally, configure internal connections within the compliance stack (e.g., linking compliance contract to compliance modules) and identity stack @@ -421,7 +421,7 @@ pub trait RWAToken: TokenInterface { ### Transfer Event -The transfer event is emitted when RWA tokens are transferred from one address +The transfer event is emitted when tokens are transferred from one address to another, including forced transfers and recovery operations. ```rust @@ -440,7 +440,7 @@ pub struct Transfer { ### Mint Event -The mint event is emitted when RWA tokens are minted to a verified address. +The mint event is emitted when tokens are minted to a verified address. ```rust #[contractevent] @@ -455,7 +455,7 @@ pub struct Mint { ### Burn Event -The burn event is emitted when RWA tokens are burned from an address. +The burn event is emitted when tokens are burned from an address. ```rust #[contractevent] @@ -617,7 +617,7 @@ some examples: #### Reference Implementation Architecture The claim-based reference implementation demonstrates the full complexity of -traditional RWA compliance: +traditional T-REX compliance: ``` ┌─────────────────────┐ @@ -731,16 +731,16 @@ pub enum ComplianceHook { #### Shared Compliance Infrastructure -Compliance contracts are designed to be **shared across multiple RWA tokens**, +Compliance contracts are designed to be **shared across multiple T-REX tokens**, reducing deployment costs and ensuring consistent regulatory enforcement: ``` ┌─────────────┐ ┌─────────────────────┐ ┌──────────────────┐ -│ RWA Token A │───▶│ │───▶│ Transfer Limits │ +│ Token A │───▶│ │───▶│ Transfer Limits │ ├─────────────┤ │ Shared Compliance │ │ Module │ -│ RWA Token B │───▶│ Contract │───▶├──────────────────┤ +│ Token B │───▶│ Contract │───▶├──────────────────┤ ├─────────────┤ │ │ │ Jurisdiction │ -│ RWA Token C │───▶│ │ │ Module │ +│ Token C │───▶│ │ │ Module │ └─────────────┘ └─────────────────────┘ └──────────────────┘ ``` @@ -786,7 +786,7 @@ Two distinct recovery flows are supported: fn recover_identity(e: &Env, old_account: Address, new_account: Address, operator: Address); ``` -2. Balance Recovery: Managed by the RWA token, transfers tokens from old to new +2. Balance Recovery: Managed by the T-REX token, transfers tokens from old to new account after verifying the identity recovery mapping exists ```rust @@ -808,12 +808,12 @@ fn forced_transfer(e: &Env, from: Address, to: Address, amount: i128, operator: ### 4. Access Control & Governance -RWA tokens require proper access control to ensure that sensitive operations +T-REX tokens require proper access control to ensure that sensitive operations are only performed by authorized entities: - **Operator Authorization**: All administrative functions require `operator` authorization -- **Flexible Access Control**: While the RWA interface itself doesn't prescribe +- **Flexible Access Control**: While the T-REX interface itself doesn't prescribe a specific access control model, implementations can integrate with external access control systems as needed - **Compliance Integration**: Access control permissions should be integrated @@ -821,14 +821,14 @@ are only performed by authorized entities: ## Extensions -The RWA token standard can be extended with additional functionality beyond the +The T-REX standard can be extended with additional functionality beyond the core specification. Extensions are optional modules that add specialized -features while maintaining compatibility with the base RWA interface. +features while maintaining compatibility with the base T-REX interface. ### Document Manager (ERC-1643) The Document Manager extension provides document management capabilities for -RWA tokens, following the ERC-1643 standard. This is particularly useful for +T-REX tokens, following the ERC-1643 standard. This is particularly useful for attaching legal documents, prospectuses, or regulatory disclosures to token contracts. @@ -902,7 +902,7 @@ For general contract upgrade patterns and best practices, refer to ## Appendix: Claim-Based Identity Verification Reference Implementation > **IMPORTANT NOTICE**: This appendix describes a **reference implementation** -> and is **NOT a part of the RWA token specification**. The RWA standard only +> and is **NOT a part of the T-REX specification**. The T-REX standard only > requires that an `IdentityVerifier` contract exposing a `verify_identity()` > function. The claim-based approach described here is one possible > implementation among many (others include Merkle tree verification, @@ -937,7 +937,7 @@ authorized to provide those claims. Investor=3) - Maps each trusted issuer to the specific claim topics they are authorized to issue -- Can be shared across multiple RWA tokens to reduce deployment costs +- Can be shared across multiple tokens to reduce deployment costs **Interface:** @@ -1344,7 +1344,7 @@ operations: 2. **Off-chain**: KYC Provider verifies identity and signs claim with private key 3. **On-chain**: Signed claim is stored in investor's IdentityClaims contract -4. **On-chain**: During token operations (transfer/mint), the RWA Token: +4. **On-chain**: During token operations (transfer/mint), the token contract: - Calls IdentityVerifier's `verify_identity()` - Required claim topics from ClaimTopicsAndIssuers is retrieved - Claims from investor's IdentityClaims contract are fetched From 547fa0b3dde9ab1c7dfc4ea2adf3cd5e48fb55f1 Mon Sep 17 00:00:00 2001 From: Leigh <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 19 Dec 2025 15:57:57 +1000 Subject: [PATCH 6/8] add changelog section to sep-0057 --- ecosystem/sep-0057.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ecosystem/sep-0057.md b/ecosystem/sep-0057.md index f756b6bed..332eab49f 100644 --- a/ecosystem/sep-0057.md +++ b/ecosystem/sep-0057.md @@ -1355,3 +1355,9 @@ operations: **Note**: The KYC Provider and Claim Issuer are the same entity. Signing happens off-chain; only the signed claim and revocation data are stored on-chain. + +--- + +## Changelog + +- `v0.1.0` - Initial draft From f6ff175fc6e699921dc480c2b43e7710d282241a Mon Sep 17 00:00:00 2001 From: Leigh <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 19 Dec 2025 16:00:55 +1000 Subject: [PATCH 7/8] align author column and add SEP-0057 --- ecosystem/README.md | 55 +++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/ecosystem/README.md b/ecosystem/README.md index d331c32ef..afa06098f 100644 --- a/ecosystem/README.md +++ b/ecosystem/README.md @@ -73,33 +73,34 @@ All SEPs have individuals fulfilling the following roles: ### Draft Proposals -| Number | Title | Author | Status | -| ----------------------- | -------------------------------------------------------------- | -------------------------------------------------- | -------------------- | -| [SEP-0015](sep-0015.md) | Attachment Convention | Interstellar | Draft | -| [SEP-0016](sep-0016.md) | Account Transfer Permissionless Payment Protocol (@p2p) | Jeremy Rubin | Draft | -| [SEP-0017](sep-0017.md) | Issuer account funding protocol (CAP-13 Based) | Tom Quisel | Draft | -| [SEP-0019](sep-0019.md) | Bootstrapping Multisig Transaction Submission | Paul Selden, Nikhil Saraf | Draft | -| [SEP-0021](sep-0021.md) | On-chain signature & transaction sharing | Mister.Ticot | Draft | -| [SEP-0022](sep-0022.md) | IPFS Support | Samuel B. Sendelbach | Draft | -| [SEP-0030](sep-0030.md) | Recoverysigner: multi-party key management of Stellar accounts | Leigh McCulloch, Lindsay Lin | Draft | -| [SEP-0032](sep-0032.md) | Asset Address | Leigh McCulloch | Draft | -| [SEP-0034](sep-0034.md) | Wallet Attribution for Anchors | Jake Urban and Leigh McCulloch | Final Comment Period | -| [SEP-0035](sep-0035.md) | Operation IDs | Isaiah Turner, Debnil Sur, Scott Fleckenstein | Draft | -| [SEP-0037](sep-0037.md) | Address Directory API | OrbitLens | Draft | -| [SEP-0038](sep-0038.md) | Anchor RFQ API | Jake Urban and Leigh McCulloch | Draft | -| [SEP-0039](sep-0039.md) | Interoperability Recommendations for NFTs | SDF, Litemint.io | Active | -| [SEP-0040](sep-0040.md) | Oracle Consumer Interface | Alex Mootz, OrbitLens, Markus Paulson-Luna | Draft | -| [SEP-0041](sep-0041.md) | Soroban Token Interface | Jonathan Jove, Siddharth Suresh | Draft | -| [SEP-0045](sep-0045.md) | Stellar Web Authentication for Contract Accounts | Philip Liu, Marcelo Salloum, Leigh McCulloch | Draft | -| [SEP-0047](sep-0047.md) | Contract Interface Discovery | Leigh McCulloch | Draft | -| [SEP-0049](sep-0049.md) | Upgradeable Contracts | OpenZeppelin, Boyan Barakov, Özgün Özerk | Draft | -| [SEP-0050](sep-0050.md) | Non-Fungible Tokens | OpenZeppelin, Boyan Barakov, Özgün Özerk | Draft | -| [SEP-0051](sep-0051.md) | XDR-JSON | Leigh McCulloch | Draft | -| [SEP-0052](sep-0052.md) | Key Sharing Method for Stellar Keys | Pamphile Roy, Jun Luo | Draft | -| [SEP-0053](sep-0053.md) | Sign and Verify Messages | Jun Luo, Pamphile Roy, OrbitLens, Piyal Basu | Draft | -| [SEP-0054](sep-0054.md) | Ledger Metadata Storage | Tamir Sen | Draft | -| [SEP-0055](sep-0055.md) | Contract Build Info | Nando Vieira | Draft | -| [SEP-0056](sep-0056.md) | Tokenized Vault Standard | OpenZeppelin, Boyan Barakov, Özgün Özerk, Sentinel | Draft | +| Number | Title | Author | Status | +| ----------------------- | -------------------------------------------------------------- | ---------------------------------------------------------- | -------------------- | +| [SEP-0015](sep-0015.md) | Attachment Convention | Interstellar | Draft | +| [SEP-0016](sep-0016.md) | Account Transfer Permissionless Payment Protocol (@p2p) | Jeremy Rubin | Draft | +| [SEP-0017](sep-0017.md) | Issuer account funding protocol (CAP-13 Based) | Tom Quisel | Draft | +| [SEP-0019](sep-0019.md) | Bootstrapping Multisig Transaction Submission | Paul Selden, Nikhil Saraf | Draft | +| [SEP-0021](sep-0021.md) | On-chain signature & transaction sharing | Mister.Ticot | Draft | +| [SEP-0022](sep-0022.md) | IPFS Support | Samuel B. Sendelbach | Draft | +| [SEP-0030](sep-0030.md) | Recoverysigner: multi-party key management of Stellar accounts | Leigh McCulloch, Lindsay Lin | Draft | +| [SEP-0032](sep-0032.md) | Asset Address | Leigh McCulloch | Draft | +| [SEP-0034](sep-0034.md) | Wallet Attribution for Anchors | Jake Urban and Leigh McCulloch | Final Comment Period | +| [SEP-0035](sep-0035.md) | Operation IDs | Isaiah Turner, Debnil Sur, Scott Fleckenstein | Draft | +| [SEP-0037](sep-0037.md) | Address Directory API | OrbitLens | Draft | +| [SEP-0038](sep-0038.md) | Anchor RFQ API | Jake Urban and Leigh McCulloch | Draft | +| [SEP-0039](sep-0039.md) | Interoperability Recommendations for NFTs | SDF, Litemint.io | Active | +| [SEP-0040](sep-0040.md) | Oracle Consumer Interface | Alex Mootz, OrbitLens, Markus Paulson-Luna | Draft | +| [SEP-0041](sep-0041.md) | Soroban Token Interface | Jonathan Jove, Siddharth Suresh | Draft | +| [SEP-0045](sep-0045.md) | Stellar Web Authentication for Contract Accounts | Philip Liu, Marcelo Salloum, Leigh McCulloch | Draft | +| [SEP-0047](sep-0047.md) | Contract Interface Discovery | Leigh McCulloch | Draft | +| [SEP-0049](sep-0049.md) | Upgradeable Contracts | OpenZeppelin, Boyan Barakov, Özgün Özerk | Draft | +| [SEP-0050](sep-0050.md) | Non-Fungible Tokens | OpenZeppelin, Boyan Barakov, Özgün Özerk | Draft | +| [SEP-0051](sep-0051.md) | XDR-JSON | Leigh McCulloch | Draft | +| [SEP-0052](sep-0052.md) | Key Sharing Method for Stellar Keys | Pamphile Roy, Jun Luo | Draft | +| [SEP-0053](sep-0053.md) | Sign and Verify Messages | Jun Luo, Pamphile Roy, OrbitLens, Piyal Basu | Draft | +| [SEP-0054](sep-0054.md) | Ledger Metadata Storage | Tamir Sen | Draft | +| [SEP-0055](sep-0055.md) | Contract Build Info | Nando Vieira | Draft | +| [SEP-0056](sep-0056.md) | Tokenized Vault Standard | OpenZeppelin, Boyan Barakov, Özgün Özerk, Sentinel | Draft | +| [SEP-0057](sep-0057.md) | T-REX (Token for Regulated EXchanges) | OpenZeppelin, Boyan Barakov, Özgün Özerk, Dennis O'Connell | Draft | ### Abandoned Proposals From 7c40ce7ee8145e822550d5602bc3d9510c263d63 Mon Sep 17 00:00:00 2001 From: Leigh <351529+leighmcculloch@users.noreply.github.com> Date: Fri, 19 Dec 2025 16:01:47 +1000 Subject: [PATCH 8/8] reflow text in sep-0057.md --- ecosystem/sep-0057.md | 47 ++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/ecosystem/sep-0057.md b/ecosystem/sep-0057.md index 332eab49f..2fea19aae 100644 --- a/ecosystem/sep-0057.md +++ b/ecosystem/sep-0057.md @@ -82,11 +82,11 @@ components: └─────────────────┘ └──────────────────┘ └─────────────────-─┘ ``` -This design enables the same core T-REX interface to work with vastly -different regulatory and technical requirements for identity verification, such -as Merkle trees, Zero-Knowledge proofs, claim-based systems, and others. -Furthermore, the modular hook-based system supports diverse regulatory -requirements through pluggable compliance rules. +This design enables the same core T-REX interface to work with vastly different +regulatory and technical requirements for identity verification, such as Merkle +trees, Zero-Knowledge proofs, claim-based systems, and others. Furthermore, the +modular hook-based system supports diverse regulatory requirements through +pluggable compliance rules. ## Interface @@ -126,7 +126,8 @@ compliance and identity verification contracts. ### Contract Connection Interface -The token contract provides simple setter/getter functions for external contracts: +The token contract provides simple setter/getter functions for external +contracts: ```rust // Compliance Contract Management @@ -145,12 +146,12 @@ To deploy a compliant T-REX token and make it functional: 1. **Deploy Core Token Contract** 2. **Deploy/Connect Compliance Contract** 3. **Deploy/Connect Identity Verifier** -4. **Configure Connections**: Link the T-REX token to its compliance and identity - verifier contracts using `set_compliance()` and `set_identity_verifier()`. - Additionally, configure internal connections within the compliance stack - (e.g., linking compliance contract to compliance modules) and identity stack - (e.g., linking identity verifier to claim topics/issuers or custom - registries) as needed for your implementation. +4. **Configure Connections**: Link the T-REX token to its compliance and + identity verifier contracts using `set_compliance()` and + `set_identity_verifier()`. Additionally, configure internal connections + within the compliance stack (e.g., linking compliance contract to compliance + modules) and identity stack (e.g., linking identity verifier to claim + topics/issuers or custom registries) as needed for your implementation. ```rust use soroban_sdk::{Address, Env, String}; @@ -421,8 +422,8 @@ pub trait RWAToken: TokenInterface { ### Transfer Event -The transfer event is emitted when tokens are transferred from one address -to another, including forced transfers and recovery operations. +The transfer event is emitted when tokens are transferred from one address to +another, including forced transfers and recovery operations. ```rust #[contractevent] @@ -731,8 +732,9 @@ pub enum ComplianceHook { #### Shared Compliance Infrastructure -Compliance contracts are designed to be **shared across multiple T-REX tokens**, -reducing deployment costs and ensuring consistent regulatory enforcement: +Compliance contracts are designed to be **shared across multiple T-REX +tokens**, reducing deployment costs and ensuring consistent regulatory +enforcement: ``` ┌─────────────┐ ┌─────────────────────┐ ┌──────────────────┐ @@ -786,8 +788,8 @@ Two distinct recovery flows are supported: fn recover_identity(e: &Env, old_account: Address, new_account: Address, operator: Address); ``` -2. Balance Recovery: Managed by the T-REX token, transfers tokens from old to new - account after verifying the identity recovery mapping exists +2. Balance Recovery: Managed by the T-REX token, transfers tokens from old to + new account after verifying the identity recovery mapping exists ```rust fn recover_balance(e: &Env, old_account: Address, new_account: Address, operator: Address) -> bool; @@ -813,9 +815,9 @@ are only performed by authorized entities: - **Operator Authorization**: All administrative functions require `operator` authorization -- **Flexible Access Control**: While the T-REX interface itself doesn't prescribe - a specific access control model, implementations can integrate with external - access control systems as needed +- **Flexible Access Control**: While the T-REX interface itself doesn't + prescribe a specific access control model, implementations can integrate with + external access control systems as needed - **Compliance Integration**: Access control permissions should be integrated with compliance rules to ensure regulatory requirements are met @@ -872,8 +874,7 @@ implementation were identified and respectively addressed: **3. Redundant Contract Hierarchies** -- **Problem**: Complex IdentityRegistry ↔ IdentityRegistryStorage - relationships +- **Problem**: Complex IdentityRegistry ↔ IdentityRegistryStorage relationships - **Solution**: Direct access patterns **4. Limited Compliance Flexibility**