TECHNICAL · V0.9

Predict Protocol Whitepaper.

A decentralised, non-custodial prediction-market protocol built on the Logarithmic Market Scoring Rule. This document specifies the market mechanism, security model, tokenomics, and operational posture in enough detail to audit and build on.

LAST REVISED · 21 APR 2026 · V0.9 DRAFT

Front matter

01Abstract#

Predict Protocol is a decentralised, non-custodial prediction-market protocol deployed on BNB Smart Chain. Users trade outcome shares that redeem for 1 USDC each if the corresponding outcome occurs and zero otherwise. Liquidity is automated via a Logarithmic Market Scoring Rule (LMSR) market maker parameterised by a protocol-funded subsidy, b, whose value bounds the protocol's worst-case loss to b · ln(2) USDC per binary market regardless of trader behaviour.

This document specifies the full protocol: the mathematical basis for the market maker, the on-chain state machine, the fee and subsidy economics, the resolution and dispute mechanism, the off-chain indexing layer, and the governance and token model. It is intended to be readable by auditors, builders, and sophisticated users, and to serve as a reference for every deployed parameter.

The central contribution is not a new market-making algorithm (LMSR is thirty years old), but a deployable instantiation that closes several well-known footguns: creator-impermanent-loss drain, unbounded protocol liability, sell-side slippage asymmetry, and ambiguity around voided markets. Each design choice is justified in the sections below against a named attack.

02Notation & conventions#

Throughout this paper:

  • n denotes the number of outcomes in a market. This document focuses on the binary case, n = 2, unless stated.
  • q_i (or q_A, q_B) denotes the outstanding share reserve on outcome i: the sum of all shares ever bought on that side minus all shares ever sold back.
  • b denotes the LMSR liquidity parameter. Units: 18-decimal fixed-point, USDC-denominated.
  • p_i denotes the implied probability of outcome i under the current reserves.
  • C(q) denotes the LMSR cost function; ΔC denotes the USDC moved by a trade.
  • USDC amounts are in 6 decimals on-chain; share amounts are in 18 decimals. Conversions happen explicitly in the contract and are highlighted where relevant.
  • A market is a single binary question with an expiry, a creator, a resolver set, and two outcome tokens (A and B, rendered as YES and NO).
  • A position is a wallet's outstanding (sharesA, sharesB) tuple on a given market.

The canonical implementation uses @prb/math's SD59x18 fixed-point type for all LMSR computations. All inequalities and bounds below refer to the integer post-rounding output of those operations.

Context

04Design goals & non-goals#

Goals, in decreasing priority:

  1. Non-custodial. No operator can move user funds. Every trade, payout, and refund routes through an audited immutable contract.
  2. Liquidity without creators underwriting IL. A creator of a market should not be exposed to impermanent loss when the crowd's belief moves. Protocol treasury absorbs the cost.
  3. Bounded protocol liability. The protocol's worst-case loss per market is a known, fixed constant chosen at market creation.
  4. Symmetric buy / sell. Sell-side trades should experience the same fee and slippage behaviour as buys. Users should never feel trapped.
  5. Economic finality. Market resolution is not trust-based; incorrect resolutions cost the resolver capital.
  6. Public indexability. All market state is reconstructible from on-chain events alone; the indexer is a cache, not an oracle.

Non-goals:

  • Multi-outcome markets at v0.9. The LMSR derivation generalises to n outcomes, but the contract implements n = 2 only.
  • Cross-chain state. The protocol is deployed on a single chain; bridging is out of scope until token launch.
  • Privacy. All trades and balances are public.
  • Fiat on-ramps. Users bring their own USDC.

Mathematical foundations

05LMSR cost function#

The Logarithmic Market Scoring Rule defines a cost function over the outstanding share reserves q = (q_1, …, q_n):

C(q) = b · ln( Σᵢ exp(qᵢ / b) )

The protocol treasury holds a dedicated balance of C(q) USDC (in 18-decimal internal units) at all times. This is the market's solvent collateral. A trade that moves reserves from q to q' moves ΔC = C(q') − C(q) USDC from trader to contract (on a buy) or contract to trader (on a sell).

For the binary case:

C(qA, qB) = b · ln( e^(qA/b) + e^(qB/b) )

At market creation, qA = qB = 0, giving:

C(0, 0) = b · ln(2)

This initial value is the subsidy: the USDC that the protocol treasury deposits into the market at creation. It is the worst-case amount the protocol can lose; see Section 06.

Path independence. Because C depends only on the endpoint reserves, any sequence of trades that returns the reserves to their starting state returns the contract to its starting balance. Traders therefore cannot "pump" the market into a state where the contract owes more than C(q).

Convexity. C is convex in q, which means buying shares on any single side increases marginal cost strictly monotonically. This gives deterministic price impact and rules out arbitrage via trade splitting.

06Bounded-loss theorem#

Claim. In an LMSR market with parameter b and n mutually exclusive outcomes, the market maker's worst-case loss is bounded by:

L_max = b · ln(n)

For the binary case: L_max = b · ln(2) ≈ 0.693 · b.

Proof sketch. At resolution, the winning outcome's shares redeem for 1 USDC each and losing shares redeem for 0. The market maker's terminal balance is therefore:

payout(w) = q_w · 1 USDC

where w is the winning outcome. The market maker's total intake over the life of the market is C(q) − C(0), where q is the reserve vector at resolution. Net maker PnL is:

PnL = C(q) − C(0) − q_w

Substituting the cost function and letting m = max_i q_i:

C(q) − C(0) = b · [ln(Σᵢ e^(qᵢ/b)) − ln(n)]
           ≥ b · [ln(e^(m/b)) − ln(n)]
           = m − b · ln(n)

Since q_w ≤ m, we have:

PnL ≥ m − b · ln(n) − q_w ≥ −b · ln(n)

Thus the maker's loss is bounded by b · ln(n), independent of trader behaviour and the realised outcome. ∎

Practical implication. With testnet b = 500 USDC, the protocol treasury's maximum net loss per binary market is ~346.57 USDC, regardless of any combination of buys, sells, outcome flips, or trade sizes. This is the single most important property of the chosen market maker.

07Price function & implied probabilities#

The marginal price of outcome i (the price an infinitesimally-small buy would pay) is the partial derivative of the cost function:

p_i(q) = ∂C/∂q_i = exp(q_i / b) / Σⱼ exp(q_j / b)

This is the softmax function over scaled reserves. It has several properties worth stating explicitly:

  • Prices are always strictly between 0 and 1, even when a side has zero shares.
  • Prices sum to 1 exactly; no numerical drift is possible.
  • Prices are invariant under adding a constant to all reserves (a hidden symmetry that the contract exploits to avoid overflow; see Section 19).
  • The price curve is smooth; there are no cliffs at zero.

Why this matters. The naive ratio q_i / Σ q_j (used by parimutuel markets) collapses to 0 or 1 whenever a single side has zero shares. The indexer in a prior iteration of this protocol used the naive ratio for chart snapshots, which caused the market-detail chart to show 100/0 the instant anyone traded only one side. The LMSR price function fixes this at the source.

08Market microstructure#

The three quantities that define a market-maker's microstructure are price impact, effective spread, and depth.

Price impact. A buy of size Δq on outcome i shifts the implied probability from p_i to:

p_i' = 1 / (1 + (1 − p_i) / p_i · exp(−Δq / b))

The larger b, the smaller the impact for a given USDC size. b is literally a depth parameter.

Effective spread. The fee schedule (see Section 10) charges 2.0% round-trip (1.5% platform + 0.5% creator). This fee widens the effective spread: a trader who buys then immediately sells recovers the midprice minus 2.0% minus any LMSR slippage incurred on both legs. A trader on a market at 50/50 trading ~0.1 · b USDC pays roughly 0.5% in slippage per leg, so the total round-trip cost is ~3%.

Depth. The LMSR depth at a probability level p (the USDC required to move the price by a given amount Δp) scales linearly with b:

USDC_to_shift ≈ b · ln(p' · (1 − p) / (p · (1 − p')))

