🧩 Pet Racing Hackathon Builder’s Guide

Build on Gigaverse’s onchain pet racing protocol deployed on Abstract.


1. Quick Start

Item Reference
Contract source contracts-zk/src/gigaverse/petRacing/PetRacingSystem.sol
Interface contracts-zk/src/gigaverse/petRacing/IPetRacingSystem.sol
Shared types / events / errors contracts-zk/src/gigaverse/petRacing/RaceTypes.sol
Abstract mainnet (chainId 2741) https://gigaverse.io/api/contracts
REST base https://gigaverse.io/api/racing/…
Discord #pet-racing-builders
Docs https://docs.gigaverse.io/gigling-racing/gigling-racing-overview

2. Architecture

Onchain (PetRacingSystem) only stores: roster, escrow, final ranking, per-pet payouts, fee accounting. Items, scoring, lap-by-lap simulation, ticks, factions, and weather are all offchain — the resolver (a wallet holding RACE_RESOLVER_ROLE) is the source of truth for ranking and finish times.

createRace (host) ──► joinRace × N (players)  ──► (auto on full) RESOLVING ──► resolveRace (resolver) ──► claimReward  (each winnner)

Value Phase Meaning
0 IDLE Not created
1 OPEN Accepting joins
2 RESOLVING Field full, waiting for resolver
3 RESOLVED Final ranking submitted, payouts claimable
4 CANCELLED Refunds claimable

OPEN → RESOLVING is automatic when the field fills. RESOLVING → RESOLVED requires resolveRace. OPEN races can be expired permissionlessly after openExpirySecs; stuck RESOLVING races require rescueRace (MANAGER_ROLE). Multiple races run concurrently — there is no global queue.


4. Key Data Structures

struct Race {
    RacePhase phase;
    uint256 raceStart;     // timestamp the race entered OPEN
    uint256 raceFinish;    // timestamp it left OPEN (filled, cancelled, or expired)
    uint256 entryFee;      // wei per joiner (excludes protocol-fee surcharge)
    uint256 pool;          // current escrowed prize pool
    uint256 fieldSize;     // pets needed to fill
    uint256 petCount;      // pets joined so far
    uint256 trackLength;   // meters (multiple of 100); 0 = pick offchain
    address creator;
    bool    isPrivate;     // true if a joinHook is configured
}

struct PayoutPreview {
    uint256 currentEntries; uint256 fieldSize;
    uint256 currentGrossPool;   uint256 currentNetPrizePool;
    uint256 projectedGrossPool; uint256 projectedNetPrizePool;
    uint256 currentProtocolFee;   uint256 currentJackpotCut;   uint256 currentCreatorFee;
    uint256 projectedProtocolFee; uint256 projectedJackpotCut; uint256 projectedCreatorFee;
    uint256[] currentPayouts;     // wei per finishing rank, at current entries
    uint256[] projectedPayouts;   // wei per finishing rank, projected to full field
}

Per-pet payout (getPetPayout(raceId, petId)):

amount         = raceAmount + jackpotAmount   // total claimable in wei
claimed        = bool
raceAmount     = wei from payout distribution OR refund (CANCELLED)
jackpotAmount  = wei from a jackpot win (only the 1st-place pet, if it rolled)

5. Smart Contract API

5.1 Host — createRace