-
Notifications
You must be signed in to change notification settings - Fork 1
/
Counter.sol
148 lines (128 loc) · 4.38 KB
/
Counter.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import "./PriceConverter.sol";
import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
import "@chainlink/contracts/src/v0.8/AutomationCompatible.sol";
contract Counter is VRFConsumerBaseV2, AutomationCompatibleInterface {
// events
event requestedCounterNumber(uint256 indexed requestId);
//errors
error Counter__UpkeepNotNeeded(uint256 currentRandomValue, bool timePassed);
using PriceConverter for uint256;
int256 public count;
uint256 public constant MINIMUMUSD = 1 * 1e18;
address[] public funders;
address public immutable owner;
// random variables
VRFCoordinatorV2Interface private immutable i_vrfCoordinator;
uint256 private immutable i_entranceFee;
bytes32 private immutable i_gasLane; //keyHash
uint64 private immutable i_subscriptionId;
uint32 private immutable i_callbackGaslimit;
uint16 private constant REQUEST_CONFIRMATIONS = 3;
uint32 private constant NUM_WORDS = 1;
uint256 private s_randomNumber;
// upkeep variables
uint256 private s_lastTimeStamp;
uitn256 private immutable i_interval;
modifier firstNeed() {
require(securityCheck(msg.sender), "Please charge the contract.");
require(count != 0, "Please increase or decrease the count first.");
_;
}
constructor(
address vrfCoordinator,
uint256 entranceFee,
bytes32 gasLane,
uint64 subscriptionId,
uint32 callbackGaslimit,
uint256 interval
) VRFConsumerBaseV2(vrfCoordinatorV2) {
i_vrfCoordinator = VRFCoordinatorV2Interface(vrfCoordinator);
i_entranceFee = entranceFee;
i_gasLane = gasLane;
i_subscriptionId = subscriptionId;
i_callbackGaslimit = callbackGaslimit;
s_lastTimeStamp = block.timestamp;
i_interval = interval;
}
function fundMe() public payable {
require(
msg.value.getConversionRate() >= MINIMUMUSD,
"Didn't send enough ETH!"
);
funders.push(msg.sender);
}
// function to increament count by 1
function increaseByOne() public {
count += 1;
}
// function to decreament count by 1
function decreaseByOne() public {
count -= 1;
}
// function to increament count by given number
function increase(int256 _elevator) public firstNeed {
count += _elevator;
}
// function to decreament count by given number
function decrease(int256 _reducer) public firstNeed {
count -= _reducer;
}
// function to multiply count by given number
function multiply(int256 _modulus) public firstNeed {
count *= _modulus;
}
// function to divide count by given number
function divide(int256 _div) public firstNeed {
count /= _div;
}
function securityCheck(address name) internal view returns (bool) {
for (uint256 data = 0; data < funders.length; data++) {
if (funders[data] == name) {
return true;
}
}
return false;
}
function checkUpkeep(
bytes calldata /*checkData*/
)
public
override
returns (
bool upkeepNeeded,
bytes memory /* performData */
)
{
bool hasValue = (!s_randomNumber == 0);
bool timePassed = ((s_lastTimeStamp - block.timestamp) > i_interval);
upkeepNeeded = (hasValue && timePassed);
}
// only gets called when checkUpkeep() is true
function performUpkeep(
bytes calldata /* performData */
) external override {
(bool upkeepNeeded, ) = checkUpkeep("");
if (!upkeepNeeded) {
revert Counter__UpkeepNotNeeded(s_randomNumber, bool(timePassed));
}
uint256 requestId = i_vrfCoordinator.requestRandomWords(
i_gasLane, //gasLane
i_subscriptionId,
REQUEST_CONFIRMATIONS,
i_callbackGasLimit,
NUM_WORDS
);
emit RequestedCounterNumber(requestId);
}
function fulfillRandomWords(
uint256, /*requestId*/
uint256[] memory randomWords
) internal override {
uint256 s_randomNumber = randomWords[0];
// reset timestamp after pick the randomNumber
s_lastTimeStamp = block.timestamp;
}
}