STRYK is a Solana-native framework for structured product vaults. It is a direct, ground-up rebuild of the Ribbon Finance Theta Vault pattern for the post-Friktion Solana stack. Where Ribbon has $200M+ TVL on Ethereum and Aevo, Solana was left without an equivalent standard after Friktion wound down in Q3 2023. STRYK is that standard.
The repository contains:
- Deterministic on-chain pricing (Black-Scholes in Q64.64 fixed-point)
- A Theta Vault runtime (impound → strike → auction → settle → roll)
- A Dutch auction settlement layer (Gnosis EasyAuction lineage)
- Five reference vault strategies (weekly calls, weekly puts, delta-neutral)
- A TypeScript SDK + CLI + mobile app covering the developer surface
- Why STRYK
- Architecture
- Vault lifecycle
- Reference strategies
- Pricing engine
- Auction layer
- Developer surface
- Cited work
- License
Friktion's wind-down left three concrete gaps on Solana:
-
Pricing gap. Prior weekly vaults settled from off-chain price snapshots provided by a keeper. STRYK computes every premium, delta, gamma, theta, vega, and rho directly on-chain in Q64.64 fixed point. Determinism is a settlement guarantee, not a hope.
-
Settlement gap. Legacy vaults used off-chain RFQs for premium discovery, which fragmented liquidity and hid clearing prices. STRYK ships a Dutch auction that runs entirely on-chain. Clearing price, winning bidder, and slashing on default are all account state.
-
Automation gap. Weekly rollover was manual on legacy vaults. STRYK vaults are woken by Clockwork threads. When expiry hits, settlement, next-strike selection, auction start, and premium distribution happen in a single tick.
%%{init: {'theme':'base', 'themeVariables': {
'primaryColor':'#0A2540',
'primaryTextColor':'#E8EAED',
'primaryBorderColor':'#5BC0EB',
'lineColor':'#8B8680',
'secondaryColor':'#0A0E27',
'tertiaryColor':'#D4AF37'
}}}%%
flowchart TD
subgraph User["User layer"]
Web[apps/web]
Mobile[packages/mobile-app]
CLI[packages/cli]
end
subgraph SDK
SDKTS[packages/sdk-ts]
end
subgraph Program["On-chain layer"]
Anchor[Vault executor -- Anchor]
Pricing[Pricing engine]
Auction[Auction layer]
Library[Vault library]
end
subgraph External["External"]
Pyth[(Pyth options oracle)]
Zeta[(Zeta Markets)]
Drift[(Drift Perpetual)]
Clock[(Clockwork threads)]
end
Web --> SDKTS
Mobile --> SDKTS
CLI --> SDKTS
SDKTS --> Anchor
Anchor --> Pricing
Anchor --> Auction
Anchor --> Library
Library --> Zeta
Library --> Drift
Pricing --> Pyth
Anchor --> Clock
The core executor lives in one Anchor program. Every strategy is a struct
implementing the VaultStrategy trait; the executor dispatches by strategy
tag stored in the vault PDA. New reservoirs can be published without
redeploying the program by adding a new strategy crate.
%%{init: {'theme':'base', 'themeVariables': {
'primaryColor':'#0A2540',
'primaryTextColor':'#E8EAED',
'primaryBorderColor':'#5BC0EB',
'lineColor':'#8B8680'
}}}%%
sequenceDiagram
participant LP
participant Vault
participant Pricing
participant Auction
participant MM as Market maker
participant Clockwork
participant Zeta
LP->>Vault: deposit(asset)
Vault->>Pricing: compute strike via target-delta
Vault->>Auction: mint option series
Auction->>MM: broadcast Dutch auction
MM->>Auction: bid(limit, size, collateral)
Auction->>Vault: clear (price, buyer)
Vault->>Zeta: CPI writeOption
Note over Clockwork: wait for expiry
Clockwork->>Vault: expire()
Vault->>Zeta: settle
Vault->>Pricing: compute next epoch
Note over Vault: auto-roll
LP->>Vault: withdraw
Every stage is idempotent under Solana's compute-limit model. open_epoch
and settle_epoch are guarded by explicit expiry checks so a re-run of the
same Clockwork thread cannot double-settle.
| Reservoir | Underlying | Asset | Strategy |
|---|---|---|---|
| Weekly SOL Covered Call | SOL | SOL | Sell weekly 15-delta OTM call on deposited SOL |
| Weekly SOL Cash-Secured Put | SOL | USDC | Sell weekly 15-delta OTM put secured by USDC |
| Weekly BTC Covered Call | BTC | WBTC | Sell weekly 15-delta OTM BTC call on WBTC |
| Weekly ETH Cash-Secured Put | ETH | USDC | Sell weekly 15-delta OTM ETH put secured by USDC |
| Delta-Neutral Yield | SOL-USDC | LP + short | Concentrated LP + Drift perpetual short |
Each reservoir maps to a distinct dam form in the STRYK visual language (arch, earthfill, steel, masonry, stepped) because each strategy impounds risk differently.
The pricing engine is a no_std-friendly Rust crate that runs bit-exact
inside the Anchor program. All state is Q64.64 fixed-point (i128 backing);
we implement our own exp, ln, sqrt, norm_pdf, and norm_cdf so no
floating-point unit and no host math routines are required.
use stryk_pricing_engine::{black_scholes::PricingInput, price_call, Q64};
let input = PricingInput {
spot: Q64::from_int(172),
strike: Q64::from_int(185),
time_to_expiry: Q64::from_f64(0.02).unwrap(),
volatility: Q64::from_f64(0.78).unwrap(),
risk_free_rate: Q64::from_f64(0.05).unwrap(),
};
let out = price_call(input).unwrap();
println!("premium = {:.6}", out.premium.to_f64());The Greeks module returns delta, gamma, theta, vega, and rho for both calls
and puts, and property tests confirm that put-call parity holds within
1e-5 across the input grid we sampled.
Auctions are a batch Dutch auction adapted from Gnosis EasyAuction. The
initial price is set to 1.1 * fair_value and decays linearly to
0.9 * fair_value over 15 minutes. Bidders must lock $STRYK collateral
proportional to their bid notional; on default the auction layer slashes the
collateral to refund LPs at the failed clearing price.
use stryk_auction_layer::{clear_auction, Auction, AuctionStatus, Bid};
let mut auction: Auction = /* initialise from open_epoch */;
let mut bids: Vec<Bid> = collect_bids();
let summary = clear_auction(&mut auction, &mut bids)?;
assert_eq!(auction.status, AuctionStatus::Cleared);Two packages are published to npm today. Both are read-only and need no wallet.
- TypeScript SDK --
@strykfi/sdk. OneStrykClientthat speaks to the STRYK API:listVaults,getVault,blackScholes,simulate, andprice. The pure pricing helperspriceCallandpricePutare exported standalone so you can value a series offline. strykCLI --stryk-cli. Everything the SDK exposes, from your terminal.- Mobile companion -- React Native + Solana Mobile SDK. Push notifications for expiry and settlement, Apple Watch and Wear OS widgets.
# TypeScript SDK
npm i @strykfi/sdk
# CLI
npm i -g stryk-cli
stryk vault list # list every live reservoir
stryk vault show <pda> # inspect one vault by its PDA
stryk simulate --vault <kind> --amount <usd> [--weeks <n>]
stryk pricing --spot <p> --strike <k> --iv <iv> --days <d> [--rate <r>] [--kind call|put]
stryk price <symbol> # spot from the STRYK APIThe CLI reads STRYK_API_URL (defaults to https://api.stryk.fi), so the same
binary can point at a local gateway during development.
- Black, F., & Scholes, M. (1973). The Pricing of Options and Corporate Liabilities. Journal of Political Economy, 81(3).
- Merton, R. C. (1973). Theory of Rational Option Pricing. Bell Journal of Economics and Management Science, 4(1).
- Ribbon Finance whitepaper -- Theta Vault v1 / v2 mechanics.
- Friktion Volts wind-down post-mortem (2023 Q3).
- Gnosis EasyAuction paper -- batch Dutch auction design.
- Squeeth / Power Perpetual whitepaper -- Opyn Labs.
- Pyth options oracle specification v2.
- Zeta Markets options venue design docs.
STRYK is released under the Apache License 2.0. See LICENSE.
P.S. I've been building this locally for the last couple of weeks and only just got around to spinning up a GitHub account to publish it. If the commit history looks a bit bursty toward the top of the graph, that's why -- the work is older than the account. Feedback and audit-style reads welcome; open an issue or reach out on X.
