Tenzro Testnet is live. Get testnet TNZO

ERC-3643: T-REX Compliance

ERC-3643 (Token for Regulated EXchanges, or T-REX) is the standard for permissioned security tokens and real-world asset (RWA) tokenization. It enforces compliance rules at the token contract level — every transfer is checked against an on-chain compliance registry before execution. Tenzro integrates ERC-3643 with the TDIP identity system, allowing compliance checks to reference verified identity claims (KYC, accreditation, jurisdiction) directly from decentralized identities rather than requiring a separate off-chain compliance database.

How It Works

When a transfer is attempted on an ERC-3643 token, the token contract calls can_transfer() on the ComplianceRegistry before allowing execution. The registry evaluates a configurable set of compliance rules against the sender and recipient identities. If any rule fails, the transfer is rejected with a specific reason code.

Transfer Request
       
       
┌──────────────────────┐
  Token Contract      
  (ERC-3643)          
  transfer(to, amount)
└──────────┬───────────┘
            can_transfer(from, to, amount)?
           
┌──────────────────────────────────────────┐
           ComplianceRegistry             
                                          
  ┌─────────┐  ┌──────────┐  ┌────────┐  
  │KYC Check│  │Accred.     │Country   
   Tier≥2    │Check       │Restrict│  
  └────┬────┘  └────┬─────┘  └───┬────┘  
                                        
  ┌────▼────┐  ┌────▼─────┐  ┌───▼────┐  
  │Freeze     │Amount      │Holding   
  │Check      │Limit       │Period    
  └────┬────┘  └────┬─────┘  └───┬────┘  
                                        
  ┌────▼────┐  ┌────▼─────┐  ┌───▼────┐  
  │Max        │Whitelist   │Custom    
  │Holders    │Check       │Rules     
  └─────────┘  └──────────┘  └────────┘  
                                          
        TDIP Identity Resolution          
  did:tenzro:human:{uuid}  claims       
└──────────────────────────────────────────┘
           
           
     Transfer Allowed  OR   ComplianceViolation

Compliance Checks

The ComplianceRegistry supports the following built-in compliance rules. Each rule can be enabled or disabled per token, and custom rules can be added through the plugin interface.

RuleCheckFailure Code
KYC TierBoth sender and recipient must have TDIP identity with KYC tier at or above the configured minimum (default: Enhanced / tier 2)INSUFFICIENT_KYC
Accredited InvestorRecipient must hold a valid AccreditedInvestor credential issued by a trusted issuerNOT_ACCREDITED
Country RestrictionSender and recipient country claims must not be in the blocked jurisdictions listRESTRICTED_COUNTRY
FreezeNeither sender nor recipient address is frozen by the token issuerADDRESS_FROZEN
Amount LimitTransfer amount does not exceed the per-transaction maximumEXCEEDS_AMOUNT_LIMIT
Holding PeriodSender has held the tokens for at least the configured minimum duration (e.g., 12 months for Reg D securities)HOLDING_PERIOD_NOT_MET
Max HoldersTransferring to a new holder does not exceed the configured maximum holder count (e.g., 2000 for Reg D 506(c))MAX_HOLDERS_REACHED
WhitelistBoth sender and recipient are on the token's transfer whitelistNOT_WHITELISTED

Identity Claims and Trusted Issuers

ERC-3643 compliance on Tenzro uses TDIP verifiable credentials as the source of truth for identity claims. Each claim topic maps to a credential type stored on the identity. The compliance registry only trusts credentials issued by addresses in the trusted issuers list.

Claim TopicTDIP Credential TypeDescription
1KycAttestationKYC verification level (Unverified, Basic, Enhanced, Full)
2AccreditedInvestorSEC Reg D accredited investor status
3CountryOfResidenceISO 3166-1 alpha-2 country code
4QualifiedInvestorMiFID II qualified/professional investor classification
5InstitutionalInvestorInstitutional classification (fund, bank, insurance)
6AmlScreeningAnti-money laundering screening clearance
use tenzro_vm::compliance::{
    ComplianceRegistry, ComplianceConfig, ComplianceRule,
    TrustedIssuer, ClaimTopic,
};
use tenzro_identity::IdentityRegistry;

// Create compliance registry with TDIP identity integration
let identity_registry = IdentityRegistry::new();
let compliance = ComplianceRegistry::new(identity_registry.clone())?;

// Configure compliance rules for a security token
let config = ComplianceConfig::new()
    .with_rule(ComplianceRule::KycTier { min_tier: 2 })          // Enhanced KYC
    .with_rule(ComplianceRule::AccreditedInvestor)                 // Reg D
    .with_rule(ComplianceRule::CountryRestriction {
        blocked: vec!["US".into(), "KP".into(), "IR".into()],     // Restricted jurisdictions
    })
    .with_rule(ComplianceRule::HoldingPeriod {
        min_duration_days: 365,                                    // 12-month lock-up
    })
    .with_rule(ComplianceRule::MaxHolders { limit: 2000 })        // Reg D 506(c)
    .with_rule(ComplianceRule::AmountLimit {
        max_per_tx: 1_000_000 * 10u128.pow(18),                  // 1M tokens per tx
    })
    .with_rule(ComplianceRule::Whitelist);                         // Only whitelisted addresses

// Register trusted issuers for identity claims
compliance.add_trusted_issuer(TrustedIssuer {
    address: kyc_provider_address,
    claim_topics: vec![ClaimTopic::Kyc, ClaimTopic::Aml],
    name: "VerifyKYC Inc.".to_string(),
})?;

