SPL Token-2022 Transfer Hook — Layer 2
Section 3: SPL Token-2022 Transfer Hook — Layer 2
RWA Tokens Platform Whitepaper · Version 10.0 Groovy Company, Inc. · May 2026 Document Reference: RWA-TH-SPEC-001 v4.0 (aligned with Whitepaper V10.0)
The complete technical specification for the platform's 42-control Transfer Hook security architecture plus module-aware extensions — the foundational compliance enforcement mechanism that makes regulatory bypass structurally impossible across all three production modules.
Total core security controls
42 (immutable, V6+)
Module-aware extensions
2 (CB-21 NAV-deviation variant — M2; REG-42 federal-action variant — M3)
Transfer coverage
100% — every ST22 transfer invokes all applicable controls
Bypass possibility
Zero — enforced at SPL Token-2022 program level by the Solana runtime
Target validation latency
< 1,000 ms (parallel execution)
Compute unit budget per validation
< 5,000 CU baseline (M1 ≈ 800 K CU, M2 ≈ 820 K CU, M3 ≈ 830 K CU including oracle reads)
Implementation language
Rust / Anchor framework
Immutability
Transfer Hook program ID bound to mint at creation; cannot be removed, repointed, or disabled (Certora E.4, E.6)
V10 change vs V8
Module-aware extensions added: CB-21 NAV-deviation variant for Module 2 (Real Estate), REG-42 federal-action variant for Module 3 (CORECM). The 42 core controls are unchanged. SecurityConfig PDA extended with module-aware fields.
3.1 The Alesia Doctrine — Compliance by Encirclement
The Transfer Hook architecture embodies 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. They are also irrelevant to many of the cross-module use cases the platform addresses (single-asset real-estate entities, basin-asset critical-minerals entities) where no traditional securities-clearing infrastructure has ever existed.
The platform'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, regardless of which module the mint belongs to — must pass through all 42 core controls plus all applicable module-aware extensions 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 Groovy Company 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.
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 — the only venue that preserves Transfer Hook semantics
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; Empire Ed25519 attestation per Solana slot
Module-specific risk (NAV drift, M2)
Application-layer NAV checks bypassable
Control CB-21 NAV-deviation variant — runtime-enforced for Module 2 mints
Module-specific risk (federal action, M3)
Manual freeze processes lag federal events
Control REG-42 federal-action variant — automatic 60-minute SLA on detection
Transfer Hook (Layer 2)
Cannot be bypassed — any failure reverts entire transaction
This is the platform's approach — compliance at the primitive
3.1.2 The April 13, 2026 Covered User Interface Statement
The SEC Staff Statement on Covered User Interface Providers (April 13, 2026) reinforces the runtime-enforcement weight in compliance characterization. UI-layer compliance is insufficient. The platform's architecture maps directly to the Statement's framework: cedex.market is a Covered UI Provider, but the substantive compliance enforcement happens at the Solana Transfer Hook layer, not at the UI. Even if a user submits transfer transactions directly to a Solana RPC endpoint bypassing cedex.market, the SPL Token-2022 program will refuse the instruction unless the registered Transfer Hook is invoked successfully. This UI-independence is what allows the platform to satisfy Pillar 6 (Investor Protection — compliance enforcement at every transfer) of Category 1 Model B as an architectural property rather than a UI-layer assertion.
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 Groovy Company, or by any trading venue.
3.2.2 Program Structure
The Transfer Hook program is implemented in Rust using the Anchor framework. Module-aware extension logic is structured as conditional execution paths that run only when SecurityConfig.module matches the relevant module.
3.2.3 Account Architecture — SecurityConfig PDA
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 mint at initialization, establishing the security parameters that govern all transfers of that token for its entire existence. V10 extends the V8 schema with module-aware fields; V8 mints have module = 1 by default and zero values for module-aware fields, preserving V8 behavior unchanged.
3.2.4 Account Architecture — HoldingPeriodAccount (Reg D / Reg S / Reg CF)
V10 expands the V7 jurisdiction enum from {US, NonUS} to {RegD, RegS, RegCF}. Existing V8 accounts continue to function; runtime mapping: US → RegD, NonUS → RegS. Reg CF requires a new account at issuance and is not retroactively added to existing investors.
3.2.5 Account Architecture — Custody Oracle (All Modules)
The Custody Oracle stores Empire Stock Transfer's Ed25519-signed attestation of the underlying equity backing the mint 1:1. The asset class is encoded in the oracle account so Control CV-04 can verify backing-class consistency with SecurityConfig.module.
3.2.6 Account Architecture — NAV Oracle (Module 2 Only)
The NAV Oracle is created per Module 2 mint at initialization. The authorized appraiser Ed25519-signs every NAV attestation. CB-21 NAV-deviation variant reads this account on every Module 2 transfer.
3.2.7 Account Architecture — Classification Oracle (Module 3 Only)
The Classification Oracle is created per Module 3 mint at initialization. The authorized Classification relay polls Federal Register, USGS, and DOE feeds with redundancy and Ed25519-signs status updates. REG-42 federal-action variant reads this account on every Module 3 transfer.
3.3 The 42 Core Security Controls
The 42 controls are organized into eight categories. Every applicable control executes on every transfer. The categories are not strictly sequential phases; most controls execute in parallel within the Anchor instruction. Sequential dependency exists only within the critical path (Controls CV-01 → CV-02 → CV-03 → CV-04 → HP-24).
3.3.1 Category 1 — Custody Verification (CV-01 through CV-07, plus CV-38, CV-40)
Verify on every transfer that circulating token supply never exceeds the custodied backing-class shares held in Empire custody. Module-aware: backing class is Common B (M1), SAE equity (M2), or BAE equity (M3).
CV-01
Custody Oracle Check
Circulating supply would exceed CustodyOracle.custodied_balance
Reject — CustodyDiscrepancy
6001
CV-02
Oracle Availability
Empire custody attestation > 400 ms stale
Reject — CustodyOracleUnavailable
6002
CV-03
Supply Integrity
Total supply inconsistency detected across mint accounts
Reject — atomic revert
6007
CV-04
Backing Class Match
CustodyOracle.class_label does not match expected for SecurityConfig.module (M1→CommonB; M2→SAE; M3→BAE)
Reject — BackingClassMismatch
6008
CV-05
Asset Identifier Match
SecurityConfig.asset_identifier does not match the bound CUSIP (M1) / property ID (M2) / basin ID (M3)
Reject — AssetIdentifierMismatch
6009
CV-06
Locked Balance
Transfer would draw from locked (holding-period) balance
Reject per HP-24
6024
CV-07
Precision Validation
Decimal precision exceeds mint-defined limit
Reject — PrecisionError
6016
CV-38
Custody Discrepancy Halt
Token supply confirmed > custodied class shares (oracle verified)
Halt all transfers for affected mint indefinitely until manual reconciliation
6038
CV-40
Oracle Consensus Failure
< 2 of 3 oracle feeds available for > 5 minutes
Halt affected hook category
6040
3.3.2 Category 2 — Sanctions and AML Compliance (SX-08 through SX-11)
OFAC/SDN real-time screening and AML risk scoring on every transfer — not just at onboarding. Empire Stock Transfer performs these checks at investor onboarding; SX-08 through SX-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.
SX-08
OFAC Sender Screen
Sender wallet matches OFAC SDN list (updated hourly)
Reject permanently — SenderSanctioned
6003
SX-09
OFAC Receiver Screen
Receiver wallet matches OFAC SDN list
Reject permanently — ReceiverSanctioned
6004
SX-10
OFAC Oracle Staleness
OFAC SDN feed not updated within 90 minutes
Reject — StaleSanctionsOracle
6005
SX-11
AML Risk Score
ML risk score for sender or receiver exceeds 70/100
Reject — HighRiskWallet
6006
3.3.3 Category 3 — Investor Eligibility and Holding Period (IV-12 through IV-19; HP-24)
Accreditation verification, KYB entity checks, and Reg D / Reg S / Reg CF holding-period enforcement on every transfer.
IV-12
Accreditation Check
Buyer wallet not in Empire's verified accredited investor registry (Reg D path)
Reject — accreditation required
6010
IV-13
KYC Status Check
Buyer or seller KYC status expired or flagged in Empire system
Reject — re-verification required
6011
IV-14
KYB Entity Check
Entity investor UBO verification lapsed or flagged
Reject — KYB re-verification required
6012
IV-15
Wallet Registration
Destination wallet not registered in Empire MSF
Reject — UnregisteredWallet
6013
IV-16
Redemption Eligibility
Redemption transaction: KYC completion and accreditation not current
Reject — KYCInvalid
6014
IV-17
Jurisdiction Flag
Wallet jurisdiction flag missing or invalid
Reject — JurisdictionUnknown
6017
IV-18
Reg S US Person Check
Non-US wallet attempting US-market transaction during compliance period
Reject — Reg S restriction
6018
IV-19
Reg CF Investor Limit
Reg CF investor total annual investment exceeds JOBS Act §4(a)(6) statutory cap
Reject — RegCFLimitExceeded (V10)
6019
HP-24
Holding Period Lock
purchase_timestamp + holding_period_secs > current_timestamp
Reject — TokensLocked
6024
Control HP-24 Deep Dive — Reg D / Reg S / Reg CF On-Chain Enforcement
Control HP-24 is the mechanism that makes the platform'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. V10 extends V7's two-jurisdiction model (US/NonUS) to a three-jurisdiction model (Reg D / Reg S / Reg CF).
Certora invariant E.5 formally proves that no execution path can shorten the holding-period timer once the HoldingPeriodAccount is created. The purchase_timestamp field is set exactly once at token delivery and is never written after.
3.3.4 Category 4 — Position Limits (PL-20 through PL-23, PL-25)
Wallet concentration caps and per-investor limits.
PL-20
Wallet Cap (statutory)
Receiver wallet would exceed max_wallet_percent of circulating supply
Reject — WalletCapExceeded
6020
PL-22
Single-Trade Cap
Trade size > 0.5% of total supply
Reject — TradeSizeExcessive
6022
PL-23
Daily Wallet Activity
Same wallet > 50 transfers/day
Reject — WalletActivityCap
6023
PL-25
Cooldown
Sender wallet last transferred < cooldown_secs ago
Reject — CooldownActive
6025
Default max_wallet_percent = 999 basis points (9.99%). Per Module 2 commercial use case, max_wallet_percent is configurable per mint via tripartite-concurrence governance up to 9.99%; per Module 1 OTC microcap default is 4.99% (statutorily aligned with §13(d) reporting threshold sensitivity).
3.3.5 Category 5 — Circuit Breakers (CB-21, CB-26, CB-27)
Price, volume, and oracle-failure circuit breakers. CB-21 has a Module 2 module-aware variant documented in Section 3.4.
CB-21
Price Halt (core)
Price moves > 10% from TWAP in 5-minute window
Halt all trades 5 minutes
6021
CB-21 (M2 variant)
NAV Deviation
|on_chain_price − NAV| / NAV > nav_deviation_max_bps / 10000 OR NAV oracle stale beyond reappraisal_cadence_secs
Reject — NavDeviationExceeded
6021-NAV
CB-26
Price Impact
Single trade impacts price > 2% vs TWAP
Reject — PriceImpactExceeded
6026
CB-27
Volume Halt
Daily sell volume > 30% of average daily volume
Halt all sell trades 24 hours
6027
3.3.6 Category 6 — Holding Period Adjacent (HP-26 through HP-33)
Eight controls related to holding-period accounting, including stake-period accounting (where applicable post-graduation) and beneficiary updates.
HP-26
Holding-period account existence
Verify HoldingPeriodAccount PDA exists for (mint, beneficiary)
HP-27
Cross-mint isolation
Holding-period account binds to one mint only
HP-28
Beneficiary identity
Beneficiary must match wallet performing transfer initiation
HP-29
Account version
Schema version field validation (≥ 7)
HP-30
Locked-flag consistency
is_locked derives from time math; cannot be unset by admin
HP-31
Re-onboarding window
New HoldingPeriodAccount requires Empire re-attestation
HP-32
Multi-jurisdiction guard
Investor cannot hold same mint under two jurisdictions simultaneously
HP-33
Jurisdiction immutability
jurisdiction field is write-once at account creation
3.3.7 Category 7 — Sanctions & Conversion (SX-34 through SX-37, PC-38 through PC-40)
OFAC re-screening on conversion events and protective conversion controls.
SX-34
Conversion-time OFAC re-check
Re-run OFAC at any redemption / burn / conversion event
SX-35
Conversion KYC re-check
KYC must be current at conversion
SX-36
Conversion accreditation re-check
Reg D investor must remain accredited at conversion (Reg D only)
SX-37
Conversion jurisdiction stability
Jurisdiction at conversion = jurisdiction at acquisition
PC-38
Custodied class verification
Conversion must produce equivalent custodied class (M1: Common B; M2: SAE; M3: BAE)
PC-39
Conversion-time supply integrity
Burn/mint atomicity at conversion
PC-40
Conversion audit emission
GA-42 emission per conversion event
3.3.8 Category 8 — Governance and Emergency (GA-41, GA-42, REG-42)
Audit emission and Regulatory Freeze. REG-42 has a Module 3 module-aware variant documented in Section 3.4.
GA-41
Audit-Log Pre-Validation
Pre-execution emission of (mint, beneficiary, amount, control results) digest
Continue (emission cannot fail; CB if storage exhausted)
6041
GA-42
Audit-Log Emission
Post-execution emission of full control evaluation set
Continue
6042-AUD
REG-42
Regulatory Freeze (manual)
Legal Counsel signoff + 3-of-5 multi-sig invocation
Halt all transfers on affected mint
6042
REG-42 (M3 variant)
Federal-Action Freeze
ClassificationOracle.federal_action_active = true for the mint
Auto-freeze with 60-minute SLA from detection; auto-resume on false
6042-FED
3.4 Module-Aware Extensions (V10)
V10 introduces two module-aware Transfer Hook extensions that plug into the immutable 42-control surface as additive runtime checks. The 42 core controls do not change; the extensions execute alongside them when applicable to the mint's module classification. Existing V8 mints with module = 1 (Equities) execute exactly as in V8 — the extensions are dormant for them. Certora invariant E.4 formally proves that the module-aware extensions cannot be removed or weakened post-deployment.
3.4.1 CB-21 NAV-Deviation Variant — Module 2 (Real Estate)
Trigger: any Module 2 transfer when the on-chain trade price deviates from the Module 2 NAV Oracle's nav_per_token by more than SecurityConfig.nav_deviation_max_bps (default 2,200 = 22%) OR when the NAV Oracle attestation is older than SecurityConfig.reappraisal_cadence_secs (default 7,776,000 = 90 days).
Why 22% default deviation tolerance. The 22% default nav_deviation_max_bps reflects the platform's fractionalization-premium pricing model: ST22 Module 2 tokens trade at up to 22% premium over the underlying property NAV to account for (a) liquidity premium of 24/7/365 secondary trading, (b) fractionalization convenience versus owning a whole property, (c) ongoing platform compliance and §17A custody costs, and (d) the protocol fee structure. The CB-21 NAV-deviation variant prevents trades from drifting outside this tolerance band, which would either undermine the NAV-bound investor protection (price falls too far below NAV, signaling distress) or signal market-manipulation activity (price spikes above NAV without underlying property revaluation). The 22% can be tightened (never loosened beyond statutory ceiling) per mint via tripartite concurrence governance.
3.4.2 REG-42 Federal-Action Variant — Module 3 (CORECM)
Trigger: any Module 3 transfer when ClassificationOracle.federal_action_active = true. Enforcement: automatic freeze with 60-minute SLA from detection. Resume: automatic when federal_action_active returns to false.
The 60-minute SLA: detection-to-enforcement latency is bounded by (a) the Classification relay polling cycle, (b) Ed25519 signing latency, (c) Solana transaction confirmation, and (d) on-chain attestation propagation. The Classification relay polls Federal Register, USGS, and DOE feeds with redundant subscriptions; on detection of a qualifying event affecting any monitored basin asset, the relay signs and submits a ClassificationOracle update within ≤ 30 minutes operational target. The remaining 30 minutes is reserved for Solana network latency, monitoring confirmation, and incident-response paging (Incident Response Playbook §13).
Federal action kinds tracked (federal_action_kind field):
Section 232 of Trade Expansion Act of 1962
1
Federal Register, Office of the President
Defense Production Act Title III
2
DOD, DOE federal-investment notices
Executive Order (e.g., EO 14017)
3
Federal Register, White House
USGS Critical Minerals List change
4
USGS publication
DOE Critical Materials Strategy event
5
DOE publication
3.5 Implementation: The Main Transfer Hook Entry Point
3.6 Compute Unit Budget by Module
Solana's compute-unit (CU) budget is finite per transaction (default 200,000 CU; max 1,400,000 CU). The 42 core controls plus oracle reads consume the bulk of the budget. Module-aware extensions add module-specific oracle reads.
Module 1 (Equities)
~770,000 CU
None applicable (CV-04 skips ext oracle reads)
~800,000 CU
Module 2 (Real Estate)
~770,000 CU
+ NAV oracle read + Ed25519 verify + deviation math ≈ 50,000 CU
~820,000 CU
Module 3 (CORECM)
~770,000 CU
+ Classification oracle read + Ed25519 verify + status check ≈ 60,000 CU
~830,000 CU
Per-control budgets are validated under load testing (Testing Guide §11). The requestUnits instruction is included in every CEDEX transaction with the appropriate per-module budget.
3.7 Error Code Registry (V10)
6001
CustodyDiscrepancy
CV-01
All
6002
CustodyOracleUnavailable
CV-02
All
6003
SenderSanctioned
SX-08
All
6004
ReceiverSanctioned
SX-09
All
6005
StaleSanctionsOracle
SX-10
All
6006
HighRiskWallet
SX-11
All
6007
SupplyInconsistency
CV-03
All
6008
BackingClassMismatch
CV-04
All
6009
AssetIdentifierMismatch
CV-05
All
6010
AccreditationRequired
IV-12
M1, M2, M3 (Reg D path)
6011
KYCInvalid
IV-13
All
6012
KYBLapsed
IV-14
All (entity investors)
6013
UnregisteredWallet
IV-15
All
6014
RedemptionKYCInvalid
IV-16
All
6016
PrecisionError
CV-07
All
6017
JurisdictionUnknown
IV-17
All
6018
RegSRestriction
IV-18
All (Reg S investors)
6019
RegCFLimitExceeded
IV-19
All (Reg CF investors) — V10
6020
WalletCapExceeded
PL-20
All
6021
PriceHalt (core)
CB-21
All
6021-NAV
NavDeviationExceeded
CB-21 NAV variant
M2 only
6021-NAV-STALE
NavReappraisalOverdue / NavOracleStale
CB-21 NAV variant
M2 only
6022
TradeSizeExcessive
PL-22
All
6023
WalletActivityCap
PL-23
All
6024
TokensLocked
HP-24
All
6025
CooldownActive
PL-25
All
6026
PriceImpactExceeded
CB-26
All
6027
VolumeHalt
CB-27
All
6038
CustodyDiscrepancyHalt
CV-38
All
6040
OracleConsensusFailure
CV-40
All
6041
AuditPreEmissionFailure
GA-41
All
6042
RegulatoryFreeze (manual)
REG-42
All
6042-FED
FederalActionActive
REG-42 federal variant
M3 only
6042-FED-STALE
ClassificationOracleStale
REG-42 federal variant
M3 only
3.8 Formal Verification Mapping
The Transfer Hook is covered by the following Certora invariants:
E.1
For every issued ST22 token there exists a 1:1 custodied equity share of the appropriate class (CommonB / SAE / BAE)
CV-01, CV-04
E.2
No execution path exists by which a Transfer Hook control or applicable module-aware extension can be bypassed
All controls + extensions
E.4
The 42 core controls and module-aware extensions cannot be removed, weakened, or repointed post-deployment
Program upgrade authority bound to mint creation
E.5
The HoldingPeriodAccount holding-period timer cannot be shortened by any execution path
HP-24, HP-30, HP-33
E.6
The Transfer Hook program ID for a given mint cannot be changed post-creation
Token-2022 transfer-hook extension immutability
Specifications and verification reports are reproducible from the public program IR.
RWA Tokens Whitepaper V10 — Section 3 — Confidential — Groovy Company, Inc.
Last updated
Was this helpful?