Skip to main content

Section 3: SPL Token-2022 Transfer Hooks — Layer 2

OTCM PROTOCOL

Comprehensive Technical Whitepaper    Version 7.0

ST22 Digital Securities Platform  |  March 2026  |  Groovy Company, Inc. dba OTCM Protocol

 

Section 3: SPL Token-2022 Transfer Hooks — Layer 2

The complete technical specification for OTCM Protocol's 42-control Transfer Hook security architecture — the foundational compliance enforcement mechanism that makes regulatory bypass structurally impossible.

 

Metric

Value

Document reference

OTCM-TH-SPEC-001 v2.0 (aligned with Whitepaper V7.0)

Total security controls

42

Transfer coverage

100% — every ST22 transfer invokes all 42 controls

Bypass possibility

Zero — enforced at SPL Token-2022 program level

Target validation latency

< 1,000ms (parallel execution)

Compute unit budget

< 5,000 CU per validation

Implementation language

Rust / Anchor framework

Immutability

Transfer Hook cannot be removed or disabled after mint creation

V7 change vs V6

Control 24 updated: vesting schedule removed; Rule 144 / Reg S holding period enforcement added

 

3.1  The Alesia Doctrine — Compliance by Encirclement

The Transfer Hook architecture embodies what OTCM Protocol calls the Alesia Doctrine: the principle that compliance should be enforced through structural encirclement rather than trust. In traditional securities markets, compliance depends on intermediaries — broker-dealers, clearinghouses, and regulators — acting in good faith. These actors can fail, be compromised, or simply be absent in the OTC microcap context where infrastructure has been abandoned.

OTCM Protocol's Transfer Hook architecture eliminates the dependency on good-faith intermediary behavior by embedding compliance enforcement in the token transfer primitive itself. Every ST22 token transfer — regardless of which wallet, front-end, or trading venue initiates it — must pass through all 42 controls before the transaction executes on-chain. There is no path around this enforcement. There is no administrative override. There is no whitelist for trusted parties. The controls execute identically for every participant on every transfer, including OTCM Protocol itself.

 

3.1.1  Why Application-Layer Compliance Fails

The January 28, 2026 Joint Staff Statement on Tokenized Securities explicitly identified the compliance gap that results when securities compliance is implemented at the application layer rather than the token standard level. When compliance is enforced by an issuer's portal or a specific trading venue, any participant who routes around that portal or venue bypasses all compliance controls. This is the architectural vulnerability that defines Category 2 (Third-Party Sponsored) tokenization — and it is precisely what the Transfer Hook architecture eliminates.

Compliance Location

Vulnerability

OTCM Protocol Approach

Application layer (portal)

Any alternative front-end bypasses all controls

Layer 2 enforcement — no front-end can bypass

Trading venue (exchange)

Any DEX that doesn't enforce compliance disables all controls

CEDEX exclusive — only venue that preserves all 42 hooks

Issuer policy

Policy can be changed, ignored, or overridden

Immutable smart contract — policy is code, code is law

Third-party custodian

Custodian can withdraw backing assets, creating de-peg risk

Transfer Hook Control 1 verifies custody on every transfer

Transfer Hook (Layer 2)

Cannot be bypassed — any failure reverts entire transaction

This is the OTCM approach — compliance at the primitive

 

3.2  Architecture

3.2.1  Transaction Flow

The Transfer Hook is invoked by the SPL Token-2022 program on every ST22 token transfer via Cross-Program Invocation (CPI). This invocation is mandatory at the protocol level — it cannot be disabled by the issuer, by OTCM Protocol, or by any trading venue. The six-step flow is as follows:

 

       Step 1 — Transfer initiation — User initiates transfer through any entry point: CEDEX order execution, hardware wallet, mobile wallet, or programmatic call

       Step 2 — Token-2022 receives instruction — SPL Token-2022 program receives the transfer instruction from the initiating party

       Step 3 — Transfer Hook invoked via CPI — Token-2022 automatically invokes OTCM's Transfer Hook program via Cross-Program Invocation. This step is mandatory and cannot be skipped

       Step 4 — All 42 controls execute — The Transfer Hook validates the transaction against all 42 security controls in parallel and sequential groups. Oracle data from Layer 6 is consumed in real-time

       Step 5 — Atomic result — If ANY control fails: the entire transaction reverts atomically with a specific error code. If ALL controls pass: execution proceeds to Layer 1 settlement

       Step 6 — Settlement and audit — Passing transactions settle on Solana. An immutable audit record of all control results is written on-chain for every transfer

 

