Fixed Odds
Fixed odds betting offers a straightforward betting approach where the potential payout is predetermined and fixed at the time of placing a bet. Unlike parimutuel betting, where odds fluctuate based on the total amount wagered, fixed odds remain constant, providing clarity and predictability to bettors.
For example, if the market is set at decimal odds of 2.2, a winning bet of 100 USDC will payout 220 USDC, clearly indicating the profit and overall return on the stake.
How It Works
- Payout: The market establishes the odds, these odds determine the potential return relative to the stake.
- Predictability: Bettors know the exact payout at the time of placing their bet, allowing for more informed betting decisions.
Technical Details
Code ID
Mainnet: None
Testnet: 10697
Instantiate
The contract is instantiated with the following parameters:
- admin_addr (
Addr
): The address with administrative privileges. - treasury_addr (
Addr
): The address where fees will be sent. - denom (
String
): The denomination of the token used for betting (e.g., “usdc
”). - denom_precision (
u32
): The number of decimal places for the token. - id (
String
): A unique identifier for the betting market. - label (
String
): A descriptive label for the market. - home_team (
String
): The name of the home team. - away_team (
String
): The name of the away team. - fee_spread_odds (
Decimal
): The fee spread in percentage points applied to odds (e.g., 0.07). - max_bet_risk_factor (
Decimal
): The maximum bet amount risk factor as a multiplier (e.g., 1.5x). - seed_liquidity_amplifier (
Decimal
): The seed liquidity and odds amplifier as a multiplier (e.g., 3x). - initial_odds_home (
Decimal
): The fixed decimal odds for the home outcome. - initial_odds_away (
Decimal
): The fixed decimal odds for the away outcome. - start_timestamp (
u64
): The UNIX timestamp indicating when the event starts.
Funds (Coins
): The initial seed liquidity (in the configured denomination) is sent along with the message.
Example:
{ "admin_addr": "neutron1...", "treasury_addr": "neutron1...", "denom": "uusdc", "denom_precision": 6, "id": "match_123", "label": "Team A vs. Team B", "home_team": "Team A", "away_team": "Team B", "fee_spread_odds": "0.07", "max_bet_risk_factor": "1.5", "seed_liquidity_amplifier": "3", "initial_odds_home": "2.2", "initial_odds_away": "1.8", "start_timestamp": 1744413315}
Possible Errors:
- InvalidAddress: If the provided addresses (e.g.,
admin_addr
ortreasury_addr
) fail validation, this error is returned with the invalid address string. - InvalidFeeSpreadOdds: Returned if
fee_spread_odds
is not within the valid range [0, 0.25]. - InvalidMaxBetRiskFactor: Returned if
max_bet_risk_factor
is not within the valid range [1, 10]. - InvalidSeedLiquidityAmplifier: Returned if
seed_liquidity_amplifier
is not within the valid range [1, 10]. - InvalidOdd: Returned if initial_odds_home or initial_odds_away are less than 1.
- MarketNotInitiallyFunded: Returned if the contract’s balance is zero during instantiation.
Query Messages
The contract provides several query endpoints to retrieve current state and betting information.
Config
Retrieves the current configuration of the market.
Example Request:
{ "config": {}}
Example Response:
{ "config": { "admin_addr": "neutron1...", "treasury_addr": "neutron1...", "denom": "uusdc", "denom_precision": 6, "fee_spread_odds": "0.07", "max_bet_risk_factor": "1.5", "seed_liquidity_amplifier": "3", "initial_odds_home": "2.2", "initial_odds_away": "1.8" }}
Market
Retrieves details about the betting market.
Example Request:
{ "market": {}}
Example Response:
{ "market": { "id": "match_123", "label": "Team A vs. Team B", "home_team": "Team A", "away_team": "Team B", "home_odds": "2.2", "away_odds": "1.8", "start_timestamp": 1744413315, "status": "ACTIVE", "result": null }}
Status: Represents the current state of the market.
pub enum Status { ACTIVE, CLOSED, CANCELLED,}
Result: Represents the final result of the market, if it has been settled.
pub enum MarketResult { HOME, AWAY,}
MaxBets
Fetches the maximum bet amounts allowed for each outcome (home and away).
Example Request:
{ "max_bets": {}}
Example Response:
{ "home": 1000000, "away": 750000}
Bets
Fetches the total bets placed in the market and the potential payouts for each outcome.
Example Request:
{ "bets": {}}
Example Response:
{ "total_amounts": { "home": 1000000, "away": 750000 }, "potential_payouts": { "home": 500000, "away": 2500000 }}
BetsByAddress
Retrieves detailed bet records for a specific address, including the total bet amount, cumulative potential payout, and average odds for each outcome.
Parameters:
- address (
Addr
): The address of the bettor.
Example Request:
{ "bets_by_address": { "address": "neutron1..." }}
Example Response:
{ "address": "neutron1...", "all_bets": { "home": { "bet_amount": 500000, "payout": 1100000, "odds": "2.2" }, "away": { "bet_amount": 0, "payout": 0, "odds": "0" } }}
Execute Messages
The contract supports several executable actions.
PlaceBet
Allows a user to place a bet on a specific outcome.
Parameters:
- result (
MarketResult
): The chosen outcome; must be one of HOME, AWAY, or DRAW. - min_odds (
Decimal
): The minimum acceptable odds for the bet. - receiver (
Option<Addr>
): Optional address to receive winnings (defaults to the sender if omitted).
Funds (Coins
): The bet amount (in the configured denomination) is sent along with the message.
Example:
{ "place_bet": { "result": "HOME", "min_odds": "2.0", "receiver": "neutron1..." }}
Possible Errors:
- MarketNotActive: If the market is not active.
- BetsNotAccepted: If the current block time is less than 5 minutes before the event start.
- MinimumOddsNotKept: If the current market odds are below the provided minimum odds.
- PaymentError: If no funds are sent or if token transfer fails.
- MaxBetExceeded: If the bet amount exceeds the maximum allowed bet.
ClaimWinnings
Allows users to claim their winnings after the market outcome has been determined.
Parameters:
- receiver (
Option<Addr>
): Optional address to receive winnings (defaults to the sender if omitted).
Example:
{ "claim_winnings": { "receiver": "neutron1..." }}
Possible Errors:
- MarketNotClosed: If the market is still active.
- ClaimAlreadyMade: If the address has already claimed winnings.
- NoWinnings: If there are no winnings available for the address.
Update (Admin Only)
Enables the admin to update market parameters.
Parameters:
- admin_addr (
Option<Addr>
): New admin address. - treasury_addr (
Option<Addr>
): New treasury address. - fee_spread_odds (
Option<Decimal>
): New fee spread in percentage points. - max_bet_risk_factor (
Option<Decimal>
): New maximum bet risk factor as a multiplier. - seed_liquidity_amplifier (
Option<Decimal>
): New seed liquidity amplifier as a multiplier. - initial_odds_home (
Option<Decimal>
): New initial odds for the home outcome. - initial_odds_away (
Option<Decimal>
): New initial odds for the away outcome. - start_timestamp (
Option<u64>
): Updated event start timestamp.
Example:
{ "update": { "admin_addr": "neutron1...", "fee_spread_odds": "0.08", "max_bet_risk_factor": "1.7", "seed_liquidity_amplifier": "3", "initial_odds_home": "2.4", "initial_odds_away": "1.9", "start_timestamp": 1744413315 }}
Possible Errors:
- Unauthorized: If the sender is not the current admin.
- MarketNotActive: If the market is not active.
- InvalidAddress: If the provided addresses (e.g.,
admin_addr
ortreasury_addr
) fail validation, this error is returned with the invalid address string. - InvalidOddsCombination: If only one of the new odds is provided or if they are invalid.
- InvalidFeeSpreadOdds: If the new fee spread odds is invalid.
- InvalidMaxBetRiskFactor: If the new max bet risk factor is invalid.
- InvalidSeedLiquidityAmplifier: If the new seed liquidity amplifier is invalid.
Score (Admin Only)
Sets the final outcome for the market.
Parameters:
- result (
MarketResult
): The winning outcome, which can be HOME or AWAY.
Example:
{ "score": { "result": "HOME" }}
Possible Errors:
- Unauthorized: If the sender is not the current admin.
- MarketNotActive: If the market is not active.
- MarketNotScoreable: If the current time is less than 30 minutes after the start.
- NoWinnings: If there are no winnings to process.
Cancel (Admin Only)
Cancels the market, resulting in refunds of all bets, no fees are captured.
Example:
{ "cancel": {}}
Possible Errors:
- Unauthorized: If the sender is not the current admin.
- MarketNotActive: If the market is not active.