Encrypted prediction markets on Solana

Predict.
Stay private.
Win big.

The first prediction market where every position is encrypted until settlement. Nobody can see your bet — not even us. Powered by Arcium MPC + ZK proofs on Solana.

3
Market types
$1–$100
Tiered lobbies
100%
Positions private
ZK
Verified payouts

Three ways to play

Each market type has different math. Same privacy guarantee across all — your prediction is encrypted the moment you submit it.

01
Binary market

Yes or No

“Will BTC close above $100k on Friday?”

Pick: YES or NO
Winners: correct side splits loser pool equally
Formula: stake_net + (stake / YES_net) × NO_net
YES pool
NO pool
$1
$10
$100
02
Accuracy market

Closest wins

“What will SOL price be on Jan 15?”

Pick: your exact numeric prediction
Cutoff: median error — top ~50% win
Weight: (1/(1+r))^6 — closer = bigger share
Single prediction pool — all vs all
$1
$10
$100
03
Multi-outcome

Pick the winner

“Who wins Champions League 2025?”

Options: 2 to 4 outcomes (v1 max: 4)
Winners: winning pool splits all losing pools
Formula: stake_net + net_losers / winner_count
Real Madrid
Arsenal
Bayern
PSG
$1
$10
$100

Every market. Three isolated pools.

Same question. Separate money. $1 bettors only compete against $1 bettors. Whales can't affect your tier.

$1
Micro lobby
Low stakes, high volume
Learn the platform
Isolated from $10/$100
1_000_000 USDC (6 decimals)
$10
Standard lobby
Core product
Deepest liquidity
Most active markets
10_000_000 USDC (6 decimals)
$100
Whale lobby
High conviction plays
Bigger pot, bigger win
Isolated from lower tiers
100_000_000 USDC (6 decimals)

From bet to payout

Seven stages. Your prediction stays encrypted from placement to settlement.

OPEN
LOCKED
RESOLVING
SETTLING
SETTLED
VOIDED
Stage 01 — Creation
Creator opens the market
Anyone can create a market. Post a $10 USDC bond, choose type (Binary/Accuracy/Multi 2–4 options), set the question, oracle source, lock time, and resolve deadline. Three tier pools go live immediately.
create_market_group() + create_tier_market() ×3 → emits GroupCreated
Stage 02 — Betting (OPEN)
Users place encrypted bets
User picks a market, tier, and prediction. The browser encrypts the prediction with the Arcium MXE public key before it leaves the device. The ciphertext goes on-chain. Nobody can read it — not validators, not other users, not Cyper.
encrypt(prediction, mxe_pubkey) → place_bet(encrypted_payload) → emits BetPlaced
Stage 03 — Lock
Betting closes
After lock_timestamp, no new bets. Permissionless — your backend calls it, but any user can too as fallback.
lock_market() → permissionless, anyone can call → emits GroupLocked
Stage 04 — Resolution
Oracle posts the answer
Pyth feed (trustless) or creator manual post. 1-hour dispute window starts. Creator's $10 bond is at risk if wrong.
post_resolution(resolved_value) → 1hr dispute window → emits ResolutionPosted
Stage 05 — Settlement (Arcium)
Encrypted compute scores everyone
Arcium MXE nodes pick up all encrypted payloads and run scoring privately. No node sees individual predictions. Output: ZK proof + payout table.
queue_settlement() → [Arcium decrypts + scores + ZK] → settle_callback() → write_position_payouts()
Stage 06 — Payout
Winners claim USDC
Position is SETTLED. User calls claim_payout — USDC moves from pool vault to their wallet. Creator earns 1.5% LP fee. Protocol takes 0.5%.
claim_payout() → pool vault → user wallet → emits PayoutClaimed
Stage 07 — Cleanup
Creator gets bond back
After all pools settle, creator calls return_bond. If they never resolved, anyone can slash the bond — it goes to treasury.
return_bond() → $10 USDC back to creator — OR — slash_bond() → treasury + GroupVoided

What lives where

Three layers. Solana handles money and state. Arcium handles encrypted computation. Your backend handles speed and indexing.

