Token Standard
The sails_securities program — security tokens with compliance enforcement at the protocol level.
Program Overview
The sails_securities program is an Solana Anchor program purpose-built for regulated securities issuance. It extends the Melusina NFT authority pattern with securities-specific logic: offering lifecycle management, compliance-gated minting, CrossConversion lockbox integration, distribution waterfall execution, and transfer enforcement via SPL-2022 Transfer Hook.
This is not a general-purpose token program. Every instruction assumes a regulated context. Every account structure encodes compliance constraints. Every event is designed for audit trail consumption. The program will reject any operation that violates its compliance rules — there is no admin override that bypasses the Transfer Hook, no backdoor for unverified wallets, no way to mint tokens to an investor without a valid KYC credential.
Instructions
The program exposes eight core instructions. Each instruction enforces its own authorization requirements — the required NFT role, the threshold level, and the compliance checks are non-negotiable:
| Instruction | Parameters | Authorization | Description |
|---|---|---|---|
init_offering |
series_id, token_config, max_supply, nominal_value |
Issuer NFT + Platform Operator approval | Creates the PDA for a new offering, links it to the DAO Series LLC, and initializes the ComplianceConfig. Sets the token mint, nominal value, and maximum supply. |
mint_security_token |
offering_id, investor_wallet, amount |
Issuer NFT or Broker NFT | Mints security tokens to an investor. Requires the investor wallet to hold a valid, unexpired KYC Credential NFT with the correct investor_class and jurisdiction_hash. Checks max_investors limit before minting. |
burn_for_crossconversion |
offering_id, amount |
Investor wallet + Trustee NFT authentication | Locks tokens in the CrossConversion lockbox PDA. Emits CrossConversionRequested event for ISIN issuance workflow. Increments the lockbox counter. |
distribute |
offering_id, amount_per_token |
Paying Agent NFT + Trustee authentication | Executes dividend or interest distribution to all token holders. Creates a DistributionRecord with a claimed bitmap for investor pull-based claiming. |
transfer_with_compliance |
from, to, amount |
Sender wallet signature | Transfers tokens between wallets with full compliance verification. Checks both wallets for valid KYC, enforces lock-up period, validates jurisdiction whitelist, verifies accreditation tier. See Transfer Rules. |
freeze_account |
investor_wallet, reason |
Security Admin NFT | Regulatory freeze on an investor's position. The investor cannot transfer, sell, or convert tokens until unfrozen. Reason is logged to the audit trail. |
force_transfer |
from, to, amount, court_order_hash |
3-of-5 keyholder threshold + court order hash | Court-ordered transfer. Requires supermajority keyholder approval and an on-chain hash of the court order document. The most restricted instruction in the program. |
close_offering |
offering_id |
Issuer NFT + Platform Operator + Trustee | Final redemption. Burns remaining tokens, settles outstanding CrossConversions, closes the offering PDA. Irreversible. |
Account Structure
The program uses Program Derived Addresses (PDAs) to store all state on-chain. Each PDA is deterministically derived from its seed parameters, ensuring that account addresses are predictable and verifiable:
| PDA Account | Seeds | Fields |
|---|---|---|
OfferingState |
["offering", series_id] |
series_id, max_supply, minted, locked_in_crossconv, nominal_value, status (active/paused/closed), version |
InvestorPosition |
["position", offering_id, wallet] |
offering_id, wallet, balance, locked_until (lock-up expiry), accreditation_tier, jurisdiction (hash) |
CrossConversionLockbox |
["lockbox", offering_id] |
offering_id, total_locked, isin_code, clearstream_ref |
DistributionRecord |
["distribution", offering_id, epoch] |
offering_id, epoch, amount_per_token, claimed_bitmap (tracks which investors have claimed) |
ComplianceConfig |
["compliance", offering_id] |
offering_id, allowed_jurisdictions, min_investment, lock_up_days, max_investors, features (bitmask), version |
All PDA accounts include a version field to support data migration when the program is upgraded. The upgrade authority is held by the 3-of-5 Master NFT keyholder set — no single party can deploy a new program version.
Events
The program emits structured events for every significant state change. These events are consumed by the Solana Event Watcher grain, which routes them to the appropriate application grains for processing:
| Event | Fields | Consumed By |
|---|---|---|
SecurityMinted |
offering, investor, amount, timestamp |
Offering Grain (cap table update), Investor Grain (portfolio notification) |
CrossConversionRequested |
offering, amount, direction, isin |
CrossConversion Operator (initiates Clearstream workflow) |
DistributionPaid |
offering, epoch, total_amount |
Investor Grains (claim notification), Broker Grain (settlement confirmation) |
ComplianceViolation |
offering, investor, reason |
DAO Manager Grain (alert), Compliance Grain (regulatory log) |
TransferCompleted |
offering, from, to, amount |
Offering Grain (cap table update), Broker Grain (trade settlement) |
Every event is also written to the Solana Event Watcher's local event log for replay capability. If a grain misses an event (network partition, grain restart), the watcher replays the missed events in order. No event is ever lost.
Compliance Extensions
The sails_securities program builds on SPL-2022 (Token Extensions) — specifically the Transfer Hook extension. This is the mechanism that makes compliance enforcement inescapable:
- Transfer Hook: The Solana runtime invokes the Transfer Hook program on every token transfer — not just transfers initiated through the
sails_securitiesprogram, but any SPL token transfer instruction that touches a Sails security token. This means compliance cannot be bypassed by calling the token program directly. - Hook Logic: The Transfer Hook reads both wallets' KYC Credential NFTs, the offering's
ComplianceConfigPDA, and the sender'sInvestorPositionPDA. If any check fails — expired KYC, jurisdiction mismatch, lock-up period active, accreditation insufficient — the hook returns an error and the entire transfer transaction is reverted. - Emergency Pause: The
ComplianceConfigincludes afeaturesbitmask. Setting the pause bit (gated by Security Admin NFT) causes the Transfer Hook to reject all transfers for that offering — a circuit breaker for regulatory emergencies. - Upgradeable Programs: All Anchor programs are deployed with upgrade authority held by the 3-of-5 Master NFT keyholder set. PDA accounts include a
versionfield for data migration. New program versions are deployed alongside old ones, and migration instructions move state from old PDAs to new PDAs. Every upgrade must pass full regression on devnet before mainnet deployment.
The result: a security token that carries its compliance rules with it. Not in documentation. Not in terms of service. In the program code that the Solana runtime executes on every transfer. This is what "compliance as code" actually means.