Build on Gigaverse’s onchain pet racing protocol deployed on Abstract.
| 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 |
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.
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)