-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSimpleLottery.sol
86 lines (71 loc) · 3.3 KB
/
SimpleLottery.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import "@openzeppelin/contracts/access/Ownable.sol";
// This is a simple lottery contract running a single round. The winner is selected at random, and
// the winner must claim their winnings
//
// NOTE: This is for demonstration purposes only and should not be used in production
//
contract SimpleLottery is Ownable {
// Price of a one lottery ticket
uint256 public ticketPrice;
// Blocks between rounds during which value can accumulate
uint256 public endBlock;
// Address array of purchasers
address[] public purchasers;
// The address of the winning ticket holder
address public winner;
// Mapping of purchasers to the number of tickets they have purchased
mapping(address => uint64) public ticketsPurchased;
// Event to be emitted when a round is completed and a winner is selected
event RoundComplete(address indexed winner, uint256 amount);
constructor() Ownable(msg.sender) {
ticketPrice = 1 ether;
// Delay the end of this lottery by 100 blocks
endBlock = block.number + 100;
}
// Function to purchase tickets
function purchaseTickets(uint64 numTickets) public payable {
require(isReadyToResolve() == false, "This lottery is over.");
require(numTickets > 0, "You must purchase at least one ticket.");
require(msg.value >= numTickets * ticketPrice, "Insufficient funds sent.");
// Increment the number of tickets purchased by the caller
ticketsPurchased[msg.sender] += numTickets;
// Push the caller's address for each ticket purchased, increasing their odds of winning
for (uint64 i = 0; i < numTickets; i++) {
purchasers.push(msg.sender);
}
}
// Function to end the round, pick a winner - callable only by the contract owner
function resolve(uint64 randomSeed) public onlyOwner returns (address, uint256) {
require(isReadyToResolve(), "Current round is not yet over.");
require(winner != address(0), "Winner has already been picked.");
if (purchasers.length == 0) {
emit RoundComplete(address(0), 0);
return (address(0), 0);
}
uint256 winnerIndex = randomFromRange(0, purchasers.length, randomSeed);
winner = purchasers[winnerIndex];
uint256 winningAmount = address(this).balance;
emit RoundComplete(winner, winningAmount);
return (winner, winningAmount);
}
// Function for winners to claim their winnings
function claimWinnings() public {
require(msg.sender == winner, "Caller is not the lottery winner");
(bool sent,) = msg.sender.call{value: address(this).balance}("");
require(sent, "Failed to send FLOW.");
}
// Returns whether the lottery has passed its end block
function isReadyToResolve() public view returns (bool) {
return block.number >= endBlock;
}
// Retrieves the number of tickets purchased
function getNumberOfTicketsPurchased() public view returns (uint256) {
return purchasers.length;
}
// Utility function to generate a pseudo-random number within a range
function randomFromRange(uint256 min, uint256 max, uint64 randomSeed) private pure returns (uint256) {
return ((randomSeed % (max - min)) + min);
}
}