// SPDX-License-Identifier: MITpragmasolidity ^0.8.1;interfaceIMerkleDistributor{
// function token() external view returns (address);// Returns the merkle root of the merkle tree containing account balances available to claim.functionmerkleRoot() externalviewreturns (bytes32);
}
import'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol';
import'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/Ownable.sol';
import'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Strings.sol';
import"@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
import"@openzeppelin/contracts/security/ReentrancyGuard.sol";
contractETRYisIMerkleDistributor,ERC721, Ownable, ReentrancyGuard{
uint256publicconstant MINT_PRICE =70000000000000000;
uintpublic REMAINING_SUPPLY =9224;
bool MINTING_ALLOWED =true;
bool PRESALE_ONLY =true;
uint PRESALE_TOKEN_MAXIMUM_AMOUNT =10;
uint WALLET_TOKEN_MAXIMUM_AMOUNT =10;
uint MINTING_STAGE =1;
usingStringsforuint256;
address FUNDS_RECIPIENT =0x16583250954Ff09EF3adBa9Cc6c94d883D26465e;
//address public override token;bytes32publicoverride merkleRoot;
// Optional mapping for token URIsmapping (uint256=>string) private _tokenURIs;
mapping(uint256=>uint256) claimedMints;
// Base URIstringprivate _baseURIextended;
uintprivate counter =0;
constructor(stringmemory _name, stringmemory _symbol, bytes32 merkleRoot_ )
ERC721(_name, _symbol){
merkleRoot = merkleRoot_;
}
functionmarkMint(uint256 index, uint256 amount) internal{
if (claimedMints[index]!=0){
claimedMints[index] = claimedMints[index] + amount;
} else {
claimedMints[index] = amount;
}
}
/*
* Stop minting. This function should just be used by the owner
*/functionstopMinting() publiconlyOwner(){
MINTING_ALLOWED =false;
}
/*
* Start minting. This function should just be used by the owner
*/functionstartMinting() publiconlyOwner(){
MINTING_ALLOWED =true;
}
//Set the MerkleProofRootfunctionchangeMerkleProofRoot(bytes32 merkleRoot_ ) externalonlyOwner() {
merkleRoot = merkleRoot_;
}
//Internal function to verify merkleProoffunctionverify(uint256 index, address account, uint stage, bytes32[] calldata merkleProof) internal{
// Verify the merkle proof.bytes32 node =keccak256(abi.encodePacked(index, account, stage));
require(MerkleProof.verify(merkleProof, merkleRoot, node), 'MerkleDistributor: Invalid proof.');
}
functioncontractURI() publicviewreturns (stringmemory) {
return _baseURI();
}
function_baseURI() internalviewvirtualoverridereturns (stringmemory) {
return _baseURIextended;
}
/*
* Owner can withdraw the contract's ETH to an external address
*/functionwithdrawETH(address ethAddress, uint amount) publiconlyOwner(){
payable(ethAddress).transfer(amount);
}
functiontokenURI(uint256 tokenId) publicviewvirtualoverridereturns (stringmemory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
stringmemory _tokenURI = _tokenURIs[tokenId];
stringmemory base = _baseURI();
// If there is no base URI, return the token URI.if (bytes(base).length==0) {
return _tokenURI;
}
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).if (bytes(_tokenURI).length>0) {
returnstring(abi.encodePacked(base, _tokenURI));
}
// If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.returnstring(abi.encodePacked(base, tokenId.toString()));
}
/*
* Mint function
*/functionmintByOwner(uint256 _amount,address recipient) publiconlyOwner() {
uint index = counter;
uint lastIndex = counter + _amount;
for (uint _index = index;_index < lastIndex;_index++ ){
_mint(recipient, _index+1);
_setTokenURI(_index+1, Strings.toString(_index+1));
counter++;
REMAINING_SUPPLY--;
}
}
/*
* Mint function
*/functionmint(uint256 _amount, uint256 merketree_index,bytes32[] calldata merkleProof, uint stage) publicpayablenonReentrant() {
require(MINTING_ALLOWED, "Minting is not allowed");
require(_amount <= REMAINING_SUPPLY,"There are not this many tokens left");
require(_amount <=10,"10 Tokens is the limit per transaction");
if (PRESALE_ONLY){
require(MINTING_STAGE >= stage, "Address not allowed in this stage");
verify(merketree_index,msg.sender, stage, merkleProof);
require(claimedMints[merketree_index]+_amount <=PRESALE_TOKEN_MAXIMUM_AMOUNT, "User already minted 10 times");
}
uint256 totalCost = getMintingCost(_amount);
require(msg.value>= totalCost,"Insufficient Gas.");
uint index = counter;
uint lastIndex = counter + _amount;
for (uint _index = index;_index < lastIndex;_index++ ){
_mint(msg.sender, _index+1);
_setTokenURI(_index+1, Strings.toString(_index+1));
counter++;
REMAINING_SUPPLY--;
}
if (PRESALE_ONLY){
markMint(merketree_index,_amount);
}
// payable(FUNDS_RECIPIENT).send(totalCost);// send the funds
}
//Return minting costfunctiongetMintingCost(uint totalItems)
privatepurereturns (uint256)
{
return totalItems * MINT_PRICE;
}
functiontotalTokensMinted() publicviewreturns(uint){
return counter;
}
functiontotalSupply() publicviewreturns(uint){
return9224;
}
functionpreSaleFlag() publicviewreturns(bool){
return PRESALE_ONLY;
}
functionenablePresale() externalonlyOwner() {
PRESALE_ONLY =true;
}
functiondisablePresale() externalonlyOwner() {
PRESALE_ONLY =false;
}
functionsetMintingStage(uint stage) externalonlyOwner() {
MINTING_STAGE = stage;
}
functionremainingSupply() publicviewreturns(uint){
return REMAINING_SUPPLY;
}
//Set the Base URIfunctionsetBaseURI(stringmemory baseURI_) externalonlyOwner() {
_baseURIextended = baseURI_;
}
function_setTokenURI(uint256 tokenId, stringmemory _tokenURI) internalvirtual{
require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
_tokenURIs[tokenId] = _tokenURI;
}
}
Contract Source Code
File 6 of 13: IERC165.sol
Contract Source Code
File 7 of 13: IERC721.sol
Contract Source Code
File 8 of 13: IERC721Metadata.sol
Contract Source Code
File 9 of 13: IERC721Receiver.sol
Contract Source Code
File 10 of 13: MerkleProof.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.8.0;/**
* @dev These functions deal with verification of Merkle Trees proofs.
*
* The proofs can be generated using the JavaScript library
* https://github.com/miguelmota/merkletreejs[merkletreejs].
* Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
*
* See `test/utils/cryptography/MerkleProof.test.js` for some examples.
*/libraryMerkleProof{
/**
* @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
* defined by `root`. For this, a `proof` must be provided, containing
* sibling hashes on the branch from the leaf to the root of the tree. Each
* pair of leaves and each pair of pre-images are assumed to be sorted.
*/functionverify(bytes32[] memory proof,
bytes32 root,
bytes32 leaf
) internalpurereturns (bool) {
bytes32 computedHash = leaf;
for (uint256 i =0; i < proof.length; i++) {
bytes32 proofElement = proof[i];
if (computedHash <= proofElement) {
// Hash(current computed hash + current element of the proof)
computedHash =keccak256(abi.encodePacked(computedHash, proofElement));
} else {
// Hash(current element of the proof + current computed hash)
computedHash =keccak256(abi.encodePacked(proofElement, computedHash));
}
}
// Check if the computed hash (root) is equal to the provided rootreturn computedHash == root;
}
}
Contract Source Code
File 11 of 13: Ownable.sol
Contract Source Code
File 12 of 13: ReentrancyGuard.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.8.0;/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/abstractcontractReentrancyGuard{
// Booleans are more expensive than uint256 or any type that takes up a full// word because each write operation emits an extra SLOAD to first read the// slot's contents, replace the bits taken up by the boolean, and then write// back. This is the compiler's defense against contract upgrades and// pointer aliasing, and it cannot be disabled.// The values being non-zero value makes deployment a bit more expensive,// but in exchange the refund on every call to nonReentrant will be lower in// amount. Since refunds are capped to a percentage of the total// transaction's gas, it is best to keep them low in cases like this one, to// increase the likelihood of the full refund coming into effect.uint256privateconstant _NOT_ENTERED =1;
uint256privateconstant _ENTERED =2;
uint256private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and make it call a
* `private` function that does the actual work.
*/modifiernonReentrant() {
// On the first call to nonReentrant, _notEntered will be truerequire(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}