Skip to content

Instantly share code, notes, and snippets.

@indiejoseph
Created March 23, 2022 03:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save indiejoseph/ed8dd258aa5a90b527a52e8f86cff3c9 to your computer and use it in GitHub Desktop.
Save indiejoseph/ed8dd258aa5a90b527a52e8f86cff3c9 to your computer and use it in GitHub Desktop.
WEARKey_v3.sol
//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