3.2.2  Program Structure

The Transfer Hook program is implemented in Rust using the Anchor framework. The program structure follows strict separation of concerns, with each component having a well-defined responsibility:

 

programs/

└── transfer-hook/

    └── src/

        ├── lib.rs                  // Program entrypoint

        ├── instructions/

           ├── mod.rs

           ├── initialize.rs       // SecurityConfig initialization

           └── transfer_hook.rs    // Main hook logic (42 controls)

        ├── state/

           ├── mod.rs

           ├── security_config.rs  // Security parameters per mint

           ├── circuit_breaker.rs  // Circuit breaker state

           └── holding_period.rs   // Rule 144 / Reg S enforcement (V7)

        ├── errors.rs               // Custom error codes (6001–6042)

        └── utils/

            ├── validation.rs       // Validation helpers

            └── math.rs             // u128 overflow-safe arithmetic

 

3.2.3  Account Architecture

The Transfer Hook utilizes Program Derived Addresses (PDAs) to store security configuration and state for each token mint. One SecurityConfig account is created per ST22 Security Token at the time of minting, establishing the security parameters that govern all transfers of that token for its entire existence.

 

#[account]

pub struct SecurityConfig {

    pub mint:                       Pubkey,   // Associated token mint

    pub authority:                  Pubkey,   // 5-of-9 multi-sig admin

    pub max_wallet_percent:          u16,     // 499 = 4.99% (basis points)

    pub circuit_breaker_threshold:   u16,     // 3000 = 30% daily volume

    pub circuit_breaker_cooldown:    i64,     // 86400 = 24 hours

    pub circuit_breaker_triggered:   bool,    // Current CB state

    pub circuit_breaker_triggered_at: i64,   // CB trigger timestamp

    pub reference_price:             u64,     // TWAP baseline

    pub holding_period_config:  HoldingPeriodConfig, // V7: Rule 144/Reg S

    pub volume_tracker:         VolumeTracker,       // 24h rolling window

    pub blacklisted_wallets:    Vec<Pubkey>,         // OFAC-blocked addresses

    pub is_paused:              bool,                // Emergency pause

    pub bump:                   u8,                  // PDA bump seed

}

 

3.2.4  V7 Architecture Change: HoldingPeriodConfig

In Version 7.0, the VestingConfig account structure used in V6 has been replaced by HoldingPeriodConfig. This reflects the change from the 5-tranche issuer vesting model (where 60% of tokens were withheld from issuers over 30 months) to the Reg D / Reg S issuance model (where 100% of tokens are distributed to accredited investors, who hold for the Rule 144 or Reg S compliance period before trading).

 

// V7 REPLACEMENT FOR VestingConfig

#[account]

pub struct HoldingPeriodAccount {

    pub version:               u8,       // Schema version — always 7

    pub beneficiary:           Pubkey,   // Investor wallet address

    pub mint:                  Pubkey,   // ST22 mint address

    pub purchase_timestamp:    i64,      // Unix timestamp at token delivery

    pub jurisdiction:          Jurisdiction, // US or NonUS

    pub holding_period_secs:   i64,      // 15_778_800 (US) | 31_536_000 (non-US)

    pub is_locked:             bool,     // True until holding period elapses

    pub bump:                  u8,       // PDA bump seed

}

 

#[derive(AnchorSerialize, AnchorDeserialize, Clone, PartialEq)]

pub enum Jurisdiction {

    US,    // Rule 144 — 6-month holding period

    NonUS, // Regulation S — 12-month distribution compliance period

}

 

// Constants

