Forward Marketplace
rFlow turns future on-chain yield into a tradable asset. LSTs, lending receipts, and Meteora LP positions become forward contracts that anyone on Solana can buy or sell — settled trustlessly by the program.
Overview#
A forward is an agreement between two parties to exchange an asset at a future date for a price agreed today. In traditional finance, forwards are used to lock in interest rates, fuel prices, and FX exposure. rFlow brings the same primitive to Solana DeFi — for yield.
When you stake SOL, lend USDC, or LP in Meteora, your principal stays locked and your yield accrues in the background. The Forward Marketplace unbundles those two streams: sellers monetize their future yield for immediate USDC, while buyers lock in a known return on a clearly-priced position — no liquidation risk, no slippage, no APY guesswork.
Tokenized Yield
Every deal is a discrete contract you can read on-chain. No yield tokens to manage, no AMM curve to fight.
Custody-Free
Receipt tokens and Position NFTs sit in PDA vaults the seller created. Only the program signs transfers.
Bounded Settlement
The current mainnet config settles expected-yield deals with a snapshotted exchange rate and tolerance band. Pyth support exists in the program but is not enabled for the live alpha.
How It Works#
The marketplace runs entirely on-chain through the rFlow Anchor program. Five steps from listing to settlement:
Seller deposits receipt tokens or LP NFT into a deal PDA vault.
Seller sets duration, expected yield, and selling price in USDC.
Buyer pays the selling price upfront; protocol takes a 2% fee.
Position keeps earning. Yield is destined for the buyer at maturity.
After ends_at, anyone can call settle. Yield to buyer, principal to seller.
Two flavors, one mechanism
For Sellers#
Anyone holding a yield-bearing position on Solana can list it. The marketplace is permissionless for whitelisted mints — no KYC, no approval, no waiting list.
Why sellers list
- Instant USDC without unstaking, exit queues, or unwinding LP positions.
- Principal stays intact. You only sell the appreciation between now and
ends_at. - Fixed cost of capital. The selling price is your effective interest expense — no rate surprises.
- Optional early exit via
buyback_dealwith a decreasing penalty (3% → 1%). - Cancel anytime before a buyer fills the deal — tokens return automatically.
Pricing a listing
The selling price is the seller's call. Most listings price below the expected yield to leave room for buyer profit. A reasonable starting point:
1// Reference pricing formula2const expectedYield = principalUsdc * apy * (durationDays / 365);34// 10–25% discount creates predictable buyer demand5const sellingPrice = expectedYield * (1 - discountRate);67// Example: $10,000 mSOL position, 7% APY, 90 days8// expectedYield = 10_000 * 0.07 * (90/365) = $172.609// sellingPrice = 172.60 * (1 - 0.15) = $146.71The protocol does not price for you
selling_price > 0 and selling_price ≤ expected_yield in the SDK, but it does not enforce a discount band. Tighter pricing means slower fills; deep discounts mean leaving money on the table. Calibrate against on-chain APY data.For Buyers#
Buyers acquire a claim on future yield without ever touching the underlying protocol. You don't stake, you don't lend, you don't LP — you pay USDC, you wait, the program pays you out at maturity.
Why buyers fill
- Locked-in return. Pay $X today, claim $Y in 30–365 days. Yield is fixed at fill time.
- Discounted entry. Buy $172 of expected mSOL yield for $146 — implied APR depends on the spread.
- No active management. No claim transactions, no compounding, no rate monitoring. Wait and settle.
- Trustless custody. Receipt tokens stay locked in the deal's vault PDA — the seller cannot rug them.
- Permissionless settlement. After
ends_at, anyone can trigger payout. Keeper bots run in the background.
Yield is variable, payout is not capped
Settlement#
Settlement is the moment the deal collapses back into its two parts. The program reads the current value of the locked position, splits the receipt tokens between buyer and seller, and closes the vault.
Yield deal settlement math
1// 1. Read current LST value via Pyth (mainnet) or oracle param (devnet)2const currentValue = oracleValue ?? currentTokenValueParam;34// 2. Yield is the appreciation since lock5const actualYield = currentValue - principalValueAtLock;67// 3. Split the locked receipt tokens proportionally8const yieldTokens = receiptTokensAmount * actualYield / currentValue;9const principalTokens = receiptTokensAmount - yieldTokens;1011// 4. Transfer12// yieldTokens -> buyer (their profit, denominated in receipt tokens)13// principalTokens -> seller (their principal, denominated in receipt tokens)The buyer receives receipt tokens, not USDC. They can hold, redeem at the source protocol, or swap. The seller receives their principal back in the same token they locked.
Meteora LP settlement
Meteora deals work a little differently because fees accrue in two tokens and must be claimed from the pool. During the active deal, the buyer can call claim_meteora_fees any number of times to harvest accumulated fees from the locked position. At ends_at, the Position NFT returns to the seller, who can then withdraw_meteora_liquidity if they want to unwind.
Permissionless
Anyone can call settle_deal after expiry. The vault rent goes to whoever pays the transaction — this is the keeper incentive.
Anti-manipulation
The exchange rate at lock is stored on the deal. Devnet settlement accepts a value within ±10% of the implied rate; mainnet LSTs use Pyth directly.
Integration#
The marketplace is a public good — any frontend, aggregator, or structured-product protocol can plug into it. There is one program, one IDL, and one canonical SDK.
Three integration paths
- Listings UI — Fetch
getAvailableDeals()from the SDK and render a marketplace. See SDK reference. - One-click create — Bundle a stake/lend transaction with
createDealso users instantly tokenize their yield as soon as they deposit. - Structured products — Buy a basket of deals on behalf of users. Settlement is permissionless, so payout requires no off-chain coordination.
Listening for activity
The reference frontend syncs deal state via Helius webhooks pointed at the program ID 2woLsnG7zvKdyd7geH9GAFgKSt6NLrnLDDMmFBUdDjFU. Each create / buy / settle emits a transaction the webhook handler parses and writes to your indexer.
1// Subscribe to program logs in any RPC client2import { Connection, PublicKey } from "@solana/web3.js";3import { PROGRAM_ID } from "@rflowdapp/rflow";45const connection = new Connection("wss://your-rpc-endpoint");67connection.onLogs(PROGRAM_ID, (logInfo) => {8 // logInfo.signature, logInfo.logs[]9 // Parse with the SDK's parsePayFlowTransactions helper10});See the live integration
TypeScript SDK
Install @rflowdapp/rflow and start listing or buying deals.
Protocol Mechanics
Read how the deal lifecycle and settlement math actually work.
Supported Receipt Tokens
Whitelisted mints with Pyth feed IDs and addresses.
Integration Guide
Build a frontend, an aggregator, or a structured product.