Overview
RWA smart contract implementation from Upside for Solana using SPL Token-2022. The core purpose of these programs is to enforce transfer restrictions and compliance requirements for regulated securities on the Solana blockchain.
This implementation attempts to balance simplicity and sufficiency for smart contract RWAs that need to comply with regulatory authorities - without adding unnecessary complexity for simple use cases.
Programs
Solana RWA consists of four main programs:
Access Control
Implements role-based access control and core asset management operations.
Key Features:
- Bitmask Role System: Contract Admin, Reserve Admin, Wallet Admin, Transfer Admin
- Asset Operations: Minting, burning, freezing, force transfers
- Token-2022 Integration: Manages mint authority and extensions
- Supply Management: Configurable maximum supply caps
Use Cases: Managing admin permissions, minting tokens, emergency asset recovery, wallet freezing
Transfer Restrictions
Enforces transfer rules using SPL Token-2022's Transfer Hook extension.
Key Features:
- Transfer Groups: Categorize wallets based on regulatory requirements (Reg D, Reg S, Reg CF, etc.)
- Transfer Rules: Define allowed transfers between groups with time locks
- Holder Management: Track unique holders across multiple wallets
- Holder Limits: Global and per-group holder caps
- On-Chain Enforcement: Automatic validation on every transfer via transfer hooks
Use Cases: Regulatory compliance, investor categorization, lockup periods, holder limits
Tokenlock
Implements token vesting and lockup schedules for employee compensation and investor lockups.
Key Features:
- Release Schedules: Reusable vesting templates with cliff and linear vesting
- Timelocks: Individual vesting instances for recipients
- Flexible Vesting: Supports cliff periods, initial releases, and periodic unlocking
- Cancelable Vestings: Optional cancellation for employee vestings
- Transfer Restrictions Bypass: Escrow transfers skip transfer restrictions
Use Cases: Employee equity vestings, investor lockups, founder allocations
Dividends
Implements merkle tree-based dividend distributions for efficient payments to token holders.
Key Features:
- Merkle Tree Distribution: Gas-efficient claiming using cryptographic proofs
- Snapshot-Based: Distributions based on historical token ownership
- Multi-Token Support: Distribute any SPL or SPL Token-2022 token
- Flexible Funding: Anyone can fund distributions
- IPFS Integration: Stores merkle tree data off-chain
Use Cases: Quarterly dividends, profit sharing, interest payments
Architecture Overview
On-Chain Holder/Wallet Management
Active Holder/Wallet management is conducted on-chain and autonomously, with multiple admin configurations that allow flexibility of transfer rule configuration. This greatly simplifies the off-chain accounting and effort required from Transfer (and other) Admins, removing the need to track Wallet holdings across different Holders.
Wallets are not programmatically prohibited from assuming multiple Admin roles. We advise against this in practice; however, this must be enforced off-chain.
Key Concepts:
- Holders are unique entities that can own multiple wallet addresses
- Wallets can be spread across multiple Transfer Groups
- Wallets are consolidated under a common
holderId - Holder counts are tracked globally and per-group
Example: Holder A can have 4 wallets spread across two Transfer Groups, X and Y. The Holder can have Wallets 1 & 2 in Group X, and Wallets 3 & 4 in Group Y. They will count as one single Holder globally, but also as one unique holder in Group X and one unique holder in Group Y.
Transfer Restrictions Overview
The RWA can be configured after deployment to enforce transfer restrictions such as the ones shown in the diagram below. Each Holder's blockchain Wallet address corresponds to a different group.
This is enforced by the Transfer Restrictions Program and Transfer Hook.
Example Transfer Group Configuration
Only transfers between wallet address groups in the direction of the arrows are allowed:
High-Level Transfer Flow
Roles and Permissions
The smart contract enforces specific admin roles. The roles divide responsibilities to reduce abuse vectors and create checks and balances. Ideally each role should be managed by a separate admin with separate key control.
In some cases, such as for the Contract Admin or Wallets Admin, it is recommended that the role's private key is managed through multi-signature (e.g., requiring 2 of 3 or N of M approvers) authentication.
Admin Types
| Role | Value | Binary | Capabilities |
|---|---|---|---|
| Contract Admin | 1 | 0001 | Grant/revoke roles, configure system settings, upgrade permissions |
| Reserve Admin | 2 | 0010 | Mint/burn tokens, force transfers, adjust supply caps |
| Wallet Admin | 4 | 0100 | Manage holder/wallet assignments, freeze/thaw wallets |
| Transfer Admin | 8 | 1000 | Set transfer restrictions, configure groups and rules, freeze/thaw wallets |
Admin Function Matrix
| Function | Contract Admin | Reserve Admin | Transfer Admin | Wallets Admin |
|---|---|---|---|---|
| grant_role() | yes | no | no | no |
| revoke_role() | yes | no | no | no |
| mint_securities() | no | yes | no | no |
| burn_securities() | no | yes | no | no |
| force_transfer_between() | no | yes | no | no |
| set_max_total_supply() | no | yes | no | no |
| initialize_transfer_rule() | no | no | yes | no |
| set_holder_max() | no | no | yes | no |
| set_holder_group_max() | no | no | yes | no |
| pause() | no | no | yes | no |
| freeze_wallet() | no | no | yes | yes |
| thaw_wallet() | no | no | yes | yes |
| initialize_holder() | no | no | yes | yes |
| initialize_holder_group() | no | no | yes | yes |
| initialize_saa() | no | no | yes | yes |
| create_release_schedule() | yes | yes | yes | yes |
| mint_release_schedule() | no | yes | no | no |
| new_distributor() | yes | no | no | no |
Note: Transfer Admins have a superset of Wallets Admin capabilities.
Initial Deployment Flow
Key Features by Use Case
Regulatory Compliance
- Accreditation Tracking: Group wallets by investor type (Reg D, Reg S, Reg CF)
- Transfer Restrictions: Enforce holding periods and flowback restrictions
- Holder Limits: Comply with Reg CF holder limits
- Wallet Freezing: Emergency compliance actions
- AML/KYC Integration: On-chain holder management
Investor Management
- Multiple Wallets per Holder: Consolidate ownership tracking
- Group Transfers: Control transfers between investor types
- Lockup Periods: Enforce time-based restrictions
- Vesting Schedules: Employee and founder token releases
- Dividend Distributions: Automatic profit sharing
Issuer Operations
- Controlled Minting: Supply caps and role-based minting
- Emergency Powers: Force transfers and burning (with safeguards)
- Flexible Administration: Separate roles for checks and balances
- Snapshot System: Historical ownership tracking for dividends
Security Considerations
Emergency Powers
Reserve Admins have significant powers that could be abused:
- Can mint up to
max_total_supply - Can burn from any address (except lockup escrow)
- Can force transfer between any addresses (except lockup)
- Can update max supply
Mitigation: Use multi-signature wallets for Reserve Admin role and implement off-chain governance processes.
Transfer Hook Security
- Transfer hooks execute on every transfer
- Escrow account can bypass transfer restrictions
- Ensure
lockup_escrow_accountis set only for legitimate tokenlock program - Never set escrow to user-controlled accounts
Merkle Distribution Security
- Merkle root is immutable after creation
- Ensure off-chain tree generation is correct
- Store merkle tree data securely (IPFS + backups)
- Reclaimer can claim unclaimed dividends (set carefully)
Integration Checklist
When integrating Solana RWA programs:
- Deploy Access Control with Token-2022 mint
- Grant appropriate admin roles to wallets/multi-sigs
- Deploy Transfer Restrictions and configure hook
- Create transfer groups for investor categories
- Set transfer rules between groups
- Initialize holders and wallets before minting
- Set maximum holder limits as needed
- (Optional) Deploy Tokenlock for vesting
- (Optional) Set lockup escrow account in Access Control and Transfer Restrictions
- (Optional) Deploy Dividends for profit sharing
- Test transfers between all group combinations
- Document admin procedures and key management
Program IDs
| Program | Program ID |
|---|---|
| Access Control | 4X79YRjz9KNMhdjdxXg2ZNTS3YnMGYdwJkBHnezMJwr3 |
| Transfer Restrictions | 6yEnqdEjX3zBBDkzhwTRGJwv1jRaN4QE4gywmgdcfPBZ |
| Tokenlock | AoodM6rkg968933giHnigMEwp9kiGi68ZEx9bPqk71Gt |
| Dividends | FUjkkUVKa9Pofs5mBdiYQe2cBVwzrhX8SunAZhGXRkog |
Additional Resources
- Audits: Security audit reports and findings
- GitHub Repository: Source code
Disclaimer
This open or closed source software is provided with no warranty. This is not legal advice. CoMakery (dba Upside) is not a legal firm and is not your lawyer. Securities are highly regulated across multiple jurisdictions. Issuing a RWA incorrectly can result in financial penalties or jail time if done incorrectly. Consult a lawyer and tax advisor. Conduct an independent security audit of the code.