This gives protocol operators a direct lever: doubling b doubles depth but also doubles the worst-case protocol subsidy loss. Section 13 discusses the calibration.

Protocol mechanics

09Market lifecycle#

A market moves through a deterministic state machine. States are stored on-chain in the Market struct; transitions are triggered by events listed in parentheses.

StateEntered byExits to
OpencreateMarketCutoff (timer), Voided (admin)
Cutoffblock.timestamp ≥ expiresAt − CUTOFFProposed (proposer), Voided (timeout)
ProposedproposeOutcomeDisputed (disputer), Finalized (timer)
DisputeddisputeProposalResolved (resolver)
Finalizedblock.timestamp ≥ proposal + DISPUTE_WINDOWResolved (auto)
Resolvedadmin or finalize(terminal: payouts claimable)
Voidedadmin or stale proposal(terminal: refunds claimable)

The betting cutoff (CUTOFF = 1 hour pre-expiry) blocks both buys and sells to prevent last-second manipulation. The dispute window (DISPUTE_WINDOW = 48 hours) is the time a proposal must survive before it auto-finalises. See Section 14 for parameter calibration.

Once Resolved, winning-side shares redeem 1:1 USDC via claimPayout. Once Voided, positions call claimRefund to retrieve their userNetSpent balance.

10Fee economics#

Every trade (buy or sell) charges:

  • 1.5% platform fee → FeeVault. After $PRED TGE, 30% of this routes to a TWAP buyback (half burned, half to resolution-staking rewards); the rest is split between treasury and LP-vault fee distribution. See Section 29.
  • 0.5% creator fee → market creator's address

These are calculated on the gross USDC moved, not the net. For a buy of x USDC, the contract pulls x from the trader, routes 0.015·x to FeeVault and 0.005·x to the creator, then applies the remaining 0.98·x against the LMSR cost function to compute shares out.

Comparison.

ProtocolTaker feeCreator cut
Polymarket0%N/A
Augur v21.0%configurable
Manifold0%N/A
Kalshi7% of winningsN/A
Predict Protocol1.5% + 0.5%0.5% for life

The 0.5% lifetime creator fee is deliberately generous to seed the long tail. The scarce resource in prediction markets is not liquidity (LMSR provides it algorithmically) but well-specified, resolvable questions. Creators should have enough cashflow to treat market-making as a serious activity.

11Buy / sell symmetry#

Both buyShares and sellShares charge the full 2% fee and both apply the LMSR cost function. This breaks a common failure mode where users feel "trapped" in a position because exiting is punitively expensive.

Sell accounting. A sell of Δq shares on outcome i pays the trader C(q) − C(q') USDC less 2% in fees, where q' has q_i − Δq on outcome i. Shares are burned from the trader's position and q_i decrements on-chain.

userNetSpent accounting. Each wallet's cost basis on each market is tracked as userNetSpent[marketId][user]. On a buy, userNetSpent += netIn; on a sell, userNetSpent = max(0, userNetSpent − grossOut). The clamp at zero ensures a user who has already extracted their stake via sells cannot claim a refund on a voided market.

Sell cutoff. Sells are blocked in the same 1-hour BETTING_CUTOFF window as buys. This is load-bearing: without it, a trader could watch on-chain resolver activity and dump shares against a market that's about to be called the other way. See Section 15.

12Subsidy & treasury accounting#

At market creation, the protocol treasury transfers subsidy = C(0) = b · ln(2) USDC into the market's collateral pool. This seeds the LMSR cost function with the bounded-loss guarantee from Section 06.

Solvency invariant. At all times during a market's life, the contract's USDC balance for that market equals:

balance = subsidy + Σ userNetSpent[marketId][*]

This equals C(q) up to rounding. The invariant is asserted in the test suite at every state transition.

Settlement. On resolution, winning shares redeem 1:1 USDC until the contract's balance for that market is exhausted. Any residual USDC (the protocol's PnL on that market) is routed to the FeeVault. On void, the subsidy is returned directly to the treasury and per-user refunds come from userNetSpent.

Treasury bootstrap (testnet). The deploy script mints 100M MockUSDC to the deployer and calls fundTreasury(100_000_000). At subsidy = 346.57 USDC, this funds roughly 288,000 markets before the treasury runs dry, comfortably more than v1 needs.

Parameter selection

13Liquidity parameter b#

The choice of b is the single most important parameter in LMSR. It trades off three things:

  • Protocol subsidy cost: linear in b. Double b, double the worst-case loss per market.
  • Depth: linear in b. Double b, the USDC required to shift the price by a fixed amount doubles.
  • Price sensitivity: the smaller b, the more responsive the market is to new information.

Testnet. b = 500 USDC is hard-coded on testnet via the isTestnet constructor flag. The implied max loss is 346.57 USDC per market. A 10 USDC trade on a fresh 50/50 market shifts the price by ~0.5%; a 100 USDC trade shifts ~5%.

