Lottery Features
Player
purchase
function purchase(Ticket[] calldata tickets, address beneficiary) external;
Anyone can execute this method
While a lottery is running (isGameActive() == true)
, users may purchase new tickets using the purchase
function.
The purchase
function uses the prizeToken
ERC-20 token for payment, so users must give allowance to the contract to move the ticket prize amount.
Alternatively, users can use the LooteryETHAdapter
contract to pay with the native token if the lottery uses the native wrapped token.
Parameters
Argument | Description | Example input |
---|---|---|
value | ticketPrize * number of tickets (ETH adapter only) | 99000000000000000000 (99 DEGEN per ticket) |
looteryAddress | The address of the lottery (ETH adapter only) | 0x8958e46ddc4c7f16a0379f1e4d007f958f607e3d |
tickets | A list of tickets to purchase. Array of tuples with [beneficiaries, pick] | [ [ "0xe737e1fd3bf4593b340fef896d77398faa2e4487", [ 5, 6, 11, 13, 14 ] ] ] |
Additional notes:
LooteryETHAdapter
: The ETH adapter contract enables you to use the native currency of the chain you have deployed to, such as ETH on Ethereum, instead of needing to use ERC-20 tokens exclusively.- Tickets: the
whomst
argument here refers to the receiver/beneficiary of the ticket, andpick
represents the sorted array of numbers that the user picks for the lottery ticket. The count of numbers needs to be exactlypickLength
, with the maximum possible number set atmaxBallValue
, no repeat numbers, and sorted from lowest to highest.
claimWinnings
function claimWinnings(uint256 tokenId) public;
Anyone can execute this method, also for foreign tickets (= claim for a user)
Users may claim a prize for a ticket at any point. The win condition is either:
- Having a winning ticket (all numbers match the winning numbers from the last draw); or
- If the last round was “apocalypse mode”, and there was no winner, then any ticket holder from any round may claim an equal share of the prize pool (a "consolation prize") by burning their ticket NFT (see the
kill
function for more information about apocalypse mode).
The user calls claimWinnings
with a token ID which either sends the ERC-20 prize, or reverts if the ticket didn’t win. The ticket NFT is burnt if the consolation prize is claimed after apocalypse mode.
To determine if a ticket is a winning ticket, the user computes the ticket pick ID and then compares it to the last draw's winningPickId
.
Owner/operator
kill
function kill() public;
Only owner can execute this method
The owner can decide to kill the lottery at any point by calling the kill
function, initiating what we like to call “apocalypse mode”.
This means that the current round will be the final round regardless of whether there are winners or not. In the case that there is no winner, all players will be able to claim an equal share of the jackpot via claimWinnings
.
Withdraw operations: withdrawAccruedFees
, rescueETH
, rescueTokens
Only owner can execute these methods
The owner can rescue native tokens and ERC-20s using rescueETH
and rescueTokens
. It is not possible to rescue the token set as the prizeToken
!
The owner can also withdraw accrued fees (accruedCommunityFees
) using withdrawAccruedFees
.
Permissionless
seedJackpot
function seedJackpot(uint256 value) public;
Anyone can execute this method
The jackpot can be topped up by anyone, provided that the lottery has not activated a cooldown period.
Alternatively, the jackpot can be seeded with native tokens via LooteryETHAdapter#seedJackpot
.
draw
function draw() public;
Anyone can execute this method
When the current round is over, anyone can execute the draw method to draw the random numbers and finalise the round.
Note that the round ends when gameData[currentGame.id].startedAt + gamePeriod < block.timestamp
.
The contract must have native currency available to pay for the VRF request. If it doesn’t have enough funds, or the round is not over yet, this transaction reverts.
Helpful view functions
Determine if a round had a winner
- Get the winning pick ID of the round
$winningId = gameData[$gameId].winningPickId
- Get the token ID of the first winning ticket
tokenByPickIdentity($gameId, $winningId, 0)
- If
tokenByPickIdentity
is zero there is no winner. Otherwise loop through all winning IDs by incrementing the last parameter and find all winning token IDs - Call
ownerOf
with winning token IDs to determine the winner addresses, or claim for them withclaimWinnings
ERC721 Interface
Every ticket is a regular ERC721 NFT and therefore can be transferred or sold on a marketplace.
Ownable Interface
The Lootery contract implements the standard Ownable
interface, so ownership can be transferred or renounced.
Lottery indexer
We provide a GraphQL API to query lottery data.
Get list of tickets that a user purchased in a given round
query tickets($gameId: String!, $whomst: String!) {
tickets(where: { whomstId: $whomst, gameId: $gameId }) {
items {
tokenId
picks
}
}
}
where:
$whomst
is the user address (in checksummed format, e.g.0x8958e46Ddc4C7f16A0379F1e4D007f958F607E3d
)$gameId
is ID of the game, in the format${lotteryId}-${roundId}
(e.g."0x8958e46Ddc4C7f16A0379F1e4D007f958F607E3d-0"
)
Get winning numbers of a round
query winningPicks($lotteryId: String!, $gameId: String!) {
lootery(id: $lotteryId) {
id
games(where: { id: $gameId }) {
items {
id
gameId
winningPicks
}
}
}
}
where:
$lotteryId
= Lottery address (in checksummed format, eg0x8958e46Ddc4C7f16A0379F1e4D007f958F607E3d
)$gameId
= ID of the game, in the format${lotteryId}-${roundId}
(e.g."0x8958e46Ddc4C7f16A0379F1e4D007f958F607E3d-0"
)winningPicks
is the list of winning numbers.