mdtanvir

Untitled

Dec 21st, 2022
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.15 KB | Source Code | 0 0
  1. // SPDX-License-Identifier: MIT
  2. pragma solidity ^0.8.7;
  3.  
  4. import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
  5. import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
  6. // AutomationCompatible.sol imports the functions from both ./AutomationBase.sol and
  7. // ./interfaces/AutomationCompatibleInterface.sol
  8. import "@chainlink/contracts/src/v0.8/AutomationCompatible.sol";
  9.  
  10. error Raffle__NotEnoughETHEntered();
  11. error Raffle__TransferFailed();
  12. error Raffle__NotOpen();
  13. error Raffle__UpkeepNotNeeded(uint256 currentBalance, uint256 numPlayers, uint256 raffleState);
  14.  
  15. /** @title a sample raffle contract
  16. * @author tanvircr7
  17. * @notice this contract creates an untamperable decentralized smart contract
  18. * @dev this implements Chainlink VRF v2 and Chainlink Keepers
  19. */
  20.  
  21. contract Raffle is VRFConsumerBaseV2, AutomationCompatibleInterface {
  22. /* Type Declractions */
  23. enum RaffleState {
  24. OPEN,
  25. CALCULATING
  26. } // uint256 0 = OPEN, 1 = CALCULATING
  27.  
  28. /* State Variables */
  29. uint256 private immutable i_entranceFee;
  30. address payable[] private s_players;
  31. VRFCoordinatorV2Interface private immutable i_vrfCoordinator;
  32. bytes32 private immutable i_gasLane;
  33. uint64 private immutable i_subscriptionId;
  34. uint16 private constant REQUEST_CONFIRMATIONS = 3;
  35. uint32 private immutable i_callbackGasLimit;
  36. uint32 private constant NUM_WORDS = 1;
  37.  
  38. // Lottery Variables
  39. address private s_recentWinner;
  40. RaffleState private s_raffleState;
  41. uint256 private s_lastTimeStamp;
  42. uint256 immutable i_interval;
  43.  
  44. /* Events */
  45. event RaffleEnter(address indexed player);
  46. event RequestedRaffleWinner(uint256 indexed requestId);
  47. event WinnerPicked(address indexed winner);
  48.  
  49. /* Functions */
  50.  
  51. constructor(
  52. address vrfCoordinator,
  53. uint256 entranceFee,
  54. bytes32 gasLane,
  55. uint64 subscriptionId,
  56. uint32 callbackGasLimit,
  57. uint256 interval
  58. ) VRFConsumerBaseV2(vrfCoordinator) {
  59. i_entranceFee = entranceFee;
  60. i_vrfCoordinator = VRFCoordinatorV2Interface(vrfCoordinator);
  61. i_gasLane = gasLane;
  62. i_subscriptionId = subscriptionId;
  63. i_callbackGasLimit = callbackGasLimit;
  64. s_raffleState = RaffleState.OPEN;
  65. s_lastTimeStamp = block.timestamp;
  66. i_interval = interval;
  67. // reset the players
  68. // s_players = new address payable[](0);
  69. }
  70.  
  71. function enterRaffle() public payable {
  72. // require (msg.value > i_entranceFee, "Not enough ETH!")
  73. if (msg.value < i_entranceFee) {
  74. revert Raffle__NotEnoughETHEntered();
  75. }
  76.  
  77. // you can't enter raffle when it isn't OPEN
  78. if (s_raffleState != RaffleState.OPEN) {
  79. revert Raffle__NotOpen();
  80. }
  81.  
  82. // payable is used for typecasting
  83. // recording all the players entering our raffle
  84. s_players.push(payable(msg.sender));
  85. emit RaffleEnter(msg.sender);
  86. }
  87.  
  88. /**
  89. * @dev this is the function that the chainlink keeper nodes call
  90. * they look for the upkeep to return true
  91. * the following should be true to return true:
  92. * 1. Time interval should have passed
  93. * 2. The lottery should have atleast 1 player, and have some ETH
  94. * 3. Our subscription is funded with LINK
  95. * 4. The lottery should be in "OPEN" state
  96. * this checkdata can even be a function
  97. */
  98.  
  99. function checkUpkeep(
  100. bytes calldata /* checkData */
  101. ) public view override returns (bool upkeepNeeded, bytes memory /* performData */) {
  102. bool isOpen = (RaffleState.OPEN == s_raffleState);
  103. bool timePassed = ((block.timestamp - s_lastTimeStamp) > i_interval);
  104. bool hasPlayers = (s_players.length > 0);
  105. bool hasBalance = address(this).balance > 0;
  106. upkeepNeeded = (isOpen && timePassed && hasPlayers && hasBalance);
  107. }
  108.  
  109. function performUpkeep(bytes calldata /* performData */) external override {
  110. (bool upkeepNeeded, ) = checkUpkeep(new bytes(0));
  111. if (!upkeepNeeded) {
  112. revert Raffle__UpkeepNotNeeded(
  113. address(this).balance,
  114. s_players.length,
  115. uint256(s_raffleState)
  116. );
  117. }
  118.  
  119. s_raffleState = RaffleState.CALCULATING;
  120.  
  121. //Q. shouldn't this be an override?
  122. //using the reqRandomWords directly and so The enclosing function can't be an override
  123. uint256 requestId = i_vrfCoordinator.requestRandomWords(
  124. i_gasLane, // gasLane
  125. i_subscriptionId,
  126. REQUEST_CONFIRMATIONS,
  127. i_callbackGasLimit,
  128. NUM_WORDS
  129. );
  130.  
  131. emit RequestedRaffleWinner(requestId);
  132. }
  133.  
  134. function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override {
  135. uint256 indexOfWinner = randomWords[0] % s_players.length;
  136. address payable recentWinner = s_players[indexOfWinner];
  137. s_recentWinner = recentWinner;
  138. //Open Raffle again
  139. s_raffleState = RaffleState.OPEN;
  140. // reset the array
  141. s_players = new address payable[](0);
  142. // reset the time
  143. s_lastTimeStamp = block.timestamp;
  144. // send them the money
  145. // we take all the money in this contract. and pass it no data
  146. (bool success, ) = recentWinner.call{value: address(this).balance}("");
  147.  
  148. if (!success) {
  149. revert Raffle__TransferFailed();
  150. }
  151. // emit recent winner to keep track
  152. emit WinnerPicked(recentWinner);
  153. }
  154.  
  155. /* View / Pure Functions */
  156. function getEntranceFee() public view returns (uint256) {
  157. return i_entranceFee;
  158. }
  159.  
  160. function getPlayer(uint256 index) public view returns (address) {
  161. return s_players[index];
  162. }
  163.  
  164. function getRecentWinner() public view returns (address) {
  165. return s_recentWinner;
  166. }
  167.  
  168. function getRaffleState() public view returns (RaffleState) {
  169. return s_raffleState;
  170. }
  171.  
  172. function getNumWords() public view returns (uint256) {
  173. return NUM_WORDS;
  174. }
  175. }
  176.  
Advertisement
Add Comment
Please, Sign In to add comment