FanVaultWorld Cup
How it works

A prediction market that never bets against you.

FanVault runs zero-house-edge parimutuel pools on Solana. Fans pool against fans, winners are paid from the losing pools, we keep a flat 2%, and every result is settled by a cryptographic TxLINE proof verified on-chain. No house, no custody, nothing to trust. Everything below is verifiable on Solana Explorer.

The problem with a sportsbook

It bets against you

A book wins when you lose. Their margin (the vig) is baked into every price, usually 5 to 10%.

You trust them to grade

The book decides the result and when you get paid. You cannot audit it.

They hold your money

Funds sit in their account. Withdrawals are a favor, not a guarantee.

Zero house edge, by design

Every market is a parimutuel pool with up to three outcomes. You stake into the side you believe. When the match settles, the whole pot, minus a flat 2% protocol fee, is split among the winning side in proportion to their stake. There is no bookmaker pricing the odds and no house taking the other side.

Your multiplier

payout = stake + 0.98 × (losing pools) × (your stake / winning pool)

Because the only deduction is 2% (vs a book's 5 to 10% margin), the same correct pick returns more here. We seed each pool to track the live de-margined TxLINE line, so opening odds are accurate, not made up.

Trustless settlement (the core)

Settlement is permissionless and tamper-proof. Anyone can settle a market, but no one can forge a result, because the outcome is proven by a TxLINE cryptographic Merkle proof verified inside the transaction.

1

A market is bound to a fixture at creation

Each market stores its TxLINE provider_fixture_id and market_kind (1X2, Over/Under, BTTS). This binding cannot be changed later.

2

Fans stake into outcome vaults

Stakes are held by the on-chain escrow program, not by us. Non-custodial from the first lamport.

3

Anyone calls settle_from_proof with the TxLINE proof

After full time, a keeper submits the match's three-stage Merkle proof fetched from TxLINE. No admin key is involved.

4

The program builds the predicate itself

FanVault constructs the outcome test from the market's own bound fixture + kind (e.g. Home wins ⇔ P1 goals − P2 goals > 0), so a caller can never substitute a different fixture or a favorable rule.

5

It CPIs into txoracle.validate_stat → bool

A Cross-Program Invocation calls TxLINE's validate_stat, which checks the claimed score against the on-chain daily Merkle root and returns true/false. We read it via get_return_data. A forged or wrong claim fails the proof and the whole transaction reverts.

6

Winners claim, trustlessly

On a true result the winning outcome is recorded and winners claim their share from the pool. The 2% fee is the only deduction.

Open a settle tx: you will see our settleFromProof instruction with an inner Txoracle: ValidateStat CPI, then the payout + 2% fee transfer.

Markets we cover

Match winner (1X2)

Home, Draw, or Away. A three-outcome pool, settled from the final score.

Over / Under goals

Total goals over or under the line (e.g. 2.5). Settled from the two-stat sum proof.

Both teams to score

Yes or No. (BTTS, on the roadmap — needs two stat checks.)

Pick’em / fantasy

Build a multi-prop ticket, each leg settled by its own proof. (Tier 2, preview.)

Architecture

Anchor escrow program — N-outcome parimutuel pools + settle_from_proof, on Solana devnet.

TxLINE txoracle — the validate_stat primitive we CPI into.

Indexer + API — reads on-chain markets/positions; serves read models + the live-odds proxy.

Next.js frontend — reads market state directly from chain; non-custodial wallet money loop.

TxLINE data we use

RESTPOST /auth/guest/start
Guest auth → bearer JWT (free tier)
on-chainsubscribe(level 1, 4 weeks) + activate
On-chain data authorization → X-Api-Token
RESTGET /api/fixtures/snapshot
World Cup fixture schedule (teams, kickoff)
RESTGET /api/odds/updates/{fixtureId}
De-margined 1X2 + Over/Under line (seed pools + live widget)
RESTGET /api/scores/snapshot/{fixtureId}
Live score / game state
RESTGET /api/scores/stat-validation
Three-stage Merkle proof for a finished fixture
on-chainCPI → txoracle.validate_stat(...) → bool
The settlement primitive: verify the score against the on-chain daily Merkle root