ETCMW ETC Most Wanted
Featured: Register HENS (.etc) Domain Name Click to register
Overview [ERC-721]
Max Total Supply:
1,201
Holders:
62
Transfers:
1,402
Profile Summary
Decimals:
0
Official Site:
FILTERED BY TOKEN HOLDER
BALANCE
40 ETCMW
VALUE
$0 (~0 ETC)
Contract name:
Etcmw
Optimization enabled :
true
Compiler version:
0.8.17+commit.8df45f5f
EVM Version:
london
Contract source code
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@thirdweb-dev/contracts/extension/Ownable.sol";
import "@thirdweb-dev/contracts/extension/ContractMetadata.sol";
import "@thirdweb-dev/contracts/extension/Multicall.sol";
import "@thirdweb-dev/contracts/extension/PrimarySale.sol";
import "@thirdweb-dev/contracts/extension/DefaultOperatorFilterer.sol";
import "@thirdweb-dev/contracts/lib/TWStrings.sol";
import "@thirdweb-dev/contracts/lib/CurrencyTransferLib.sol";

import "./ERC721R.sol";
import "./ERC721REnumerable.sol";
import "./ERC721URIStorage.sol";

/**
 * @dev etcher.etc: Implementation of ERC721 Non-Fungible Token Standard with new features,
 * Including safu random batch minting and burning rewards mechanics, updated Enumerable and URI Storage.
 * Created special for ETC MostWanted #ETCMW
 * website: etcmw.org
 */