Mainnet. Creators choose b in the range [100, 10000] USDC at market creation. Smaller b suits markets where creators expect low volume and want tighter price discovery; larger b suits anticipated-high-volume markets where smooth price action matters.

Why a range, not a free float. Below 100 USDC the market is effectively illiquid; a single 10 USDC bet moves the price by 20%+. Above 10,000 USDC the protocol subsidy per market exceeds the expected revenue per market at current fee rates, making the market maker unprofitable in expectation. The range was chosen by expressing the break-even volume for the protocol under a 2% fee:

break_even_volume = b · ln(2) / 0.02 ≈ 34.65 · b

so a creator choosing b = 10,000 must generate ≥ ~346,500 USDC in lifetime volume for the protocol to be neutral on that market.

14Dispute window & proposer bond#

Proposing an outcome requires staking a proposer bond of 100 USDC that is refunded (plus a 10 USDC reward from the rewardPool) if the proposal finalises unchallenged. If the proposal is successfully disputed, the bond is forfeited to the disputer.

The dispute window is 48 hours. During this window, anyone can post a matching 100 USDC bond and submit a counter-outcome. A disputed proposal escalates to the permissioned resolver set (see Section 23).

Calibration target: the bond must exceed the maximum expected profit an adversary could earn by pushing a false outcome through. For binary markets with b ≤ 10,000 USDC, the maximum combined profit is bounded by the sum of outstanding shares on the market's actual losing side, which is bounded by b · ln(2) + total volume · max_share_fraction. For testnet scale (b = 500) a 100 USDC bond is conservative. The bond scales with creator-chosen b on mainnet; the scaling law is still being modelled.

Dispute window length. 48 hours is a deliberate compromise between user experience (fast payouts) and the practical time needed for a disputer to notice a false proposal, locate source material, and post the bond. Shorter windows (12h) create unfairness against non-US timezones; longer windows (7d) create capital inefficiency for honest proposers.

15Betting cutoff#

BETTING_CUTOFF = 1 hour before expiresAt. In this window, both buyShares and sellShares revert. This blocks an attack pattern where a trader watches the oracle-facing information source (a sports stream, an election feed) and trades against the market immediately before expiry.

The symmetric block on sells is load-bearing. Without it, a holder seeing their outcome is about to lose could dump shares against the remaining pool, extracting value that should flow to the eventual winners. One hour is long enough to absorb practical latency between real-world event and oracle update; shorter windows (5 min) are insufficient for propagation, and longer windows (24h) strand too much user capital.

Adversarial analysis

16Threat model#

We enumerate the actors and their capabilities. Each attack in the next section is evaluated against this model.

  • Rational trader. Profit-maximising. Has arbitrary USDC. Can submit arbitrary transactions but cannot forge signatures, reorder blocks beyond short-term MEV, or alter oracle state.
  • Market creator. Rational trader who also selects b, market text, and the resolver set (from a whitelist on mainnet).
  • Resolver. Permissioned address in the protocol's resolver whitelist. Has one capability: proposing and arbitrating outcome disputes. Has no admin key.
  • Disputer. Any wallet willing to post a 100 USDC bond. Can escalate a resolver proposal.
  • MEV searcher. Rational trader who additionally controls transaction ordering within a block (via private relayers or validator collusion).
  • Sybil cluster. A single economic actor operating arbitrarily many wallets.
  • External oracle adversary. An actor who can manipulate the real-world event being predicted, or the sources that resolvers use.

We do NOT trust: trader rationality, creator honesty, or resolver honesty in isolation. Every economic guarantee must survive one of those breaking.

17Attack vectors#

Creator IL drain (closed). In CPMM-style markets, the creator's liquidity is the losing side's payout. A creator who funds a $1,000 AMM can be drained as sentiment converges. LMSR's bounded loss closes this: the creator funds nothing; the protocol funds the subsidy.

Wash trading. Round-trip trades on a single market generate no PnL for the wash trader (2% fee round-trip) and no impact on implied probabilities beyond noise. Wash-based volume-pumping for leaderboard inflation is dissuaded by the explicit fee cost; the frontend also flags wallets exceeding 50 bets / 24h or <10s inter-trade intervals via wallet_activity.

Sybil for subsidy extraction. An attacker opens many markets to farm subsidies. Mitigated by: (a) creators must bond capital for each market's initial liquidity; (b) market creation is rate-limited by the treasury's replenishment schedule; (c) mainnet creation will require posting a $PRED bond.

Oracle manipulation. A resolver proposes a false outcome. Mitigated by the 48h dispute window + 100 USDC bond slashing. Residual risk: the permissioned resolver set colludes on a market below the dispute threshold, addressed by resolver rotation and limited parameter scope (Section 24).

Liquidity sniping. A trader sees a new market, buys on one side immediately, then exits as the crowd corrects. This is the intended behaviour of an AMM: providing this arbitrage is how LMSR achieves price discovery. The protocol captures 2% of every leg, so this is a revenue mechanism, not a vulnerability.

MEV / front-running. A searcher observes an incoming trade in mempool and front-runs. LMSR's convexity bounds the impact: the victim pays the marginal price after the front-runner, but the front-runner's exit costs them the other direction. Net effect at small sizes is a few basis points of extra slippage.

Griefing via mass-void. An adversary tries to force a market void to recover stake on a losing bet. Requires corrupting the resolver set AND surviving dispute; not economic.

Expiry-timestamp manipulation. Validators can skew block.timestamp by ~±15s. This is immaterial against the 1-hour cutoff and 48-hour dispute window.

18Mitigations & residual risks#

The mitigations for each attack above are structural: they arise from protocol mechanics (bounded loss, bond forfeiture, betting cutoff, symmetric fees) rather than from detection or reactive measures. This is deliberate. Detection-based systems produce false negatives at the worst possible time.

Residual risks.

  • Resolver collusion on undisputed markets. If all 100 USDC disputers are asleep for 48 hours, a false proposal finalises. Mitigated by community bounty for discovering false proposals; no structural fix.
  • Real-world event manipulation. The protocol cannot distinguish "Team A won the game" from "Team A bribed the ref". Out of scope.
  • Upstream RPC censorship. A single RPC provider could reject transactions. Mitigated by frontend-side fallback RPC list; full fix requires user-operated RPC.
  • Known-unknowns. The dispute-bond calibration for mainnet b beyond 5,000 USDC has not been empirically tested. v1 launches with a conservative creator-selectable cap of 10,000 and will revisit after audit.

System architecture

19Smart contracts#