pub const RULE_144_HOLDING_SECS:  i64 = 15_778_800; // 6 months

pub const REG_S_COMPLIANCE_SECS:  i64 = 31_536_000; // 12 months

 

3.3  The 42 Security Controls

The 42 controls are organized into six categories. Every control executes on every transfer — there are no exceptions, no bypass mechanisms, and no administrative overrides. The categories are not sequential phases; most controls execute in parallel. The sequential dependency exists only within the critical path (Controls 1→2→3→4→24).

 

Category 1: Custody & Asset Backing Verification  ·  9 controls (1–7, 38, 40) controls

Verify at every transfer that circulating token supply never exceeds Series M preferred shares held in Empire custody

 

#

Control Name

Trigger Condition

Enforcement Action

Error

1

Custody Oracle Check

Circulating supply would exceed Empire-custodied share count

Reject — Error 6001 (CustodyDiscrepancy)

6001

2

Oracle Availability

Empire custody feed unavailable or attestation > 400ms stale

Reject — Error 6002 (CustodyOracleUnavailable)

6002

3

Supply Integrity

Total supply inconsistency detected across mint accounts

Reject — atomic revert

6007

4

Locked Balance

Transfer would draw from locked (holding-period) balance

Reject — Error 6024 per Control 24

6024

5

Zero Balance Guard

Transfer from zero-balance account or dust amount

Reject — zero transfer guard

6014

6

Precision Validation

Decimal precision exceeds mint-defined limit

Reject — precision error

6016

7

Supply Integrity Cross-Check

Secondary oracle cross-reference disagrees with primary

Circuit breaker — halt transfers for affected mint

6038

38

Custody Discrepancy Halt

Token supply confirmed > custodied shares (oracle verified)

Halt all transfers for affected mint indefinitely

6038

40

Oracle Consensus Failure

< 2 of 3 oracle feeds available for > 5 minutes

Halt affected hook category

6040

 

Category 2: Sanctions & AML Compliance  ·  4 controls (8–11) controls

OFAC/SDN real-time screening and AML risk scoring on every transfer — not just at onboarding

 

Controls 8–11 implement continuous sanctions and AML compliance. Empire Stock Transfer performs these checks at investor onboarding — Controls 8–11 ensure they are re-applied on every subsequent transfer. A wallet that was clean at onboarding but later added to the OFAC SDN list is blocked immediately on its next transfer attempt.

 

#

Control Name

Trigger Condition

Enforcement Action

Error

8

OFAC Sender Screen

Sender wallet matches OFAC SDN list (updated hourly)

Reject permanently — Error 6003 (SenderSanctioned)

6003

9

OFAC Receiver Screen

Receiver wallet matches OFAC SDN list

Reject permanently — Error 6004 (ReceiverSanctioned)

6004

10

OFAC Oracle Staleness

OFAC SDN feed not updated within 90 minutes

Reject — stale oracle, Error 6005

6005

11

AML Risk Score

ML risk score for sender or receiver exceeds 70/100 threshold

Reject — Error 6006 (SenderHighRisk). Score 31–70: flag for compliance review

6006

 

// Control 11: AML Risk Scoring — three-tier system

pub fn check_aml_risk(risk_score: u8) -> Result<AMLDecision> {

    match risk_score {

        0..=30  => Ok(AMLDecision::Approve),

        31..=70 => Ok(AMLDecision::EnhancedReview), // flag, don't reject

        71..=100 => Err(TransferHookError::SenderHighRisk.into()),

        _ => Err(TransferHookError::InvalidRiskScore.into()),

    }

}

 

Category 3: Investor Eligibility & Holding Period Enforcement  ·  8 controls (12–19) controls

Accreditation verification, KYB entity checks, and Rule 144 / Reg S holding period enforcement on every transfer

 

Category 3 is the most significant change in the V7 Transfer Hook specification. In V6, this category was called 'Vesting Enforcement' and enforced the 5-tranche issuer vesting schedule over 30 months. In V7, the vesting schedule has been removed. Control 24 (formerly the vesting enforcement control) now enforces the Rule 144 and Regulation S mandatory holding periods for accredited investors. The control number is retained for error code continuity; the underlying logic is completely rewritten.

 

