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:

1. Lock

Seller deposits receipt tokens or LP NFT into a deal PDA vault.

2. List

Seller sets duration, expected yield, and selling price in USDC.

3. Buy

Buyer pays the selling price upfront; protocol takes a 2% fee.

4. Accrue

Position keeps earning. Yield is destined for the buyer at maturity.

5. Settle

After ends_at, anyone can call settle. Yield to buyer, principal to seller.

Two flavors, one mechanism
rFlow currently supports two deal types: Yield Deals for receipt tokens that appreciate via a growing exchange rate (mSOL, jitoSOL, bSOL, cUSDC, kUSDC), and Meteora LP Deals for DAMM v2 positions that earn trading fees. Both follow the same lifecycle.

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_deal with 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:

typescript
1// Reference pricing formula
2const expectedYield = principalUsdc * apy * (durationDays / 365);
3
4// 10–25% discount creates predictable buyer demand
5const sellingPrice = expectedYield * (1 - discountRate);
6
7// Example: $10,000 mSOL position, 7% APY, 90 days
8// expectedYield = 10_000 * 0.07 * (90/365) = $172.60
9// sellingPrice = 172.60 * (1 - 0.15) = $146.71
The protocol does not price for you
rFlow validates that 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
The buyer receives the actual appreciation between lock and settlement, not a fixed amount. If the LST exchange rate rises faster than projected, the buyer wins more; if it stalls, the buyer wins less. The selling price is the only number that is fixed at fill.

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

settle_deal.rs (logic)
1// 1. Read current LST value via Pyth (mainnet) or oracle param (devnet)
2const currentValue = oracleValue ?? currentTokenValueParam;
3
4// 2. Yield is the appreciation since lock
5const actualYield = currentValue - principalValueAtLock;
6
7// 3. Split the locked receipt tokens proportionally
8const yieldTokens = receiptTokensAmount * actualYield / currentValue;
9const principalTokens = receiptTokensAmount - yieldTokens;
10
11// 4. Transfer
12// 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 createDeal so 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.

typescript
1// Subscribe to program logs in any RPC client
2import { Connection, PublicKey } from "@solana/web3.js";
3import { PROGRAM_ID } from "@rflowdapp/rflow";
4
5const connection = new Connection("wss://your-rpc-endpoint");
6
7connection.onLogs(PROGRAM_ID, (logInfo) => {
8 // logInfo.signature, logInfo.logs[]
9 // Parse with the SDK's parsePayFlowTransactions helper
10});
See the live integration
The rFlow app at rflow.fund/app/invest uses the same SDK calls you would. It is open source — copy what fits your product.