eigerco / nebula

A soroban contract library
https://nebula.eiger.co
Apache License 2.0
7 stars 2 forks source link

Lottery contract discussion #61

Closed mariopil closed 1 year ago

mariopil commented 1 year ago

The Lottery contract would implement a classic lottery in the form of, for example, "5 out of 50." Each player selects a certain number of numbers (let's say 5 out of 50), and the contract randomly draws them. Players who correctly select all the numbers win the largest prize. There would be thresholds defined with different prizes for different amount of correctly selected numbers, so that players who select for instance 3 or 4 numbers correctly also win something. In cases where some tokens are left in the pool, perhaps because no numbers were selected correctly or no one wins the full prize, the allocated tokens are carried over to the next lottery.

Contract Requirements:

  1. The init method would require additional arguments compared to the Raffle contract:

    • number_of_elements: Specifies how many numbers players need to select.
    • max_range: Sets the maximum number that can be selected, effectively defining the lottery range limit.
    • thresholds: A map containing the percentage of prizes to be awarded for correctly selecting fewer than number_of_elements numbers.
    • min_players_count: Specifies the minimum number of players required to conduct the lottery, ensuring there are enough tokens for the prizes.
  2. Each entered ticket must be checked to verify whether the selected numbers are correct, meaning they fall within the specified range, and the count equals number_of_elements.

  3. Prizes should be calculated appropriately, taking into account the total number of entered tickets and the balance of the contract from previous draws.

  4. In case there are multiple winners, the prize amount should be divided among them fairly.

  5. If there are no winners or any tokens left in the lottery, they should be saved for future draws.

  6. If the total amount of prizes is bigger than the pool, new prize thresholds need to be calculated (see example below).

  7. The contract needs to maintain a map of players with their selections for the draw.

  8. After each lottery, the map should be cleared, and when a new lottery is announced, players should be able to buy tickets, and a new map should be created.

  9. Each new lottery can have different rules

Example:

Suppose there's a lottery where players select 5 numbers out of 50, and the minimum number of players required to enter the lottery is 10. The ticket price is 100 tokens. Prize thresholds are defined as follows (taking into account 10 players entered the lottery which gives us total amount of 1000 tokens in the pool):

Example cases

  1. All players correctly select 3 numbers, each of them will receive a 100-token payout, equal to the ticket price.

  2. If there is one player who correctly selects all 5 numbers, 2 players who got 4 numbers, and 3 players who got 3 numbers, the prizes are paid out as follows:

    • The prize for correctly selecting all 5 numbers is paid equals 30% of the pool, which is 300 tokens.
    • The next 2 players who got 4 receive 15% each, which is 150 tokens each, 300 tokens in total.
    • The next 3 players who got 3 receive 10% each, which is 100 tokens each, 300 tokens in total.
    • There are now 100 tokens left in the pool, which are carried over to the next drawing.
  3. If a total number of prizes is bigger than the pool, new thresholds need to be calculated. Let say there are 5 players who got 5 and 4 players who got 4, leaving 1 player without any prize. In such a case the thresholds would be calculated as follows:

    5 x 30% = 150%
    4 x 15% = 60%
    --------------
    total: 210%

New pool spread out is calculated using proportion:

  for 5: 150*100/210 = 71%
  for 4: 60*100/210 = 29%

The same algorithm should be valid for all such cases.

geofmureithi commented 1 year ago

This looks great, looking forward to seeing it come to life.

eloylp commented 1 year ago

Great idea, and very well explained !