-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathUtravelNFT.sol
154 lines (129 loc) · 5.45 KB
/
UtravelNFT.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
149
150
151
152
153
154
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/[email protected]/token/ERC721/ERC721.sol";
import "@openzeppelin/[email protected]/access/Ownable.sol";
import "@openzeppelin/[email protected]/utils/Counters.sol";
import "@openzeppelin/[email protected]/utils/cryptography/MerkleProof.sol";
contract UtravelNFT is ERC721, Ownable {
using Strings for uint256;
// Variables
bytes32 private root;
uint256 public constant MAX_TOKENS = 10000;
uint256 private constant TOKENS_RESERVED = 1;
uint256 public price = 0;
uint256 public MAX_MINT_PER_TX = 1000;
uint256 public MAX_MINT_PER_WALLET = 1000;
uint256 public totalSupply;
bool public isSaleActive = false;
bool public isWhitelistActive = false;
mapping(address => uint256) private mintedPerWallet;
string public baseUri;
string public baseExtension = ".json";
// Run on deploy
constructor() ERC721("UtravelNFT", "Utravel Collectibles") {
baseUri = "https://ipfs.io/ipfs/QmT7esGneeEPRX4etHtPKGg4N8ieVgPng1MELdaoLhkxCX?filename=1.jpg";
for (uint256 i = 1; i <= TOKENS_RESERVED; ++i) {
_safeMint(msg.sender, i);
}
totalSupply = TOKENS_RESERVED;
}
// Whitelist mint
function whitelistMint(bytes32[] memory proof, uint256 _amount) external payable {
require(isWhitelistActive, "Whitelist not active");
require(isValid(proof, keccak256(abi.encodePacked(msg.sender))), "Not whitelisted");
require(_amount <= MAX_MINT_PER_TX, "You can only mint a maximum of 5 per transaction.");
require(mintedPerWallet[msg.sender] + _amount <= MAX_MINT_PER_WALLET, "You can only mint 5 per wallet.");
uint256 curTotalSupply = totalSupply;
require(curTotalSupply + _amount <= MAX_TOKENS, "Exceeds max tokens");
require(_amount * price <= msg.value, "Incorrect ETH value");
for (uint256 i = 1; i <= _amount; ++i) {
_safeMint(msg.sender, curTotalSupply + i);
}
mintedPerWallet[msg.sender] += _amount;
totalSupply += _amount;
}
// Public mint
function publicMint(uint256 _amount) external payable {
require(isSaleActive, "Public sale not active");
require(_amount <= MAX_MINT_PER_TX, "You can only mint a maximum of 5 per transaction");
require(mintedPerWallet[msg.sender] + _amount <= MAX_MINT_PER_WALLET, "You can only mint 5 per wallet");
uint256 curTotalSupply = totalSupply;
require(curTotalSupply + _amount <= MAX_TOKENS, "Exceeds max tokens");
require(_amount * price <= msg.value, "Incorrect ETH value");
for (uint256 i = 1; i <= _amount; ++i) {
_safeMint(msg.sender, curTotalSupply + i);
}
mintedPerWallet[msg.sender] += _amount;
totalSupply += _amount;
}
// Dev mint
function devMint(uint256 _amount) external payable onlyOwner {
uint256 curTotalSupply = totalSupply;
require(curTotalSupply + _amount <= MAX_TOKENS, "Exceeds max tokens");
for (uint256 i = 1; i <= _amount; ++i) {
_safeMint(msg.sender, curTotalSupply + i);
}
mintedPerWallet[msg.sender] += _amount;
totalSupply += _amount;
}
// Flip sale state
function flipSaleState() external onlyOwner {
isSaleActive = !isSaleActive;
}
// Flip whitelist state
function flipWhitelistState() external onlyOwner {
isWhitelistActive = !isWhitelistActive;
}
// Presale on
function presaleOn() external onlyOwner {
isSaleActive = false;
isWhitelistActive = true;
}
// Public sale on
function publicSaleOn() external onlyOwner {
isSaleActive = true;
isWhitelistActive = false;
}
// Check if proof is valid
function isValid(bytes32[] memory proof, bytes32 leaf) public view returns (bool) {
return MerkleProof.verify(proof, root, leaf);
}
// Set root
function setRoot(bytes32 _root) public onlyOwner {
root = _root;
}
// Set base URI
function setBaseURI(string memory _baseUri) external onlyOwner {
baseUri = _baseUri;
}
// Set price
function setPrice(uint256 _price) external onlyOwner {
price = _price;
}
// Change max mint per wallet
function setMaxMintPerWallet(uint256 _amount) external onlyOwner {
MAX_MINT_PER_TX = _amount;
MAX_MINT_PER_WALLET = _amount;
}
// Get token URI
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory currentBaseURI = _baseURI();
return bytes(currentBaseURI).length > 0
? string(abi.encodePacked(currentBaseURI, tokenId.toString(), baseExtension))
: "";
}
// Get base URI
function _baseURI() internal view virtual override returns (string memory) {
return baseUri;
}
// Withdraw ETH
// function withdrawAll() external payable onlyOwner {
// uint256 balance = address(this).balance;
// uint256 balanceOne = balance * 67 / 100;
// uint256 balanceTwo = balance * 33 / 100;
// (bool transferOne, ) = payable(0x21c9fc30A4aC35B0C8924f20aacD92c948cA14b5).call{value: balanceOne}("");
// (bool transferTwo, ) = payable(0x21c9fc30A4aC35B0C8924f20aacD92c948cA14b5).call{value: balanceTwo}("");
// require(transferOne && transferTwo, "Transfer failed.");
// }
}