contract Etcmw is
    ERC721r,
    ERC721rEnumerable,
    Ownable,
    ContractMetadata,
    Multicall,
    PrimarySale,
    DefaultOperatorFilterer,
    ERC721URIStorage
{
    string public baseUri = "ipfs://Qmf7GAcUt3MWsCPh6wjdz3z8WfqJix947A3hF2enTf4Dyo/";
    string public baseExtension = ".json";
    bool public isMintingEnabled = true;
    uint256 private constant max_Supply = 10000;
    uint256 private constant maxTxMints = 10;
    uint256 private constant priceA = 1 ether; //phase 1
    uint256 private constant priceB = 2 ether; //phase 2
    uint256 private constant priceC = 3 ether; //phase 3
    uint256 private constant rwrdA = 0; //phase 1
    uint256 private constant rwrdB = 0.5 ether; //phase 2
    uint256 private constant rwrdC = 1 ether; //phase 3++
    uint256 private constant phase1 = 1000; //items
    uint256 private constant phase2 = 5000; //items. phase 3 items = max - (phase 1 + phase 2)

    // Common  - 0 //default
    // Miner - 1
    // Investor - 2
    // Dev - 3
    enum Role {
        Common,
        Miner,
        Investor,
        Dev
    }

    // we use index as token id. Id's starting from 0
    Role[] private _tokensRole;

    constructor(
        address _defaultAdmin,
        string memory _name,
        string memory _symbol,
        string memory _contractURI,
        address _primarySaleRecipient
    ) ERC721r(_name, _symbol, max_Supply) {
        _setupOwner(_defaultAdmin);
        _setupContractURI(_contractURI);
        _setupPrimarySaleRecipient(_primarySaleRecipient);
        _setOperatorRestriction(true);
    }

    using TWStrings for uint256;
    using SafeMath for uint256;

    receive() external payable {}

    function tokenURI(
        uint256 tokenId
    )
        public
        view
        virtual
        override(ERC721r, ERC721URIStorage)
        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
                    )
                )
                : "";
    }

    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 setTokenURI(uint256 tokenId, string memory uri) public onlyOwner {
        require(_exists(tokenId), "Token ID does not exist");
        _setTokenURI(tokenId, uri);
    }

    function stopmint() public onlyOwner {
        isMintingEnabled = false;
    }

    function enablemint() public onlyOwner {
        isMintingEnabled = true;
    }

    function totalMinted() public view returns (uint256) {
        require(_availableToMint() <= _maxSupply, "caught up");
        return _maxSupply - _availableToMint();
    }

    function getPrice() public view returns (uint256) {
        if (totalMinted() >= phase1 && totalMinted() < phase2) return priceB;
        if (totalMinted() >= phase2) return priceC;
        return priceA;
    }

    function getBurnRwd() public view returns (uint256) {
        if (totalMinted() >= phase1 && totalMinted() < phase2) return rwrdB;
        if (totalMinted() >= phase2) return rwrdC;
        return rwrdA;
    }

    function getBatchPrice(uint256 amount) public view returns (uint256) {
        require(totalMinted() + amount <= max_Supply, "caught up");
        require(amount <= maxTxMints, "caught up");
        return amount.mul(getPrice()); //if totalMinted < next phase && totalMinted + amount > next phase its ok to let mint some items without price increase(max amount 10 and it can only happen twice). This is preferable to overcomplicating the minting calculations
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256[] memory tokenIdxs
    ) internal virtual override(ERC721r, ERC721rEnumerable) {
        ERC721rEnumerable._beforeTokenTransfer(from, to, tokenIdxs);
    }

    function totalSupply()
        public
        view
        override(ERC721r, ERC721rEnumerable)
        returns (uint256)
    {
        return ERC721rEnumerable.totalSupply();
    }

    /// @dev See ERC165: https://eips.ethereum.org/EIPS/eip-165
    function supportsInterface(
        bytes4 interfaceId
    ) public view virtual override(ERC721r, ERC721rEnumerable) returns (bool) {
        return
            interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
            interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721
            interfaceId == 0x5b5e139f || // ERC165 Interface ID for ERC721Metadata
            interfaceId == 0x780e9d63; // ERC721Enumerable
    }

    /**
     * @dev Release etc to saleRecipient
     */
    function release(uint256 totalAmount) external onlyOwner {
        address payable saleRecipient = payable(primarySaleRecipient());
        uint256 balance = address(this).balance;
        require(balance >= totalAmount, "Insufficient balance");
        CurrencyTransferLib.transferCurrency(
            CurrencyTransferLib.NATIVE_TOKEN,
            address(this),
            saleRecipient,
            totalAmount
        );
    }

    function mint(uint256 quantity) external payable mintingEnabled {
        require(quantity <= maxTxMints, "caught up");
        require(quantity <= _availableToMint(), "caught up");
        require(quantity > 0, "caught up");
        uint256 totalPrice = getBatchPrice(quantity);
        bool validMsgValue = msg.value == totalPrice;
        require(validMsgValue, "Invalid msg value");
        address payable saleRecipient = payable(primarySaleRecipient());
        _mintRandom(msg.sender, quantity);
        CurrencyTransferLib.transferCurrency(
            CurrencyTransferLib.NATIVE_TOKEN,
            msg.sender,
            saleRecipient,
            totalPrice / 2
        );
        CurrencyTransferLib.transferCurrency(
            CurrencyTransferLib.NATIVE_TOKEN,
            msg.sender,
            address(this),
            totalPrice / 2
        );
    }

    function _burn(
        uint256 tokenId
    ) internal override(ERC721r, ERC721URIStorage) {
        ERC721r._burn(tokenId);
    }

    function burn(uint256 tokenId) external {
        require(_exists(tokenId), "Not exists");
        address payable owner = payable(ERC721r.ownerOf(tokenId));
        uint256 rwrd = getBurnRwd();
        uint256 balance = address(this).balance;
        require(_msgSender() == tx.origin, "Contracts cannot burn");
        require(_msgSender() == owner, "Not owner");
        _burn(tokenId);
        if (rwrd > 0 && balance >= rwrd) {
            CurrencyTransferLib.transferCurrency(
                CurrencyTransferLib.NATIVE_TOKEN,
                address(this),
                owner,
                rwrd
            );
        }
    }

    modifier mintingEnabled() {
        require(isMintingEnabled, "Minting disabled");
        _;
    }

    function getTokenRole(
        uint256 tokenId
    ) public view virtual returns (string memory) {
        require(_exists(tokenId), "Query for nonexistent token");
        if (_tokensRole[tokenId] == Role.Investor) return "Investor";
        if (_tokensRole[tokenId] == Role.Miner) return "Miner";
        if (_tokensRole[tokenId] == Role.Dev) return "Dev";
        return "Common";
    }

    function initTokensRole(Role[] memory tokensRole) public onlyOwner {
        require(tokensRole.length == max_Supply, "require max supply length");
        _tokensRole = tokensRole;
    }

    /// @dev Checks whether owner can be set in the given execution context.
    function _canSetOwner() internal view virtual override returns (bool) {
        return msg.sender == owner();
    }

    /// @dev Checks whether contract metadata can be set in the given execution context.
    function _canSetContractURI()
        internal
        view
        virtual
        override
        returns (bool)
    {
        return msg.sender == owner();
    }

    /// @dev Checks whether primary sale recipient can be set in the given execution context.
    function _canSetPrimarySaleRecipient()
        internal
        view
        virtual
        override
        returns (bool)
    {
        return msg.sender == owner();
    }

    /// @dev Returns whether operator restriction can be set in the given execution context.
    function _canSetOperatorRestriction()
        internal
        virtual
        override
        returns (bool)
    {
        return msg.sender == owner();
    }
}
Contract ABI
[{"inputs":[{"internalType":"address","name":"_defaultAdmin","type":"address"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"string","name":"_contractURI","type":"string"},{"internalType":"address","name":"_primarySaleRecipient","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"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":false,"internalType":"string","name":"prevURI","type":"string"},{"indexed":false,"internalType":"string","name":"newURI","type":"string"}],"name":"ContractURIUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"restriction","type":"bool"}],"name":"OperatorRestriction","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"prevOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"}],"name":"PrimarySaleRecipientUpdated","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"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","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":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enablemint","outputs":[],"stateMutability":"nonpayable","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":"getBatchPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBurnRwd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getTokenRole","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum Etcmw.Role[]","name":"tokensRole","type":"uint8[]"}],"name":"initTokensRole","outputs":[],"stateMutability":"nonpayable","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":"isMintingEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operatorRestriction","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"primarySaleRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"totalAmount","type":"uint256"}],"name":"release","outputs":[],"stateMutability":"nonpayable","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":"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":"string","name":"_uri","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_restriction","type":"bool"}],"name":"setOperatorRestriction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_saleRecipient","type":"address"}],"name":"setPrimarySaleRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"uri","type":"string"}],"name":"setTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stopmint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_subscription","type":"address"}],"name":"subscribeToRegistry","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":"totalMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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"},{"stateMutability":"payable","type":"receive"}]