๐ช SECTION 5: SPL TOKEN-2022 TRANSFER HOOKS
5.1 ๐ Architectural Innovation
SPL Token-2022 Transfer Hooks represent a fundamental architectural innovation in blockchain-based securities infrastructure, enabling execution of arbitrary smart contract code during token transfers on the Solana blockchain. This capability transforms compliance from a discretionary administrative function into an immutable, mathematically-enforced property of the token itself.
OTCM Protocol leverages Transfer Hooks to implement federal securities law requirements as non-discretionary smart contract code, creating a paradigm where regulatory compliance is not a matter of corporate policy but of cryptographic certainty. Every ST22 transfer triggers sequential execution of six independent verification hooks, completing comprehensive compliance verification before transaction settlement.
5.1.1 ๐ SPL Token-2022 Standard Overview
SPL Token-2022 (also known as Token Extensions Program) is Solana's next-generation token standard, introducing programmable extensions that enable sophisticated token functionality impossible with the original SPL Token Program:
Extension | Capability | OTCM Usage |
|---|---|---|
๐ช Transfer Hook | Execute custom logic on every transfer | 42 security controls, compliance verification |
๐ Permanent Delegate | Irrevocable transfer authority | Protocol-level recovery capability |
๐ Confidential Transfers | Zero-knowledge encrypted amounts | Future: Privacy-preserving compliance |
๐ต Transfer Fee | Protocol-level fee collection | 5% fee distribution automation |
๐ Metadata Pointer | On-chain token metadata | Security details, issuer info, CUSIP |
๐ซ Non-Transferable | Soulbound token capability | Compliance NFTs, investor credentials |
5.1.2 โ๏ธ Transfer Hook Extension Mechanism
The Transfer Hook extension enables token mints to specify a program that must be invoked during every token transfer. This mechanism operates at the Solana runtime level, making it impossible to transfer tokens without executing the hook program:
rust
// Transfer Hook Extension Data Structure
pub struct TransferHook {
/// The program ID that implements the transfer hook
pub program_id: Pubkey,
/// Optional: Authority that can update the hook program
pub authority: Option<Pubkey>,
}
// When a transfer occurs, Solana runtime automatically:
// 1. Checks if mint has TransferHook extension
// 2. If yes, invokes the specified program_id with transfer context
// 3. If hook returns error, ENTIRE transaction reverts
// 4. If hook succeeds, transfer completes
// โ ๏ธ This is MANDATORY - there is no way to bypass the hook
// The token literally cannot move without hook approval
5.1.3 ๐ Compliance-as-Code Philosophy
OTCM's Transfer Hook implementation embodies the "Compliance-as-Code" philosophy: regulatory requirements are translated into deterministic smart contract logic that executes identically every time, without human discretion, administrative override, or interpretation variability.
"Traditional compliance asks: 'Did you follow the rules?' OTCM's Transfer Hooks ask: 'Can you mathematically prove compliance?' The answer is always verifiable on-chain."
Aspect | โ Traditional Compliance | โ Transfer Hook Compliance |
|---|---|---|
โ๏ธ Enforcement | Policy-based, discretionary | Code-based, deterministic |
๐ Override Capability | Admin can bypass | No bypass possible |
๐ Audit Trail | Mutable logs, editable | Immutable blockchain record |
โ Verification | Requires trust in operator | Cryptographically verifiable |
๐ Consistency | Varies by analyst/day | 100% identical execution |
โฑ๏ธ Timing | Post-trade review (T+n) | Pre-trade blocking (T-0) |
5.1.4 โ๏ธ Regulatory Advantages
Transfer Hook execution provides regulatory advantages unattainable through traditional compliance procedures:
Advantage | Description |
|---|---|
๐ Immutable Audit Trails | Every compliance check is recorded on-chain with cryptographic proof of execution timestamp, inputs, and outcomes |
๐ฏ Zero Discretion | Compliance decisions are algorithmicโno analyst judgment, no selective enforcement, no regulatory arbitrage |
โก Real-Time Enforcement | Non-compliant transfers are blocked before execution, not flagged for review after the fact |
๐ Cryptographic Proof | Regulators can independently verify any historical compliance decision by replaying on-chain data |
๐ Continuous Operation | 24/7/365 enforcement with no business hours, holidays, or staffing gaps |
๐ก SEC Modernization Alignment: OTCM's Transfer Hook architecture aligns with SEC Chair Gensler's stated goal of 'bringing crypto into compliance' and the SEC Crypto Task Force's exploration of blockchain-native compliance mechanisms.
5.2 ๐ Transfer Hook Execution Flow
This section details the precise execution sequence when an ST22 token transfer is initiated, from user action through final settlement.
5.2.1 ๐ช Hook Invocation Sequence
When a user initiates an ST22 transfer, the following sequence executes:
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๐ช ST22 TRANSFER HOOK EXECUTION SEQUENCE โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
๐ค User Initiates Transfer
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ๏ธ SOLANA RUNTIME: Detects TransferHook extension on ST22 mint โ
โ Invokes OTCM Transfer Hook Program with transfer context โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๐ HOOK 1: CUSTODY VERIFICATION โ
โ โฑ๏ธ (100-150ms) โ
โ Query Empire Stock Transfer โ Verify 1:1 backing โ Error 6001 โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
PASS
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๐ซ HOOK 2: OFAC SCREENING โ
โ โฑ๏ธ (200-500ms) โ
โ Check SDN List โ Address clustering โ Error 6002 โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
PASS
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๐ต๏ธ HOOK 3: AML ANALYTICS โ
โ โฑ๏ธ (300-400ms) โ
โ ML risk scoring โ 200+ features โ Error 6003 โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
PASS
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๐ชช HOOK 4: REDEMPTION ELIGIBILITY โ
โ โฑ๏ธ (50-100ms) โ
โ KYC status โ Accreditation โ 72hr cooling โ Error 6004 โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
PASS
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๐ HOOK 5: PRICE IMPACT LIMIT โ
โ โฑ๏ธ (50-100ms) โ
โ Calculate impact โ Compare TWAP โ 2% threshold โ Error 6006 โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
PASS
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ ๐ง HOOK 6: LIQUIDITY SUFFICIENCY โ
โ โฑ๏ธ (50-100ms) โ
โ Check LP ratio โ 150% minimum โ Error 6007 โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
PASS
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ
ALL HOOKS PASSED โ
โ Transfer executes, transaction commits โ
โ Settlement: ~13 seconds (32 blocks) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
5.2.2 ๐ Sequential vs Parallel Execution
OTCM implements sequential hook execution rather than parallel for critical security reasons:
Mode | โ Advantage | โ ๏ธ Trade-off |
|---|---|---|
๐ Sequential (OTCM) | Early exit on failure, deterministic order, simpler debugging | Higher latency (750-1,350ms total) |
โก Parallel | Lower latency (~500ms total) | Non-deterministic, race conditions, wasted compute on early failures |
Sequential execution ensures that if Hook 1 (Custody Verification) fails, Hooks 2-6 never executeโsaving oracle costs and compute resources. It also provides deterministic error reporting: users always know which specific hook rejected their transaction.
5.2.3 โ๏ธ Atomic Transaction Guarantees
Solana's account model provides atomic transaction guarantees: if any hook fails, the entire transaction reverts as if it never occurred. There is no intermediate state where tokens have transferred but compliance verification is incomplete.
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ๏ธ ATOMIC EXECUTION GUARANTEE โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// Scenario A: All hooks pass โ
// Result: Transaction commits, tokens move, state updates
// Scenario B: Hook 3 (AML) rejects due to risk score โ
// Result: ENTIRE transaction reverts
// โข No tokens moved
// โข No fees charged
// โข No state changes
// โข Error returned to user: 6003 (AML_RISK_EXCEEDED)
// โ ๏ธ There is NO partial execution state
// This is guaranteed by Solana runtime, not OTCM code
5.2.4 โฑ๏ธ Execution Timing Diagram
Hook | โฑ๏ธ Min (ms) | โฑ๏ธ Max (ms) | โฑ๏ธ Avg (ms) | ๐ง Primary Bottleneck |
|---|---|---|---|---|
1๏ธโฃ Custody Oracle | 100 | 150 | 125 | Empire API latency |
2๏ธโฃ OFAC Screening | 200 | 500 | 350 | SDN list size, clustering |
3๏ธโฃ AML Analytics | 300 | 400 | 350 | ML inference time |
4๏ธโฃ Redemption Eligibility | 50 | 100 | 75 | KYC database lookup |
5๏ธโฃ Price Impact | 50 | 100 | 75 | TWAP calculation |
6๏ธโฃ LP Sufficiency | 50 | 100 | 75 | Pool state read |
โฑ๏ธ TOTAL | 750 | 1,350 | 1,050 | Sequential sum |
5.3 ๐ Hook 1: Custody Verification Oracle
The Custody Verification Oracle confirms that all circulating ST22 tokens are backed by equivalent equity shares held at Empire Stock Transfer, the SEC-registered transfer agent providing qualified custody services for OTCM Protocol.
5.3.1 ๐๏ธ Oracle Architecture
The custody oracle operates as a cryptographically-signed data feed from Empire Stock Transfer's registry systems:
rust
// Custody Oracle Data Structure
pub struct CustodyOracleData {
/// CIK number of the issuing company
pub issuer_cik: [u8; 10],
/// CUSIP identifier for the security
pub cusip: [u8; 9],
/// Share class (Series M preferred)
pub share_class: ShareClass,
/// Total shares held in custody
pub custodied_balance: u64,
/// Total ST22 tokens in circulation
pub circulating_tokens: u64,
/// Ed25519 signature from Empire's HSM
pub attestation_signature: [u8; 64],
/// Merkle root of current shareholder registry
pub registry_hash: [u8; 32],
/// Unix timestamp of attestation
pub attestation_timestamp: i64,
/// Block height when attestation was recorded
pub attestation_slot: u64,
}
5.3.2 ๐๏ธ Empire Stock Transfer Integration
Empire Stock Transfer provides real-time custody attestations through a dedicated API integration:
Component | Specification |
|---|---|
๐ API Endpoint |
|
๐ Authentication | API Key + Ed25519 request signing |
โ๏ธ Response Signing | HSM-secured Ed25519 signature on every attestation |
โฑ๏ธ Update Frequency | Every Solana slot (~400ms) |
๐ Failover | Multi-region deployment with automatic failover |
5.3.3 โ ๏ธ Discrepancy Detection
The hook implements strict discrepancy detection with configurable thresholds:
rust
// Custody Verification Implementation (Rust/Anchor)
pub const MAX_DISCREPANCY_BPS: u64 = 1; // 0.01% maximum discrepancy
pub fn verify_custody(
oracle_data: &CustodyOracleData,
transfer_amount: u64,
) -> Result<()> {
// Verify signature authenticity
verify_ed25519_signature(
&oracle_data.attestation_signature,
&EMPIRE_PUBLIC_KEY,
&oracle_data.serialize(),
)?;
// Check attestation freshness (max 10 minutes old)
let current_time = Clock::get()?.unix_timestamp;
require!(
current_time - oracle_data.attestation_timestamp <= 600,
CustodyError::StaleAttestation // 6001
);
// Calculate discrepancy
let expected_tokens = oracle_data.custodied_balance;
let actual_tokens = oracle_data.circulating_tokens;
let discrepancy = if expected_tokens > actual_tokens {
expected_tokens - actual_tokens
} else {
actual_tokens - expected_tokens
};
let discrepancy_bps = discrepancy * 10000 / expected_tokens;
require!(
discrepancy_bps <= MAX_DISCREPANCY_BPS,
CustodyError::CustodyDiscrepancy // 6001
);
// Verify sufficient custody for this transfer
require!(
oracle_data.custodied_balance >= transfer_amount,
CustodyError::InsufficientCustody // 6001
);
Ok(())
}
๐ Regulatory Reference: 17 CFR Section 240.17a-1 et seq. โ Transfer Agent Custody Requirements
โ Error Code 6001: CUSTODY_VERIFICATION_FAILED Indicates custody verification failure. Possible causes: stale attestation (>10 min), discrepancy >0.01%, insufficient custodied shares, or invalid Empire signature. User should wait for fresh attestation or contact issuer.
5.4 ๐ซ Hook 2: OFAC Sanctions Screening
The OFAC Sanctions Screening hook prevents transactions to or from wallets associated with the Office of Foreign Assets Control's Specially Designated Nationals (SDN) list, implementing federal sanctions law requirements at the protocol level.
5.4.1 ๐ SDN List Integration
OTCM maintains an on-chain oracle updated hourly from OFAC's official SDN list, supplemented by blockchain-specific address intelligence:
rust
// OFAC Screening Implementation
pub struct OfacOracleData {
/// Merkle root of current SDN list
pub sdn_merkle_root: [u8; 32],
/// Number of entries in SDN list
pub sdn_entry_count: u32,
/// Blockchain-specific blocked addresses
pub crypto_sdn_addresses: Vec<Pubkey>,
/// Last update timestamp
pub last_update: i64,
/// OFAC publication reference
pub publication_id: [u8; 16],
}
// Screening checks BOTH sender and recipient
pub fn screen_ofac(
sender: &Pubkey,
recipient: &Pubkey,
oracle: &OfacOracleData,
) -> Result<OfacScreeningResult> {
// Direct address matching
let sender_blocked = oracle.crypto_sdn_addresses.contains(sender);
let recipient_blocked = oracle.crypto_sdn_addresses.contains(recipient);
if sender_blocked || recipient_blocked {
return Err(OfacError::SanctionedAddress.into()); // 6002
}
// Address clustering analysis (see 5.4.2)
check_cluster_association(sender, recipient, oracle)?;
Ok(OfacScreeningResult::Clear)
}
5.4.2 ๐ Address Clustering Analysis
Beyond direct SDN address matching, OTCM implements sophisticated address clustering analysis to detect wallets associated with sanctioned entities:
Analysis | Description |
|---|---|
๐ฐ Funding Source Analysis | Traces wallet funding sources to identify indirect SDN connections |
๐ฅ Common Ownership Detection | Identifies wallets controlled by same entity through transaction pattern analysis |
๐ Mixer/Tumbler Detection | Flags wallets with significant exposure to known mixing services |
๐ High-Risk Jurisdiction Exposure | Elevated scrutiny for wallets with connections to OFAC-sanctioned jurisdictions |
5.4.3 ๐ Implementation
rust
// Cluster Analysis Implementation
pub fn check_cluster_association(
sender: &Pubkey,
recipient: &Pubkey,
oracle: &OfacOracleData,
) -> Result<()> {
// Query clustering oracle for both addresses
let sender_cluster = get_cluster_data(sender)?;
let recipient_cluster = get_cluster_data(recipient)?;
// Check for SDN cluster membership
if sender_cluster.sdn_association_score > 70 {
return Err(OfacError::ClusterAssociation {
address: *sender,
score: sender_cluster.sdn_association_score,
reason: "High SDN cluster association".to_string(),
}.into());
}
if recipient_cluster.sdn_association_score > 70 {
return Err(OfacError::ClusterAssociation {
address: *recipient,
score: recipient_cluster.sdn_association_score,
reason: "High SDN cluster association".to_string(),
}.into());
}
Ok(())
}
๐ Regulatory Reference: 31 CFR ยง 500-598 โ OFAC Sanctions Administration Regulations
โ Error Code 6002: OFAC_SANCTIONS_MATCH Indicates wallet is blocked due to OFAC sanctions. This is a PERMANENT blockโthe wallet cannot transact ST22 tokens. There is no appeal process through OTCM; affected parties must resolve sanctions status with OFAC directly.
5.5 ๐ต๏ธ Hook 3: Blockchain Analytics Screening
The Blockchain Analytics Screening hook implements Bank Secrecy Act Anti-Money Laundering (AML) requirements through machine learning-based risk assessment, analyzing 200+ transaction features to identify money laundering patterns, sanctions evasion, theft proceeds, and coordinated suspicious activity.
5.5.1 ๐ค ML Risk Assessment
OTCM integrates with institutional-grade blockchain analytics providers to execute real-time risk assessment on every transfer:
rust
// AML Risk Assessment Data Structure
pub struct AmlRiskAssessment {
/// Overall risk score (0-100)
pub risk_score: u8,
/// Risk category breakdown
pub categories: AmlRiskCategories,
/// Specific risk flags triggered
pub triggered_flags: Vec<AmlFlag>,
/// Confidence in assessment
pub confidence: u8,
/// Model version used
pub model_version: [u8; 8],
}
pub struct AmlRiskCategories {
pub sanctions_evasion: u8, // 0-100
pub money_laundering: u8, // 0-100
pub theft_proceeds: u8, // 0-100
pub darknet_exposure: u8, // 0-100
pub mixer_exposure: u8, // 0-100
pub gambling_exposure: u8, // 0-100
pub coordinated_activity: u8, // 0-100
}
5.5.2 ๐ Risk Scoring Model
The risk scoring model classifies transactions into three tiers with automated responses:
Score | Risk Level | โ๏ธ Automated Action | ๐ Follow-up |
|---|---|---|---|
๐ข 0-30 | Low | Auto-approve | None required |
๐ก 31-70 | Medium | Enhanced review queue | Manual analyst review within 24h |
๐ด 71-100 | High | Auto-reject (Error 6003) | SAR filing evaluation |
5.5.3 ๐ฌ Chainalysis/TRM Integration
OTCM integrates with industry-leading blockchain analytics providers:
Provider | Capability |
|---|---|
๐ฌ Chainalysis KYT | Real-time transaction screening with 15-second SLA |
๐ TRM Labs Forensics | Deep historical analysis and entity resolution |
๐ Elliptic Navigator | Cross-chain exposure analysis for multi-chain actors |
5.5.4 ๐ Implementation
rust
// AML Screening Implementation
pub const LOW_RISK_THRESHOLD: u8 = 30;
pub const HIGH_RISK_THRESHOLD: u8 = 71;
pub fn screen_aml(
sender: &Pubkey,
recipient: &Pubkey,
amount: u64,
) -> Result<AmlScreeningResult> {
// Query analytics providers
let sender_risk = query_chainalysis(sender)?;
let recipient_risk = query_chainalysis(recipient)?;
// Use higher of two risk scores
let max_risk = sender_risk.risk_score.max(recipient_risk.risk_score);
match max_risk {
0..=30 => Ok(AmlScreeningResult::AutoApprove),
31..=70 => {
// Queue for enhanced review but allow transaction
emit!(EnhancedReviewQueued {
sender: *sender,
recipient: *recipient,
risk_score: max_risk,
amount,
});
Ok(AmlScreeningResult::ApproveWithReview)
},
71..=100 => {
// Auto-reject high-risk transactions
Err(AmlError::RiskThresholdExceeded {
score: max_risk,
threshold: HIGH_RISK_THRESHOLD,
}.into()) // 6003
},
_ => unreachable!(),
}
}
๐ Regulatory Reference: 31 CFR ยง 1010 โ Bank Secrecy Act AML Requirements
โ Error Code 6003: AML_RISK_EXCEEDED Transaction rejected due to high AML risk score (71-100). Wallet may have exposure to: money laundering, sanctions evasion, theft proceeds, darknet markets, or coordinated suspicious activity. Appeal requires compliance review.
5.6 ๐ชช Hook 4: Redemption Eligibility Verification
The Redemption Eligibility Verification hook implements a critical distinction in OTCM's compliance architecture: while permissionless trading allows any wallet to purchase and transfer ST22 tokens, redemption (conversion to underlying equity shares) requires investor verification in accordance with federal securities law.
5.6.1 ๐ KYC/AML Requirements
Before a wallet can redeem ST22 tokens for underlying shares, the beneficial owner must complete comprehensive verification:
Requirement | Verification Method |
|---|---|
๐ชช Identity Verification | Government-issued photo ID + liveness check via Jumio/Onfido |
๐ Address Verification | Utility bill or bank statement within 90 days |
๐ข SSN/TIN Verification | IRS W-9 form with SSN/TIN matching |
๐ซ Sanctions Screening | 72-hour waiting period after initial OFAC/SDN clear |
๐ PEP Screening | Politically Exposed Person database check |
5.6.2 ๐๏ธ Accredited Investor Verification
For offerings conducted under SEC Regulation D Rule 506(c), additional accreditation verification is required:
rust
// Accreditation Status Types
pub enum AccreditationStatus {
/// Not verified - cannot redeem Reg D offerings
NotVerified,
/// Verified accredited investor
Accredited {
method: AccreditationMethod,
verification_date: i64,
expiration_date: i64, // Typically 90 days
verifier: String, // e.g., "VerifyInvestor.com"
},
/// Non-accredited but permitted (Reg A+ or Reg CF)
NonAccreditedPermitted {
regulation: OfferingRegulation,
investment_limit: u64,
},
}
pub enum AccreditationMethod {
Income, // $200K/$300K annual income
NetWorth, // $1M+ net worth excluding residence
Professional, // Series 7, 65, or 82 license
Entity, // Qualified entity (bank, trust, etc.)
KnowledgeTest, // SEC proposed "accreditation exam"
}
5.6.3 ๐ Implementation
rust
// Redemption Eligibility Verification
pub fn verify_redemption_eligibility(
wallet: &Pubkey,
token_mint: &Pubkey,
amount: u64,
) -> Result<()> {
// Load investor record
let investor = get_investor_record(wallet)?;
// Check KYC completion
require!(
investor.kyc_status == KycStatus::Verified,
RedemptionError::KycIncomplete // 6004
);
// Check 72-hour sanctions cooling period
let current_time = Clock::get()?.unix_timestamp;
let cooling_period = 72 * 60 * 60; // 72 hours in seconds
require!(
current_time - investor.sanctions_clear_timestamp >= cooling_period,
RedemptionError::SanctionsCoolingPeriod // 6004
);
// Load offering details
let offering = get_offering_details(token_mint)?;
// Check accreditation if Reg D 506(c)
if offering.regulation == Regulation::RegD506c {
match &investor.accreditation {
AccreditationStatus::Accredited { expiration_date, .. } => {
require!(
current_time < *expiration_date,
RedemptionError::AccreditationExpired // 6004
);
},
_ => {
return Err(RedemptionError::AccreditationRequired.into());
}
}
}
Ok(())
}
๐ Regulatory Reference: 17 CFR 230.506(c) โ Regulation D Accredited Investor Requirements
โ Error Code 6004: REDEMPTION_ELIGIBILITY_FAILED Wallet not eligible for redemption. Possible causes: KYC incomplete, sanctions cooling period active (<72h), accreditation expired/missing for Reg D offerings. Note: Trading is still permitted; only redemption to shares is blocked.
5.7 ๐ Hook 5: Price Impact Circuit Breaker
The Price Impact Circuit Breaker prevents single transactions from causing excessive market movement, implementing regulatory objectives prohibiting manipulative trading devices. Any transaction causing greater than 2% price movement against the Time-Weighted Average Price (TWAP) oracle is automatically rejected.
5.7.1 ๐ TWAP Oracle Integration
The TWAP oracle provides manipulation-resistant reference pricing:
rust
// TWAP Oracle Implementation
pub struct TwapOracle {
pub token_mint: Pubkey,
/// Rolling 1-hour TWAP
pub twap_1h: u64,
/// Rolling 24-hour TWAP
pub twap_24h: u64,
/// Number of observations in window
pub observation_count: u32,
/// Minimum observations required
pub min_observations: u32,
/// Last update slot
pub last_update_slot: u64,
}
impl TwapOracle {
pub fn get_reference_price(&self) -> Result<u64> {
// Use shorter TWAP for more responsive circuit breakers
// but require minimum observations to prevent manipulation
require!(
self.observation_count >= self.min_observations,
OracleError::InsufficientObservations
);
Ok(self.twap_1h)
}
}
5.7.2 ๐ 2% Threshold Enforcement
The 2% threshold forces large market participants to execute trades gradually, preventing sudden price dislocations:
rust
// Price Impact Circuit Breaker Implementation
pub const MAX_PRICE_IMPACT_BPS: u64 = 200; // 2.00%
pub fn check_price_impact(
pool: &LiquidityPool,
trade_amount: u64,
trade_direction: TradeDirection,
) -> Result<()> {
// Get TWAP reference price
let twap = pool.twap_oracle.get_reference_price()?;
// Calculate expected post-trade price using CPMM formula
let (new_sol_reserve, new_token_reserve) = match trade_direction {
TradeDirection::Buy => (
pool.sol_reserve + trade_amount,
pool.token_reserve - calculate_output(trade_amount, pool)?,
),
TradeDirection::Sell => (
pool.sol_reserve - calculate_output(trade_amount, pool)?,
pool.token_reserve + trade_amount,
),
};
let post_trade_price = new_sol_reserve * 1_000_000_000 / new_token_reserve;
// Calculate deviation from TWAP
let deviation = if post_trade_price > twap {
(post_trade_price - twap) * 10000 / twap
} else {
(twap - post_trade_price) * 10000 / twap
};
require!(
deviation <= MAX_PRICE_IMPACT_BPS,
CircuitBreakerError::PriceImpactExceeded {
expected_impact_bps: deviation,
max_allowed_bps: MAX_PRICE_IMPACT_BPS,
} // 6006
);
Ok(())
}
๐ Regulatory Reference: 17 CFR 240.10b-5(b) โ Prohibition on Manipulative Trading Devices
โ Error Code 6006: PRICE_IMPACT_EXCEEDED Transaction would cause >2% price movement from TWAP. User should reduce trade size or split into multiple smaller transactions. This protects all market participants from sudden price manipulation.
5.8 ๐ง Hook 6: Liquidity Pool Sufficiency
The Liquidity Pool Sufficiency hook ensures the OTCM Liquidity Pool maintains adequate reserves to support all outstanding ST22 tokens. The hook confirms the pool maintains a minimum 150% ratio of locked capital to circulating ST22 value before allowing redemption transactions.
5.8.1 ๐ 150% Ratio Requirement
The 150% over-collateralization provides a safety buffer ensuring redemptions can always be honored:
Component | Calculation |
|---|---|
๐ฐ Locked Capital | Total SOL in unified LP (permanently locked) |
๐ซ Circulating Value | Sum of (ST22 supply ร current price) for all tokens |
๐ Sufficiency Ratio | Locked Capital / Circulating Value ร 100% |
โ Minimum Required | โฅ 150% โ redemptions pause if below |
5.8.2 ๐ Implementation
rust
// Liquidity Sufficiency Check
pub const MIN_SUFFICIENCY_RATIO_BPS: u64 = 15000; // 150%
pub fn check_liquidity_sufficiency(
pool: &UnifiedLiquidityPool,
redemption_amount: u64,
) -> Result<()> {
// Calculate current ratio
let locked_capital = pool.total_sol_reserve;
let circulating_value = calculate_total_circulating_value(pool)?;
// Add redemption impact
let post_redemption_capital = locked_capital - redemption_amount;
let post_redemption_ratio = post_redemption_capital * 10000 / circulating_value;
require!(
post_redemption_ratio >= MIN_SUFFICIENCY_RATIO_BPS,
LiquidityError::InsufficientLiquidity {
current_ratio: post_redemption_ratio,
required_ratio: MIN_SUFFICIENCY_RATIO_BPS,
} // 6007
);
Ok(())
}
๐ Regulatory Reference: Securities Exchange Act Rule 15c2-11 โ Capital Adequacy Requirements
โ Error Code 6007: LIQUIDITY_INSUFFICIENT Pool ratio below 150% threshold. Redemptions temporarily paused until trading volume rebuilds reserves. Regular ST22 trading (non-redemption) remains permitted. Users can wait for ratio recovery or reduce redemption amount.
5.9 ๐ก๏ธ Thirty-Six Supplementary Security Controls
Beyond the six primary Transfer Hooks, OTCM implements thirty-six supplementary security controls integrated into the transfer hook logic, creating a comprehensive 42-point security framework.
5.9.1 ๐ Smart Contract Controls (1-6)
# | Control | Description |
|---|---|---|
1๏ธโฃ | Formal Verification | Certora Prover mathematical proof of contract correctness |
2๏ธโฃ | Multi-Audit Requirement | Independent audits by Quantstamp, Halborn, and OtterSec |
3๏ธโฃ | Immutable Bytecode | No proxy patternโcode cannot be changed post-deployment |
4๏ธโฃ | Bug Bounty Program | Up to $500K rewards for critical vulnerabilities |
5๏ธโฃ | Reentrancy Guards | Check-Effects-Interactions pattern enforcement |
6๏ธโฃ | Integer Overflow Protection | Rust's checked arithmetic prevents overflow attacks |
5.9.2 ๐ Access Control Framework (7-12)
# | Control | Description |
|---|---|---|
7๏ธโฃ | Multi-Sig Administration | 4-of-7 threshold for administrative actions |
8๏ธโฃ | Timelock Delays | 48-hour delay on all parameter changes |
9๏ธโฃ | Role-Based Access | Granular permission system (operator, compliance, admin) |
๐ | Emergency Pause | 2-of-7 emergency pause with 24hr auto-unpause |
1๏ธโฃ1๏ธโฃ | DAO Override | 2/3 supermajority required for lock override |
1๏ธโฃ2๏ธโฃ | Key Rotation | Quarterly key rotation with HSM backing |
5.9.3 โ๏ธ Transaction Integrity Controls (13-18)
# | Control | Description |
|---|---|---|
1๏ธโฃ3๏ธโฃ | Atomic Execution | All-or-nothing transaction commitment |
1๏ธโฃ4๏ธโฃ | Orphan Prevention | No partial execution states possible |
1๏ธโฃ5๏ธโฃ | Replay Protection | Unique transaction signatures prevent replay |
1๏ธโฃ6๏ธโฃ | Nonce Management | Sequential nonces prevent transaction ordering attacks |
1๏ธโฃ7๏ธโฃ | Deadline Enforcement | Transactions expire after specified block height |
1๏ธโฃ8๏ธโฃ | Slippage Protection | User-configurable maximum price deviation |
5.9.4 ๐ฎ Oracle & Data Controls (19-24)
# | Control | Description |
|---|---|---|
1๏ธโฃ9๏ธโฃ | Multi-Oracle Consensus | Cross-reference multiple data sources |
2๏ธโฃ0๏ธโฃ | Staleness Detection | Reject data older than threshold (10 min) |
2๏ธโฃ1๏ธโฃ | Signature Verification | Ed25519 verification of all oracle data |
2๏ธโฃ2๏ธโฃ | Rate Limiting | Maximum oracle queries per block per mint |
2๏ธโฃ3๏ธโฃ | Fallback Oracles | Automatic failover to backup data sources |
2๏ธโฃ4๏ธโฃ | Data Freshness Proofs | On-chain attestation of data recency |
5.9.5 ๐๏ธ Monitoring & Alerting (25-30)
# | Control | Description |
|---|---|---|
2๏ธโฃ5๏ธโฃ | Real-Time Monitoring | 24/7 transaction pattern analysis |
2๏ธโฃ6๏ธโฃ | Anomaly Detection | ML-based unusual activity identification |
2๏ธโฃ7๏ธโฃ | SEC Notification | Automatic reporting of compliance failures |
2๏ธโฃ8๏ธโฃ | Compliance Dashboard | Real-time visibility for regulators |
2๏ธโฃ9๏ธโฃ | Audit Log Export | On-demand historical data retrieval |
3๏ธโฃ0๏ธโฃ | Alert Escalation | Tiered notification for severity levels |
5.9.6 ๐๏ธ Governance & Recovery (31-36)
# | Control | Description |
|---|---|---|
3๏ธโฃ1๏ธโฃ | Proposal System | On-chain governance for parameter changes |
3๏ธโฃ2๏ธโฃ | Voting Mechanism | Token-weighted voting with delegation |
3๏ธโฃ3๏ธโฃ | Quorum Requirements | Minimum participation thresholds |
3๏ธโฃ4๏ธโฃ | Veto Power | Compliance officer veto on security-relevant proposals |
3๏ธโฃ5๏ธโฃ | Migration Capability | Controlled upgrade path for critical fixes |
3๏ธโฃ6๏ธโฃ | Disaster Recovery | Documented procedures for catastrophic scenarios |
5.10 โ ๏ธ Error Handling and Recovery
Code | Hook | Condition | ๐ง User Action |
|---|---|---|---|
โ 6001 | ๐ Custody | Discrepancy >0.01% | Wait, retry, contact issuer |
โ 6002 | ๐ซ OFAC | Sanctioned address | PERMANENT โ contact OFAC |
โ 6003 | ๐ต๏ธ AML | Risk score 71-100 | Request compliance review |
โ 6004 | ๐ชช Redemption | KYC/accreditation issue | Complete verification |
โ 6006 | ๐ Price Impact | >2% TWAP deviation | Reduce size, split trade |
โ 6007 | ๐ง Liquidity | <150% pool ratio | Wait for ratio recovery |
5.11 ๐ Performance Specifications
Metric | Value | Notes |
|---|---|---|
โฑ๏ธ Total Hook Latency | 750-1,350ms | Sequential execution |
๐ข Compute Units | ~800,000 CU | Per complete transfer |
โก Effective TPS | 400-600 | Compliance overhead |
๐ต Oracle Cost/Transfer | $2-5 | Chainalysis, Empire APIs |
5.12 ๐ Security Audit Status
Auditor | Status |
|---|---|
๐ฌ Quantstamp | Audit scheduled Q1 2026 |
๐ Halborn | Engagement in progress |
๐ฆฆ OtterSec | Preliminary review complete |
โ Certora Formal Verification | Specification development underway |
๐ Bug Bounty | $500K program launching with mainnet |
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
ยฉ 2025 OTCM Protocol, Inc. | All Rights Reserved