Skip to main content
This page answers common technical questions about how ezpz.fi is built. It describes the current M1 architecture (AMM-first, custodial trading, closed API).

Oracle and settlement data sources

ezpz.fi does not use Solana-native oracle networks (Pyth, Switchboard, etc.) to resolve markets. Settlement is a two-step process:
  1. Off-chain truth gathering — feeds, crons, and operators determine the outcome.
  2. On-chain settlement — a trusted platform oracle signs resolve_market on buukie-market, which records the winner and enables redemption.

By vertical

VerticalOff-chain data sourceWho submits on-chain resolution
SportsPolymarket Gamma API + CLOB WebSocket via polymarket-soccer-fixer-api; match-end timestamps from matches-analyzerOperator reviews in oracle-admin, then signs resolve_market
Crypto (price events)Spot/index feeds for charts; declared resolution source per market (often Polymarket-style Chainlink rounds for up/down factories)Cron resolvers (resolve_count_bars, factory crons) or operator
BTC up/down (5m)Polymarket crypto-price rounds (Chainlink-backed on Polymarket); bar outcomes from fixer dataAutomated cron → on-chain resolve_market
Pump.funpump.fun APIs; snapshot crons for market cap and graduationCron resolvers (resolve_pumpfun_*) or operator
Custom maker marketsDeclared resolution source + criteria stored in market metadataOperator (MVP); future: automated where source is deterministic
Every market declares a resolution source and criteria at creation. Operators (or automated crons for factory markets) must follow that declaration. Disputes are handled off-chain in oracle-admin; on-chain, dispute_market / uphold_resolution / overturn_resolution gate redemption.

Solana-native vs off-chain oracles

MechanismUsed?Role
Pyth / Switchboard / Chainlink on SolanaNoNot used for settlement
On-chain price accountsNoPrices are not written to oracle accounts on a schedule
Trusted platform_oracle signerYesSubmits resolve_market, void_market, dispute outcomes
Off-chain feeds + cronsYesGather real-world results; drive operator queue or auto-resolve

How positions are represented

Single-market predictions — SPL tokens

Player positions on binary markets are real SPL tokens, not opaque database balances:
  • Each market leg has a YES mint and a NO mint (anchor_spl::token::Mint).
  • When a player makes a prediction, USDC is converted to a complete set (YES + NO) via mint_tokens / mint_tokens_v2, then the unwanted side is swapped via the AMM.
  • Tokens sit in the player’s custodial token account (ATA) managed by the platform.
  • Portfolio and the API project on-chain balances; the indexer mirrors mint, swap, and redeem events.
Winning players call redeem to burn winning tokens and receive USDC from the market vault.

Parlays — on-chain program accounts

Parlay predictions are not outcome SPL positions. They are recorded in Parlay accounts on buukie-parlay:
  • Stake is USDC in the parlay LP pool.
  • Legs reference underlying markets; resolve_leg reads each market’s on-chain outcome.
  • Payout is USDC from the parlay pool via settle_parlay.

CLOB positions (future / v2)

CLOB inventory is also SPL-based: makers hold USDC and outcome tokens in ATAs with exchange-delegate approval so buukie-exchange::settle_match can move tokens atomically after off-chain matching.

Solana-native dependencies

ezpz.fi keeps on-chain dependencies minimal. There is no Jupiter swap integration, no Pyth price feed, and no external AMM router in the settlement path.
DependencyUsed for
Anchor + SPL TokenAll five on-chain programs
Solana Ed25519 precompileCLOB OrderIntent signature verification in buukie-exchange
Jupiter wallet adapterWallet connect in the web app only (not pricing or settlement)
External off-chain data (not Solana programs):
  • Polymarket Gamma / CLOB WebSocket (sports + crypto reference data)
  • pump.fun APIs (coin markets)
  • Spot exchanges (Coinbase, Kraken, etc.) for charting where configured
  • Supabase (auth), PostgreSQL (app + indexer state)

On-chain update frequency and price feeds

Prices are not posted on-chain on a schedule.
DataWhere it livesUpdate pattern
AMM trade pricesbuukie-amm pool state (q_yes, q_no, LS-LMSR)Updates only when someone trades (swap / mint path)
CLOB quotesclob-engine in-memory books + PostgresContinuous off-chain; settles on match via settle_match
Charts / discovery UIIndexer (ix_* tables) + APIProjected from on-chain swap events + off-chain snapshots
Crypto spot (display)Off-chain REST/WebSocket feedsFor charts and factories; not written to Solana oracle accounts
There is no requirement for sub-second on-chain price updates. The AMM price at trade time is whatever the pool math returns for that transaction.

On-chain vs off-chain components

LayerOn-chainOff-chain
Auth & accountsCustodial keypairs hold SPL ATAsSupabase auth, session, MFA
Market discoveryAPI + Postgres + indexer projections
AMM tradingmint_tokens_v2 + swapAPI builds and submits txs via signer
CLOB tradingsettle_match onlyMatching, order book, signing in clob-engine
Parlayscreate_parlay, resolve_leg, settle_parlayAPI orchestration, soccer leg validation
Resolutionresolve_market, redeem, refundFeeds, crons, operator review
FeesFee vaults, claim_feesDashboards, reconciliation crons
Source of truth for funds: Solana programs. Postgres and the indexer are projections of on-chain events, not authoritative ledgers for USDC custody.

Pricing model

M1 retail trading uses an automated market maker (AMM), not a central limit order book.
ModelStatusDescription
LS-LMSR (liquidity-sensitive LMSR)Rolling outCost-function market maker: C(q) = b(q) · ln(e^(q_yes/b) + e^(q_no/b)). Trades priced by ΔC. Vig is embedded in the curve (prices can sum to > $1).
CPMM (constant product)Legacy / dev transitionx · y = k swap curve; being replaced in place per pool upgrade spec.
CLOB (limit order book)v2Off-chain matching; on-chain atomic settlement. Not the M1 retail path.
LS-LMSR is a bonding-curve-style market maker: the pool maintains a cost function over outstanding quantities rather than a traditional order book. It is not a Uniswap-style constant-product pool once upgraded.

What runs where: pricing, matching, odds, settlement

FunctionOn-chainOff-chain
Opening oddsSeed verified at initialize_pool (target implied probability)Maker chooses odds in authoring UI
Live AMM pricebuukie-amm LS-LMSR ΔC on every swapIndexer/API expose marginal prices for charts
CLOB order matchingclob-engine (Postgres-backed books)
CLOB fill settlementbuukie-exchange::settle_matchclob-settler submits matched fills
Parlay combined oddsStored on Parlay account at creationAPI validates legs and computes product
Market resolutionresolve_market(outcome)Feeds + operator or cron decides outcome
Payoutredeem (winners), refund (void), settle_parlay
CLOB retail trading is gated off in M1. Players trade via the AMM. Makers and factory markets may still use CLOB infrastructure in preparation for v2.

End-to-end: single AMM prediction

  1. Off-chain: Player confirms trade in UI; API checks balance and market status.
  2. On-chain: Custodial signer submits swap (which CPIs mint_tokens_v2 + AMM math).
  3. On-chain: Player holds YES or NO SPL tokens in custodial ATA.
  4. Off-chain: After event ends, operator or cron determines winner.
  5. On-chain: resolve_market → dispute window → redeem pays USDC from market vault.
See also: Venues, Prices & AMM, Resolution, Outcome tokens.