Updated 70 days ago

WinWin Lottery

The first on-chain lottery that pays out 100% to players

  • Crypto / Web3
  • GameFi
  • AVS
  • Eigenlayer
  • Movement

🎰 WinWin Lottery on Movement

Website | Repo

🎰 WinWin Lottery on Movement is the first and only on-chain lottery with 100% (or more) Return To Player (RTP). The pooled money in the lottery contract is put to work, until the lottery closes and the winner randomly selected. The lottery pool is earning yield according to pre-defined rules that all parties (players and organizers) have agreed upon. The winning player(s) receive 100% of the total pool, and the creator/organizer gets the yield that was earned. To safeguard the integrity of the lottery, an Eigenlayer AVS is ensuring that the yield is earned in a fair manner and the prize pool is never at risk.

⚙️ Built using Move, Eigenlayer, Movement, React and Typescript.

🧱 I build this project using Scaffold-ETH 2, modifying it to work with Move contracts instead of Solidity/EVM. I did this because the Move starter kit repos that I found did not have a pretty and clean frontend. I have created another project to build a Scaffold starter kit for move, check it out here.

Diagram

Untitled-2024-06-18-1427(3).png

Screenshots

Landing page Create and Overview
1.png 2.png
Lottery AVS Dashboard
3.png 4.png

Contracts

lottery.move

The Lottery contract is the core of our dApp. After each ticket sale, the proceeds are send to a yield earning protocol, where the money earns interest for the organizer. When the lottery closes, the money is withdrawn from the yield earning protocol. Then,one player is chosen randomly and he receives 100% of the original prize pool. Any profits made on the yield earning protocol are for the organizer.

create_lottery

Creates a new lottery in exchange for a small fee. Takes in a u64 value between 100 and 200, which is the RTP (Return To Player) percentage.

place_bet

Swap MOVE tokens for lottery tickets at a 1:1 rate. It takes the amount and lottery_id as inputs. The amount paid for the ticket is automatically transferred to the yield contract.

draw_winner

Closes the lottery and randomly determines the winner. Takes a lottery_id as input. After selecting the winner, the lottery pool money is withdrawn from the yield contract and transferred to the player.

yield.move

The Yield contract serves as an example for the happy flow scenario. It's a very simple (and lucrative) yield generating contract, where each deposit earns 10% upon withdrawal. After deploying the contract, it needs to be funded by the deployer so it can pay the yield. Obviously it's only for testing purposes, to showcase how the lottery works.

deposit

Lets any user deposit tokens into the contract. The address and amount is recorded in the contract.

withdraw

Withdraws all tokens for this user. The total amount is the sum of all deposits and the yield that was generated between the deposit and withdrawal. For testing purposes the yield is fixed at 10% upon withdrawal.

LotteryServiceManager.sol

This is the AVS contract for the WinWin Lottery. It is used to verify if the lottery contract/owner is using the pool money to earn yield according to the rules set when creating the contract. It verifies the used yield protocol (MOVE address) against a list of approved yield protocols.

createNewTask

Creates a new task on the contract which contains all lottery information, including an array of approved yield protocols (MOVE addresses). Emits a NewTaskCreated event.

respondToTask

Callable by operators registered to this AVS. Takes in a task and a signature containing the address of the yield protocol used by the lottery. The smart contract verifies if the address of the yield protocol exists in the array of approved yield protocol addresses.

Operator script

This is a script for the AVS operator. The script watches for new tasks submitted to the AVS. It uses the lotteryId specified in the task to query the Movement M1 blockchain, to see which yield protocol (address) was used by the specified lottery. The operator responds to the task, providing the address of the used yield protocol, after checking if this address exists in the array of allowed yield protocols.

Next steps

  • Include Aptos randomness module (code is there, but not working on Movement M1 devnet)
  • Display recent ticket sales (cannot read events, no indexer on Movement M1 devnet)
  • Automate the closing of the lottery
    • Based on time, amount or randomness? Have this as option for creator/owner

Links

Presentation

Vercel

Github repos

Contracts

Team