Skip to content

A decentralized horse racing game built on Solana where players can create races, join with referral codes, and compete for prizes using native GOR tokens.

Notifications You must be signed in to change notification settings

codewithmide/gor-race

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

7 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿ‡ GOR Race - Solana Horse Racing Game

A decentralized horse racing betting game built on Solana where players can create races, join with referral codes, and compete for prizes using native GOR tokens.

๐ŸŽฏ Overview

GOR Race is a blockchain-based horse racing simulation where:

  • Anyone can create races with configurable wait times
  • Players join races using unique referral codes
  • Races have a two-phase system: joining period + 60-second race simulation
  • Winners are determined randomly and can claim their prizes
  • Platform takes a 5% fee from the total pool
  • Players can create profiles with usernames and track their statistics
  • Comprehensive leaderboard system ranks players by various metrics

๐Ÿ—๏ธ System Architecture

Race Lifecycle

  1. Profile Creation: Players create profiles with usernames for leaderboard tracking
  2. Race Creation: Race creator sets wait time (30-180 seconds) and receives a referral code
  3. Joining: Players use referral codes to join races and select horses (1-10)
  4. Execution Phase 1: After wait time expires, race simulation begins (60 seconds)
  5. Execution Phase 2: Race completes, winners are determined
  6. Prize Claiming: Winners can claim their share of the prize pool
  7. Stats Update: Players update their statistics for leaderboard tracking

Race States

  • Pending: Waiting for players to join
  • Racing: 60-second race simulation in progress
  • Completed: Race finished, prizes available
  • Cancelled: Not enough players joined (minimum 1 player required)

๐Ÿš€ Quick Start

Prerequisites

  • Node.js and npm installed
  • Solana CLI configured
  • Anchor framework installed
  • Wallet with GOR tokens on the GOR network

Installation

git clone https://github.com/codewithmide/gor-race
cd gor-race
npm install

Environment Setup .env

# Set your Solana cluster
export ANCHOR_PROVIDER_URL="https://rpc.gorbagana.wtf"
export ANCHOR_WALLET="~/.config/solana/id.json"

Build and Deploy

# Build the program
npm run build

# Deploy to GOR network
npm run deploy

# Initialize the platform (one-time setup)
npm run initialize

๐ŸŽฎ Commands Reference

๐Ÿ‘ค Player Profile Management

Create Profile

Create a player profile with a username for leaderboard tracking.

# Create profile with username
npm run create-profile HorseRacer123
npm run create-profile CryptoJockey
npm run create-profile SpeedDemon

Requirements:

  • Username must be unique per wallet
  • Max 32 characters
  • Only letters, numbers, underscore (_), dash (-), and dot (.) allowed
  • Cannot be empty

Output:

  • Profile creation confirmation
  • Profile details display
  • Next steps guidance

View Profile

View your own profile or another player's profile.

# View your own profile
npm run profile

# View another player's profile by wallet address
npm run profile <PLAYER_WALLET_ADDRESS>

Output:

  • Username and basic info
  • Race statistics (races, wins, podiums, earnings)
  • Performance metrics (win rate, podium rate)
  • Achievements and rankings
  • Comparison with other players

๐Ÿ† Leaderboard

View the leaderboard with various sorting options.

# Default leaderboard (sorted by score, top 10)
npm run leaderboard

# Sort by different metrics
npm run leaderboard wins       # Sort by total wins
npm run leaderboard races      # Sort by total races
npm run leaderboard earnings   # Sort by total earnings
npm run leaderboard winrate    # Sort by win percentage
npm run leaderboard podiums    # Sort by podium finishes

# Specify number of players to show
npm run leaderboard score 20   # Top 20 by score
npm run leaderboard wins 5     # Top 5 by wins

Sorting Options:

  • score (default): Weighted ranking considering wins, podiums, and consistency
  • wins: Total number of 1st place finishes
  • races: Total number of races participated
  • earnings: Total GOR earned from prizes
  • winrate: Win percentage (wins/races)
  • podiums: Total podium finishes (1st, 2nd, 3rd)