#

Control Name

Trigger Condition

Enforcement Action

Error

12

Accreditation Check

Buyer wallet not in Empire's verified accredited investor registry

Reject — accreditation required. Error 6004

6004

13

KYC Status Check

Buyer or seller KYC status expired or flagged in Empire system

Reject — re-verification required

6004

14

KYB Entity Check

Entity investor UBO verification lapsed or flagged

Reject — KYB re-verification required

6004

15

Wallet Registration

Destination wallet not registered in Empire Master Securityholder File

Reject — unregistered wallet cannot receive ST22 tokens

6004

16

Redemption Eligibility

Redemption transaction: KYC completion and accreditation not current

Reject — Error 6004 (KYCInvalid)

6004

17

Jurisdiction Flag

Wallet jurisdiction flag missing or invalid

Reject — jurisdiction cannot be determined

6024

18

Reg S US Person Check

Non-US wallet attempting US market transaction during compliance period

Reject — Reg S restriction

6024

24

Holding Period Lock

Purchase timestamp + holding_period_secs > current_timestamp

Reject — Error 6024 (TokensLocked). US: 6-month Rule 144. Non-US: 12-month Reg S

6024

 

3.3.1  Control 24 Deep Dive — Rule 144 / Reg S On-Chain Enforcement

Control 24 is the mechanism that makes OTCM Protocol's issuance model legally compliant without relying on investor self-discipline or post-hoc regulatory action. It is the on-chain expression of the mandatory holding periods that securities law imposes on restricted security holders.

 

// Control 24: Holding Period Enforcement

pub fn check_holding_period(

    ctx: Context<TransferHook>,

    transfer_amount: u64,

) -> Result<()> {

    let holding = &ctx.accounts.holding_period_account;

    let current_ts = Clock::get()?.unix_timestamp;

 

    // Check if holding period has elapsed

    let required_period = match holding.jurisdiction {

        Jurisdiction::US    => RULE_144_HOLDING_SECS,  // 15_778_800s (6 months)

        Jurisdiction::NonUS => REG_S_COMPLIANCE_SECS,  // 31_536_000s (12 months)

    };

 

    let elapsed = current_ts - holding.purchase_timestamp;

 

    require!(

        elapsed >= required_period,

        TransferHookError::TokensLocked // Error 6024

    );

 

    Ok(())

}

 

Key properties of Control 24 in V7:

 

       Purchase timestamp is immutable — Set by Empire Stock Transfer at token delivery and recorded on-chain. Cannot be altered by any party after it is set.

       Jurisdiction determines holding period — US investors (Reg D 506(c)) hold 6 months under Rule 144. Non-US investors (Reg S) hold 12 months under the Regulation S distribution compliance period. Determined by Empire's KYC/KYB determination at onboarding.

       No grace period — The check is exact to the second. A transfer attempt at 6 months minus 1 second is rejected identically to a transfer attempt at day 1.

       No administrative override — No wallet, no key, no multisig, and no DAO vote can override Control 24. The holding period is enforced by the immutable Transfer Hook program.

       Automatic clearance — Once the holding period elapses, Control 24 clears on the next transfer attempt with no action required from any party.

       Volume limits still apply after clearance — After Control 24 clears, the remaining 41 controls still apply. Investors can trade but are subject to the 4.99% wallet concentration limit, 1% daily sell limit, price impact circuit breaker, and all other protections.

 

Category 4: Market Integrity & Position Limits  ·  9 controls (20–28) controls

Wallet concentration limits, circuit breakers, volume halts, and price impact controls

 

#

Control Name

Trigger Condition

Enforcement Action

Error

20

Max Wallet Limit

Post-transfer balance would exceed 4.99% of total supply for destination

Reject — whale concentration limit. Error: WalletLimitExceeded

6020

21

Pre-Transfer Balance

Source wallet has insufficient transferable balance (excluding locked)

Reject — insufficient balance

