Lottery
Github Link: https://github.com/eatthepie/contracts-layer2/blob/main/src/Lottery.sol
This contract implements the core features of the Eat The Pie L2 lottery system.
Key Features
- 🎟️ Multiple ticket purchase support (up to 100 tickets per transaction)
- 🔢 Three difficulty levels affecting number ranges (Easy, Medium, Hard)
- 🎲 Secure random number generation using Witnet
- 💰 Three-tiered prize system (Gold, Silver, Bronze)
- 🏆 NFT minting for jackpot winners
- 🔄 Automatic difficulty adjustment based on win patterns
- 💸 Configurable token-based ticket pricing with scheduled changes
- 🛡️ Comprehensive security measures with Permit2 integration
- 💎 Prize pool management with excess handling
- 🔍 Detailed game information tracking and querying
- ⏮️ Emergency refund system
Contract Structure
Inheritance
Ownable: Provides basic authorization control functionsReentrancyGuard: Prevents reentrant calls to functions
Dependencies
IWitnetRandomness: Contract for secure randomness generationNFTPrize: Contract for minting prize NFTsIERC20: Interface for ERC20 token paymentsIPermit2: Interface for gasless approvals
Constants
BASIS_POINTS: 10000 (for percentage calculations)GOLD_PERCENTAGE: 6000 (60% of prize pool)SILVER_PLACE_PERCENTAGE: 2500 (25% of prize pool)BRONZE_PLACE_PERCENTAGE: 1400 (14% of prize pool)FEE_PERCENTAGE: 100 (1% of prize pool)FEE_MAX_IN_TOKENS: 1,000,000 tokens- Difficulty-based number ranges:
- Easy: 1-25 (main), 1-10 (etherball)
- Medium: 1-50 (main), 1-10 (etherball)
- Hard: 1-75 (main), 1-10 (etherball)
DRAW_MIN_TIME_PERIOD: 4 days
Key State Variables
currentGameNumber: Current game identifierticketPrice: Price of a single ticket in tokenslastDrawTime: Timestamp of the last drawconsecutiveJackpotGames: Counter for consecutive games with jackpot winnersconsecutiveNonJackpotGames: Counter for consecutive games without jackpot winners- Prize pool and game state mappings
- Winner tracking mappings for each prize tier
Core Functionality
Ticket Purchase
function buyTickets(
uint256[4][] calldata tickets,
IPermit2.PermitTransferFrom calldata permit,
bytes calldata signature
) external nonReentrant
- Allows purchase of up to 100 tickets in one transaction
- Uses Permit2 for gasless token approvals
- Each ticket requires 4 numbers (3 main numbers + 1 etherball)
- Automatically tracks tickets for all prize tiers
- Emits
TicketPurchasedandTicketsPurchasedevents
Drawing Process
- Draw Initiation
function initiateDraw() external payable nonReentrant
- Requires minimum time period (4 days)
- Initiates Witnet randomness request
- Starts the next game
- Emits
DrawInitiatedevent
- Random Value Setting
function setRandomAndWinningNumbers(uint256 gameNumber) external
- Fetches randomness from Witnet
- Sets winning numbers
- Emits
WinningNumbersSetevent
- Payout Calculation
function calculatePayouts(uint256 gameNumber) external nonReentrant
- Calculates prizes for each tier
- Handles excess fee management
- Transfers remaining prize pool to next game
- Emits payout information
Prize Claiming
function claimPrize(uint256 gameNumber) external nonReentrant
- Allows winners to claim their prizes
- Prevents double claiming
- Emits
PrizeClaimedevent
function mintWinningNFT(uint256 gameNumber) external nonReentrant
- Available only to gold tier winners
- Mints unique NFT through NFTPrize contract
- Emits
NFTMintedevent
Emergency Functions
function stopGameAndEnableRefunds(uint256 targetGame) external onlyOwner
- Allows owner to stop current or next game
- Enables refund mechanism for players
function refundTickets(uint256 gameNumber) external nonReentrant
- Allows players to refund tickets for stopped games
- Updates prize pool accordingly
- Emits
TicketsRefundedevent
Difficulty Management
function changeDifficulty() external
- Automatically adjusts difficulty based on win patterns
- Requires 3 consecutive games for adjustment
- Changes take effect on the next game
- Emits
DifficultyChangedevent
Administrative Functions
setTicketPrice: Schedules ticket price changessetFeeRecipient: Updates fee recipient address
Query Functions
function getCurrentGameInfo() external view returns (
uint256 gameNumber,
Difficulty difficulty,
uint256 prizePool,
uint256 drawTime,
uint256 timeUntilDraw
)
function getBasicGameInfo(uint256 startGameId, uint256 endGameId)
external view returns (GameBasicInfo[] memory)
function getDetailedGameInfo(uint256 gameId)
external view returns (GameDetailedInfo memory)
function getUserGameWinnings(uint256 gameNumber, address user)
external view returns (bool, bool, bool, uint256, bool)
Events
TicketPurchased: Individual ticket purchase detailsTicketsPurchased: Bulk ticket purchase informationDrawInitiated: Start of drawing processRandomSet: Initial random value setWinningNumbersSet: Final winning numbersDifficultyChanged: Difficulty level updatesTicketPriceChangeScheduled: Future price changesExcessPrizePoolTransferred: Prize pool managementGamePrizePayoutInfo: Prize distribution detailsFeeRecipientChanged: Fee recipient updatesPrizeClaimed: Winner prize claimsNFTMinted: NFT prize creationGameStopped: Emergency game stoppageGameRefundsEnabled: Refund availabilityTicketsRefunded: Ticket refund processing