Smart Contracts
Architecture
LastHash uses a modular smart contract architecture deployed on Base (Ethereum L2). The system consists of four core contracts that separate concerns for security and upgradeability.
┌──────────────────┐
│ LastHashFactory │
│ (Game Creator) │
└────────┬─────────┘
│ creates
┌────────▼─────────┐
│ LastHashCore │
│ (Game Instance) │
└────────┬─────────┘
│ uses
┌──────────────┼──────────────┐
│ │ │
┌────────▼───────┐ ┌───▼────────┐ ┌──▼──────────────┐
│ LastHashVault │ │ Pyth Oracle│ │ LastHashReferral │
│ (Fund Custody) │ │ (Pricing) │ │ (Commissions) │
└────────────────┘ └────────────┘ └──────────────────┘
Contract Overview
LastHashFactory
The factory contract is responsible for creating new game instances and managing global configuration.
Key Functions:
createGameManually()— Creates a new game with current default configurationperformUpkeep()— Chainlink Automation-compatible function for auto game creationsetDefaultGameConfig()— Updates game parameters for future gamesgetActiveGames()— Returns list of currently active game addresses
Features:
- Automatic game creation via Chainlink Automation at configurable intervals
- Stores past game summaries in a circular buffer (last 20 games)
- Enforces configuration limits (fee caps, duration bounds, player limits)
LastHashCore
Each game is an independent LastHashCore contract instance. It handles the full game lifecycle from registration through reward claims.
Key Functions:
registerPlayer()— Join a game with a wager and initial predictionsubmitPrediction()— Change prediction during intermissionsrevivePlayer()— Pay revival fee to re-enter after eliminationclaimRewards()— Withdraw winnings after game completionadvancePhase()— Move game to next phase (callable by operator)
State Management:
- Tracks all player states (deposit, prediction, elimination status, revival status)
- Records round prices from Pyth oracle
- Manages vote counts and deposit totals per side per round
LastHashVault
The vault contract holds all USDC funds and handles secure distribution.
Key Functions:
depositFromGame()— Receives player deposits during registrationprocessWinnerPayout()— Distributes rewards with fee splittingprocessEmergencyWithdrawal()— Returns funds in emergency scenarios
Security Features:
- Role-based access control (only whitelisted game contracts can interact)
- Automatic fee splitting (platform fee, referral commission)
- 360-day unclaimed fund sweep to prevent permanent fund locks
- Emergency withdrawal with 7-day auto-unlock safety net
LastHashReferral
Manages referral tracking and commission distribution.
Key Functions:
trackReferral()— Records referral relationship when player registerscreditReferralReward()— Credits commission when referred player winsclaimReferralRewards()— Allows referrers to withdraw accumulated commissions
Features:
- Prevents duplicate tracking (same referrer-player-game combination)
- Accumulates rewards across all games
- No minimum claim amount
Oracle Integration
LastHash uses Pyth Network for real-time ETH/USD price data.
Why Pyth?
- Sub-second updates — prices are updated in real-time by a network of institutional publishers
- High accuracy — includes confidence intervals to filter noisy data
- Base native — deployed on Base with low-cost price updates
- Tamper resistant — decentralized publisher network prevents manipulation
Price Validation
The contract applies multiple validation checks on oracle prices:
| Check | Requirement | Default |
|---|---|---|
| Price freshness | Published within last N seconds | 120 seconds (2 min) |
| Price positivity | Price must be > 0 | Always enforced |
| Confidence interval | Within acceptable range | Validated |
| Price deviation | Change from last price within bounds | 10% max |
If the oracle fails to provide valid pricing during a round, the game detects the failure and allows affected players to claim a full refund via claimOracleFailureRefund().
Security Model
Access Control
OPERATOR_ROLE → Advance phases, manage game state
TREASURY_ROLE → Receive fees, sweep unclaimed funds
FACTORY_ROLE → Create games, whitelist new game contracts
EMERGENCY_ROLE → Enable emergency withdrawals (timelocked)
Fund Safety
- No admin can access player funds during an active game
- Emergency withdrawal is auto-enabled after 7 days of inactivity
- Unclaimed funds are swept to treasury after 360 days (prevents permanent lock)
- Pull-based claims — players withdraw their own funds (no batch processing risk)
Elimination Integrity
- Eliminations are determined solely by Pyth oracle prices — no human input
- Pull-based pattern means gas costs don't scale with player count
- Each player's status is verified against immutable round data
Configuration Limits
The factory contract enforces hard limits on all configurable parameters:
| Parameter | Minimum | Maximum |
|---|---|---|
| Lobby Duration | 5 minutes | 60 minutes |
| Round Duration | 1 minute | 30 minutes |
| Min Participants | 2 | — |
| Max Participants | — | 500 |
| Platform Fee | — | 20% |
| Referral Commission | — | 5% |
| Revival Fee (R1/R2) | — | 35% |
| Price Deviation | — | 20% |
| Price Age | 60 seconds | 300 seconds |
| Max Overtime Rounds | — | 5 |
These limits are enforced at the contract level and cannot be bypassed.
Deployed Addresses
Contract addresses will be published here after mainnet deployment. All contracts are verified on BaseScan for public code review.
| Contract | Address | Verified |
|---|---|---|
| LastHashFactory | TBD | - |
| LastHashVault | TBD | - |
| LastHashReferral | TBD | - |
| USDC (Base) | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 | Yes |