Skip to content

Transfer Rules

Protocol-level enforcement — non-compliant transfers don't get logged and ignored, they get rejected.

Transfer Compliance Checks

The transfer_with_compliance instruction is the gate through which every security token transfer must pass. It performs five checks in sequence. If any check fails, the entire transaction reverts — the tokens do not move, and a ComplianceViolation event is emitted with the specific reason for rejection.

Check 1: KYC Validity

Both the sender and receiver wallets must hold valid, unexpired KYC Credential NFTs. The instruction reads the expires_at field on each credential and compares it to the current slot time. An expired credential is treated the same as no credential — the transfer is rejected.

Additionally, both credentials must have aml_clear: true and pep_clear: true. If either flag has been revoked since the credential was issued (via a compliance officer action), the transfer is rejected.

Check 2: Lock-Up Period

The sender's InvestorPosition PDA contains a locked_until timestamp. For Reg D securities, this is typically set to 6-12 months after the initial purchase. The instruction compares locked_until against the current slot time. If the lock-up period has not elapsed, the transfer is rejected — no exceptions, no overrides (except force_transfer with court order, see below).

Check 3: Jurisdiction Whitelist

The receiver's KYC Credential NFT contains a jurisdiction_hash — a SHA-256 hash of their ISO country code. The instruction reads the offering's ComplianceConfig PDA and checks whether this hash appears in the allowed_jurisdictions list. A Reg S offering that excludes US investors will reject any transfer to a wallet whose jurisdiction hash matches the US code hash.

Check 4: Accreditation Tier

The receiver's KYC Credential NFT contains an investor_class field: Accredited, Professional, Qualified Purchaser, or Retail. The instruction checks this against the offering's accreditation requirements. A Reg D 506(c) offering requires Accredited status or above — a Retail investor cannot receive these tokens, period.

Check 5: Investor Count

If the receiver does not already hold tokens in this offering (i.e., this transfer would create a new investor position), the instruction checks the offering's current investor count against the max_investors limit in the ComplianceConfig. Reg D offerings have strict investor count limits — the program enforces them at the protocol level.

Transfer Hook Mechanism

The compliance checks described above are not merely enforced by the sails_securities program — they are enforced by the SPL-2022 Transfer Hook, which operates at a lower level in the Solana runtime.

Here is what this means in practice: even if someone bypasses the sails_securities program entirely and calls the SPL Token program directly to transfer Sails security tokens, the Transfer Hook is still invoked. The Solana runtime calls the hook on every transfer of a token mint that has the Transfer Hook extension enabled. There is no way to move tokens without passing through the compliance checks.

The Transfer Hook execution flow:

  1. A transfer instruction is submitted to the Solana runtime (via any program — sails_securities, raw SPL Token, a DEX, anything).
  2. The runtime detects that the token mint has a Transfer Hook extension configured.
  3. The runtime invokes the Transfer Hook program with the transfer details: source wallet, destination wallet, amount, and the mint address.
  4. The hook program reads the KYC Credential NFTs on both wallets, the ComplianceConfig PDA, and the sender's InvestorPosition PDA.
  5. If all five compliance checks pass, the hook returns success and the transfer proceeds.
  6. If any check fails, the hook returns an error. The entire transaction is reverted. The tokens do not move. A ComplianceViolation event is emitted.

This is the critical architectural decision: compliance is not enforced by application logic that can be bypassed. It is enforced by the Solana runtime itself. The Transfer Hook is as inescapable as gravity.

Account Freezing

The freeze_account instruction locks an investor's position — preventing all transfers, sales, CrossConversions, and distribution claims until the freeze is lifted.

Aspect Detail
Authorization Requires Security Admin NFT (from the Melusina Admin NFT system, level=Security)
Parameters investor_wallet — the wallet to freeze; reason — logged to audit trail
Effect Sets a frozen flag on the InvestorPosition PDA. The Transfer Hook checks this flag and rejects all outgoing transfers. Distribution claims are blocked. CrossConversion requests are blocked.
Unfreezing Same authorization level (Security Admin NFT). Reason for unfreeze also logged.
Emergency Freeze For high-urgency situations, a 2-of-3 threshold signing ceremony can freeze an account even if the Security Admin NFT is unavailable.
Audit Trail Every freeze and unfreeze action is logged with the actor's wallet, NFT role, timestamp, and reason. 7-year retention.

Account freezing is a regulatory tool. It exists for AML/SAR compliance, court orders, and regulatory investigations. It is not a general-purpose moderation feature — every use is logged, audited, and requires a documented reason.

Forced Transfers

The force_transfer instruction is the most restricted operation in the entire program. It moves tokens from one wallet to another without the sender's consent — a power that exists solely for court-ordered transfers and regulatory enforcement actions.

Requirement Detail
Keyholder Threshold 3-of-5 Master NFT keyholder threshold signing. Three separate keyholders, using hardware wallets, in three separate locations, must independently sign the transaction.
Court Order Hash A SHA-256 hash of the court order document must be included in the instruction. This hash is stored on-chain permanently — cryptographic proof that a legal basis existed for the forced transfer.
Parameters from — source wallet; to — destination wallet; amount — token amount; court_order_hash — SHA-256 of the court order
Compliance Bypass Force transfer does bypass the standard Transfer Hook compliance checks (lock-up, jurisdiction, accreditation). The court order supersedes contract-level compliance rules. However, the transfer is still logged and the destination wallet's KYC status is recorded.
Audit Trail Critical-severity audit event. All 3+ signing keyholders recorded. Court order hash immutably stored on-chain. Notification sent to all platform operators and the Trustee.

This instruction exists because regulated securities exist in a legal system. Courts can order transfers. Regulators can mandate seizures. The platform must comply — but it does so with maximum transparency, maximum auditability, and maximum friction. Three keyholders must agree. A court order must be on record. The entire action is visible on-chain forever.

Jurisdiction Rules

Jurisdiction enforcement is one of the most critical compliance functions — especially for offerings that operate under multiple regulatory regimes simultaneously.

How Jurisdiction Matching Works

Each investor's KYC Credential NFT contains a jurisdiction_hash — a SHA-256 hash of their ISO 3166-1 country code. The offering's ComplianceConfig PDA contains an allowed_jurisdictions list of these same hashes. The Transfer Hook compares the receiver's hash against the whitelist. Match: transfer proceeds. No match: transfer rejected.

The hashing serves a privacy function — the blockchain does not reveal which country an investor is in. Only the hash is stored on-chain. The Transfer Hook can verify membership in the whitelist without exposing the underlying country code.

Common Jurisdiction Configurations

Offering Type Jurisdiction Rule Effect
Reg D 506(b/c) US-only Only wallets with US jurisdiction hash can receive tokens. International investors are blocked at the Transfer Hook level.
Reg S Non-US only US jurisdiction hash is explicitly excluded. Flowback restrictions prevent tokens from reaching US wallets during the distribution compliance period.
Dual Reg D + Reg S Segregated tranches Separate token mints for US (Reg D) and non-US (Reg S) tranches. Each mint has its own ComplianceConfig with the appropriate jurisdiction whitelist. Cross-tranche transfers are blocked.
Restricted Jurisdictions Sanctions compliance OFAC-sanctioned jurisdiction hashes are never included in any offering's whitelist. The KYC Credential NFT is never issued for sanctioned jurisdictions in the first place — double enforcement.

Jurisdiction rules are immutable once set on an offering's ComplianceConfig — they can only be modified by the Issuer with Platform Operator approval, and any change is logged to the audit trail. This ensures that an offering's regulatory status cannot be silently changed after investors have committed capital.