Output:

  • Ranked list of players with statistics
  • Performance metrics for each player
  • Total player counts and activity stats

๐Ÿ“Š Update Statistics

Update your player statistics after completing a race.

# Update stats using referral code
npm run update-stats XYVSYS00

# Update stats using race ID
npm run update-stats 1751510633

Requirements:

  • Must have participated in the race
  • Race must be completed
  • Player profile must exist

Output:

  • Race results display
  • Statistics update confirmation
  • Updated player statistics

๐Ÿ Create Race

Create a new horse race with configurable wait time.

# Create race with default wait time (60 seconds)
npm run create-race

# Create race with custom wait time (30-180 seconds)
npm run create-race 90
npm run create-race 120
npm run create-race 180

Output:

  • Race ID and PDAs
  • Unique 8-character referral code (e.g., XYVSYS00)
  • Race details (horses, timing, max players)

Parameters:

  • wait_time (optional): 30-180 seconds, defaults to 60

๐ŸŽ Join Race

Join an existing race using its referral code.

# Join race with referral code, select horse 1-10
npm run join-race XYVSYS00 3
npm run join-race R3ZSYS00 7

# Default to horse 1 if not specified
npm run join-race XYVSYS00

Requirements:

  • Valid referral code (8 characters)
  • Horse number 1-10
  • 0.1 GOR entry fee
  • Race must be in Pending status
  • Race must not be full (max 100 players)

Output:

  • Confirmation of race joining
  • Selected horse information
  • Updated race statistics

๐Ÿƒ Execute Race

Execute race transitions - from joining to racing, and from racing to completed.

# Execute using referral code
npm run execute-race XYVSYS00

# Execute using race ID
npm run execute-race 1751510633

Two-Phase Execution:

Phase 1: Start Race Simulation

  • Triggered when wait time expires + minimum 1 player joined
  • Changes status from Pending โ†’ Racing
  • Begins 60-second race simulation

Phase 2: Complete Race

  • Triggered after 60-second simulation completes
  • Changes status from Racing โ†’ Completed
  • Determines winners and distributes prizes

Output:

  • Race status updates
  • Timing information
  • Winner announcements (in Phase 2)

๐Ÿ† Claim Prize

Claim winnings after race completion.

# Claim using referral code
npm run claim-prize XYVSYS00

# Claim using race ID
npm run claim-prize 1751510633

Requirements:

  • Race must be completed
  • Player must have participated in the race
  • Player's horse must have won (1st, 2nd, or 3rd place)
  • Prize not already claimed

Prize Distribution:

  • ๐Ÿฅ‡ 1st Place: 50% of total pool
  • ๐Ÿฅˆ 2nd Place: 30% of total pool
  • ๐Ÿฅ‰ 3rd Place: 15% of total pool
  • Platform Fee: 5% of total pool

Output for Winners:

  • Race results display
  • Prize amount
  • Transaction confirmation
  • Updated GOR balance

Output for Non-Winners:

  • Race results with all horses
  • Encouraging message
  • Tips for future races

๐Ÿ”ง Utility Commands

# Player Management
npm run create-profile <USERNAME>    # Create player profile
npm run profile [PLAYER_ADDRESS]     # View profile
npm run leaderboard [SORT] [LIMIT]   # View leaderboard
npm run update-stats <RACE_REF>      # Update race statistics

# Race Management  
npm run create-race [WAIT_TIME]      # Create new race
npm run join-race <CODE> [HORSE]     # Join race
npm run execute-race <RACE_REF>      # Execute race
npm run claim-prize <RACE_REF>       # Claim winnings

# Development
npm run build                        # Build program
npm run deploy                       # Deploy program
npm run initialize                   # Initialize platform (one-time)
npm run clean                        # Clean build artifacts
npm run test                         # Run tests
npm run lint                         # Lint code

