-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLL420RollOGList.sol
114 lines (89 loc) · 3.11 KB
/
LL420RollOGList.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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.4;
import "@chainlink/contracts/src/v0.8/VRFConsumerBase.sol";
contract LL420RollOGList is VRFConsumerBase {
bytes32 internal keyHash;
uint256 internal fee;
uint256 internal randomNumber;
uint256 public totalFilled;
uint256 public totalRuns;
uint256 public spotLimit;
address public owner;
mapping(address => bool) public rollBook;
address[] public signedAddresses;
event RollWin(uint256 indexed index, address indexed user);
event AllSpotsFilled();
modifier onlyOwner() {
require(msg.sender == owner, "Only owner can call this function");
_;
}
constructor(
address _vrfCoordinator,
address _linkToken,
bytes32 _keyHash,
uint256 _fee,
uint256 _spotLimit
) VRFConsumerBase(_vrfCoordinator, _linkToken) {
keyHash = _keyHash;
fee = _fee;
spotLimit = _spotLimit;
owner = msg.sender;
}
function initialize(address[] calldata _lists) external onlyOwner {
for (uint256 i = 0; i < _lists.length; i++) {
signedAddresses.push(_lists[i]);
}
}
function rollAddress() internal returns (address) {
require(totalFilled < spotLimit, "All spots have been filled");
uint256 index = random() % signedAddresses.length;
address selectedAddress = signedAddresses[index];
if (rollBook[selectedAddress] == false) {
rollBook[selectedAddress] = true;
emit RollWin(totalFilled, selectedAddress);
totalFilled++;
return selectedAddress;
}
return address(0);
}
function batchRoll(uint256 _count) public {
require(_count < signedAddresses.length, "Exceeds the max limit");
require(randomNumber > 0, "Random number is not fulfilled");
for (uint256 i = 0; i < _count; i++) {
if (totalFilled >= spotLimit) {
emit AllSpotsFilled();
break;
}
rollAddress();
}
// Requires to use new random number on the next run
randomNumber = 0;
}
function singleRoll() external {
batchRoll(1);
}
function setSpotLimit(uint256 _newLimit) external onlyOwner {
require(_newLimit < signedAddresses.length, "Exceeds the max amount");
spotLimit = _newLimit;
}
function withdrawLink() external onlyOwner {
LINK.transfer(owner, LINK.balanceOf(address(this)));
}
/**
* Requests randomness
*/
function startRoll() external onlyOwner returns (bytes32 requestId) {
require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK - fill the contract with faucet");
return requestRandomness(keyHash, fee);
}
function random() internal returns (uint256) {
totalRuns += 1;
return uint256(keccak256(abi.encodePacked(randomNumber, totalRuns)));
}
/**
* Callback function used by VRF Coordinator
*/
function fulfillRandomness(bytes32, uint256 randomness) internal override {
randomNumber = randomness;
}
}