Learn how to create a no-loss lottery pool that leverages stacking yield.
A no-loss lottery contract offers a unique way for participants to stack their assets and potentially earn a larger reward without the risk of losing their initial deposit.
This contract ensures that participants can stack their assets in a yield-generating pool, receive an NFT ticket, and have a chance to win additional rewards while retaining their original investment.
In this guide, you will learn how to:
1Define constants and data variables
2Create and manage participants and tickets
3Implement the lottery functionality
4Handle the selection of winners
5Claim and distribute rewards
Note
This example uses the CityCoins protocol for the stacking yield mechanism, but leveraging a Stacking pool using Proof of Transfer (PoX4) can also be used.
First, define some constants and data variables to manage the state of your contract. Constants are used for fixed values, and data variables store the state that can change during the contract execution.
(define-constantOWNERtx-sender)
(define-constantERR_UNAUTHORIZED (erru101000))
(define-data-varlotteryPooluintu0)
(define-data-vartotalYielduintu0)
(define-data-varticketCounteruintu0)
The OWNER constant defines the contract owner with administrative privileges, while ERR_UNAUTHORIZED handles unauthorized access attempts.
Key data variables include lotteryPool for tracking stacked assets, totalYield for accumulated earnings, and ticketCounter for managing issued tickets.
The roll-the-dice function enables participants to join the lottery by depositing assets, specifying the city (cityName), the deposit amount (amount), and the lock period (lockPeriod).
This function is crucial for managing lottery entries and ensuring assets are properly locked for the specified duration.
When a participant calls this function, the following steps occur:
1Generate ticket and determine lock period: A new ticket ID is generated, and the lock period is set (defaulting to 1 if not specified).
2Transfer assets and mint NFT ticket: The specified amount of assets is transferred from the participant to the contract, and an NFT representing the lottery ticket is minted and assigned to the participant.
3Update participant and ticket data: The participant's information, including ticket ID, amount, cycle, and expiration, is stored, and the ticket's ownership information is updated.
4Update lottery pool and return ticket ID: The total amount in the lottery pool is updated, the ticket counter is incremented, and the function returns the newly generated ticket ID to the participant.
This streamlined process ensures that each participant's entry is properly recorded and their assets are securely managed within the lottery system.
The select-winner function randomly selects a winner using a number from the VRF contract (get-save-rnd) and updates their status with unwrap!. This ensures a fair and transparent winner selection process.
When this function is called, the following steps occur:
1Fetch random number: A random number is obtained from the VRF contract by calling get-save-rnd with the previous block height.
2Determine winning ticket: The winning ticket ID is calculated by taking the modulus of the random number with the total number of tickets (ticketCounter).
3Retrieve winner information: The winner's ticket and participant information are retrieved using the calculated ticket ID.
4Update winner status: The participant's status is updated to indicate they are a winner by setting isWinner to true in the Participants map.
This process ensures that the winner is selected fairly and their status is accurately updated in the system.
The claim-rewards function enables participants to claim their staking rewards, while the distribute-rewards function calls select-winner to randomly select and reward winners, ensuring a fair distribution process.
When the claim-rewards function is called, the following steps occur:
1Retrieve city ID and balance: The city ID is retrieved using the get-city-id function, and the balance for the specified cycle is obtained from the treasury contract.
2Send stacking rewards: Depending on the city (mia or nyc), the appropriate stacking reward function is called to send the rewards for the specified cycle.
3Claim stacking reward: The contract claims the stacking reward for the specified city and cycle.
When the distribute-rewards function is called, it performs the following step:
1Select winner: The select-winner function is called to randomly select a winner from the participants and update their status.
This process ensures that participants can claim their rewards and that winners are selected and rewarded fairly.