6008

22

Zero-Amount Guard

Transfer amount = 0

Reject — zero transfer

6014

23

Self-Transfer Guard

Source wallet = destination wallet

Reject — self transfer

6015

25

Price Impact Limit

Transaction would cause > 2% price deviation from TWAP

Reject — Error 6006 circuit breaker trigger

6006

26

TWAP Oracle Integrity

TWAP feed stale or deviation > 10% from secondary price feed

Reject — stale oracle, cannot enforce price impact

6019

27

Volume Halt

Single wallet attempts to sell > 30% of circulating supply in 24 hours

24-hour trading suspension for that wallet

6037

28

Circuit Breaker

> 30% price movement in single Solana slot for affected ST22

Halt mint-specific transfers for 1 hour

6037

36

Global Circuit Breaker

Protocol-wide pause activated by 3-of-4 multisig

Reject all ST22 transfers platform-wide

6036

 

// Control 20: Max Wallet Limit (4.99%)

pub fn check_wallet_limit(

    destination_balance: u64,

    transfer_amount: u64,

    total_supply: u64,

    config: &SecurityConfig,

) -> Result<()> {

    let new_balance = destination_balance

        .checked_add(transfer_amount)

        .ok_or(TransferHookError::ArithmeticOverflow)?;

 

    let max_allowed = (total_supply as u128)

        .checked_mul(config.max_wallet_percent as u128) // 499 bps

        .ok_or(TransferHookError::ArithmeticOverflow)?

        .checked_div(10_000)

        .ok_or(TransferHookError::ArithmeticOverflow)? as u64;

 

    require!(new_balance <= max_allowed, TransferHookError::WalletLimitExceeded);

    Ok(())

}

 

Category 5: CEI Pattern & Reentrancy Prevention  ·  9 controls (29–35, 41, 42) controls

Checks-Effects-Interactions enforcement preventing reentrancy and CPI privilege escalation attacks

 

Category 5 enforces the Checks-Effects-Interactions (CEI) pattern across all Cross-Program Invocations in the Transfer Hook execution chain. This prevents reentrancy attacks — a class of exploit that has drained hundreds of millions of dollars from DeFi protocols by calling back into a contract before state updates complete. In OTCM's context, a reentrancy attack could theoretically allow an attacker to transfer tokens multiple times before balance state is updated.

 

#

Control Name

Trigger Condition

Enforcement Action

Error

29

Signer Validation

Expected signer(s) not present in transaction

Reject — invalid signer. Error 6007

6007

30

Account Owner Check

Account not owned by expected program

Reject — wrong account owner. Error 6008

6008

31

Mint Consistency

Source/destination token accounts reference different mints

Reject — mint mismatch. Error 6009

6009

32

Account Size Validation

Account data length < minimum expected struct size

Reject — corrupt account. Error 6010

6010

33

Discriminator Check

Account discriminator ≠ expected 8-byte Anchor prefix

Reject — type confusion. Error 6011

6011

34

Token Account State

Source or destination account in Frozen state

Reject — account frozen. Error 6012

6012

35

Delegate Scope

Delegated transfer amount > approved delegation amount

Reject — delegation exceeded. Error 6013

6013

41

Controlled Migration

Emergency contract migration: 4-of-7 multisig + 48h timelock required

Allow migration only with full governance approval

6041

42

Regulatory Compliance Override

Law enforcement or SEC regulatory freeze order received

Comply per legal process — targeted freeze only

6042

 

Category 6: Transaction Integrity & Audit  ·  13 controls (43–55 mapped as 3, 5, 6, 16–19, 32–35, 37, 39) controls

Arithmetic safety, atomic reversion guarantees, compute budget enforcement, and immutable audit log writes

 

Note on numbering: The Transfer Hook technical specification numbers controls 1–42 with some controls mapped to operational sub-functions. The following table presents the transaction integrity and audit controls with their operational identifiers for reference. All execute on every transfer.

 

#

Control Name

Trigger Condition

Enforcement Action

Error

16

Arithmetic Overflow Guard

Any u64 arithmetic would overflow

