BaseBase
0x19...a8e2
Pepe Inscriptions

Pepe Inscriptions

PEPI

代币
市值
$1.00
 
价格
2%
此合同的源代码已经过验证!
合同元数据
编译器
0.8.25+commit.b61c2a91
语言
Solidity
合同源代码
文件 1 的 8:Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}
合同源代码
文件 2 的 8:Erc20.sol
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "@openzeppelin/contracts/utils/Context.sol";

contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) internal _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 internal _totalSupply;
    uint8 internal constant _decimals = 9;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the default value returned by this function, unless
     * it's overridden.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public pure returns (uint8) {
        return _decimals;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(
        address account
    ) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(
        address owner,
        address spender
    ) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(
        address spender,
        uint256 amount
    ) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(
        address spender,
        uint256 addedValue
    ) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, allowance(owner, spender) + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(
        address spender,
        uint256 subtractedValue
    ) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = allowance(owner, spender);
        require(
            currentAllowance >= subtractedValue,
            "ERC20: decreased allowance below zero"
        );
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");

        uint256 fromBalance = _balances[from];
        require(
            fromBalance >= amount,
            "ERC20: transfer amount exceeds balance"
        );
        unchecked {
            _balances[from] = fromBalance - amount;
            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
            // decrementing then incrementing.
            _balances[to] += amount;
        }

        emit Transfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _totalSupply += amount;
        unchecked {
            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
            _balances[account] += amount;
        }
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Erases `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
            // Overflow not possible: amount <= accountBalance <= totalSupply.
            _totalSupply -= amount;
        }

        emit Transfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(
                currentAllowance >= amount,
                "ERC20: insufficient allowance"
            );
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }
}
合同源代码
文件 3 的 8:Generator.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "./lib/Ownable.sol";

uint constant levelsCount = 6;
uint constant bcgroundsCount = 6;
uint8 constant pixelsCount = 32;
uint constant seedLevel2 = 11;
uint constant seedLevel3 = 22;
uint constant seedLevel4 = 33;
uint constant seedLevel5 = 44;
uint constant seedLevel6 = 56;
string constant description = "A collection of PEPis, an inscriptions ERC-20i collection. 6 different levels from egg mass to a fully grown Pepe. Which one is yours?$PEPi is a unique, fully on-chain art project built on the innovative new ERC-20i format with inscription metadata. Each portion of tokens resembles a seed that generates unique 32x32 dynamic images of Pepe stored on-chain, depending on the wallet's token balance.";
string constant web = "https://pepe-erc20i.vip/";

struct ItemData {
    uint lvl; // starts 1
    string background;
    uint body; // number or 0
    string bodyColor;
    uint cloth; // number or 0
    uint eyes; // number or 0
    uint mouth; // number or 0
    uint accessory; // number or 0
    uint hat; // number or 0
    uint ears; // number or 0
}

struct Rect {
    uint8 x;
    uint8 y;
    uint8 width;
    uint8 height;
}

struct RectColored {
    uint8 x;
    uint8 y;
    uint8 width;
    uint8 height;
    uint24 color;
}

struct FileData {
    uint lvl;
    uint file;
    Rect[] rects;
}

struct FileDataColored {
    uint lvl;
    uint file;
    RectColored[] rects;
}

struct ColorsData {
    string[] lvl0;
    string[] lvl1;
    string[] lvl2;
    string[] lvl3;
    string[] lvl4;
}

struct SeedData {
    uint seed;
    uint seed2;
    uint extra;
}

struct Rand {
    uint seed;
    uint seed2;
    uint extra;
    uint nonce;
    uint nonce2;
}

library RandLib {
    function next(Rand memory rnd) internal pure returns (uint) {
        return
            uint(
                keccak256(
                    abi.encodePacked(rnd.seed + rnd.nonce++ - 1, rnd.extra)
                )
            );
    }

    function next2(Rand memory rnd) internal pure returns (uint) {
        return uint(keccak256(abi.encodePacked(rnd.seed2 + rnd.nonce2++ - 1)));
    }

    function random_value(uint nonce) internal view returns (uint) {
        return
            uint256(
                keccak256(
                    abi.encodePacked(
                        block.timestamp,
                        msg.sender,
                        nonce,
                        block.number
                    )
                )
            );
    }

    function lvl(Rand memory rnd) internal pure returns (uint) {
        if (rnd.seed < seedLevel2) return 0;
        if (rnd.seed < seedLevel3) return 1;
        if (rnd.seed < seedLevel4) return 2;
        if (rnd.seed < seedLevel5) return 3;
        if (rnd.seed < seedLevel6) return 4;
        return 5;
    }

    function random(
        string[] memory data,
        Rand memory rnd
    ) internal pure returns (string memory) {
        return data[randomIndex(data, rnd)];
    }

    function random2(
        string[] memory data,
        Rand memory rnd
    ) internal pure returns (string memory) {
        return data[randomIndex2(data, rnd)];
    }

    function randomIndex(
        string[] memory data,
        Rand memory rnd
    ) internal pure returns (uint) {
        return next(rnd) % data.length;
    }

    function randomIndex2(
        string[] memory data,
        Rand memory rnd
    ) internal pure returns (uint) {
        return next2(rnd) % data.length;
    }
}

library ColorConvert {
    function toSvgColor(uint24 value) internal pure returns (string memory) {
        return string(abi.encodePacked("#", toHex(value)));
    }

    function toHex(uint24 value) internal pure returns (bytes memory) {
        bytes memory buffer = new bytes(6);
        for (uint i = 0; i < 3; ++i) {
            buffer[5 - i * 2] = hexChar(uint8(value) & 0x0f);
            buffer[4 - i * 2] = hexChar((uint8(value) >> 4) & 0x0f);
            value >>= 8;
        }
        return buffer;
    }

    function hexChar(uint8 value) internal pure returns (bytes1) {
        if (value < 10) return bytes1(uint8(48 + (uint(value) % 10)));
        return bytes1(uint8(65 + uint256((value - 10) % 6)));
    }
}

library LayersLib {
    function setLayers(
        mapping(uint => mapping(uint => Rect[])) storage rects,
        FileData[] calldata data,
        uint8[levelsCount] storage counts
    ) internal {
        for (uint i = 0; i < data.length; ++i) {
            setFile(rects, data[i], counts);
        }
    }

    function setLayers(
        mapping(uint => mapping(uint => RectColored[])) storage rects,
        FileDataColored[] calldata data,
        uint8[levelsCount] storage counts
    ) internal {
        for (uint i = 0; i < data.length; ++i) {
            setFile(rects, data[i], counts);
        }
    }

    function setFile(
        mapping(uint => mapping(uint => Rect[])) storage rects,
        FileData calldata input,
        uint8[levelsCount] storage counts
    ) internal {
        Rect[] storage storageFile = rects[input.lvl - 1][input.file - 1];
        if (storageFile.length > 0) delete rects[input.lvl - 1][input.file - 1];
        else ++counts[input.lvl - 1];
        for (uint i = 0; i < input.rects.length; ++i) {
            storageFile.push(input.rects[i]);
        }
    }

    function setFile(
        mapping(uint => mapping(uint => RectColored[])) storage rects,
        FileDataColored calldata input,
        uint8[levelsCount] storage counts
    ) internal {
        RectColored[] storage storageFile = rects[input.lvl - 1][
            input.file - 1
        ];
        if (storageFile.length > 0) delete rects[input.lvl - 1][input.file - 1];
        else ++counts[input.lvl - 1];
        for (uint i = 0; i < input.rects.length; ++i) {
            storageFile.push(input.rects[i]);
        }
    }

    function getLvl(
        mapping(uint => mapping(uint => Rect[])) storage rects,
        uint lvl
    ) internal view returns (mapping(uint => Rect[]) storage) {
        return rects[lvl];
    }

    function to_lvl_1(uint l) internal pure returns (uint) {
        if (l > 0) --l;
        return l;
    }
}

library Converter {
    function toString(uint value) internal pure returns (string memory) {
        if (value == 0) {
            return "0";
        }
        uint temp = value;
        uint 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);
    }
}

library RectLib {
    using RectLib for Rect;
    using RectLib for RectColored;
    using RandLib for Rand;
    using RandLib for string[];
    using Converter for uint8;
    using ColorConvert for uint24;

    function toSvg(
        Rect memory r,
        string memory color
    ) internal pure returns (string memory) {
        return
            string(
                abi.encodePacked(
                    "<rect x='",
                    r.x.toString(),
                    "' y='",
                    r.y.toString(),
                    "' width='",
                    r.width.toString(),
                    "' height='",
                    r.height.toString(),
                    "' fill='",
                    color,
                    "'/>"
                )
            );
    }

    function toSvg(RectColored memory r) internal pure returns (string memory) {
        return
            string(
                abi.encodePacked(
                    "<rect x='",
                    r.x.toString(),
                    "' y='",
                    r.y.toString(),
                    "' width='",
                    r.width.toString(),
                    "' height='",
                    r.height.toString(),
                    "' fill='",
                    r.color.toSvgColor(),
                    "'/>"
                )
            );
    }

    function toSvg(
        Rect[] storage rects,
        string[] storage colors,
        Rand memory rnd
    ) internal view returns (string memory) {
        string memory res;
        for (uint i = 0; i < rects.length; ++i) {
            res = string(
                abi.encodePacked(res, rects[i].toSvg(colors.random(rnd)))
            );
        }
        return res;
    }

    function toSvg(
        Rect[] storage rects,
        string memory color
    ) internal view returns (string memory) {
        string memory res;
        for (uint i = 0; i < rects.length; ++i) {
            res = string(abi.encodePacked(res, rects[i].toSvg(color)));
        }
        return res;
    }

    function toSvg(
        RectColored[] storage rects
    ) internal view returns (string memory) {
        string memory res;
        for (uint i = 0; i < rects.length; ++i) {
            res = string(abi.encodePacked(res, rects[i].toSvg()));
        }
        return res;
    }
}

contract Generator is Ownable {
    using LayersLib for mapping(uint => mapping(uint => Rect[]));
    using LayersLib for mapping(uint => mapping(uint => RectColored[]));
    using LayersLib for mapping(uint => string[]);
    using LayersLib for uint;
    using RectLib for Rect;
    using RectLib for Rect[];
    using RectLib for RectColored;
    using RectLib for RectColored[];
    using RandLib for Rand;
    using RandLib for string[];
    using Converter for uint;
    using Converter for uint8;
    using ColorConvert for uint24;

    uint8[levelsCount] bodyLevelCounts;
    uint8[levelsCount] clothLevelCounts;
    uint8[levelsCount] eyesLevelCounts;
    uint8[levelsCount] mouthLevelCounts;
    uint8[levelsCount] accessoryLevelCounts;
    uint8[levelsCount] hatLevelCounts;
    uint8[levelsCount] earsLevelCounts;

    mapping(uint => mapping(uint => Rect[])) bodies;
    mapping(uint => mapping(uint => RectColored[])) cloths;
    mapping(uint => mapping(uint => RectColored[])) eyes;
    mapping(uint => mapping(uint => RectColored[])) mouths;
    mapping(uint => mapping(uint => RectColored[])) accessories;
    mapping(uint => mapping(uint => RectColored[])) hats;
    mapping(uint => mapping(uint => RectColored[])) ears;

    string[] private backgroundColors = [
        "#c37100",
        "#db4161",
        "#9aeb00",
        "#9241f3",
        "#5182ff",
        "#a2a2a2",
        "#fff392"
    ];

    string[] private skin_colors = [
        // Greens
        "#538234",
        "#49a269",
        "#67d487",
        "#4b9540",
        "#538234",
        "#49a269",
        "#67d487",
        "#4b9540",
        "#538234",
        "#49a269",
        "#67d487",
        "#4b9540",
        "#538234",
        "#49a269",
        "#67d487",
        "#4b9540",
        "#538234",
        "#49a269",
        "#67d487",
        "#4b9540",
        "#538234",
        "#49a269",
        "#67d487",
        "#4b9540",
        "#538234",
        "#49a269",
        "#67d487",
        "#4b9540",
        // Browns and Yellows
        "#794100",
        "#8a8a00",
        "#b6a41d",
        "#dcc724",
        // Blues
        "#4192c3",
        "#61a2ff",
        "#61d3e3",
        "#a271ff",
        // Reds, Oranges, and Pinks
        "#d44f06",
        "#cf458c",
        "#d4a37c",
        "#FFC0CB",
        "#800080",
        "#8F00FF"
    ];

    constructor() {}

    function setBodies(FileData[] calldata data) external onlyOwner {
        bodies.setLayers(data, bodyLevelCounts);
    }

    function setCloths(FileDataColored[] calldata data) external onlyOwner {
        cloths.setLayers(data, clothLevelCounts);
    }

    function setEyes(FileDataColored[] calldata data) external onlyOwner {
        eyes.setLayers(data, eyesLevelCounts);
    }

    function setMouths(FileDataColored[] calldata data) external onlyOwner {
        mouths.setLayers(data, mouthLevelCounts);
    }

    function setAccessories(
        FileDataColored[] calldata data
    ) external onlyOwner {
        accessories.setLayers(data, accessoryLevelCounts);
    }

    function setHats(FileDataColored[] calldata data) external onlyOwner {
        hats.setLayers(data, hatLevelCounts);
    }

    function setEars(FileDataColored[] calldata data) external onlyOwner {
        ears.setLayers(data, earsLevelCounts);
    }

    // DATA

    function getItemData(
        SeedData calldata seed_data
    ) external view returns (ItemData memory) {
        Rand memory rnd = Rand(
            seed_data.seed,
            seed_data.seed2,
            seed_data.extra,
            0,
            0
        );
        ItemData memory data;
        data.lvl = rnd.lvl() + 1;
        setBcGround(data, rnd);
        setBody(data, rnd);
        setCloth(data, rnd);
        setEyes(data, rnd);
        setMouth(data, rnd);
        setAccessory(data, rnd);
        setHat(data, rnd);
        setEars(data, rnd);

        // limits
        if (data.lvl == 3) {
            if (data.mouth == 9) {
                if (data.accessory == 1 || data.accessory == 2)
                    data.accessory = 0;
            }
            if (data.eyes == 5) {
                if (
                    data.accessory == 3 ||
                    data.accessory == 6 ||
                    (data.accessory >= 15 && data.accessory <= 20)
                ) data.accessory = 0;
            }
        }
        if (data.lvl == 4) {
            if (data.eyes == 5) {
                if (
                    data.accessory == 1 ||
                    data.accessory == 5 ||
                    (data.accessory >= 8 && data.accessory <= 13) ||
                    (data.accessory >= 14 && data.accessory <= 19) ||
                    (data.accessory >= 20 && data.accessory <= 25)
                ) data.accessory = 0;
            }
            if (data.accessory == 5) {
                if (
                    data.eyes == 5 ||
                    data.accessory == 9 ||
                    data.accessory == 10
                ) data.eyes = 0;
            }
        }
        if (data.lvl == 5) {
            if (data.mouth == 9) {
                if (
                    data.accessory == 44 ||
                    (data.accessory >= 20 && data.accessory <= 25)
                ) data.accessory = 0;
            }
            if (data.eyes == 5) {
                if (
                    (data.accessory >= 8 && data.accessory <= 13) ||
                    (data.accessory >= 14 && data.accessory <= 19) ||
                    (data.accessory >= 26 && data.accessory <= 31) ||
                    (data.accessory >= 32 && data.accessory <= 37)
                ) data.accessory = 0;
            }
            if (data.hat == 49) {
                if (
                    data.accessory == 2 ||
                    data.accessory == 5 ||
                    data.accessory == 6 ||
                    data.accessory == 44 ||
                    (data.accessory >= 20 && data.accessory <= 25) ||
                    (data.accessory >= 38 && data.accessory <= 43)
                ) data.accessory = 0;
            }
        }
        if (data.lvl == 6) {
            if (data.mouth == 9) {
                if (
                    data.accessory == 3 ||
                    data.accessory == 48 ||
                    data.accessory == 55 ||
                    (data.accessory >= 30 && data.accessory <= 35) ||
                    (data.accessory >= 36 && data.accessory <= 41) ||
                    (data.accessory >= 49 && data.accessory <= 54)
                ) data.accessory = 0;
            }
            if (data.eyes == 5) {
                if (
                    data.accessory == 17 ||
                    (data.accessory >= 5 && data.accessory <= 10) ||
                    (data.accessory >= 11 && data.accessory <= 16) ||
                    (data.accessory >= 18 && data.accessory <= 23) ||
                    (data.accessory >= 42 && data.accessory <= 47)
                ) data.accessory = 0;
            }
            if (data.hat == 50) {
                if (
                    data.accessory == 2 ||
                    data.accessory == 17 ||
                    data.accessory == 48 ||
                    data.accessory == 55 ||
                    (data.accessory >= 24 && data.accessory <= 29) ||
                    (data.accessory >= 30 && data.accessory <= 35) ||
                    (data.accessory >= 36 && data.accessory <= 41)
                ) data.accessory = 0;
            }
        }

        return data;
    }

    function setBcGround(ItemData memory data, Rand memory rnd) private view {
        data.background = backgroundColors.random2(rnd);
    }

    function setBody(ItemData memory data, Rand memory rnd) private view {
        uint count = bodyLevelCounts[data.lvl - 1];
        if (count == 0) return;
        data.body = 1 + (rnd.next() % count);
        data.bodyColor = skin_colors.random2(rnd);
    }

    function setCloth(ItemData memory data, Rand memory rnd) private view {
        uint count = clothLevelCounts[data.lvl - 1];
        if (count == 0) return;
        if (!(rnd.next() % 100 < 60)) return;
        data.cloth = 1 + (rnd.next() % count);
    }

    function setEyes(ItemData memory data, Rand memory rnd) private view {
        uint count = eyesLevelCounts[data.lvl - 1];
        if (count == 0) return;
        data.eyes = 1 + (rnd.next() % count);
    }

    function setMouth(ItemData memory data, Rand memory rnd) private view {
        uint count = mouthLevelCounts[data.lvl - 1];
        if (count == 0) return;
        data.mouth = 1 + (rnd.next() % count);
    }

    function setAccessory(ItemData memory data, Rand memory rnd) private view {
        uint count = accessoryLevelCounts[data.lvl - 1];
        if (count == 0) return;
        if (!(rnd.next() % 100 < 37)) return;
        data.accessory = 1 + (rnd.next() % count);
    }

    function setHat(ItemData memory data, Rand memory rnd) private view {
        uint count = hatLevelCounts[data.lvl - 1];
        if (count == 0) return;
        if (!(rnd.next() % 100 < 37)) return;
        data.hat = 1 + (rnd.next() % count);
    }

    function setEars(ItemData memory data, Rand memory rnd) private view {
        uint count = earsLevelCounts[data.lvl - 1];
        if (count == 0) return;
        if (!(rnd.next() % 100 < 3)) return;
        data.ears = 1 + (rnd.next() % count);
    }

    // META

    function getMeta(
        SeedData calldata seed_data
    ) external view returns (string memory) {
        ItemData memory data = this.getItemData(seed_data);
        bytes memory lvl = abi.encodePacked('"level":', data.lvl.toString());
        bytes memory background = abi.encodePacked(
            ',"background":"',
            data.background,
            '"'
        );
        bytes memory body = abi.encodePacked(
            ',"bodyColor":"',
            data.bodyColor,
            '"'
        );
        bytes memory cloth = abi.encodePacked(
            ',"clothes":',
            data.cloth.toString()
        );
        bytes memory eyes = abi.encodePacked(',"eyes":', data.eyes.toString());
        bytes memory mouth = abi.encodePacked(
            ',"mouth":',
            data.mouth.toString()
        );
        bytes memory accessory = abi.encodePacked(
            ',"accessory":',
            data.accessory.toString()
        );
        bytes memory hat = abi.encodePacked(
            ',"Head Item":',
            data.hat.toString()
        );
        bytes memory ears = abi.encodePacked(',"ears":', data.ears.toString());
        bytes memory web_text = abi.encodePacked(',"web":"', web, '"');
        bytes memory description_text = abi.encodePacked(
            ',"description":"',
            description,
            '"'
        );

        return
            string(
                abi.encodePacked(
                    "{",
                    abi.encodePacked(
                        lvl,
                        background,
                        body,
                        cloth,
                        eyes,
                        mouth,
                        accessory,
                        hat,
                        ears
                    ),
                    web_text,
                    description_text,
                    "}"
                )
            );
    }

    // SVG

    function getSvg(
        SeedData calldata seed_data
    ) external view returns (string memory) {
        return toSvg(this.getItemData(seed_data));
    }

    function toSvg(ItemData memory data) private view returns (string memory) {
        require(data.lvl > 0, "lvl is zero");
        bytes memory svgStart = abi.encodePacked(
            "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0",
            " ",
            pixelsCount.toString(),
            " ",
            pixelsCount.toString(),
            "'>"
        );

        return
            string(
                abi.encodePacked(
                    svgStart,
                    backgroundSvg(data),
                    bodySvg(data),
                    clothSvg(data),
                    earsSvg(data),
                    mouthSvg(data),
                    eyesSvg(data),
                    accessorySvg(data),
                    hatSvg(data),
                    "</svg>"
                )
            );
    }

    function backgroundSvg(
        ItemData memory data
    ) private pure returns (string memory) {
        Rect memory r = Rect(0, 0, pixelsCount, pixelsCount);
        return r.toSvg(data.background);
    }

    function bodySvg(
        ItemData memory data
    ) private view returns (string memory) {
        if (data.body == 0) return "";
        return bodies[data.lvl - 1][data.body - 1].toSvg(data.bodyColor);
    }

    function clothSvg(
        ItemData memory data
    ) private view returns (string memory) {
        if (data.cloth == 0) return "";
        return cloths[data.lvl - 1][data.cloth - 1].toSvg();
    }

    function eyesSvg(
        ItemData memory data
    ) private view returns (string memory) {
        if (data.eyes == 0) return "";
        return eyes[data.lvl - 1][data.eyes - 1].toSvg();
    }

    function mouthSvg(
        ItemData memory data
    ) private view returns (string memory) {
        if (data.mouth == 0) return "";
        return mouths[data.lvl - 1][data.mouth - 1].toSvg();
    }

    function accessorySvg(
        ItemData memory data
    ) private view returns (string memory) {
        if (data.accessory == 0) return "";
        return accessories[data.lvl - 1][data.accessory - 1].toSvg();
    }

    function hatSvg(ItemData memory data) private view returns (string memory) {
        if (data.hat == 0) return "";
        return hats[data.lvl - 1][data.hat - 1].toSvg();
    }

    function earsSvg(
        ItemData memory data
    ) private view returns (string memory) {
        if (data.ears == 0) return "";
        return ears[data.lvl - 1][data.ears - 1].toSvg();
    }
}
合同源代码
文件 4 的 8:IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the value of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 value) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}
合同源代码
文件 5 的 8:IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}
合同源代码
文件 6 的 8:Ownable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract Ownable {
    address _owner;

    event RenounceOwnership();

    constructor() {
        _owner = msg.sender;
    }

    modifier onlyOwner() {
        require(_owner == msg.sender, "only owner");
        _;
    }

    function owner() external view virtual returns (address) {
        return _owner;
    }

    function ownerRenounce() public onlyOwner {
        _owner = address(0);
        emit RenounceOwnership();
    }

    function transferOwnership(address newOwner) external onlyOwner {
        _owner = newOwner;
    }
}
合同源代码
文件 7 的 8:Pepi.sol
//https://twitter.com/Pepi_ERC20i
//https://t.me/pepe_ERC20i
//https://pepe-erc20i.vip/

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;

import "./Erc20.sol";
import "./PoolCreatableErc20i.sol";
import "../Generator.sol";

library ExtraSeedLibrary {
    function extra(
        address account,
        uint extraSeed
    ) internal pure returns (uint256) {
        return uint(keccak256(abi.encodePacked(account, extraSeed)));
    }
}

abstract contract Mushrooms is PoolCreatableErc20i {
    using ExtraSeedLibrary for address;
    mapping(address owner => uint) _counts;
    mapping(address owner => mapping(uint index => SeedData seed_data)) _ownedTokens;
    mapping(address owner => mapping(uint tokenId => uint)) _ownedTokensIndex;
    mapping(address owner => mapping(uint => bool)) _owns;
    mapping(address owner => SeedData seed_data) _spores;
    mapping(uint index => address user) _holderList;
    mapping(address user => uint index) _holderListIndexes;
    uint _mushroomsTotalCount;
    uint _holdersCount;
    uint _sporesTotalCount;
    uint _random_nonce;

    event OnMushroomTransfer(
        address indexed from,
        address indexed to,
        SeedData seed_data
    );
    event OnSporesGrow(address indexed holder, SeedData seed_data);
    event OnSporesShrink(address indexed holder, SeedData seed_data);

    constructor() PoolCreatableErc20i("Pepe Inscriptions", "PEPI", msg.sender) {}

    modifier holder_calculate(address acc1, address acc2) {
        bool before1 = _isHolder(acc1);
        bool before2 = _isHolder(acc2);
        _;
        bool after1 = _isHolder(acc1);
        bool after2 = _isHolder(acc2);
        if (!before1 && after1) _addHolder(acc1);
        if (before1 && !after1) _removeHolder(acc1);
        if (!before2 && after2) _addHolder(acc2);
        if (before2 && !after2) _removeHolder(acc2);
    }

    function _isHolder(address account) private view returns (bool) {
        if (
            account == address(this) ||
            account == _pool ||
            account == address(0)
        ) return false;

        return (_spores[account].seed + this.mushroomCount(account)) > 0;
    }

    function trySeedTransfer(
        address from,
        address to,
        uint amount
    ) internal holder_calculate(from, to) {
        if (from == address(this)) return;
        uint seed = amount / (10 ** decimals());

        if (seed > 0 && from != _pool && to != _pool) {
            // transfer growing mushroom
            if (_spores[from].seed == seed) {
                SeedData memory data = _spores[from];
                _removeSeedCount(from, seed);
                _addTokenToOwnerEnumeration(to, data);
                emit OnMushroomTransfer(from, to, data);
                return;
            }

            // transfer collected mushroom
            if (_owns[from][seed] && !_owns[to][seed]) {
                SeedData memory data = _ownedTokens[from][
                    _ownedTokensIndex[from][seed]
                ];
                _removeTokenFromOwnerEnumeration(from, seed);
                _addTokenToOwnerEnumeration(to, data);
                emit OnMushroomTransfer(from, to, data);
                return;
            }
        }

        // transfer spores
        uint lastBalanceFromSeed = _balances[from] / (10 ** decimals());
        uint newBalanceFromSeed = (_balances[from] - amount) /
            (10 ** decimals());
        _removeSeedCount(from, lastBalanceFromSeed - newBalanceFromSeed);
        _addSeedCount(to, seed);
    }

    function _addHolder(address account) private {
        _holderList[_holdersCount] = account;
        _holderListIndexes[account] = _holdersCount;
        ++_holdersCount;
    }

    function _removeHolder(address account) private {
        if (_holdersCount == 0) return;
        --_holdersCount;
        uint removingIndex = _holderListIndexes[account];
        _holderList[removingIndex] = _holderList[_holdersCount];
        delete _holderList[_holdersCount];
        delete _holderListIndexes[account];
    }

    function getHolderByIndex(uint index) public view returns (address) {
        return _holderList[index];
    }

    function getHoldersList(
        uint startIndex,
        uint count
    ) public view returns (address[] memory) {
        address[] memory holders = new address[](count);
        for (uint i = 0; i < count; ++i)
            holders[i] = getHolderByIndex(startIndex + i);
        return holders;
    }

    function _addSeedCount(address account, uint seed) private {
        if (seed == 0) return;
        if (account == _pool) return;
        SeedData memory last = _spores[account];

        if (_spores[account].seed == 0)
            _spores[account].seed2 = RandLib.random_value(++_random_nonce);            
        _spores[account].seed += seed;
        _spores[account].extra = account.extra(++_random_nonce);

        if (last.seed == 0 && _spores[account].seed > 0) ++_sporesTotalCount;

        emit OnSporesGrow(account, _spores[account]);
    }

    function _removeSeedCount(address account, uint seed) private {
        if (seed == 0) return;
        if (account == _pool) return;
        SeedData memory lastSpores = _spores[account];
        if (_spores[account].seed >= seed) {
            _spores[account].seed -= seed;
            _spores[account].extra = account.extra(++_random_nonce);
            if (lastSpores.seed > 0 && _spores[account].seed == 0)
                --_sporesTotalCount;
            emit OnSporesShrink(account, _spores[account]);
            return;
        }
        uint seedRemains = seed - _spores[account].seed;
        _spores[account].seed = 0;
        _spores[account].extra = account.extra(++_random_nonce);

        // remove mushrooms
        uint count = _counts[account];
        uint removed;
        for (uint i = 0; i < count && removed < seedRemains; ++i) {
            removed += _removeFirstTokenFromOwner(account);
        }

        if (removed > seedRemains) {
            _spores[account].seed += removed - seedRemains;
            _spores[account].extra = account.extra(++_random_nonce);
        }
        if (lastSpores.seed > 0 && _spores[account].seed == 0)
            --_sporesTotalCount;
        emit OnSporesShrink(account, _spores[account]);
    }

    function _addTokenToOwnerEnumeration(
        address to,
        SeedData memory data
    ) private {
        if (to == _pool) return;
        ++_counts[to];
        ++_mushroomsTotalCount;
        uint length = _counts[to] - 1;
        _ownedTokens[to][length] = data;
        _ownedTokensIndex[to][data.seed] = length;
        _owns[to][data.seed] = true;
    }

    function _removeTokenFromOwnerEnumeration(address from, uint seed) private {
        if (from == _pool) return;
        --_counts[from];
        --_mushroomsTotalCount;
        _owns[from][seed] = false;
        uint lastTokenIndex = _counts[from];
        uint tokenIndex = _ownedTokensIndex[from][seed];
        SeedData memory data = _ownedTokens[from][tokenIndex];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            SeedData memory lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[from][lastTokenId.seed] = tokenIndex; // Update the moved token's index
        }

        delete _ownedTokensIndex[from][data.seed];
        delete _ownedTokens[from][lastTokenIndex];
    }

    function _removeFirstTokenFromOwner(address owner) private returns (uint) {
        uint count = _counts[owner];
        if (count == 0) return 0;
        uint seed = _ownedTokens[owner][0].seed;
        _removeTokenFromOwnerEnumeration(owner, seed);
        return seed;
    }

    function isOwnerOf(address owner, uint seed) external view returns (bool) {
        return _owns[owner][seed];
    }

    function sporesDegree(
        address owner
    ) external view returns (SeedData memory data) {
        return _spores[owner];
    }

    function mushroomCount(address owner) external view returns (uint) {
        return _counts[owner];
    }

    function mushroomOfOwnerByIndex(
        address owner,
        uint index
    ) external view returns (SeedData memory data) {
        return _ownedTokens[owner][index];
    }

    function mushroomsTotalCount() external view returns (uint) {
        return _mushroomsTotalCount;
    }

    function holdersCount() external view returns (uint) {
        return _holdersCount;
    }

    function sporesTotalCount() external view returns (uint) {
        return _sporesTotalCount;
    }
}

contract Pepi is Mushrooms, Generator {
    uint constant _startTotalSupply = 13370 * (10 ** _decimals);
    uint constant _startMaxBuyCount = (_startTotalSupply * 5) / 10000;
    uint constant _addMaxBuyPercentPerSec = 5; // 100%=_addMaxBuyPrecesion add 0.005%/second
    uint constant _addMaxBuyPrecesion = 100000;

    constructor() {
        _mint(msg.sender, _startTotalSupply);
    }

    modifier maxBuyLimit(uint256 amount) {
        require(amount <= maxBuy(), "max buy limit");
        _;
    }

    function maxBuy() public view returns (uint256) {
        if (!isStarted()) return _startTotalSupply;
        uint256 count = _startMaxBuyCount +
            (_startTotalSupply *
                (block.timestamp - _startTime) *
                _addMaxBuyPercentPerSec) /
            _addMaxBuyPrecesion;
        if (count > _startTotalSupply) count = _startTotalSupply;
        return count;
    }

    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal override {
        if (isStarted()) {
            trySeedTransfer(from, to, amount);
        } else {
            require(from == _owner || to == _owner, "not started");
        }

        // allow burning
        if (to == address(0)) {
            _burn(from, amount);
            return;
        }

        // system transfers
        if (from == address(this)) {
            super._transfer(from, to, amount);
            return;
        }

        if (_feeLocked) {
            super._transfer(from, to, amount);
            return;
        } else {
            if (from == _pool) {
                buy(to, amount);
                return;
            }
        }

        super._transfer(from, to, amount);
    }

    function buy(
        address to,
        uint256 amount
    ) private maxBuyLimit(amount) lockFee {
        super._transfer(_pool, to, amount);
    }

    function burnCount() public view returns (uint256) {
        return _startTotalSupply - totalSupply();
    }
}
合同源代码
文件 8 的 8:PoolCreatableErc20i.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.21;

import "./Erc20.sol";

abstract contract PoolCreatableErc20i is ERC20 {
    address internal _pool;
    uint256 internal _startTime;
    bool internal _feeLocked;
    address immutable _pairCreator;

    constructor(
        string memory name_,
        string memory symbol_,
        address pairCreator
    ) ERC20(name_, symbol_) {
        _pairCreator = pairCreator;
    }

    modifier lockFee() {
        _feeLocked = true;
        _;
        _feeLocked = false;
    }

    function launch(address poolAddress) external payable {
        require(msg.sender == _pairCreator);
        require(!isStarted());
        _pool = poolAddress;
        _startTime = block.timestamp;
    }

    function isStarted() internal view returns (bool) {
        return _pool != address(0);
    }

    function pool() external view returns (address) {
        return _pool;
    }
}
设置
{
  "compilationTarget": {
    "contracts/token/Pepi.sol": "Pepi"
  },
  "evmVersion": "paris",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": []
}
ABI
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"components":[{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"uint256","name":"seed2","type":"uint256"},{"internalType":"uint256","name":"extra","type":"uint256"}],"indexed":false,"internalType":"struct SeedData","name":"seed_data","type":"tuple"}],"name":"OnMushroomTransfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"holder","type":"address"},{"components":[{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"uint256","name":"seed2","type":"uint256"},{"internalType":"uint256","name":"extra","type":"uint256"}],"indexed":false,"internalType":"struct SeedData","name":"seed_data","type":"tuple"}],"name":"OnSporesGrow","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"holder","type":"address"},{"components":[{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"uint256","name":"seed2","type":"uint256"},{"internalType":"uint256","name":"extra","type":"uint256"}],"indexed":false,"internalType":"struct SeedData","name":"seed_data","type":"tuple"}],"name":"OnSporesShrink","type":"event"},{"anonymous":false,"inputs":[],"name":"RenounceOwnership","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burnCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getHolderByIndex","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"getHoldersList","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"uint256","name":"seed2","type":"uint256"},{"internalType":"uint256","name":"extra","type":"uint256"}],"internalType":"struct SeedData","name":"seed_data","type":"tuple"}],"name":"getItemData","outputs":[{"components":[{"internalType":"uint256","name":"lvl","type":"uint256"},{"internalType":"string","name":"background","type":"string"},{"internalType":"uint256","name":"body","type":"uint256"},{"internalType":"string","name":"bodyColor","type":"string"},{"internalType":"uint256","name":"cloth","type":"uint256"},{"internalType":"uint256","name":"eyes","type":"uint256"},{"internalType":"uint256","name":"mouth","type":"uint256"},{"internalType":"uint256","name":"accessory","type":"uint256"},{"internalType":"uint256","name":"hat","type":"uint256"},{"internalType":"uint256","name":"ears","type":"uint256"}],"internalType":"struct ItemData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"uint256","name":"seed2","type":"uint256"},{"internalType":"uint256","name":"extra","type":"uint256"}],"internalType":"struct SeedData","name":"seed_data","type":"tuple"}],"name":"getMeta","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"uint256","name":"seed2","type":"uint256"},{"internalType":"uint256","name":"extra","type":"uint256"}],"internalType":"struct SeedData","name":"seed_data","type":"tuple"}],"name":"getSvg","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"holdersCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"seed","type":"uint256"}],"name":"isOwnerOf","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"poolAddress","type":"address"}],"name":"launch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"maxBuy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"mushroomCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"mushroomOfOwnerByIndex","outputs":[{"components":[{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"uint256","name":"seed2","type":"uint256"},{"internalType":"uint256","name":"extra","type":"uint256"}],"internalType":"struct SeedData","name":"data","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mushroomsTotalCount","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":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownerRenounce","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"lvl","type":"uint256"},{"internalType":"uint256","name":"file","type":"uint256"},{"components":[{"internalType":"uint8","name":"x","type":"uint8"},{"internalType":"uint8","name":"y","type":"uint8"},{"internalType":"uint8","name":"width","type":"uint8"},{"internalType":"uint8","name":"height","type":"uint8"},{"internalType":"uint24","name":"color","type":"uint24"}],"internalType":"struct RectColored[]","name":"rects","type":"tuple[]"}],"internalType":"struct FileDataColored[]","name":"data","type":"tuple[]"}],"name":"setAccessories","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"lvl","type":"uint256"},{"internalType":"uint256","name":"file","type":"uint256"},{"components":[{"internalType":"uint8","name":"x","type":"uint8"},{"internalType":"uint8","name":"y","type":"uint8"},{"internalType":"uint8","name":"width","type":"uint8"},{"internalType":"uint8","name":"height","type":"uint8"}],"internalType":"struct Rect[]","name":"rects","type":"tuple[]"}],"internalType":"struct FileData[]","name":"data","type":"tuple[]"}],"name":"setBodies","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"lvl","type":"uint256"},{"internalType":"uint256","name":"file","type":"uint256"},{"components":[{"internalType":"uint8","name":"x","type":"uint8"},{"internalType":"uint8","name":"y","type":"uint8"},{"internalType":"uint8","name":"width","type":"uint8"},{"internalType":"uint8","name":"height","type":"uint8"},{"internalType":"uint24","name":"color","type":"uint24"}],"internalType":"struct RectColored[]","name":"rects","type":"tuple[]"}],"internalType":"struct FileDataColored[]","name":"data","type":"tuple[]"}],"name":"setCloths","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"lvl","type":"uint256"},{"internalType":"uint256","name":"file","type":"uint256"},{"components":[{"internalType":"uint8","name":"x","type":"uint8"},{"internalType":"uint8","name":"y","type":"uint8"},{"internalType":"uint8","name":"width","type":"uint8"},{"internalType":"uint8","name":"height","type":"uint8"},{"internalType":"uint24","name":"color","type":"uint24"}],"internalType":"struct RectColored[]","name":"rects","type":"tuple[]"}],"internalType":"struct FileDataColored[]","name":"data","type":"tuple[]"}],"name":"setEars","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"lvl","type":"uint256"},{"internalType":"uint256","name":"file","type":"uint256"},{"components":[{"internalType":"uint8","name":"x","type":"uint8"},{"internalType":"uint8","name":"y","type":"uint8"},{"internalType":"uint8","name":"width","type":"uint8"},{"internalType":"uint8","name":"height","type":"uint8"},{"internalType":"uint24","name":"color","type":"uint24"}],"internalType":"struct RectColored[]","name":"rects","type":"tuple[]"}],"internalType":"struct FileDataColored[]","name":"data","type":"tuple[]"}],"name":"setEyes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"lvl","type":"uint256"},{"internalType":"uint256","name":"file","type":"uint256"},{"components":[{"internalType":"uint8","name":"x","type":"uint8"},{"internalType":"uint8","name":"y","type":"uint8"},{"internalType":"uint8","name":"width","type":"uint8"},{"internalType":"uint8","name":"height","type":"uint8"},{"internalType":"uint24","name":"color","type":"uint24"}],"internalType":"struct RectColored[]","name":"rects","type":"tuple[]"}],"internalType":"struct FileDataColored[]","name":"data","type":"tuple[]"}],"name":"setHats","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"lvl","type":"uint256"},{"internalType":"uint256","name":"file","type":"uint256"},{"components":[{"internalType":"uint8","name":"x","type":"uint8"},{"internalType":"uint8","name":"y","type":"uint8"},{"internalType":"uint8","name":"width","type":"uint8"},{"internalType":"uint8","name":"height","type":"uint8"},{"internalType":"uint24","name":"color","type":"uint24"}],"internalType":"struct RectColored[]","name":"rects","type":"tuple[]"}],"internalType":"struct FileDataColored[]","name":"data","type":"tuple[]"}],"name":"setMouths","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"sporesDegree","outputs":[{"components":[{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"uint256","name":"seed2","type":"uint256"},{"internalType":"uint256","name":"extra","type":"uint256"}],"internalType":"struct SeedData","name":"data","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sporesTotalCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","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":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]