๐Ÿ—๏ธ Architecture

Folder Structure

gor-race/
โ”œโ”€โ”€ programs/
โ”‚   โ””โ”€โ”€ gor-race/
โ”‚       โ”œโ”€โ”€ src/
โ”‚       โ”‚   โ”œโ”€โ”€ lib.rs
โ”‚       โ”‚   โ”œโ”€โ”€ state/
โ”‚       โ”‚   โ”‚   โ”œโ”€โ”€ mod.rs
โ”‚       โ”‚   โ”‚   โ”œโ”€โ”€ race.rs
โ”‚       โ”‚   โ”‚   โ”œโ”€โ”€ player_entry.rs
โ”‚       โ”‚   โ”‚   โ””โ”€โ”€ platform_vault.rs
โ”‚       โ”‚   โ”œโ”€โ”€ instructions/
โ”‚       โ”‚   โ”‚   โ”œโ”€โ”€ mod.rs
โ”‚       โ”‚   โ”‚   โ”œโ”€โ”€ initialize.rs
โ”‚       โ”‚   โ”‚   โ”œโ”€โ”€ create_race.rs
โ”‚       โ”‚   โ”‚   โ”œโ”€โ”€ join_race.rs
โ”‚       โ”‚   โ”‚   โ”œโ”€โ”€ execute_race.rs
โ”‚       โ”‚   โ”‚   โ””โ”€โ”€ claim_prize.rs
โ”‚       โ”‚   โ”œโ”€โ”€ errors/
โ”‚       โ”‚   โ”‚   โ””โ”€โ”€ mod.rs
โ”‚       โ”‚   โ”œโ”€โ”€ constants/
โ”‚       โ”‚   โ”‚   โ””โ”€โ”€ mod.rs
โ”‚       โ”‚   โ””โ”€โ”€ utils/
โ”‚       โ”‚       โ”œโ”€โ”€ mod.rs
โ”‚       โ”‚       โ””โ”€โ”€ random.rs
โ”‚       โ”œโ”€โ”€ Cargo.toml
โ”‚       โ””โ”€โ”€ Xargo.toml
โ”œโ”€โ”€ tests/
โ”‚   โ””โ”€โ”€ gor-race.ts
โ”œโ”€โ”€ migrations/
โ”‚   โ””โ”€โ”€ deploy.ts
โ”œโ”€โ”€ Anchor.toml
โ”œโ”€โ”€ Cargo.toml
โ”œโ”€โ”€ package.json
โ”œโ”€โ”€ tsconfig.json
โ””โ”€โ”€ README.md

Program Accounts

  1. PlatformVault: Stores platform configuration and fee collection
  2. Race: Stores race state, participants, and results
  3. PlayerEntry: Individual player's race entry with stats tracking
  4. PlayerProfile: Player's username and statistics for leaderboard
  5. TokenVault: Holds race entry fees until distribution

Leaderboard Scoring System

The leaderboard uses a weighted scoring system that considers multiple factors:

Base Score Calculation:

  • ๐Ÿฅ‡ Wins: 10 points each
  • ๐Ÿ† Podium finishes: 3 points each
  • ๐ŸŽฏ Race participation: 1 point each
  • ๐Ÿ’ฐ Earnings: 1 point per GOR earned

Consistency Bonus: Players with 10+ races get additional multipliers based on win rate:

  • 30%+ win rate: 1.5x multiplier
  • 20%+ win rate: 1.3x multiplier
  • 10%+ win rate: 1.1x multiplier

This rewards both high performance and consistent participation.

๐Ÿ“ฆ Deployment

1. Update Anchor.toml

[features]
seeds = false
skip-lint = false

[programs.localnet]
gor_race = "YOUR_PROGRAM_ID"

[programs.testnet]
gor_race = "YOUR_PROGRAM_ID"

[registry]
url = "https://api.apr.dev"

[provider]
cluster = "https://rpc.gorbagana.wtf"
wallet = "~/.config/solana/gor-race.json"