🧑 Creator — frontend
create_market_group
Posts $10 bond. Writes MarketGroup PDA. One per event.
→ GroupCreated
+ create_tier_market ×3
👤 User — frontend
place_bet
Encrypts prediction locally. Transfers USDC. Creates Position PDA.
→ BetPlaced (no prediction info)
⏰ Anyone — permissionless
lock_market
Closes betting. Freezes accuracy sigma. Backend or any user.
→ GroupLocked
🔮 Oracle / Creator
post_resolution
Pyth feed or creator posts real answer. 1hr dispute window.
→ ResolutionPosted
🤖 Backend (after dispute)
queue_settlement
All encrypted payloads → Arcium mempool. One per pool.
→ SettlementQueued
🔐 Arcium MXE — automatic
settle_callback
ZK proof verified. Fees sent. Pool → SETTLED.
→ PoolSettled
🤖 Backend (batched)
write_position_payouts
Writes payout amounts to Position PDAs. 20 per tx. Idempotent.
→ (no event)
👤 User — frontend
claim_payout
USDC from vault to user wallet. Only if payout > 0.
→ PayoutClaimed
😈 Anyone if creator fails
slash_bond
Missed deadline. Bond → treasury. Market voided.
→ BondSlashed + GroupVoided

How your bet stays private

Three steps. Everything sensitive is encrypted client-side before touching the chain.

01 — Your device
prediction: YES
tier: $10 pool
plaintext in browser only
never sent unencrypted
02 — On-chain (Position PDA)
8f4a2c9e1b7d3f5a0e6c8b4a2f9d1e3b7c5a0f2e4d8b6c3a1f9e7d5b3c1a9f7e2d4b6a8c0e2f4b6a...
encrypted with MXE pubkey
stored as opaque blob
03 — Arcium MXE (settlement)
payout: $24.71
ZK proof: verified ✓
MPC: no node sees plaintext
ZK verifies scoring
WHAT'S PRIVATE
Your prediction (YES/NO/number/outcome)
Your entry timing strategy
Your wallet association to a position
WHAT'S PUBLIC
Pool participant count per tier
Total USDC staked per pool
Payout amounts (post-settlement only)
ARCIUM GUARANTEE
MPC: key shards split across nodes
ZK proof: scoring correctness verifiable
Even Cyper cannot read your prediction

The math

Total fee = 2%. LP fee 1.5% goes to market creator. Protocol fee 0.5% goes to treasury. All math runs inside Arcium MXE.

Binary
net_pot = total × 0.98
YES_net = yes_count × stake × 0.98
NO_net = no_count × stake × 0.98

// YES wins:
payout_i = stake_net
    + (stake_net / YES_net) × NO_net
Accuracy
error_i = |predict_i − actual|
sort by error ascending
median = sorted[floor((N+1)/2)]

won_i = error_i < median // strict <
r_i = error_i / median
w_i = (1 / (1+r_i)) ^ 6

payout_i = stake + (w_i / Σw) × loser_pool
Multi-outcome (2–4)
outcomes: 2 to 4 options
each has own pool per tier

// winning outcome takes all:
loser_pool = Σ(all other pools)
net_pot = loser_pool × 0.98

payout_i = stake_net + net_pot / winner_count
→ Interactive math simulator with live editing: math simulator →

Who owns what

On Solana, every account has three distinct properties: who paid the rent, who has program authority over it, and who can sign to interact with it.

