Smart Contracts
DevnetComplete reference for the rFlow Anchor program on Solana. 13 instructions across core yield deals and Meteora LP fee deals.
Overview#
The rFlow program supports two types of yield deals:
- Yield Deals - Lock receipt tokens (kUSDC, mSOL, jitoSOL) and sell future appreciation
- Meteora LP Deals - Lock Position NFT and sell future LP fees
Program Information#
| Program ID | 2yUwGR18L5a8UqfkX49M4SenYCrS4B48chioKWCnMG3y |
| Version | 0.1.0 |
| Framework | Anchor 0.32.1 |
| Language | Rust 2021 |
| Instructions | 13 total (8 core + 5 Meteora LP) |
| Network | Devnet |
Audit Status
Core Instructions#
8 instructions for managing yield deals with receipt tokens (lending, liquid staking):
initializeInitialize the protocol configuration. Can only be called once by the deployer.
Accounts
authority (signer)config (PDA)treasurysystem_programcreate_dealCreate a new yield deal by locking receipt tokens in a vault PDA.
Accounts
seller (signer)configdeal (PDA)seller_token_accountvault (PDA)receipt_token_mintpayment_minttoken_programsystem_programParameters
receipt_tokens_amount:u64principal_value_at_lock:u64expected_yield:u64selling_price:u64duration_days:u16source_protocol:SourceProtocolbuy_dealPurchase a deal. Transfers payment to seller (minus protocol fee) and activates the deal.
Accounts
buyer (signer)configdealbuyer_payment_accountseller_payment_accounttreasury_accounttoken_programcancel_dealCancel a deal before it's purchased. Returns locked tokens to seller.
Accounts
seller (signer)dealvaultseller_token_accounttoken_programsettle_dealSettle a deal after expiry. Distributes yield to buyer and principal to seller based on token appreciation.
Accounts
payer (signer)dealvaultbuyer_token_accountseller_token_accounttoken_programParameters
current_token_value:u64buyback_dealSeller exits deal early by paying back buyer with a penalty (15% base, decreasing to 5% near expiry).
Accounts
seller (signer)configdealvaultseller_payment_accountseller_receipt_accountbuyer_payment_accounttoken_programParameters
yield_accumulated:u64crank_settlePermissionless settlement for expired deals. Caller receives vault rent as incentive.
Accounts
payer (signer)dealvaultbuyer_token_accountseller_token_accounttoken_programParameters
current_token_value:u64Meteora LP Instructions#
5 instructions for Meteora DLMM LP fee deals. Locks Position NFT and sells future fee rights:
create_meteora_lp_dealCreate a Meteora LP deal by locking a Position NFT in PayFlow vault.
Accounts
seller (signer)configdeal (PDA)position_nft_mintposition_accountpoolseller_nft_accountvault (PDA)token_programsystem_programParameters
expected_fee_a:u64expected_fee_b:u64expected_fee_value_usdc:u64selling_price:u64duration_days:u16buy_meteora_lp_dealPurchase a Meteora LP deal. Buyer gains rights to claim fees during the deal period.
Accounts
buyer (signer)configdealbuyer_payment_accountseller_payment_accounttreasury_accounttoken_programclaim_meteora_feesClaim accumulated LP fees. Buyer can call anytime during the deal to collect fees.
Accounts
buyer (signer)dealposition_accountpooltoken_a_vaulttoken_b_vaultbuyer_token_a_accountbuyer_token_b_accountmeteora_programsettle_meteora_lp_dealSettle after expiry. Returns Position NFT to seller. Permissionless.
Accounts
payer (signer)dealvaultseller_nft_accounttoken_programcancel_meteora_lp_dealCancel before purchase. Seller retrieves their Position NFT.
Accounts
seller (signer)dealvaultseller_nft_accounttoken_programAdmin Instructions#
update_configUpdate protocol configuration. Authority only.
Accounts
configauthority (signer)Parameters
fee_bps:Option<u16>base_penalty_bps:Option<u16>min_penalty_bps:Option<u16>is_paused:Option<bool>new_treasury:Option<Pubkey>new_authority:Option<Pubkey>add_mint:Option<Pubkey>remove_mint:Option<Pubkey>State Accounts#
ProtocolConfig
Global protocol configuration. Seeds: [b"protocol_config"]
1pub struct ProtocolConfig {2 pub authority: Pubkey, // Admin3 pub treasury: Pubkey, // Fee recipient4 pub fee_bps: u16, // Protocol fee (default: 200 = 2%)5 pub min_duration_days: u16, // Min duration (30)6 pub max_duration_days: u16, // Max duration (365)7 pub base_penalty_bps: u16, // Buyback penalty (1500 = 15%)8 pub min_penalty_bps: u16, // Min penalty (500 = 5%)9 pub is_paused: bool, // Emergency pause10 pub deal_counter: u64, // Auto-increment ID11 pub allowed_mints: Vec<Pubkey>, // Whitelist (max 10)12 pub bump: u8,13}YieldDeal
Receipt token deal. Seeds: [b"yield_deal", deal_id.to_le_bytes()]
1pub struct YieldDeal {2 pub deal_id: u64,3 pub bump: u8,4 pub seller: Pubkey,5 pub buyer: Pubkey,6 pub receipt_token_mint: Pubkey,7 pub receipt_token_vault: Pubkey,8 pub receipt_tokens_amount: u64,9 pub principal_value_at_lock: u64,10 pub expected_yield: u64,11 pub selling_price: u64,12 pub payment_mint: Pubkey,13 pub duration_days: u16,14 pub created_at: i64,15 pub purchased_at: i64,16 pub ends_at: i64,17 pub status: DealStatus,18 pub source_protocol: SourceProtocol,19}MeteoraLpDeal
Meteora LP fee deal. Seeds: [b"meteora_lp_deal", deal_id.to_le_bytes()]
1pub struct MeteoraLpDeal {2 pub deal_id: u64,3 pub bump: u8,4 pub seller: Pubkey,5 pub buyer: Pubkey,6 // Position info7 pub position_nft_mint: Pubkey,8 pub position_account: Pubkey,9 pub position_nft_vault: Pubkey,10 pub pool: Pubkey,11 pub token_a_mint: Pubkey,12 pub token_b_mint: Pubkey,13 // Fee snapshots at lock14 pub fee_a_at_lock: u64,15 pub fee_b_at_lock: u64,16 // Expected fees17 pub expected_fee_a: u64,18 pub expected_fee_b: u64,19 pub expected_fee_value_usdc: u64,20 // Payment21 pub selling_price: u64,22 pub payment_mint: Pubkey,23 // Timing24 pub duration_days: u16,25 pub created_at: i64,26 pub purchased_at: i64,27 pub ends_at: i64,28 pub status: DealStatus,29}Enums#
DealStatus
1pub enum DealStatus {2 Created, // Waiting for buyer3 Active, // Purchased, in progress4 Settled, // Ended, distributions complete5 Cancelled, // Cancelled before purchase6 BoughtBack, // Seller did early buyback7}SourceProtocol
Supported yield sources organized by phase:
1pub enum SourceProtocol {2 // Phase 1 - Lending (receipt tokens appreciate)3 Kamino, // kUSDC, kSOL4 MarginFi, // mTokens5 Solend, // cTokens6 Save, // saveTokens78 // Phase 1 - Liquid Staking9 Marinade, // mSOL10 Jito, // jitoSOL (includes MEV)11 Blaze, // bSOL12 Sanctum, // INF, various LSTs13 Lido, // wstSOL1415 // Phase 2 - LP Positions (fee claiming)16 RaydiumLp,17 MeteoraLp,18 OrcaLp,1920 // Phase 3 - Fee Streams21 FeeStream,22}Error Codes#
| Code | Name | Description |
|---|---|---|
| 6000 | ProtocolPaused | Protocol is paused |
| 6001 | InvalidDuration | Duration must be 30, 60, or 90 days |
| 6002 | InvalidPrice | Price must be > 0 |
| 6003 | InvalidAmount | Amount must be > 0 |
| 6004 | DealNotAvailable | Deal not in Created state |
| 6005 | DealNotActive | Deal not in Active state |
| 6006 | DealNotEnded | Deal hasn't expired yet |
| 6007 | DealEnded | Deal has already ended |
| 6008 | DealAlreadyActive | Deal already purchased |
| 6009 | NotSeller | Caller is not the seller |
| 6010 | NotBuyer | Caller is not the buyer |
| 6011 | InsufficientFunds | Not enough tokens for buyback |
| 6012 | Unauthorized | Not authority |
| 6013 | MathOverflow | Arithmetic overflow |
| 6014 | InvalidMint | Mint not in whitelist |
| 6015 | WhitelistFull | Cannot add more than 10 mints |
| 6016 | MintAlreadyWhitelisted | Mint already in whitelist |
| 6017 | MintNotInWhitelist | Mint not found in whitelist |
| 6018 | InvalidMeteoraPosition | Invalid Meteora position |
| 6019 | PositionPoolMismatch | Position doesn't belong to expected pool |
| 6020 | InvalidPositionNft | Position NFT must be amount 1 |
| 6021 | NotDealBuyer | Caller is not the deal buyer |