18.04
($-0.99%)
| 1 Gwei
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; import "@openzeppelin/contracts@4.8.2/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts@4.8.2/token/ERC721/extensions/ERC721Enumerable.sol"; import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import "@openzeppelin/contracts@4.8.2/security/Pausable.sol"; import "@openzeppelin/contracts@4.8.2/access/Ownable.sol"; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; import "@thirdweb-dev/contracts/eip/interface/IERC20.sol"; contract Froggies is ERC721, ERC721Enumerable, Pausable, Ownable { using SafeMath for uint256; using EnumerableSet for EnumerableSet.UintSet; constructor() ERC721("Froggies", "FRGG") {} bytes32 private merkleRoot = 0x7b83c8ea4644507afaaa60c15c9ddb6239b4787cd286065e2144b6df0cbd9cd2; using EnumerableSet for EnumerableSet.UintSet; address private withdrawalAddress1; address private withdrawalAddress2; address private withdrawalAddress3; uint256 private constant MAX_MINTS_PER_TX = 20; string public baseExtension = ".json"; uint256 public constant maxSupply = 7777; uint256 public maxMintAmount = 20; bool public revealed = true; bool private isMintingEnabled = false; address public burnAddress = 0x000000000000000000000000000000000000dEaD; string public notRevealedUri; string public baseUri = "ipfs://bafybeih2yqav3jcyvw7veszemipucimug4y3eoaoy263p7k4vgursvvscu/"; uint256 public mintPrice = .4 ether; uint256 internal totalMinted = 0; // Random uint256 internal nonce = 0; uint256[maxSupply] internal indices; //Claim Variables address public eligibleTokenAddress = 0x731e2E78c318f6763DbBc9EFA4675a8061C11164; // storage mapping (uint256 => address) internal tokenToOwner; mapping (uint256 => address) internal tokenToApproval; mapping (address => mapping (address => bool)) internal ownerToOperators; address internal addressZero = address(0); EnumerableSet.UintSet internal tokensOnSale; bool internal isReentrancyLock = false; mapping(address => EnumerableSet.UintSet) private _ownedNFTs; function changeMaxMintAmount(uint256 newMax) public onlyOwner { require(newMax > 0, "Mint price must be greater than 0"); maxMintAmount = newMax; } function pause() public onlyOwner { isMintingEnabled = false; } function unpause() public onlyOwner { isMintingEnabled = true; } function transferOwnership(address newOwner) public onlyOwner override{ require(newOwner != address(0), "New owner cannot be zero address"); _transferOwnership(newOwner); } function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) internal whenNotPaused override(ERC721, ERC721Enumerable) { super._beforeTokenTransfer(from, to, tokenId, batchSize); } function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable) returns (bool) { return super.supportsInterface(interfaceId); } function sendBatch(address recipient, uint256[] memory tokenIds) public onlyOwner{ for (uint256 i = 0; i < tokenIds.length; i++) { _safeMint(recipient, tokenIds[i]); } } function claimNFT() external { // Check for at least 1 eligible token balance require(IERC20(eligibleTokenAddress).balanceOf(msg.sender) >= 1 ether, "You need to hold at least 1 eligible token"); require(IERC20(eligibleTokenAddress).allowance(msg.sender, address(this)) >= 1 ether, "Please approve this contract to spend your tokens"); // Transfer 1 token to the contract require(IERC20(eligibleTokenAddress).transferFrom(msg.sender, address(this), 1 ether), "Payment failed"); _mint(msg.sender); } function airdrop(address[] memory recipients, uint256 amount) public onlyOwner { require(amount >= 1, 'You cannot mint lower than 1 NFT'); require((totalMinted + amount) < maxSupply, "Exceeds maximum supply. Please try to mint fewer NFTs."); require(recipients.length <= amount, "Number of recipients exceeds the specified amount."); for (uint256 i = 0; i < amount; i++) { _mint(recipients[i]); } } function getNFTPrice(uint256 amount) public view returns (uint256) { require(totalMinted < maxSupply, "Sale has already ended."); return amount.mul(mintPrice); } function mint(uint256 amount) external payable reentrancyGuard mintingEnabled { require(msg.value >= (mintPrice * amount), "Insufficient funds to purchase"); require(amount >= 1, 'You cannot mint lower than 1 NFT'); require(amount <= maxMintAmount, 'You cannot mint more than 20 NFTs per once'); require((totalMinted + amount) < maxSupply, "Exceeds maximum supply. Please try to mint less NFTs."); if (msg.value > getNFTPrice(amount)) { payable(msg.sender).transfer(msg.value - getNFTPrice(amount)); } for (uint i = 0; i < amount; i++) { _mint(msg.sender); } } function _mint(address _to) internal notZeroAddress(_to) returns (uint256 _mintedTokenId) { require(totalMinted <= maxSupply, "All tokens are minted"); uint randomId = _tryGenerateRandomId(); totalMinted++; if (randomId == 0) { randomId = _tryGenerateRandomId(); totalMinted++; } if (randomId != 0) { _safeMint(_to, randomId ); emit Mint(randomId, msg.sender, _to); } return randomId; } function _tryGenerateRandomId() private returns (uint256) { uint256 randId = _generateRandomId(); if (tokenToOwner[randId] == addressZero) { return randId; } else { return 0; } } function _generateRandomId() private returns (uint256) { uint256 totalSize = maxSupply - totalMinted; uint256 index = uint256(keccak256(abi.encodePacked(nonce, msg.sender, block.difficulty, block.timestamp))) % totalSize; uint256 value = 0; if (indices[index] != 0) { value = indices[index]; } else { value = index; } // Move last value to selected position if (indices[totalSize - 1] == 0) { indices[index] = totalSize - 1; // Array position not initialized, so use position } else { indices[index] = indices[totalSize - 1]; // Array position holds a value so use that } nonce++; // Don't allow a zero index, start counting at 1 return value + 1; } function setWithdrawalAddresses(address _withdrawalAddress1, address _withdrawalAddress2, address _withdrawalAddress3) public onlyOwner { withdrawalAddress1 = _withdrawalAddress1; withdrawalAddress2 = _withdrawalAddress2; withdrawalAddress3 = _withdrawalAddress3; } function withdraw() public onlyOwner { require(withdrawalAddress1 != address(0) && withdrawalAddress2 != address(0) && withdrawalAddress3 != address(0), "Withdrawal addresses not set"); uint256 balance = address(this).balance; require(balance > 0, "Insufficient balance"); uint256 amountPerAddress = balance / 3; (bool success1,) = withdrawalAddress1.call{value: amountPerAddress}(""); require(success1, "Withdrawal failed for address 1"); (bool success2,) = withdrawalAddress2.call{value: amountPerAddress}(""); require(success2, "Withdrawal failed for address 2"); (bool success3,) = withdrawalAddress3.call{value: amountPerAddress}(""); require(success3, "Withdrawal failed for address 3"); } function uintToString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } function _baseURI() internal view virtual override returns (string memory) { return baseUri; } function setBaseURI(string memory newBaseURI) public onlyOwner { require(bytes(newBaseURI).length > 0, "Base URI cannot be empty"); baseUri = newBaseURI; } function tokenURI(uint256 tokenId) public view virtual override(ERC721) returns (string memory){ require( _exists(tokenId), "ERC721Metadata: URI query for nonexistent token" ); if(revealed == false) { return notRevealedUri; } string memory currentBaseURI = _baseURI(); return bytes(currentBaseURI).length > 0 ? string(abi.encodePacked(currentBaseURI, uintToString(tokenId), baseExtension)) : ""; } function changeMintPrice(uint256 newMintPrice) public onlyOwner { require(newMintPrice > 0, "Mint price must be greater than 0"); mintPrice = newMintPrice; } modifier notZeroAddress(address _addr) { require(_addr != addressZero, 'Address can not be 0x0'); _; } event Mint(uint indexed tokenId, address indexed mintedBy, address indexed mintedTo); modifier reentrancyGuard { if (isReentrancyLock) { require(!isReentrancyLock, 'Reentrancy is locked'); } isReentrancyLock = true; _; isReentrancyLock = false; } modifier mintingEnabled() { require(isMintingEnabled, 'Minting disabled'); _; } }
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"mintedBy","type":"address"},{"indexed":true,"internalType":"address","name":"mintedTo","type":"address"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"airdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burnAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMax","type":"uint256"}],"name":"changeMaxMintAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMintPrice","type":"uint256"}],"name":"changeMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"eligibleTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"getNFTPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMintAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"notRevealedUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"sendBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_withdrawalAddress1","type":"address"},{"internalType":"address","name":"_withdrawalAddress2","type":"address"},{"internalType":"address","name":"_withdrawalAddress3","type":"address"}],"name":"setWithdrawalAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]