A standard for prediction markets outcomes on Sui. Inspired by Gnosis Conditional Tokens but designed for Sui's object model.
- Sui's
Coinor balanceSupplystandard requires deploying new packages per market (impractical) - Need outcome differentiation (YES/NO shares)
- Need market isolation (prevent cross-market contamination)
- Enable DeFi composability (use shares as collateral, in Lending, in AMMs, etc)
- Witness-based supply state creation - only market module can mint
- Market isolation - shares tied to specific markets via UID
- Share operations - split, join, destroy_zero
- Supply tracking - monitor minted/burned per outcome
- DeFi ready -
key + storefor wallets, kiosks, transfers
module my_market::prediction {
struct PredictionPlatform() has drop;
public fun create(ctx: &mut TxContext) {
let market_uid = object::new(ctx);
let (supply_state, cap) = supply::create(
PredictionPlatform(),
&market_uid,
2, // outcomes (YES/NO), (UP/DOWN), etc
ctx
);
// Store supply state and capability in your market object
}
}supply::create(market: &mut UID, num_outcomes: u64): (SupplyState, SupplyCap)supply::mint(cap: &SupplyCap, state: &mut SupplyState, outcome_index: u64, value: u64, ctx: &mut TxContext): Sharesupply::mint_vec(cap: &SupplyCap, state: &mut SupplyState, value: u64, ctx: &mut TxContext): vector<Share>(one per outcome index, empty ifnum_outcomes == 0)supply::burn(cap: &SupplyCap, state: &mut SupplyState, share: Share): u64supply::burn_vec(cap: &SupplyCap, state: &mut SupplyState, shares: vector<Share>)(burns provided shares; caller enforces shape)
share::split(share: &mut Share, amount: u64, ctx: &mut TxContext): Shareshare::join(share: &mut Share, other: Share)share::destroy_zero(share: Share)share::keep_or_destroy_zero(share: Share)share::into_balance(share: Share): Balanceshare::from_balance(balance: Balance, ctx: &mut TxContext): Share
Share getters:
share::value(share: &Share): u64share::outcome_index(share: &Share): u64share::market_id(share: &Share): IDshare::id(share: &Share): IDshare::is_zero(share: &Share): boolshare::belongs_to_market(share: &Share, market_id: ID): bool
Supply State getters:
supply::total_supply(state: &SupplyState, outcome_index: u64): u64supply::supply_values(state: &SupplyState): vector<u64>supply::num_outcomes(state: &SupplyState): u64supply::market_id(state: &SupplyState): IDsupply::id(state: &SupplyState): ID
Supply State Capability getters:
supply::supply_state_id(cap: &SupplyCap): IDsupply::cap_id(cap: &SupplyCap): IDsupply::is_state_cap(cap: &SupplyCap, state: &SupplyState): bool
- No outcome names - just indices (0, 1, 2...). Markets map to names (YES/NO, Trump/Biden)
- No complete sets - markets implement their own mint/burn economics
- No collateral handling - token standard doesn't touch collateral
- Minimal core - markets add features on top
- Market binding via UID reference
- Capability control via SupplyCap
- Overflow protection in minting and burning
vs Sui Coin or balance Supply
- No deployment per market
- Outcome differentiation
- Shared infrastructure
vs Custom Tokens
- Standardized interface
- Security patterns
- Instant composability
Standardized shares enable:
- Transfer and trading -
key + storeabilities for wallets and explorers - AMM liquidity - Trade shares against tokens or other shares
- Marketplace integration - List on NFT marketplaces via kiosks
One integration supports ALL markets.
- Conditional tokens - markets that depend on other market outcomes
- Batch operations - mint/burn multiple shares efficiently
- Flash share loans - borrow shares within a transaction
MIT