Created
March 23, 2022 03:57
-
-
Save indiejoseph/ed8dd258aa5a90b527a52e8f86cff3c9 to your computer and use it in GitHub Desktop.
WEARKey_v3.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.4; | |
import "erc721a/contracts/ERC721A.sol"; | |
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; | |
import "@openzeppelin/contracts/access/Ownable.sol"; | |
contract WEARKey is ERC721A, Ownable { | |
// events | |
event WhitelistMint(address sender, uint256 count); | |
event Mint(address sender, uint256 count); | |
event SetMerkleRoot(bytes32 merkleRoot); | |
event SetBaseURI(string baseURI); | |
event Pause(); | |
event Unpause(); | |
event ToggleSale(bool saleIsOpen); | |
event Withdraw(uint256 balance); | |
string public _baseTokenURI; | |
bool public saleIsOpen; | |
bool public paused; | |
bytes32 public merkleRoot; | |
mapping(address => uint256) public whitelistClaimed; | |
uint256 public constant basePrice = 0.35 ether; | |
uint256 public constant preSalePrice = 0.15 ether; | |
uint256 public constant START_TOKEN_ID = 1; | |
uint256 public constant MAX_SUPPLY = 1000 + 1; | |
uint256 public constant MAX_PER_USER = 15 + 1; | |
uint256 public constant MAX_PER_WHITELIST = 1 + 1; | |
modifier notPaused() { | |
if (_msgSender() != owner()) { | |
require(!paused, "Pausable: paused"); | |
} | |
_; | |
} | |
modifier onlySaleOpen() { | |
require(saleIsOpen, "Public sale is not started yet"); | |
_; | |
} | |
modifier onlyWhitelistedUser(bytes32[] calldata _merkleProof) { | |
address _caller = _msgSender(); | |
bytes32 leaf = keccak256(abi.encodePacked(_caller)); | |
require(whitelistClaimed[_caller] < MAX_PER_WHITELIST, "Address has already claimed"); | |
require(MerkleProof.verify(_merkleProof, merkleRoot, leaf), "Invalid proof"); | |
_; | |
} | |
constructor(string memory baseTokenURI_) ERC721A("WEARKey", "WEARKEY") { | |
_baseTokenURI = baseTokenURI_; | |
} | |
function totalMint() public view returns (uint256) { | |
return totalSupply(); | |
} | |
function setMerkleRoot(bytes32 _merkleRoot) public onlyOwner { | |
emit SetMerkleRoot(_merkleRoot); | |
merkleRoot = _merkleRoot; | |
} | |
function _mint(uint256 _count) private { | |
address _caller = _msgSender(); | |
uint256 maxItemId = MAX_SUPPLY + START_TOKEN_ID; | |
require(_currentIndex + _count < maxItemId, "Exceeds max supply"); | |
require(msg.value >= price(_count), "Value below price"); | |
require(_count > 0, "No 0 mints"); | |
require(tx.origin == _caller, "No contracts"); | |
_safeMint(_caller, _count); | |
} | |
function mint(uint256 _count) external payable onlySaleOpen notPaused { | |
address _caller = _msgSender(); | |
require(balanceOf(_caller) + _count < MAX_PER_USER, "You are not allowed to mint this many!"); | |
_mint(_count); | |
emit Mint(_msgSender(), _count); | |
} | |
function whitelistMint(uint256 _count, bytes32[] calldata _merkleProof) | |
external | |
payable | |
notPaused | |
onlyWhitelistedUser(_merkleProof) | |
{ | |
address _caller = _msgSender(); | |
require( | |
balanceOf(_caller) + _count < MAX_PER_WHITELIST, | |
"You are not allowed to mint this many!" | |
); | |
_mint(_count); | |
whitelistClaimed[_caller] = _count; | |
emit WhitelistMint(_msgSender(), _count); | |
} | |
function price(uint256 _count) public view returns (uint256) { | |
if (saleIsOpen == false) { | |
return preSalePrice * _count; | |
} else { | |
return basePrice * _count; | |
} | |
} | |
function setBaseURI(string memory baseURI) public onlyOwner { | |
_baseTokenURI = baseURI; | |
emit SetBaseURI(baseURI); | |
} | |
// https://docs.opensea.io/docs/1-structuring-your-smart-contract#creature-erc721-contract | |
function baseTokenURI() public view returns (string memory) { | |
return _baseTokenURI; | |
} | |
// internal | |
function _baseURI() internal view virtual override returns (string memory) { | |
return _baseTokenURI; | |
} | |
function pause() public onlyOwner { | |
paused = true; | |
emit Pause(); | |
} | |
function unpause() public onlyOwner { | |
paused = false; | |
emit Unpause(); | |
} | |
function toggleSale() public onlyOwner { | |
saleIsOpen = !saleIsOpen; | |
emit ToggleSale(saleIsOpen); | |
} | |
// widthdraw fund from the contract | |
function withdraw() public onlyOwner { | |
uint256 balance = address(this).balance; | |
require(balance > 0, "Balance is 0"); | |
(bool sent, ) = payable(owner()).call{value: balance}(""); | |
require(sent, "Failed to send Ether"); | |
emit Withdraw(balance); | |
} | |
function _startTokenId() internal view virtual override returns (uint256) { | |
return START_TOKEN_ID; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment