-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLL420BudReveal.sol
146 lines (120 loc) · 4.5 KB
/
LL420BudReveal.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
//
// __ __ _____ ______
// /__/\/__/\ /_____/\ /_____/\
// \ \ \: \ \__\:::_:\ \\:::_ \ \
// \::\_\::\/_/\ _\:\| \:\ \ \ \
// \_::: __\/ /::_/__ \:\ \ \ \
// \::\ \ \:\____/\\:\_\ \ \
// \__\/ \_____\/ \_____\/
//
// 420.game Reveal Buds
//
// by LOOK LABS
//
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "./interfaces/ILL420BudStaking.sol";
import "./libraries/MerkleMultiProof.sol";
import "./libraries/ArraySort.sol";
/**
* @title LL420BudReveal
* @dev Store the revealed timestamp to the staking contract, and also set the THC of a bud to the staking contract,
* based on the verification of merkle proof
*
*/
contract LL420BudReveal is Ownable, Pausable, ReentrancyGuard {
uint16 public constant TOTAL_SUPPLY = 20000;
uint256 public revealPeriod = 7 days;
bytes32 public merkleRoot;
address public immutable stakingContractAddress;
mapping(uint256 => bool) public requested;
event RequestReveal(uint256 indexed _budId, address indexed _user, uint256 indexed _timestamp);
constructor(address _stakingAddress) {
require(_stakingAddress != address(0), "Zero address");
stakingContractAddress = _stakingAddress;
}
/* ==================== External METHODS ==================== */
/**
* @dev Reveal the buds
*
* @param _id Id of game key
* @param _ids Id array of buds
*/
function reveal(uint256 _id, uint256[] memory _ids) external nonReentrant whenNotPaused {
require(_ids.length <= TOTAL_SUPPLY, "Incorrect bud ids");
uint256 _revealPeriod = revealPeriod;
ILL420BudStaking BUD_STAKING = ILL420BudStaking(stakingContractAddress);
uint256[] memory budIds = BUD_STAKING.getGKBuds(_id, _msgSender());
/// Check if the ids belong to correct owner
/// Check if the id is in pending of reveal
for (uint256 i = 0; i < _ids.length; i++) {
require(!requested[_ids[i]], "Bud is already requested to reveal");
bool belong = false;
for (uint256 j = 0; j < budIds.length; j++) {
if (_ids[i] == budIds[j]) {
belong = true;
break;
}
}
require(belong, "Bud not belong to the sender");
}
/// Check if Buds can be revealed
(uint256[] memory periods, ) = BUD_STAKING.getBudInfo(_ids);
for (uint256 i = 0; i < periods.length; i++) {
require(periods[i] >= _revealPeriod, "Staked more than limit");
requested[_ids[i]] = true;
emit RequestReveal(_ids[i], _msgSender(), block.timestamp);
}
BUD_STAKING.setRevealTimestamps(block.timestamp, _msgSender());
}
/**
* @dev Set THCs of revealed buds
*
* @param _ids bud id array
* @param _thcs THC array
* @param _proofs Multi-merkle proofs
* @param _proofFlags Proof flags
*/
function setBudTHCs(
uint256[] calldata _ids,
uint256[] calldata _thcs,
bytes32[] calldata _proofs,
bool[] calldata _proofFlags
) external whenNotPaused nonReentrant {
require(_ids.length == _thcs.length && _ids.length > 0, "Unmatched thc count");
require(merkleRoot != 0, "Merklet root not set");
bytes32[] memory nodes = new bytes32[](_ids.length);
uint256 factor = 10**18;
for (uint256 i = 0; i < _ids.length; i++) {
nodes[i] = keccak256(abi.encodePacked(_ids[i] * factor, _thcs[i] * factor));
}
nodes = ArraySort.sort(nodes);
bool isValid = MerkleMultiProof.verifyMultiProof(merkleRoot, nodes, _proofs, _proofFlags);
require(isValid, "Invalid proof");
ILL420BudStaking(stakingContractAddress).setRevealedTHC(_ids, _thcs);
}
/* ==================== OWNER METHODS ==================== */
/**
*/
function pause() external onlyOwner {
_pause();
}
/**
*/
function unpause() external onlyOwner {
_unpause();
}
/**
* @dev this set the reveal lock period for test from owner side.
* @param _seconds reveal period in seconds
*/
function setRevealPeriod(uint256 _seconds) external onlyOwner {
revealPeriod = _seconds;
}
function setMerkleRoot(bytes32 _merkleRoot) external onlyOwner {
merkleRoot = _merkleRoot;
}
}