The protocol deploys six long-lived contracts plus a per-position runtime artifact:

  • PredictMarketLMSR.sol: the core. Holds all market state, implements buy/sell, resolution, dispute, claim, refund.
  • FeeVault.sol: DAO-controlled escrow for the 1.5% platform fee. Immutable, keyed to the DAO's eventual Timelock.
  • LeverageVault.sol: opens 2×/3×/5×/10× leveraged positions against any market's LMSR. Holds collateral, manages TWAP-based liquidation, and owns the insurance reserve. See Section 40.
  • LPVault.sol: pooled USDC lender to LeverageVault. Multi-tier deposits (Flex / 90d / 180d / 365d) accrue airdrop points and a pro-rata share of leverage-trade fees. See Section 41.
  • BetProxy.sol: a minimal proxy deployed by LeverageVault on every openPosition. Each proxy holds the LMSR shares for exactly one leveraged position and is destroyed in the close path.
  • MockUSDC.sol: testnet-only ERC20. Mainnet uses the canonical BSC USDC.
  • Faucet.sol: testnet refillable USDC dispenser. Dispenses 10,000 USDC per claim per wallet and auto-refills from its admin-funded balance when its own holdings drop below 1,000 USDC. Replaces the older one-shot MockUSDC.mint() path (which gave each wallet a single mint and was a constant operational bottleneck on testnet).

Storage layout. Every market lives in a Market struct keyed by uint256 marketId. Positions are mapping(marketId => mapping(user => (sharesA, sharesB))). userNetSpent and userClaimed are parallel mappings.

LMSR arithmetic. Computed with @prb/math's SD59x18 signed 59.18 fixed-point type. To prevent overflow when q_i / b is large, the contract subtracts max(q_A, q_B) from both arguments before exponentiating. This is the invariance property from Section 07. The worst-case input to exp is therefore 0, and the worst-case output is 1.

Upgrade posture. The contracts are not upgradeable. There is no proxy, no admin upgrade function. New market types (multi-outcome, scalar, conditional) will be deployed as separate contracts sharing a common FeeVault.

Pausing. The contract exposes pause() and unpause() to the owner for emergency stop. Only buyShares, sellShares, and createMarket are pausable; claims and refunds always execute.

20Off-chain indexing#

The indexer is a read-only view layer; it provides no privileged data and can be rebuilt from on-chain events alone. Its sole job is to make queries like "all bets by wallet X" or "odds history for market 42" fast for the frontend.

Pipeline.

  1. Moralis Streams subscribes to the LMSR contract and posts decoded events to a public HTTP webhook.
  2. Webhook handler (Express / TypeScript) verifies the signed payload, filters events to our contract's topic0 set, and writes them to Supabase (Postgres).
  3. The Next.js frontend reads from Supabase via a REST API layer that mirrors the event model.

Reorg handling. Moralis only delivers confirmed events (10+ block confirmations on BSC). This is deeper than typical BSC reorg depth and sufficient for the protocol's use case.

Cold start / backfill. A standalone backfill script reads events from a specified BACKFILL_FROM_BLOCK through getLogs, replays them deterministically into the Supabase tables, and is idempotent via unique transaction_hash constraints. This is run on deploy and on any indexer outage.

Failure posture. If the indexer goes down, the frontend's on-chain paths continue to work: useMarkets, useUserShares, getOdds all read directly from the contract. The degraded UX is that "X minutes ago" timestamps and leaderboard lose freshness; the trading and payout paths are unaffected.

21Frontend#

The frontend is a Next.js 14 App Router application written in TypeScript, using wagmi + viem for chain interaction and RainbowKit for wallet connection. It is deployed to Netlify as a static build; all chain reads and writes happen client-side.

RPC fallback. The frontend configures a fallback-ordered list of BSC public RPCs. The first alive one wins; failures cascade. This is important for BSC testnet where the default endpoint (data-seed-prebsc) historically has flaky getLogs behaviour; see the indexer's note on publicnode.com.

Read batching. Dashboards fetch per-market shares / odds / netSpent / claimed via wagmi.useReadContracts, which wraps them in a single multicall3 RPC round-trip. A portfolio view with 50 positions makes 1 RPC call instead of 200.

Refresh semantics. The frontend polls the on-chain event feed every 8s and the indexer every 15s. Both refresh immediately on a successful trade so new trades appear in the feed and chart without a page reload. See the useBetEvents + RecentBets merge logic for the race-condition handling.

Animation + perf. Market grids virtualise above a 50-item threshold; portfolio reads are batched; chart redraws skip when the tab is hidden; DPR is clamped at 2 for canvas charts. See Section 32 for the ongoing performance budget.

22Data availability#

A clear boundary between on-chain and off-chain data:

DataLives on-chainLives off-chain
Market reserves (q_A, q_B)mirror for queries
User shares / userNetSpentmirror
Resolved outcomemirror
Fees collected✓ (in FeeVault)n/a
Odds history (snapshots)reconstructible from eventsprimary
Market text (question, options)✓ (event args)cached
Leaderboard aggregatesreconstructible from eventsprimary

Every off-chain primary view is reconstructible from the event log. The indexer is a cache, not a trust root. If every off-chain provider vanished tomorrow, a new operator could replay events from genesis and rebuild every view in hours.

Oracle & governance

23Resolution mechanism#

Resolution is a propose → dispute → finalize flow:

  1. Propose. After market expiry, any whitelisted resolver calls proposeOutcome(marketId, outcome) with a 100 USDC bond. This transitions the market to Proposed state.
  2. Dispute window. For 48 hours, anyone can call disputeProposal(marketId, counterOutcome) with a matching 100 USDC bond. This transitions the market to Disputed.
  3. Finalize. If the window elapses with no dispute, anyone can call finalizeProposal(marketId). The proposal becomes the resolved outcome; the proposer recovers their bond plus a 10 USDC reward from the rewardPool.
  4. Arbitrate. A disputed proposal escalates to a majority vote of the resolver whitelist (or, post-token, to a staked-$PRED vote). The winning side takes both bonds.

Why this works. An honest proposer forfeits nothing and earns the reward. An adversarial proposer of a false outcome loses their bond to any single honest disputer. The only way an adversary wins is if nobody shows up in 48 hours, a scenario bounded by community incentive, not structural guarantee.

Resolver set. Bootstrap v1 launches with a permissioned whitelist: the core team, three community operators, and a Chainlink-powered automated resolver for well-specified sports / crypto markets. Post-TGE, the set rotates via $PRED governance (Section 24).