SOLANA BASICS — THREE DIFFERENT THINGS
Rent payer
Who deposited SOL to keep the account alive. Gets it back when the account is closed (if ever).
Program authority
Which program owns and can write to the account data. For PDAs, this is always your Solana program.
Signer authority
Which wallet must sign transactions that interact with this account.
CyperMarket PDA
Global config. 1 total.
RENT PAID BY
Admin wallet
Pays ~0.002 SOL once at deploy.
PROGRAM / CUSTODY
Your Solana program
Only the program can write to this account.
SIGNER AUTHORITY
Admin wallet
Only admin can initialize, update_fees, pause.
MarketGroup PDA
1 per event
RENT PAID BY
Market creator
~0.004 SOL. Paid at create_market_group.
PROGRAM / CUSTODY
Your Solana program
Program writes status, resolved_value, dispute_deadline.
SIGNER AUTHORITY
Creator (privileged) / Anyone (lock)
Creator for cancel/return_bond. lock_market is permissionless.
Bond PDA + vault
1 per event
RENT PAID BY
Market creator
~0.002 SOL PDA + ~0.002 SOL vault.
PROGRAM / CUSTODY
bond_vault_authority PDA
Seeds: ["bond_authority", bond.key]. No private key — program signs only.
SIGNER AUTHORITY
Program only (via CPI)
return_bond → creator. slash_bond → treasury. Both require on-chain conditions.
Market PDA ×3
3 per event (one per tier)
RENT PAID BY
Market creator
~0.003 SOL × 3 = ~0.009 SOL.
PROGRAM / CUSTODY
Your Solana program
Program updates status, participants, volume.
SIGNER AUTHORITY
Creator (creation only)
has_one = creator on parent MarketGroup.
Pool PDA + vault
2–4 per market per tier
RENT PAID BY
Market creator
~0.002 SOL pool + ~0.002 SOL vault each.
PROGRAM / CUSTODY
pool_vault_authority PDA
Seeds: ["vault_authority", pool.key]. Only program signs.
SIGNER AUTHORITY
Program only (settle + claim)
USDC out via settle_callback (fees) or claim_payout (user).
Position PDA
1 per user per pool
RENT PAID BY
The bettor
~0.003 SOL per bet. Hidden cost users pay.
PROGRAM / CUSTODY
Your Solana program
Program writes payout and status. Backend writes via write_position_payouts.
SIGNER AUTHORITY
User (claim only)
PDA seeds include user.pubkey — only they can claim.
RENT COST SUMMARY
Market creator pays
MarketGroup PDA: ~0.004 SOL
Bond PDA + vault: ~0.004 SOL
3× Market PDAs: ~0.009 SOL
6× Pool PDAs (binary): ~0.012 SOL
6× Pool vaults: ~0.012 SOL
~0.041 SOL (~$8 at $200 SOL)
Plus $10 USDC bond (returned)
Each bettor pays
Position PDA rent: ~0.003 SOL
Transaction fee: ~0.00001 SOL
~0.003 SOL (~$0.60)
Plus the USDC bet ($1/$10/$100)
Your backend pays
lock_market tx: ~0.00001 SOL
queue_settlement ×N: ~0.0001 SOL
write_position_payouts ×N: ~0.0002 SOL
~0.001 SOL per market
$10 SOL covers thousands of markets
THE VAULT AUTHORITY CHAIN
Pool vault (token account)
  └── authority = pool_vault_authority PDA (seeds: ["vault_authority", pool.key])
      └── program signs in 2 instructions only:
          settle_callback → fees (requires valid ZK proof)
          claim_payout → user (requires position.status == SETTLED)

Bond vault (token account)
  └── authority = bond_vault_authority PDA (seeds: ["bond_authority", bond.key])
      └── return_bond → creator (requires market.status == SETTLED)
      └── slash_bond → treasury (requires deadline passed + no resolution)

// No human wallet can ever directly sign a transfer from any vault.

Common questions

Why can't anyone see other people's bets?+

Every prediction is encrypted with the Arcium MXE public key client-side in your browser before it's submitted. The encrypted blob is stored on-chain. Nobody — not other users, not validators, not Cyper — can decrypt it without the MXE's private key shards, which are split across multiple MPC nodes and only combined inside the secure computation at settlement.

What stops a creator from posting a wrong resolution?+

Three things: a $10 USDC bond (slashed if they misbehave), a 1-hour dispute window after any resolution, and Pyth on-chain price feeds for crypto markets which require no human input at all. For custom markets, the bond + dispute window is the protection layer.

How many outcomes can a multi-outcome market have?+

Between 2 and 4 outcomes in v1. Each outcome creates its own pool PDA for each tier — a 4-outcome market creates 12 pool PDAs. Solana has an account limit per transaction, so we cap at 4 for v1 to keep market creation in one transaction. More outcomes will come in v2.

Can I bet in multiple tiers on the same market?+

Yes. The one-bet-per-pool rule is enforced by PDA uniqueness — seeds include your wallet and pool address. You can bet in the $1 pool and $10 pool simultaneously. You cannot place two bets in the same pool.

What token is used?+

USDC only, across all market types. Stable value means your $10 bet is worth $10 at settlement. If you only have SOL, swap on Jupiter first — one click, 5 seconds.

Is the contract upgradeable?+

Yes, with a multisig upgrade authority. No single key can upgrade the program. We'll add a 48-hour timelock announcement window as we grow. All accounts have reserved padding bytes so upgrades don't require migrating existing market data.

What happens if nobody bets on the winning side?+

Edge case handled in the settlement contract — if winner_count is 0, the entire net pool goes to protocol treasury to prevent permanent fund lock. For accuracy markets this cannot happen — the top ~50% always win by definition of the median cutoff.