[scripts]
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"

2. Deploy the program

# Set program keypair
anchor keys sync

# Deploy to Gorbagana testnet
anchor deploy --provider.cluster https://rpc.gorbagana.wtf

# Note the deployed program ID

3. Initialize platform vault

# Run initialization script
anchor run initialize

๐ŸŽฎ Usage

Initialize Platform (Admin only)

await program.methods
  .initialize(platformFeeBps)
  .accounts({
    platformVault: platformVaultPda,
    authority: authority.publicKey,
    systemProgram: SystemProgram.programId,
  })
  .signers([authority])
  .rpc();

Create a Race

await program.methods
  .createRace()
  .accounts({
    race: racePda,
    creator: creator.publicKey,
    systemProgram: SystemProgram.programId,
    clock: SYSVAR_CLOCK_PUBKEY,
  })
  .signers([creator])
  .rpc();

Join a Race

await program.methods
  .joinRace(horseNumber)
  .accounts({
    race: racePda,
    playerEntry: playerEntryPda,
    player: player.publicKey,
    playerTokenAccount: playerTokenAccount,
    raceTokenVault: raceTokenVault,
    tokenProgram: TOKEN_PROGRAM_ID,
    systemProgram: SystemProgram.programId,
  })
  .signers([player])
  .rpc();

Execute Race (Automatic after 60 seconds)

await program.methods
  .executeRace()
  .accounts({
    race: racePda,
    randomnessOracle: randomnessOracle,
    clock: SYSVAR_CLOCK_PUBKEY,
  })
  .rpc();

Claim Prize

await program.methods
  .claimPrize()
  .accounts({
    race: racePda,
    playerEntry: playerEntryPda,
    player: player.publicKey,
    playerTokenAccount: playerTokenAccount,
    raceTokenVault: raceTokenVault,
    platformVault: platformVaultPda,
    platformTokenAccount: platformTokenAccount,
    tokenProgram: TOKEN_PROGRAM_ID,
  })
  .signers([player])
  .rpc();

๐Ÿงช Testing

Run all tests

anchor test --provider.cluster https://rpc.gorbagana.wtf

Run specific test

anchor test --provider.cluster https://rpc.gorbagana.wtf -- --grep "should create race"

๐Ÿ” Security Considerations

  1. Randomness: Uses on-chain randomness combining slot hashes and timestamps
  2. Reentrancy Protection: State transitions prevent double claims
  3. Authority Checks: Only authority can modify platform settings
  4. Overflow Protection: Uses checked math operations
  5. Time-based Execution: Races auto-execute after timeout

๐Ÿ“Š Horse Names Pool

The program randomly selects 10 horses from this pool for each race:

  • Bonk, Samo, Orca, Raydium, Marinade
  • Serum, Mango, Drift, Jupiter, Phantom
  • Solend, Saber, Mercurial, Tulip, Francium
  • Port, Oxygen, Bonfida, Step, Grape
  • Sunny, Quarry, Aldrin, Cyclos, Lifinity
  • Hubble, Kamino, Marginfi, Cypher, Zeta

๐Ÿ› ๏ธ Troubleshooting

Common Issues

  1. Insufficient GOR tokens

    • Ensure you have enough GOR for transactions and rent
    • Request from Gorbagana faucet
  2. Program deployment fails

    • Check wallet balance
    • Verify RPC endpoint is correct
    • Ensure program size is within limits
  3. Transaction fails

    • Check account ownership
    • Verify PDA derivation
    • Ensure proper token accounts exist

๐Ÿค Contributing

  1. Fork the repository
  2. Create feature branch (git checkout -b feature/amazing-feature)
  3. Commit changes (git commit -m 'Add amazing feature')
  4. Push to branch (git push origin feature/amazing-feature)
  5. Open Pull Request

About

A decentralized horse racing game built on Solana where players can create races, join with referral codes, and compete for prizes using native GOR tokens.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published