A comprehensive Solana smart contract built with Anchor framework for tokenizing real-world assets. This contract enables the digitization of physical and intangible assets into blockchain-based tokens with built-in compliance, KYC verification, and transfer controls.
The contract is structured around three main components:
- RwaConfig: Global configuration for RWA tokenization parameters
- AssetRecord: Individual asset metadata and compliance status
- UserProfile: User KYC and accreditation information
- Asset Tokenization: Convert real-world assets into SPL tokens
- KYC/AML Compliance: Built-in user verification system
- Multi-Asset Support: Real estate, equipment, commodities, art, IP, and more
- Custody Integration: Support for multiple custody providers
- Oracle Integration: Real-time asset valuation updates
- Transfer Hooks: Custom transfer logic with compliance checks
- Fee Management: Configurable tokenization and transfer fees
- Rust (latest stable)
- Solana CLI (v1.18+)
- Anchor Framework (v0.31.1)
- Node.js (v16+)
- Yarn
-
Clone the repository
git clone <repository-url> cd rwa_contract
-
Install dependencies
yarn install
-
Build the program
anchor build
-
Deploy to localnet
anchor deploy
The contract supports various asset classes:
RealEstate
- Properties, land, buildingsEquipment
- Machinery, vehicles, toolsCommodity
- Gold, oil, agricultural productsArtAndCollectibles
- Artwork, antiques, collectiblesIntellectualProperty
- Patents, copyrights, trademarksInfrastructure
- Utilities, transportation assetsOther
- Custom asset types
Set up the global configuration for your RWA platform:
await program.methods
.initializeRwaConfig({
transferFeeBps: 100, // 1% transfer fee
kycRequired: true,
accreditationRequired: false,
kycProvider: [kycProviderPubkey],
custodyProvider: [custodyProviderPubkey],
oracleProgram: oracleProgramPubkey,
tokenizationFeeBps: 50, // 0.5% tokenization fee
assetClass: { realEstate: {} }
})
.accounts({
rwaConfig: rwaConfigPda,
admin: adminKeypair.publicKey,
systemProgram: SystemProgram.programId,
})
.signers([adminKeypair])
.rpc();
Verify users before they can participate:
await program.methods
.verifyUserKyc()
.accounts({
userProfile: userProfilePda,
user: userKeypair.publicKey,
kycProvider: kycProviderKeypair.publicKey,
rwaConfig: rwaConfigPda,
systemProgram: SystemProgram.programId,
})
.signers([kycProviderKeypair])
.rpc();
Create a tokenization request for an asset:
await program.methods
.initializeTokenizeRequest({
assetId: "PROP001",
name: "Downtown Office Building",
valuation: new anchor.BN(1000000), // $1M
totalSupply: new anchor.BN(1000000), // 1M tokens
metadataUri: "https://example.com/metadata.json",
})
.accounts({
assetRecord: assetRecordPda,
creator: creatorKeypair.publicKey,
rwaConfig: rwaConfigPda,
systemProgram: SystemProgram.programId,
})
.signers([creatorKeypair])
.rpc();
Compliance officers can verify submitted assets:
await program.methods
.verifyAsset()
.accounts({
assetRecord: assetRecordPda,
complianceOfficer: complianceOfficerKeypair.publicKey,
rwaConfig: rwaConfigPda,
})
.signers([complianceOfficerKeypair])
.rpc();
Convert the verified asset into SPL tokens:
await program.methods
.tokenizeAsset({
tokenName: "Office Building Token",
tokenSymbol: "OBT",
tokenDecimals: 6,
metadataUri: "https://example.com/token-metadata.json",
})
.accounts({
assetRecord: assetRecordPda,
mint: mintKeypair.publicKey,
creator: creatorKeypair.publicKey,
rwaConfig: rwaConfigPda,
// ... other required accounts
})
.signers([creatorKeypair, mintKeypair])
.rpc();
Mint tokens to authorized users:
await program.methods
.mintAsset(new anchor.BN(1000)) // Mint 1000 tokens
.accounts({
assetRecord: assetRecordPda,
mint: mintPubkey,
userTokenAccount: userTokenAccountPubkey,
custodyOfficer: custodyOfficerKeypair.publicKey,
// ... other required accounts
})
.signers([custodyOfficerKeypair])
.rpc();
Run the comprehensive test suite:
# Run Anchor tests
anchor test
# Run LiteSVM tests for faster iteration
cd litesvm_tests
cargo test
The test suite covers:
- Configuration initialization
- User KYC processes
- Asset tokenization workflow
- Transfer restrictions and compliance
- Fee calculations
- Error handling scenarios
Instruction | Description |
---|---|
initialize_rwa_config |
Set up global RWA configuration |
verify_user_kyc |
Verify user KYC status |
initialize_tokenize_request |
Create asset tokenization request |
verify_asset |
Compliance verification of assets |
tokenize_asset |
Convert verified asset to SPL token |
mint_asset |
Mint tokens to authorized users |
transfer_hook |
Custom transfer validation logic |
rwa_contract/
βββ programs/rwa_contract/
β βββ src/
β β βββ args/ # Instruction arguments
β β βββ instructions/ # Program instructions
β β βββ states/ # Account structures
β β βββ error.rs # Custom errors
β β βββ events.rs # Program events
β β βββ lib.rs # Main program entry
βββ tests/ # Anchor integration tests
βββ litesvm_tests/ # Fast unit tests
βββ target/ # Build artifacts
- Extend the
AssetClass
enum instates/rwa_config.rs
- Update validation logic in relevant instructions
- Add test cases for the new asset class
The contract implements SPL Token 2022 transfer hooks for:
- KYC compliance checking
- Transfer restrictions
- Fee collection
- Audit logging
- Access Control: Role-based permissions for different operations
- Input Validation: Comprehensive validation of all user inputs
- Oracle Security: Trusted oracle integration for asset valuations
- Transfer Restrictions: Configurable compliance-based transfer controls
- Audit Trail: Complete event logging for regulatory compliance
This project is licensed under the ISC License.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
For questions and support, please open an issue in the repository or contact the development team.