Reject — overflow detected. All arithmetic uses u128 intermediate

6016

17

Atomic Revert Guarantee

Any prior control in chain has failed

Full atomic rollback — no partial state changes persist

6017

18

Hook Order Validation

Controls not executing in defined sequence

Reject — hook order violation

6018

19

Duplicate Detection

Highly similar transaction signature seen within 1 slot

Reject — probable duplicate

6019

32

Compute Budget Enforcement

Remaining CU < 50,000 before Hook 6

Reject — insufficient compute budget

6032

33

Account Rent Validation

Any account below rent-exempt minimum

Reject — rent depleted

6033

34

Program Version Check

Caller program version < minimum compatible

Reject — version mismatch

6034

35

Key Rotation Compliance

Oracle signer key not in current oracle registry

Reject — unrecognized signer

6035

37

Per-Mint Circuit Breaker

> 30% price movement in single slot

Halt mint-specific transfers 1 hour

6037

39

OFAC Emergency Block

New OFAC SDN entry matching active wallet

Immediate freeze — no grace period

6039

 

3.4  Complete Error Code Registry

Every control failure produces a specific error code enabling precise diagnosis and compliance reporting. The following is the authoritative error code registry for V7:

 

#[error_code]

pub enum TransferHookError {

    // Custody & Asset Backing

    #[msg("Custody oracle: token supply exceeds custodied shares")]

    CustodyDiscrepancy = 6001,

    #[msg("Custody oracle: attestation unavailable or stale (>400ms)")]

    CustodyOracleUnavailable = 6002,

 

    // Sanctions & AML

    #[msg("OFAC: sender wallet matches SDN list")]

    SenderSanctioned = 6003,

    #[msg("OFAC: receiver wallet matches SDN list")]

    ReceiverSanctioned = 6004,

    #[msg("OFAC: oracle data stale — cannot verify sanctions status")]

    OfacOracleStale = 6005,

    #[msg("AML: sender or receiver risk score exceeds 70/100")]

    SenderHighRisk = 6006,

 

    // Investor Eligibility

    #[msg("KYC/Accreditation: buyer not verified accredited investor")]

    KYCInvalid = 6004,

    #[msg("Holding period: tokens locked — Rule 144 / Reg S not satisfied")]

    TokensLocked = 6024,   // V7: replaces VestingLocked from V6

 

    // Market Integrity

    #[msg("Wallet limit: destination would exceed 4.99% of supply")]

    WalletLimitExceeded = 6020,

    #[msg("Circuit breaker: price impact exceeds 2% TWAP deviation")]

    CircuitBreakerTriggered = 6006,

    #[msg("Volume halt: single wallet exceeds 30% daily sell limit")]

    DailySellLimitExceeded = 6037,

 

    // CEI & Integrity

    InvalidSigner = 6007,

    WrongAccountOwner = 6008,

    MintMismatch = 6009,

    CorruptAccountSize = 6010,

    AccountTypeConfusion = 6011,

    AccountFrozen = 6012,

    DelegationExceeded = 6013,

    ZeroTransfer = 6014,

    SelfTransfer = 6015,

    ArithmeticOverflow = 6016,

    AtomicRevert = 6017,

    HookOrderViolation = 6018,

    StaleAttestation = 6019,

 

    // Emergency

    GlobalCircuitBreaker = 6036,

    PerMintCircuitBreaker = 6037,

    CustodyDiscrepancyHalt = 6038,

    OFACEmergencyBlock = 6039,

    OracleConsensusFail = 6040,

    ControlledMigration = 6041,

    RegulatoryOverride = 6042,

}

 

3.5  Main Transfer Hook Entry Point

The main Transfer Hook entry point coordinates all 42 controls through a structured validation sequence. Critical path controls (1, 8, 11, 12, 24) execute sequentially — each must pass before the next runs. All other controls execute in parallel groups to minimize total latency.

 

#[program]

pub mod transfer_hook {

    use super::*;

 

