Built on Solana

One Solana program, three protocols.

The duel program mints outcome tokens, holds the USDC behind them and settles from Pyth. Trading runs in Meteora DAMM v2 pools against xStocks.

Pyth receiverPriceUpdateV2 accountsresolveduel programMarket PDAmints YES and NOCollateral vaultUSDCReward vault AAAPLxReward vault BNVDAxYour walletUSDCYES / NOAAPLx / NVDAxmint_set, merge_setredeemdistributeswapMeteora DAMM v2 poolsUSDC / AAPLxYES / AAPLxUSDC / NVDAxNO / NVDAxfees in AAPLx, claimed by the crankfees in NVDAx

Why Solana

Atomic

One transaction, two swaps

A bet is two Meteora swaps in one Solana transaction. Both fill or nothing moves.

Fees

Fractions of a cent

Cheap enough to pay every holder their share of the fees, pro rata, a few times a day.

Speed

400 ms blocks

A swap confirms in about a second and the odds on the board move with it.

Tokens

Plain SPL tokens

YES, NO and xStocks show in any wallet and route through any Solana aggregator.

01

Mint a set

mint_set takes one USDC into the vault and returns one YES plus one NO. merge_set reverses it. A set always redeems for exactly one USDC.

1 USDCmint_setmerge_set1 YES+1 NOone set, redeems for exactly 1 USDCheld by the market PDACollateral vaultUSDC

02

Trade through the stock

YES trades against AAPLx and NO against NVDAx in Meteora pools that keep their fee in the stock. A bet is one Solana transaction: USDC to AAPLx, AAPLx to YES.

swap 1swap 2USDCUSDC / AAPLxpoolfee in USDCAAPLxYES / AAPLxpoolquote-only feeYESFee, in AAPLxpaid to YES holders

03

Read the odds

No order book. Each side's dollar price is its pool price times the stock's Pyth price, and the board scales the two to add up to one. Drift past a cent and minting or merging a set pulls it back.

yes_raw = P(YES in AAPLx) × P(AAPLx in USD)
no_raw  = P(NO in NVDAx)  × P(NVDAx in USD)
odds    = yes_raw / (yes_raw + no_raw)
Apple 54Nvidia 46

04

Fees become rewards

A crank claims each pool's fees, deposits them with deposit_rewards and pays every holder pro rata with distribute, 12 per call. Fees never leave the stock.

Claim feespool fees, AAPLxdeposit_rewardsreward vault ASnapshot holdersevery YES accountdistributepro rata12 per callRewardsPaideventoperator keyinto vault Anot pools or vaultscrank key, sum ≤ vaultread by the ledger

05

Settle from Pyth

After resolve_ts anyone posts the Pyth prices and calls resolve. The program checks the feed ids and a six-hour freshness window, then the template picks the winner. A quiet feed past the grace period falls back to the resolver.

Pyth Hermessigned pricesPyth receiverwrites PriceUpdateV2resolveanyoneafter resolve_tsResolvedwinnerprices, timeresolve checksowner is the Pyth receiverfull verificationfeed id matchesprice age under 6 hresolve_manualresolver keyafter the grace

Cap compare

price_a × shares_a > price_b × shares_b

Outperform

price_a / price_b > start_ratio

Price above

price > threshold

06

Redeem

redeem burns winning tokens for one USDC each. The losing token is worth zero. Any stock you were paid along the way stays yours.

Nine instructions

Everything the program does is mint, burn, transfer and read a Pyth account. The AMM, the oracle and the stock issuer are not ours.

InstructionSignerEffect
create_marketanyoneMarket PDA, YES and NO mints, collateral vault, two reward vaults.
set_poolscreator, onceRecords the two Meteora pool addresses.
mint_setanyoneUSDC in, the same amount of YES and NO out.
merge_setanyoneBurns a YES and a NO per USDC returned.
resolveanyone, after resolve_tsReads the Pyth accounts, stores the winner.
resolve_manualresolver, after the grace periodStores the winner from printed prices.
redeemanyone, once resolvedBurns winning tokens, pays one USDC each.
deposit_rewardsanyoneMoves stock tokens into a reward vault.
distributecrankPays up to 12 holders, emits RewardsPaid.
duel programAN2TEyFH3zCsv5MENn2uo9LJx69J2EUC8iScAVeDbW25
Meteora DAMM v2cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG
Pyth receiverrec5EKMGg6MxZYaMdyBfgwp4d5rB9T1VQH5pJv5LtFJ

On devnet, USDC, AAPLx and NVDAx are mock mints. The registry maps each to its mainnet xStocks mint and the program runs unchanged.

Risks

  • Not available everywhere

    Versus is not offered to persons in the United States or in any other restricted jurisdiction. Do not use it where prediction markets or tokenised stocks are not permitted.

  • Outcome tokens can go to zero

    The losing side redeems for nothing at the bell. Only put in what you can lose in full.

  • Rewards are other traders' fees

    Stock payouts are a redistribution of trading fees, not yield or interest. They depend on volume and can be small or nothing.

  • Stock tokens have an issuer

    xStocks can be paused, frozen or seized by their issuer, including inside the pools and reward vaults. Collateral is USDC, so the one-dollar redemption is not affected.

  • Resolution has a fallback

    Pyth prices decide each duel. If a feed is stale past the grace period, the resolver settles manually with the published prices.

  • Not advice

    Nothing here is legal, tax or investment advice. Devnet and localnet use mock tokens with no value.

Ready when you are.

The board is live. Pick a side and the odds move with you.

Powered by