compliance.add_trusted_issuer(TrustedIssuer {
    address: accreditation_provider_address,
    claim_topics: vec![ClaimTopic::AccreditedInvestor, ClaimTopic::QualifiedInvestor],
    name: "SecureAccred LLC".to_string(),
})?;

// Apply configuration to a token
compliance.configure_token(security_token_address, config)?;

Transfer Compliance Check

// The can_transfer() check runs automatically before every transfer.
// It can also be called externally to pre-validate a transfer.

let result = compliance.can_transfer(
    security_token_address,
    sender_address,
    recipient_address,
    transfer_amount,
)?;

match result {
    ComplianceResult::Allowed => {
        println!("Transfer permitted — all compliance checks passed");
    }
    ComplianceResult::Denied { violations } => {
        for violation in &violations {
            match violation {
                ComplianceViolation::InsufficientKyc { address, required, actual } => {
                    println!("{} has KYC tier {} but tier {} required",
                        address, actual, required);
                }
                ComplianceViolation::NotAccredited { address } => {
                    println!("{} missing AccreditedInvestor credential", address);
                }
                ComplianceViolation::RestrictedCountry { address, country } => {
                    println!("{} located in restricted jurisdiction: {}", address, country);
                }
                ComplianceViolation::AddressFrozen { address } => {
                    println!("{} is frozen by token issuer", address);
                }
                ComplianceViolation::HoldingPeriodNotMet { required_days, held_days } => {
                    println!("Must hold for {} days, only held {} days",
                        required_days, held_days);
                }
                ComplianceViolation::MaxHoldersReached { limit } => {
                    println!("Token already has {} holders (max)", limit);
                }
                _ => {}
            }
        }
    }
}

Issuer Controls

Token issuers have administrative controls to manage compliance and address permissions:

ActionDescriptionCLI Command
Freeze AddressBlock all transfers from/to an addresstenzro compliance freeze
Unfreeze AddressRe-enable transfers for a frozen addresstenzro compliance unfreeze
Add to WhitelistAdd an address to the transfer whitelisttenzro compliance whitelist-add
Remove from WhitelistRemove an address from the whitelisttenzro compliance whitelist-remove
Force TransferIssuer-initiated transfer (recovery, court orders)tenzro compliance force-transfer
Pause TokenHalt all transfers globallytenzro compliance pause
Update RulesModify compliance configurationtenzro compliance update-rules

CLI Usage

# Create a compliant security token
tenzro token create --name "Real Estate Fund I" --symbol REF1 \
  --decimals 18 --supply 10000000 --compliance erc3643

# Configure compliance rules
tenzro compliance update-rules --token <token-address> \
  --kyc-tier 2 \
  --require-accreditation \
  --blocked-countries US,KP,IR \
  --holding-period 365 \
  --max-holders 2000 \
  --max-per-tx 1000000

# Add trusted claim issuers
tenzro compliance add-issuer --token <token-address> \
  --issuer 0xkyc_provider...abc \
  --claims kyc,aml \
  --name "VerifyKYC Inc."

# Whitelist an address
tenzro compliance whitelist-add --token <token-address> \
  --address 0xinvestor...def

# Check if a transfer would be allowed (dry run)
tenzro compliance check-transfer --token <token-address> \
  --from 0xsender...abc --to 0xrecipient...def --amount 50000

# Freeze an address
tenzro compliance freeze --token <token-address> \
  --address 0xsuspicious...ghi --reason "pending investigation"

# View compliance status for a token
tenzro compliance info --token <token-address>

# List all frozen addresses
tenzro compliance frozen --token <token-address>

Use Cases

Real-World Asset Tokenization

Tokenize real estate, commodities, or fund shares with built-in transfer restrictions. Configure KYC requirements, investor accreditation checks, and jurisdiction-based restrictions to comply with securities regulations in each target market.

Regulated Securities (Reg D / Reg S)

Issue security tokens that enforce SEC Regulation D requirements: accredited investor verification, 12-month holding periods, and 2,000 holder limits. Reg S tokens can restrict US investors while allowing unrestricted transfers in other jurisdictions.

Carbon Credits and ESG Assets

Tokenize verified carbon credits with compliance checks ensuring only certified entities can hold and trade them. The holding period rule prevents speculative short-term trading, and the whitelist ensures only verified offset buyers participate.

Enterprise Bond Issuance

Issue corporate bonds on-chain with compliance rules that enforce institutional investor requirements, minimum investment amounts, and jurisdiction restrictions. Integrates with Canton DAML for enterprise settlement workflows.

TDIP Integration Flow

The compliance check resolves wallet addresses to TDIP identities and reads verifiable credentials. This flow is fully on-chain and requires no external API calls during transfer execution:

  1. Transfer initiated: token.transfer(recipient, amount)
  2. Token contract calls ComplianceRegistry.can_transfer(from, to, amount)
  3. Registry resolves from and to addresses to TDIP DIDs via the WalletBinder
  4. For each DID, the registry reads verifiable credentials from the IdentityRegistry
  5. Credentials are verified: issuer is trusted, signature is valid, not expired
  6. Each compliance rule is evaluated against the resolved claims
  7. If all rules pass, transfer proceeds. Otherwise, ComplianceViolation is returned.

Credential caching: The compliance registry caches resolved credentials for a configurable TTL (default: 300 seconds) to avoid repeated identity lookups during high-throughput transfer periods. The cache is invalidated when a credential is revoked or a DID status changes.