    pub fn transfer_hook(ctx: Context<TransferHook>, amount: u64) -> Result<()> {

        let config = &ctx.accounts.security_config;

 

        // ── CRITICAL PATH: Sequential ─────────────────────────

        // Control 1: Custody verification (Empire oracle)

        verify_custody_oracle(&ctx.accounts.custody_oracle, amount, config)?;

 

        // Controls 8-10: OFAC sanctions screening

        check_ofac_sender(&ctx.accounts.sender, config)?;

        check_ofac_receiver(&ctx.accounts.receiver, config)?;

        check_ofac_oracle_freshness(&ctx.accounts.ofac_oracle)?;

 

        // Control 11: AML risk scoring

        check_aml_risk(ctx.accounts.aml_oracle.sender_score)?;

 

        // Controls 12-18: Investor eligibility & holding period

        check_accreditation(&ctx.accounts.receiver, config)?;

        check_holding_period(&ctx.accounts.holding_period_account)?; // Control 24

 

        // ── PARALLEL: Market integrity, CEI, Audit ───────────

        check_wallet_limit(amount, config)?;        // Control 20

        check_price_impact(amount, config)?;        // Control 25

        check_volume_halt(amount, config)?;         // Control 27

        check_circuit_breaker(config)?;             // Control 28

        validate_cei_pattern(&ctx.accounts)?;       // Controls 29-35

        enforce_arithmetic_safety(amount)?;         // Controls 16-19

        // ... remaining controls 36-42 (emergency + audit) ...

 

        // ── AUDIT: Write immutable on-chain compliance record ─

        emit!(TransferValidated {

            mint:      ctx.accounts.mint.key(),

            from:      ctx.accounts.source.key(),

            to:        ctx.accounts.destination.key(),

            amount,

            timestamp: Clock::get()?.unix_timestamp,

            all_controls_passed: true,

        });

 

        Ok(())

    }

}

 

3.6  Immutability Guarantee

The Transfer Hook cannot be removed or disabled after mint creation. This is a property of the SPL Token-2022 standard: once a token mint is created with a Transfer Hook extension, the hook program address is permanently stored in the mint account. The Token-2022 program will invoke that hook on every transfer for the entire existence of the token.

OTCM Protocol's Transfer Hook program upgrade authority is held by a 5-of-9 multi-signature wallet with geographically distributed key holders. All upgrades require a 24-hour timelock period during which the upgrade can be cancelled through DAO governance. Critically, even an upgrade cannot remove the 42 security controls — the controls are defined in the program logic, and any upgrade that would materially weaken investor protections requires a DAO vote that passes the 66.67% supermajority threshold and satisfies the account schema compatibility attestation requirement.

 

Property

Mechanism

Who Controls It

Hook address permanence

SPL Token-2022 stores hook address in mint account permanently

No one — Token-2022 program level, cannot be changed

Hook invocation

Token-2022 automatically calls hook via CPI on every transfer

No one — mandatory at protocol level

Program upgrade authority

5-of-9 multi-sig with 24-hour timelock

5 of 9 designated key holders (geographically distributed)

Security control immutability

Controls in immutable on-chain program — outside DAO governance scope

Cannot be weakened by any party including OTCM Protocol

Parameter adjustments

DAO vote with 66.67% supermajority, 48-hour timelock, audit attestation

OTCM Security Token stakers

 

V7 Change Summary — Transfer Hook Architecture

The only architectural change in V7 vs V6 for Section 3 is Control 24. In V6, Control 24 enforced the 5-tranche issuer vesting schedule (20% unlocking at token minting, graduation, 6/12/18 months post-graduation). In V7, Control 24 enforces the Rule 144 holding period (6 months for US accredited investors) and the Regulation S distribution compliance period (12 months for non-US investors). The VestingConfig account structure is replaced by HoldingPeriodAccount. All other controls (1–23, 25–42) are unchanged from V6. Error code 6024 is retained for continuity with the Technical Specification document OTCM-TH-SPEC-001.

 

Groovy Company, Inc. dba OTCM Protocol  |  CIK: 1499275  |  Version 7.0  |  March 2026  |  Confidential