Voiding. If the proposer's outcome is invalidated during arbitration without a clear alternative (e.g. the resolution source no longer exists), the market is voided and every user's userNetSpent is refunded. The proposer's bond is forfeited.

24Governance model#

The protocol is operated by the team on testnet and during the mainnet bootstrap phase. Governance transfers to a $PRED-staked DAO at TGE + 3 months.

DAO scope. The DAO can set:

  • The resolver whitelist (add / remove addresses)
  • The b range for creator-selectable liquidity
  • The dispute window (bounded: 12h – 7d)
  • The proposer bond and reward (bounded: 10 – 1000 USDC)
  • The fee schedule (bounded: 0% – 5% platform, 0% – 1% creator)
  • Treasury withdrawals from the FeeVault
  • New market-type deployments (multi-outcome, scalar)

DAO cannot:

  • Upgrade the core contract. (It's immutable.)
  • Confiscate user positions or funds.
  • Change the resolved outcome of a finalised market.
  • Modify userNetSpent or userClaimed mappings.

Timelock. All parameter changes execute through a 48-hour timelock. Emergency actions (pause) bypass the timelock but are bounded: pause can be triggered by a 2-of-N multisig but can only last 7 days before it auto-unpauses.

25Upgrade path#

Because the core contract is immutable, "upgrades" mean new deployments. A v2 contract with multi-outcome support would be a new address, sharing the same FeeVault and resolver whitelist. Markets on v1 continue to resolve on v1; new markets can be created on v2.

The frontend supports multiple contract versions simultaneously via a static config. Historical markets on older contracts remain tradeable until resolution; once resolved, they become read-only history.

This approach accepts that some operational complexity (multiple contracts, version-aware indexing) is the cost of avoiding upgradeability's two failure modes: admin keys that can change contract behaviour, and proxy storage collisions that cause silent data corruption.

Token economics

26$PRED utility#

$PRED is a BEP-20 token on BNB Chain with a fixed supply of 30,000,000,000. It serves five purposes:

  • Market resolution staking. Stake $PRED to participate in dispute resolution. Honest resolvers earn fees from the FeeVault; addresses that propose or affirm a losing outcome have their stake slashed and distributed to the winning side.
  • Fee discounts. Tiered platform-fee reductions for $PRED holders and stakers, scaling with stake size.
  • Governance. Token-weighted voting on fee rates, supported markets, treasury deployment, and oracle integrations (Section 24).
  • Liquidity mining. Market makers and active traders earn $PRED for providing depth and non-wash volume. Wash activity is filtered using the same heuristics described in Section 17.
  • Market creation. Creating a market requires a small $PRED bond, returned on clean resolution. This is a spam filter, not a tax.

Value accrual. 30% of every protocol fee is routed into a buyback program executed via TWAP on the canonical USDC/$PRED pool. 50% of the bought-back tokens are burned permanently; the remaining 50% recirculates to the resolution-staking reward pool. This couples token value to protocol throughput without relying on emissions.

27Supply & allocation#

Fixed supply of 30,000,000,000 $PRED (BEP-20, BNB Chain). Allocation:

BucketAllocationTokensNotes
Ecosystem & Rewards22%6,600,000,000Trading rewards, liquidity mining, referral incentives
Community & Airdrops20%6,000,000,000Retroactive airdrops and ongoing community campaigns
Team & Founders17%5,100,000,0003-month cliff, 12-month linear vest
Treasury / DAO13%3,900,000,000DAO-controlled; growth, audits, grants, partner integrations
Liquidity & Market Making8%2,400,000,000Initial DEX liquidity + market-maker inventory
Pre-Seed Investors8%2,400,000,000$20M valuation, $0.0008/token. 3-month cliff, 12-month vest
Seed / Strategic7%2,100,000,000Strategic round. 3-month cliff, 12-month vest
Advisors & KOLs3%900,000,0003-month cliff, 12-month vest
Public Sale2%600,000,000Open, no allowlist. Fully unlocked at TGE

Vesting envelope. Every insider allocation (Team, Pre-Seed, Seed, Advisors) sits behind a maximum 3-month cliff and a maximum 12-month linear vest from TGE. By month 3 every cliff has ended; by month 13, the entire 30B supply is unlocked. See Section 28 for the circulating-supply curve.

28Circulating supply curve#

Circulating supply against the 30,000,000,000 total, measured from TGE:

TimeCirculating% of supply
TGE4,950,000,00016.5%
Month 15,500,000,00018.3%
Month 3 (all cliffs end)9,200,000,00030.7%
Month 616,500,000,00055.0%
Month 923,800,000,00079.3%
Month 1229,800,000,00099.3%
Month 1330,000,000,000100%

The TGE float is dominated by the Ecosystem, Community, Liquidity and Public Sale tranches; insider buckets stay locked through month 3 and unlock linearly thereafter. From month 13 the supply is fixed and the only protocol-level change to circulating $PRED is the buyback-and-burn flow described in Section 26.

29Buyback & burn#

30% of every protocol fee (platform fee on trades, plus the DAO's configurable cut of leverage-vault fees) is routed into a buyback contract that executes on the canonical USDC/$PRED pool via TWAP, smoothing out price impact and frontrunning.

The buyback contract splits the acquired tokens:

  • 50% burned permanently, sent to 0x0. This is monotonic deflation: from month 13 onward the supply only ever decreases.
  • 50% recirculated to the market-resolution staking reward pool, paying honest resolvers (Section 26) in $PRED rather than USDC. This concentrates token demand at the same place token holders are doing protocol-essential work.

The remaining 70% of protocol fees stays liquid: a configurable split between the DAO treasury (operations, audits, grants) and the LP-vault fee distribution (Section 41). The buyback fraction is DAO-adjustable within bounds [10%, 50%] through the normal 48h-timelock governance path.

Worked example. At a hypothetical $500M annual trading volume under a 1.5% platform fee (7.5M USDC gross), 30% (2.25M USDC) routes through the buyback. At a $0.005 average buyback price that's 450M $PRED acquired per year — 1.5% of total supply — of which 225M is burned and 225M flows to resolvers.

30Launch mechanism#

Funding is structured as a staged raise rather than a single public event:

  • Pre-Seed (8%, 2.4B $PRED) — $20M valuation, $0.0008/token. Closed strategic round to a small set of long-horizon backers. 3-month cliff, 12-month linear vest from TGE.
  • Seed / Strategic (7%, 2.1B $PRED). Priced at a premium to pre-seed; closes pre-mainnet. Same 3-month cliff, 12-month vest.
  • Public Sale (2%, 600M $PRED). Open, no allowlist, no vesting, no cliff. Held immediately before TGE on a BNB-Chain-native venue. Target TGE FDV: $150M.
  • Liquidity & Market Making (8%, 2.4B $PRED). Seeds the canonical USDC/$PRED pool plus market-maker inventory at TGE. The DEX-pool portion is locked.

Pre-seed-to-TGE ratio targets ~7.5× ($20M → $150M FDV) — modest by sector standards, deliberately so. The team's view is that an aggressive opening multiple is the single biggest predictor of post-launch token failure; modest first-day pricing buys the runway for buybacks (Section 29) to actually do work.

Security & operations

31Audit plan#

The mainnet deployment is gated on a third-party audit by one of: Trail of Bits, OpenZeppelin, Spearbit, or ChainSecurity. The scope includes:

  • PredictMarketLMSR.sol in its entirety
  • FeeVault.sol
  • Integration with @prb/math's SD59x18 usage (specifically the overflow pre-conditioning)
  • Timelock + multisig configuration

Audit acceptance criteria:

  • Zero critical or high findings at final re-audit
  • Medium findings either resolved or documented with risk acceptance
  • Public audit report published under the protocol's domain

Parallel to the audit, the test suite currently stands at 83 passing tests covering the full lifecycle: creation, buy/sell under all pricing regimes, fee accounting, resolution, dispute, void, refund, claim, and reentrancy. A property-based fuzzing pass via Foundry is planned for mainnet prep.

32Bug bounty#

Post-audit, the contract enters an Immunefi bug bounty with the following tiers:

SeverityPayout
Critical (funds at risk)10% of funds up to 250,000 USDC
HighUp to 50,000 USDC
MediumUp to 10,000 USDC
LowUp to 2,000 USDC

The frontend and indexer also have a bounty scope, with caps one order of magnitude lower. They are not funds-bearing, but phishing / XSS vectors can still damage users.

33Incident response#

A 2-of-3 multisig holds the pause() key. The multisig can be triggered in two scenarios:

  • Code vulnerability disclosure. An exploit is reported or observed in mempool. Pause immediately, patch (via new deployment), unpause.
  • Oracle corruption. Evidence that a resolver is compromised. Pause new proposals on affected markets while the DAO rotates the resolver.

Pause blocks buyShares, sellShares, createMarket, and proposeOutcome. It does NOT block claimPayout, claimRefund, or disputeProposal. These are user-protective operations and must always execute.

Pause auto-expires after 7 days. This prevents a compromised multisig from holding the protocol hostage indefinitely. The DAO can re-pause via the normal governance path if a longer stop is needed.

34Treasury operations#

The protocol treasury funds every new market's subsidy on createMarket. It is topped up by:

  • Residual USDC from resolved markets (see Section 12 settlement)
  • Voided market subsidy returns
  • DAO grants from the FeeVault

Solvency monitoring. A public dashboard tracks:

  • Treasury USDC balance
  • Outstanding subsidy commitment (Σ b_i · ln(2) over open markets)
  • FeeVault USDC balance
  • Rate of market creation per day

A runway metric (treasury balance divided by subsidy burn rate) surfaces if the treasury is trending below 30 days of coverage. In that state, the DAO either raises fees temporarily, closes new market creation for new creators, or transfers from FeeVault.

Compliance & risk

35Non-custodial posture#

The protocol is non-custodial in the strict sense: no operator, administrator, or governance action can move user funds. A user's outstanding shares, their claimable payout on a resolved market, and their refundable balance on a voided market are all computable from on-chain state alone, without any off-chain cooperation.

This is load-bearing for both the security model (Section 17) and the regulatory posture (Section 37). It also constrains the product: features that would require custodial intermediation (e.g. fiat on-ramps, off-chain matching, instant withdrawals beyond block finality) are explicitly out of scope.

36Jurisdictional filtering#

The frontend enforces geo-filtering at the application layer for jurisdictions where the legal status of on-chain prediction markets is either prohibited or ambiguous. The filter is advisory, not a security boundary. Users who bypass it retain the full contract-level rights, but the team does not offer a frontend path in those jurisdictions.

Current filtered jurisdictions: United States, Canada, United Kingdom, Australia, France, Germany, Spain, China, Hong Kong, Singapore, South Korea, Japan, and any country on the OFAC sanctions list. The list is reviewed quarterly and will be revised as local regulation clarifies.

The contract itself is permissionless and address-neutral; filtering is frontend-only.

37Regulatory classification#

The protocol is designed and documented as a peer-to-peer information service. Specifically, it does not:

  • Hold customer funds
  • Operate an order book or central matching engine
  • Take the other side of trades (the LMSR is algorithmic; the protocol does not profit from trader losses as a counterparty would)
  • Provide investment advice or recommend specific market outcomes
  • Target residents of jurisdictions where prediction markets are classified as regulated instruments

We believe this structure is most closely analogous to a software publisher distributing a non-custodial tool, not to a regulated derivatives venue. This is, however, not legal advice: each user is responsible for determining the regulatory status of their own use in their own jurisdiction.

The team has engaged outside counsel during the mainnet preparation phase to review the product's classification in the key jurisdictions. Findings will be published in a companion memo pre-mainnet.

38Enumerated user risks#

A non-exhaustive list, ordered by severity.

  • Total loss. Losing-side shares pay zero. A user can lose 100% of their stake on a single market.
  • Smart-contract bug. Despite the audit, undiscovered bugs could permanently lock or drain funds. The multisig pause can mitigate some classes but not all.
  • Oracle error. A resolver can propose a wrong outcome that survives the dispute window if no disputer posts a bond.
  • Network censorship. BSC validators could (collectively) censor the user's transactions. Extremely unlikely in practice but possible in theory.
  • RPC failure. The frontend's ability to read contract state depends on third-party RPCs. A coordinated outage would render the UI unusable, though users retain direct contract access via any node.
  • Regulatory risk. A user's jurisdiction may, at any time, criminalise the activity. The protocol itself is neutral, but users bear the legal consequences.
  • MEV / sandwich. A large trade announced in the mempool may be front-run, increasing the slippage relative to the quoted price at transaction-submission time.
  • Frontend-specific risk. The predictprotocol.app frontend could be compromised (DNS, hosting, phishing). Experienced users are encouraged to verify contract addresses against the published list and use their own frontend if paranoid.

Roadmap

39Roadmap#

PhaseTargetExit criteria
Testnet launchQ2 2026LMSR core + lifecycle live on BSC Testnet ✓
Leverage v1Q2 202610× leverage + LP vault + leaderboard + achievements ✓
Mainnet betaQ3 2026Audit complete, permissionless creation, partner integrations
TGE + $PREDQ3 2026Token live, airdrop by priority stack, CEX listings
Cross-chain & APIQ4 2026Additional EVM chains, public API, native mobile apps

Leverage & LP staking

40Leveraged trading#

Leveraged trading sits on top of the unchanged LMSR. Rather than fork the AMM, the protocol lets a user collateralise a position with a fraction of its notional and borrow the rest from the LP vault. The LMSR sees a normal-sized trade; the leveraged trader sees an amplified payoff.

Three contracts cooperate.

  • LeverageVault.sol: owns the position registry, the TWAP buffer, and the insurance reserve. All user-facing entry points (openPosition, liquidate, closeEarly, closePosition) live here.
  • LPVault.sol: pooled USDC. Exposes lendToLeverage + repayLoan + writeOffLoan + notifyFee — the four hooks that the leverage layer uses to move money across the trust boundary. See Section 41 for the LP-side mechanics.
  • BetProxy.sol: a fresh contract deployed per openPosition call. Each proxy is the on-chain owner of the LMSR shares for exactly one leveraged position; this keeps user shares and leveraged shares strictly separated inside PredictMarketLMSR's userShares mapping.

Open flow.

  1. User picks a side, tier, and collateral amount. The contract pulls collateral × leverage USDC: the collateral from the user, the rest from LPVault.lendToLeverage.
  2. A BetProxy is deployed; the full collateral + borrowed is sent to it.
  3. The proxy approves PM and calls buyShares on the user's chosen side. The shares now sit in the proxy.
  4. A LeveragedPosition struct is stored on the vault with side, leverage, collateral, borrowed, opening odds, and liquidation threshold.

Tiers and liquidation thresholds.

TierYES-side liquidationNO-side liquidationVolume gate
YES < 25%YES > 75%none
YES < 33%YES > 67%none
YES < 40%YES > 60%market totalVolume ≥ $10K
10×YES < 45%YES > 55%market totalVolume ≥ $50K

Liquidation is permissionless and pays the caller a 5% bonus on the position's collateral, drawn from the insurance reserve. The position's owner cannot self-liquidate; a 1-hour cooldown from open also prevents instant-liquidation griefing if a market jumps inside the opening block.

TWAP, not spot. Liquidation reads a 30-minute time-weighted YES-odds value rather than spot. A trader can momentarily push odds across a tier's threshold without triggering a liquidation; the TWAP must cross. This trades a small amount of capital-efficiency loss for resistance to flash-price manipulation. The contract maintains a rolling buffer of odds snapshots (kept for 1 hour) and recomputes the TWAP on every liquidation check.

Caps and gates.

  • Per-position: collateral between $50 and MAX_POSITION/leverage; total bet ≤ $2,000.
  • Per wallet: ≤ 5 active positions; combined open exposure ≤ $5,000.
  • Per vault: total open borrowed ≤ 20% of LP TVL; total outstanding loans ≤ 50% of LP TVL (defense-in-depth for the window between liquidation and close).
  • Per day: combined realized losses (from writeOffLoan) ≤ 10% of LP TVL. Crossing this triggers a permissionless emergencyPause path.
  • Opening cutoff: 2 hours before market expiry. The TWAP window can't stabilize closer than that.
  • Open odds must sit inside [20%, 80%] for the TWAP at open time — leverage on lopsided markets is too cheap to game.

Close paths.

  • closePosition(positionId) (owner only, post-resolution): proxy claims the winning payout from PM, the LP loan is repaid first, the remainder goes to the user. If the side lost, both collateral and the loan are written off — writeOffLoan books the LP-side loss and bumps the day's loss counter.
  • closeEarly(positionId, minUsdcOut) (owner only, pre-resolution): proxy sells all of its shares back into the LMSR at the current cost-function price. Proceeds repay the loan; surplus goes to the user. If proceeds < loan, the shortfall writes off against LP TVL and the user forfeits all collateral. Slippage floor is enforced inside PM's sellShares.
  • liquidate(positionId) (permissionless, TWAP-triggered): position is flagged liquidated; the bonus is paid; the actual unwind happens later when anyone calls closePosition on the liquidated row. Liquidated positions are fully assigned to the LP — any post-liquidation payout flows to the vault as a fee, never to the user.

Insurance reserve. Seeded from creator-side fees + a fixed share of leverage-trade fees. Pays liquidator bonuses. Decoupled from LP TVL so a depleted reserve doesn't pause the vault; instead, the bonus is silently clamped to whatever's left.

41LP staking & airdrop points#

The LP vault is both a yield source and the protocol's airdrop accrual mechanism. Deposits earn two distinct streams: a pro-rata share of leverage-trade fees (denominated in USDC) and a continuously-accrued points balance that will redeem into $PRED at TGE.

Tiers.

TierLockPoints multiplier (locked)Points multiplier (post-unlock)
Flexnone
90-day90 days
180-day180 days
365-day365 days

Two invariants in the multiplier table are worth calling out:

  • Post-unlock decay. A 365-day position keeps its 8× multiplier exactly through its lock period; the moment block.timestamp ≥ unlockTime, accrual drops to 1×. Old locks do not farm bonus points indefinitely — the system pushes capital cycling rather than rewarding inertia.
  • Cooldown is uniform. A 7-day cooldown applies between requestWithdraw and the actual withdraw call, including for Flex. This defeats flash-deposit fee-grab attacks (deposit just before a big liquidation, claim the fee distribution, withdraw the next block) and gives the protocol breathing room when the LP becomes more tightly coupled to LMSR liquidity in Phase 2.

Fee distribution. The leverage layer pushes USDC into LPVault.notifyFee on three triggers: (1) liquidated positions' winning-side payouts (after loan repayment), (2) closeEarly surpluses above the loan, (3) a configurable cut of PredictMarketLMSR platform fees that the DAO can route into the LP. Each notifyFee call increments accFeesPerShare by amount × 1e18 / totalShares, and every position has a feeDebt snapshot — the standard MasterChef-style accumulator pattern. Per-position pending fees are amount × accFeesPerShare / 1e18 − feeDebt, claimable at any time via claimFees.

Points accrual. Defined as amount × tierBps × dt / POINTS_DIVISOR, where POINTS_DIVISOR = 31,536,000 × 10^9. A 1,000 USDC deposit at 1× for 1 year yields 10 points; at 8× for 1 year, 80 points. Points are stored as uint128 pointsAccrued on the position and updated on every interaction (deposit, fee claim, withdraw). Points carry no on-chain redemption today; they are read by the airdrop snapshot taken at TGE.

Loss absorption. The LP vault is on the hook for leverage-side bad debt. When writeOffLoan fires, totalShares is reduced by the write-off amount — this depresses every existing position's pro-rata claim by the same percentage. This is the LP's risk: yield from fees in return for taking the first-loss tranche on leverage. The 10%-of-TVL daily cap on combined losses bounds the per-day damage; the 20% exposure cap bounds the worst-case loss given a black-swan liquidation event.

Deposit constraints. Minimum deposit $10. Maximum 20 active positions per wallet (so the position scan in fee distribution stays cheap). Each position is independent — you can hold a 365-day deposit and a Flex deposit simultaneously, and each has its own multiplier.

Appendices

AEvent signatures#

event MarketCreated(
    uint256 indexed marketId,
    address indexed creator,
    string  question,
    string  optionA,
    string  optionB,
    uint256 expiresAt,
    uint256 b,
    uint256 subsidy
);
event SharesBought(
    uint256 indexed marketId,
    address indexed user,
    Side    side,
    uint256 usdcIn,
    uint256 netIn,
    uint256 sharesOut,
    uint256 platformFee,
    uint256 creatorFee
);
event SharesSold(
    uint256 indexed marketId,
    address indexed user,
    Side    side,
    uint256 sharesIn,
    uint256 grossOut,
    uint256 netOut,
    uint256 platformFee,
    uint256 creatorFee
);
event MarketResolved(
    uint256 indexed marketId,
    Outcome result,
    uint256 qSharesA,
    uint256 qSharesB,
    uint256 totalCollateral
);
event PayoutClaimed(uint256 indexed marketId, address indexed user, uint256 payout);
event MarketVoided(uint256 indexed marketId);
event RefundClaimed(uint256 indexed marketId, address indexed user, uint256 amount);

BContract addresses#

BSC Testnet (chainId 97)

ContractAddress
PredictMarketLMSR0x58904b2E25dcC8b516a4daad38ACD79F45f50BDf
FeeVault0x10A6980891f2e80a73486c38D6b47A170dbE1714
LeverageVault0x649907038D6470a0Eaac6f740A13AB49a6A88502
LPVault0x29a416Bf4518d4d291BF313b1a0155efa63AB009
MockUSDC0xe0Aa0bf82663B2095a52656A79153dFa21417913
Faucet0x9B46E7B684F0deEc1F5aED150D462891A6B4C4a2

BetProxy instances are deployed per leveraged position by LeverageVault.openPosition and have no fixed address.

BSC Mainnet (chainId 56)

Not yet deployed. Will be added here on the mainnet launch cutover.

CProofs expanded#

C.1. Path independence of LMSR.

For any sequence of trades that takes the reserves from q⁰ through q¹, q², …, qᵏ back to q⁰, the total USDC moved is zero. Proof:

total = Σᵢ (C(qⁱ) − C(qⁱ⁻¹))
      = C(qᵏ) − C(q⁰)
      = C(q⁰) − C(q⁰)   [since qᵏ = q⁰]
      = 0

This is a direct consequence of C being a function of the endpoint only.

C.2. Convexity of LMSR cost.

The Hessian of C at any q is:

Hᵢⱼ = (1/b) · (pᵢ · (δᵢⱼ − pⱼ))

where δ is the Kronecker delta. This is the covariance matrix of the softmax distribution, which is positive semi-definite by construction. Therefore C is convex. Strict convexity holds whenever p is not degenerate.

C.3. Bounded loss for n outcomes.

Following Section 06 with n outcomes instead of 2:

C(q) − C(0) ≥ m − b · ln(n)
PnL       = C(q) − C(0) − q_w
          ≥ m − b · ln(n) − q_w
          ≥ −b · ln(n)          [since q_w ≤ m]

The generalisation preserves the bound; b · ln(n) grows sublinearly in n, making multi-outcome markets cheap to subsidise.

DGlossary#

  • AMM:Automated Market Maker. A contract that quotes prices algorithmically from its reserves.
  • b:LMSR liquidity parameter. Units: USDC. Depth and subsidy are both linear in b.
  • Bonded proposer:A resolver who has locked capital as a commitment to the truthfulness of their proposed outcome.
  • Cost function:A function C(q) whose difference across a trade gives the USDC moved.
  • CPMM:Constant-product market maker (x · y = k).
  • Dispute window:The 48-hour period during which a proposed outcome can be challenged.
  • FeeVault:DAO-controlled escrow for the 1.5% platform fee.
  • LMSR:Logarithmic Market Scoring Rule. The market maker used by this protocol.
  • Market creator:The wallet that calls createMarket and receives the 0.5% creator fee.
  • Position:A wallet's outstanding (sharesA, sharesB) on a given market.
  • Resolver:A whitelisted address with the capability to propose and arbitrate outcomes.
  • Share:A claim that pays 1 USDC if its outcome wins, 0 otherwise.
  • Subsidy:The C(0) = b · ln(2) USDC seeded into a market at creation.
  • Void:A terminal market state in which users recover userNetSpent via refund.
  • userNetSpent:Per-user, per-market running total of USDC in minus USDC out (clamped at 0).

EReferences#

  • Hanson, R. (2003). Combinatorial Information Market Design. Information Systems Frontiers, 5(1), 107–119.
  • Hanson, R. (2007). Logarithmic Market Scoring Rules for Modular Combinatorial Information Aggregation. Journal of Prediction Markets, 1(1), 3–15.
  • Pennock, D. M., Sami, R. (2007). Computational Aspects of Prediction Markets. In Algorithmic Game Theory, N. Nisan et al., Cambridge University Press.
  • Othman, A., Pennock, D. M., Reeves, D. M., Sandholm, T. (2013). A Practical Liquidity-Sensitive Automated Market Maker. ACM Transactions on Economics and Computation.
  • Augur Core Developers. Augur v2 Whitepaper. (2020).
  • Polymarket Team. Polymarket CTF Specification. (2022).
  • Gnosis Conditional Tokens Framework: https://docs.gnosis.io/conditionaltokens/.
  • Aboutaleb, P. (@prb). prb-math: Solidity fixed-point math. https://github.com/PaulRBerg/prb-math