APE Price: $0.47 (-12.66%)

Contract

0x9761FE2A0239AbCdfB80DDD4Ce1E1E924fe8B23A

Overview

APE Balance

Apechain LogoApechain LogoApechain Logo0 APE

APE Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Update Metadata ...101652112025-02-17 13:00:1420 days ago1739797214IN
0x9761FE2A...24fe8B23A
0 APE0.0017786625.42069
Update Metadata ...98635692025-02-14 3:43:3823 days ago1739504618IN
0x9761FE2A...24fe8B23A
0 APE0.0016932725.42069
Update Metadata ...98634262025-02-14 3:40:3923 days ago1739504439IN
0x9761FE2A...24fe8B23A
0 APE0.0017644525.42069
Update Metadata ...86347002025-01-22 20:37:2346 days ago1737578243IN
0x9761FE2A...24fe8B23A
0 APE0.0017641425.42069
Update Metadata ...86116952025-01-22 9:04:4146 days ago1737536681IN
0x9761FE2A...24fe8B23A
0 APE0.0017811725.42069
Update Metadata ...86108582025-01-22 8:31:5646 days ago1737534716IN
0x9761FE2A...24fe8B23A
0 APE0.0018523525.42069
Update Metadata ...74274582025-01-02 1:36:5066 days ago1735781810IN
0x9761FE2A...24fe8B23A
0 APE0.0016930125.42069
Update Metadata ...72179332024-12-26 10:51:5173 days ago1735210311IN
0x9761FE2A...24fe8B23A
0 APE0.0016745125.42069
Update Metadata ...72177432024-12-26 10:41:3173 days ago1735209691IN
0x9761FE2A...24fe8B23A
0 APE0.0016745325.42069
Update Metadata ...72175332024-12-26 10:29:0473 days ago1735208944IN
0x9761FE2A...24fe8B23A
0 APE0.0016745325.42069
Update Metadata ...72173862024-12-26 10:19:3973 days ago1735208379IN
0x9761FE2A...24fe8B23A
0 APE0.0016745325.42069
Update Metadata ...70044992024-12-22 19:40:1377 days ago1734896413IN
0x9761FE2A...24fe8B23A
0 APE0.0017644525.42069
Update Metadata ...70013882024-12-22 18:39:2377 days ago1734892763IN
0x9761FE2A...24fe8B23A
0 APE0.0015349525.42069
Update Metadata ...70011772024-12-22 18:35:0377 days ago1734892503IN
0x9761FE2A...24fe8B23A
0 APE0.001677325.42069
Update Metadata ...70007182024-12-22 18:22:2477 days ago1734891744IN
0x9761FE2A...24fe8B23A
0 APE0.0016772825.42069
Update Metadata ...70006172024-12-22 18:19:3977 days ago1734891579IN
0x9761FE2A...24fe8B23A
0 APE0.001677325.42069
Update Metadata ...68038502024-12-17 22:05:3082 days ago1734473130IN
0x9761FE2A...24fe8B23A
0 APE0.00232825.42069
Update Metadata ...57117232024-11-28 12:25:19101 days ago1732796719IN
0x9761FE2A...24fe8B23A
0 APE0.0017455125.42069
Update Metadata ...54288502024-11-25 19:05:53104 days ago1732561553IN
0x9761FE2A...24fe8B23A
0 APE0.0017479725.42069
Update Metadata ...54280992024-11-25 19:02:11104 days ago1732561331IN
0x9761FE2A...24fe8B23A
0 APE0.0018191825.42069
Update Metadata ...53727642024-11-25 12:42:30104 days ago1732538550IN
0x9761FE2A...24fe8B23A
0 APE0.0017454825.42069
Update Metadata ...48729622024-11-21 11:15:38108 days ago1732187738IN
0x9761FE2A...24fe8B23A
0 APE0.0017479725.42069
Update Metadata ...48726262024-11-21 11:10:39108 days ago1732187439IN
0x9761FE2A...24fe8B23A
0 APE0.0018191525.42069
Update Metadata ...40688572024-11-11 13:38:35118 days ago1731332315IN
0x9761FE2A...24fe8B23A
0 APE0.0017454625.42069
Update Metadata ...40650652024-11-11 12:27:07118 days ago1731328027IN
0x9761FE2A...24fe8B23A
0 APE0.001674325.42069
View all transactions

Parent Transaction Hash Block From To
View All Internal Transactions

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
DropMetadataRenderer

Compiler Version
v0.8.25+commit.b61c2a91

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion
File 1 of 7 : DropMetadataRenderer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

import {StringsUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol";
import {IMetadataRenderer} from "../interfaces/IMetadataRenderer.sol";
import {MetadataRenderAdminCheck} from "./MetadataRenderAdminCheck.sol";

/// @notice Drops metadata system
contract DropMetadataRenderer is IMetadataRenderer, MetadataRenderAdminCheck {
    error MetadataFrozen();

    /// Event to mark updated metadata information
    event MetadataUpdated(
        address indexed target,
        string metadataBase,
        string metadataExtension,
        string contractURI,
        uint256 freezeAt
    );

    /// @notice Hash to mark updated provenance hash
    event ProvenanceHashUpdated(address indexed target, bytes32 provenanceHash);

    /// @notice Struct to store metadata info and update data
    struct MetadataURIInfo {
        string base;
        string extension;
        string contractURI;
        uint256 freezeAt;
    }

    /// @notice NFT metadata by contract
    mapping(address => MetadataURIInfo) public metadataBaseByContract;

    /// @notice Optional provenance hashes for NFT metadata by contract
    mapping(address => bytes32) public provenanceHashes;

    /// @notice Standard init for drop metadata from root drop contract
    /// @param data passed in for initialization
    function initializeWithData(bytes memory data) external {
        // data format: string baseURI, string newContractURI
        (string memory initialBaseURI, string memory initialContractURI) = abi
            .decode(data, (string, string));
        _updateMetadataDetails(
            msg.sender,
            initialBaseURI,
            "",
            initialContractURI,
            0
        );
    }

    /// @notice Update the provenance hash (optional) for a given nft
    /// @param target target address to update
    /// @param provenanceHash provenance hash to set
    function updateProvenanceHash(
        address target,
        bytes32 provenanceHash
    ) external requireSenderAdmin(target) {
        provenanceHashes[target] = provenanceHash;
        emit ProvenanceHashUpdated(target, provenanceHash);
    }

    /// @notice Update metadata base URI and contract URI
    /// @param baseUri new base URI
    /// @param newContractUri new contract URI (can be an empty string)
    function updateMetadataBase(
        address target,
        string memory baseUri,
        string memory newContractUri
    ) external requireSenderAdmin(target) {
        _updateMetadataDetails(target, baseUri, "", newContractUri, 0);
    }

    /// @notice Update metadata base URI, extension, contract URI and freezing detailsUpdate metadata base URI, extension, contract URI and freezing detailsUpdate metadata base URI, extension, contract URI and freezing detailsUpdate metadata base URI, extension, contract URI and freezing detailsUpdate metadata base URI, extension, contract URI and freezing detailsUpdate metadata base URI, extension, contract URI and freezing detailsUpdate metadata base URI, extension, contract URI and freezing detailsUpdate metadata base URI, extension, contract URI and freezing details
    /// @param target target contract to update metadata for
    /// @param metadataBase new base URI to update metadata with
    /// @param metadataExtension new extension to append to base metadata URI
    /// @param freezeAt time to freeze the contract metadata at (set to 0 to disable)
    function updateMetadataBaseWithDetails(
        address target,
        string memory metadataBase,
        string memory metadataExtension,
        string memory newContractURI,
        uint256 freezeAt
    ) external requireSenderAdmin(target) {
        _updateMetadataDetails(
            target,
            metadataBase,
            metadataExtension,
            newContractURI,
            freezeAt
        );
    }

    /// @notice Internal metadata update function
    /// @param metadataBase Base URI to update metadata for
    /// @param metadataExtension Extension URI to update metadata for
    /// @param freezeAt timestamp to freeze metadata (set to 0 to disable freezing)
    function _updateMetadataDetails(
        address target,
        string memory metadataBase,
        string memory metadataExtension,
        string memory newContractURI,
        uint256 freezeAt
    ) internal {
        if (freezeAt != 0 && freezeAt > block.timestamp) {
            revert MetadataFrozen();
        }

        metadataBaseByContract[target] = MetadataURIInfo({
            base: metadataBase,
            extension: metadataExtension,
            contractURI: newContractURI,
            freezeAt: freezeAt
        });
        emit MetadataUpdated({
            target: target,
            metadataBase: metadataBase,
            metadataExtension: metadataExtension,
            contractURI: newContractURI,
            freezeAt: freezeAt
        });
    }

    /// @notice A contract URI for the given drop contract
    /// @dev reverts if a contract uri is not provided
    /// @return contract uri for the contract metadata
    function contractURI() external view override returns (string memory) {
        string memory uri = metadataBaseByContract[msg.sender].contractURI;
        if (bytes(uri).length == 0) revert();
        return uri;
    }

    /// @notice A token URI for the given drops contract
    /// @dev reverts if a contract uri is not set
    /// @return token URI for the given token ID and contract (set by msg.sender)
    function tokenURI(
        uint256 tokenId
    ) external view override returns (string memory) {
        MetadataURIInfo memory info = metadataBaseByContract[msg.sender];

        if (bytes(info.base).length == 0) revert();

        return
            string(
                abi.encodePacked(
                    info.base,
                    StringsUpgradeable.toString(tokenId),
                    info.extension
                )
            );
    }
}

File 2 of 7 : StringsUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

import "./math/MathUpgradeable.sol";
import "./math/SignedMathUpgradeable.sol";

/**
 * @dev String operations.
 */
library StringsUpgradeable {
    bytes16 private constant _SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = MathUpgradeable.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toString(int256 value) internal pure returns (string memory) {
        return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMathUpgradeable.abs(value))));
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, MathUpgradeable.log256(value) + 1);
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }

    /**
     * @dev Returns true if the two strings are equal.
     */
    function equal(string memory a, string memory b) internal pure returns (bool) {
        return keccak256(bytes(a)) == keccak256(bytes(b));
    }
}

File 3 of 7 : IMetadataRenderer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

interface IMetadataRenderer {
    function tokenURI(uint256) external view returns (string memory);
    function contractURI() external view returns (string memory);
    function initializeWithData(bytes memory initData) external;
}

File 4 of 7 : MetadataRenderAdminCheck.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

import {IERC721Drop} from "../interfaces/IERC721Drop.sol";

contract MetadataRenderAdminCheck {
    error Access_OnlyAdmin();

    /// @notice Modifier to require the sender to be an admin
    /// @param target address that the user wants to modify
    modifier requireSenderAdmin(address target) {
        if (target != msg.sender && !IERC721Drop(target).isAdmin(msg.sender)) {
            revert Access_OnlyAdmin();
        }

        _;
    }
}

File 5 of 7 : MathUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library MathUpgradeable {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1, "Math: mulDiv overflow");

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
        }
    }
}

File 6 of 7 : SignedMathUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard signed math utilities missing in the Solidity language.
 */
library SignedMathUpgradeable {
    /**
     * @dev Returns the largest of two signed numbers.
     */
    function max(int256 a, int256 b) internal pure returns (int256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two signed numbers.
     */
    function min(int256 a, int256 b) internal pure returns (int256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two signed numbers without overflow.
     * The result is rounded towards zero.
     */
    function average(int256 a, int256 b) internal pure returns (int256) {
        // Formula from the book "Hacker's Delight"
        int256 x = (a & b) + ((a ^ b) >> 1);
        return x + (int256(uint256(x) >> 255) & (a ^ b));
    }

    /**
     * @dev Returns the absolute unsigned value of a signed value.
     */
    function abs(int256 n) internal pure returns (uint256) {
        unchecked {
            // must be unchecked in order to support `n = type(int256).min`
            return uint256(n >= 0 ? n : -n);
        }
    }
}

File 7 of 7 : IERC721Drop.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

import {IMetadataRenderer} from "../interfaces/IMetadataRenderer.sol";

/// @notice Interface for Freee Drops contract
interface IERC721Drop {
    // Enums

    /// @notice Phase type
    enum PhaseType {
        Public,
        Presale,
        Airdrop,
        AdminMint
    }

    // Access errors

    /// @notice Only admin can access this function
    error Access_OnlyAdmin();
    /// @notice Missing the given role or admin access
    error Access_MissingRoleOrAdmin(bytes32 role);
    /// @notice Withdraw is not allowed by this user
    error Access_WithdrawNotAllowed();
    /// @notice Cannot withdraw funds due to ETH send failure.
    error Withdraw_FundsSendFailure();
    /// @notice Mint fee send failure
    error MintFee_FundsSendFailure();
    /// @notice Protocol Rewards withdraw failure
    error ProtocolRewards_WithdrawSendFailure();

    /// @notice Call to external metadata renderer failed.
    error ExternalMetadataRenderer_CallFailed();

    /// @notice Thrown when the operator for the contract is not allowed
    /// @dev Used when strict enforcement of marketplaces for creator royalties is desired.
    error OperatorNotAllowed(address operator);

    /// @notice Thrown when there is no active market filter DAO address supported for the current chain
    /// @dev Used for enabling and disabling filter for the given chain.
    error MarketFilterDAOAddressNotSupportedForChain();

    /// @notice Used when the operator filter registry external call fails
    /// @dev Used for bubbling error up to clients.
    error RemoteOperatorFilterRegistryCallFailed();

    /// @notice Used when attempt to transfer soulbound token
    error Transfer_NotAllowed();

    // Sale/Purchase errors
    /// @notice Sale is inactive
    error Sale_Inactive();
    /// @notice Presale is inactive
    error Presale_Inactive();
    /// @notice Presale merkle root is invalid
    error Presale_MerkleNotApproved();
    /// @notice Wrong price for purchase
    error Purchase_WrongPrice(uint256 correctPrice);
    /// @notice NFT sold out
    error Mint_SoldOut();
    /// @notice Too many purchase for address
    error Purchase_TooManyForAddress();
    /// @notice Too many presale for address
    error Presale_TooManyForAddress();

    // Admin errors
    /// @notice Royalty percentage too high
    error Setup_RoyaltyPercentageTooHigh(uint16 maxRoyaltyBPS);
    /// @notice Invalid admin upgrade address
    error Admin_InvalidUpgradeAddress(address proposedAddress);
    /// @notice Unable to finalize an edition not marked as open (size set to uint64_max_value)
    error Admin_UnableToFinalizeNotOpenEdition();
    /// @notice Cannot reserve every mint for admin
    error InvalidMintSchedule();

    /// @notice Event emitted for mint fee payout
    /// @param mintFeeAmount amount of the mint fee
    /// @param mintFeeRecipient recipient of the mint fee
    /// @param success if the payout succeeded
    event MintFeePayout(uint256 mintFeeAmount, address mintFeeRecipient, bool success);

    /// @notice Event emitted for each sale
    /// @param phase phase of the sale
    /// @param to address sale was made to
    /// @param quantity quantity of the minted nfts
    /// @param pricePerToken price for each token
    /// @param firstPurchasedTokenId first purchased token ID (to get range add to quantity for max)
    event Sale(PhaseType phase, address indexed to, uint256 indexed quantity, uint256 indexed pricePerToken, uint256 firstPurchasedTokenId);

    /// @notice Event emitted for each sale
    /// @param sender address sale was made to
    /// @param tokenContract address of the token contract
    /// @param tokenId first purchased token ID (to get range add to quantity for max)
    /// @param quantity quantity of the minted nfts
    /// @param comment caller provided comment
    event MintComment(address indexed sender, address indexed tokenContract, uint256 indexed tokenId, uint256 quantity, string comment);

    /// @notice Sales configuration has been changed
    /// @dev To access new sales configuration, use getter function.
    /// @param changedBy Changed by user
    event SalesConfigChanged(address indexed changedBy);

    /// @notice Event emitted when the funds recipient is changed
    /// @param newAddress new address for the funds recipient
    /// @param changedBy address that the recipient is changed by
    event FundsRecipientChanged(address indexed newAddress, address indexed changedBy);

    /// @notice Event emitted when the funds are withdrawn from the minting contract
    /// @param withdrawnBy address that issued the withdraw
    /// @param withdrawnTo address that the funds were withdrawn to
    /// @param amount amount that was withdrawn
    /// @param feeRecipient user getting withdraw fee (if any)
    /// @param feeAmount amount of the fee getting sent (if any)
    event FundsWithdrawn(address indexed withdrawnBy, address indexed withdrawnTo, uint256 amount, address feeRecipient, uint256 feeAmount);

    /// @notice Event emitted when an open mint is finalized and further minting is closed forever on the contract.
    /// @param sender address sending close mint
    /// @param numberOfMints number of mints the contract is finalized at
    event OpenMintFinalized(address indexed sender, uint256 numberOfMints);

    /// @notice Event emitted when the soulbound status is changed
    /// @param isSoulbound new soulbound status
    /// @param changedBy address that the soulbound status is changed by
    event SoulboundStatusChanged(bool isSoulbound, address changedBy);

    /// @notice Event emitted when metadata renderer is updated.
    /// @param sender address of the updater
    /// @param renderer new metadata renderer address
    event UpdatedMetadataRenderer(address sender, IMetadataRenderer renderer);

    /// @notice Admin function to update the sales configuration settings
    /// @param publicSalePrice public sale price in ether
    /// @param maxSalePurchasePerAddress Max # of purchases (public) per address allowed
    /// @param publicSaleStart unix timestamp when the public sale starts
    /// @param publicSaleEnd unix timestamp when the public sale ends (set to 0 to disable)
    /// @param presaleStart unix timestamp when the presale starts
    /// @param presaleEnd unix timestamp when the presale ends
    /// @param presaleMerkleRoot merkle root for the presale information
    function setSaleConfiguration(
        uint104 publicSalePrice,
        uint32 maxSalePurchasePerAddress,
        uint64 publicSaleStart,
        uint64 publicSaleEnd,
        uint64 presaleStart,
        uint64 presaleEnd,
        bytes32 presaleMerkleRoot
    ) external;

    /// @notice General configuration for NFT Minting and bookkeeping
    struct Configuration {
        /// @dev Metadata renderer (uint160)
        IMetadataRenderer metadataRenderer;
        /// @dev Total size of edition that can be minted (uint160+64 = 224)
        uint64 editionSize;
        /// @dev Royalty amount in bps (uint224+16 = 240)
        uint16 royaltyBPS;
        /// @dev Funds recipient for sale (new slot, uint160)
        address payable fundsRecipient;
        /// @dev soulboundNFT
        bool isSoulbound;
    }

    /// @notice Sales states and configuration
    /// @dev Uses 3 storage slots
    struct SalesConfiguration {
        /// @dev Public sale price (max ether value > 1000 ether with this value)
        uint104 publicSalePrice;
        /// @notice Purchase mint limit per address (if set to 0 === unlimited mints)
        /// @dev Max purchase number per txn (90+32 = 122)
        uint32 maxSalePurchasePerAddress;
        /// @dev uint64 type allows for dates into 292 billion years
        /// @notice Public sale start timestamp (136+64 = 186)
        uint64 publicSaleStart;
        /// @notice Public sale end timestamp (186+64 = 250)
        uint64 publicSaleEnd;
        /// @notice Presale start timestamp
        /// @dev new storage slot
        uint64 presaleStart;
        /// @notice Presale end timestamp
        uint64 presaleEnd;
        /// @notice Presale merkle root
        bytes32 presaleMerkleRoot;
    }

    /// @notice Return value for sales details to use with front-ends
    struct SaleDetails {
        // Synthesized status variables for sale and presale
        bool publicSaleActive;
        bool presaleActive;
        // Price for public sale
        uint256 publicSalePrice;
        // Timed sale actions for public sale
        uint64 publicSaleStart;
        uint64 publicSaleEnd;
        // Timed sale actions for presale
        uint64 presaleStart;
        uint64 presaleEnd;
        // Merkle root (includes address, quantity, and price data for each entry)
        bytes32 presaleMerkleRoot;
        // Limit public sale to a specific number of mints per wallet
        uint256 maxSalePurchasePerAddress;
        // Information about the rest of the supply
        // Total that have been minted
        uint256 totalMinted;
        // The total supply available
        uint256 maxSupply;
    }

    /// @notice Return type of specific mint counts and details per address
    struct AddressMintDetails {
        /// Number of total mints from the given address
        uint256 totalMints;
        /// Number of presale mints from the given address
        uint256 presaleMints;
        /// Number of public mints from the given address
        uint256 publicMints;
    }

    /// @notice External purchase function (payable in eth)
    /// @param quantity to purchase
    /// @return first minted token ID
    function purchase(uint256 quantity) external payable returns (uint256);

    /// @notice External purchase presale function (takes a merkle proof and matches to root) (payable in eth)
    /// @param quantity to purchase
    /// @param maxQuantity can purchase (verified by merkle root)
    /// @param pricePerToken price per token allowed (verified by merkle root)
    /// @param merkleProof input for merkle proof leaf verified by merkle root
    /// @return first minted token ID
    function purchasePresale(uint256 quantity, uint256 maxQuantity, uint256 pricePerToken, bytes32[] memory merkleProof) external payable returns (uint256);

    /// @notice Function to return the global sales details for the given drop
    function saleDetails() external view returns (SaleDetails memory);

    /// @notice Function to return the specific sales details for a given address
    /// @param minter address for minter to return mint information for
    function mintedPerAddress(address minter) external view returns (AddressMintDetails memory);

    /// @notice This is the opensea/public owner setting that can be set by the contract admin
    function owner() external view returns (address);

    /// @notice Update the metadata renderer
    /// @param newRenderer new address for renderer
    /// @param setupRenderer data to call to bootstrap data for the new renderer (optional)
    function setMetadataRenderer(IMetadataRenderer newRenderer, bytes memory setupRenderer) external;

    /// @notice This is an admin mint function to mint a quantity to a specific address
    /// @param to address to mint to
    /// @param quantity quantity to mint
    /// @return the id of the first minted NFT
    function adminMint(address to, uint256 quantity) external returns (uint256);

    /// @notice This is an admin mint function to mint a single nft each to a list of addresses
    /// @param to list of addresses to mint an NFT each to
    /// @return the id of the first minted NFT
    function adminMintAirdrop(address[] memory to) external returns (uint256);

    /// @dev Getter for admin role associated with the contract to handle metadata
    /// @return boolean if address is admin
    function isAdmin(address user) external view returns (bool);
}

Settings
{
  "remappings": [
    "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "erc721a-upgradeable/=lib/ERC721A-Upgradeable/contracts/",
    "forge-std/=lib/forge-std/src/",
    "ERC721A-Upgradeable/=lib/ERC721A-Upgradeable/contracts/",
    "ds-test/=lib/forge-std/lib/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
    "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "openzeppelin/=lib/openzeppelin-contracts/contracts/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "viaIR": true,
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"name":"Access_OnlyAdmin","type":"error"},{"inputs":[],"name":"MetadataFrozen","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"string","name":"metadataBase","type":"string"},{"indexed":false,"internalType":"string","name":"metadataExtension","type":"string"},{"indexed":false,"internalType":"string","name":"contractURI","type":"string"},{"indexed":false,"internalType":"uint256","name":"freezeAt","type":"uint256"}],"name":"MetadataUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"bytes32","name":"provenanceHash","type":"bytes32"}],"name":"ProvenanceHashUpdated","type":"event"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"name":"initializeWithData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"metadataBaseByContract","outputs":[{"internalType":"string","name":"base","type":"string"},{"internalType":"string","name":"extension","type":"string"},{"internalType":"string","name":"contractURI","type":"string"},{"internalType":"uint256","name":"freezeAt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"provenanceHashes","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"string","name":"baseUri","type":"string"},{"internalType":"string","name":"newContractUri","type":"string"}],"name":"updateMetadataBase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"string","name":"metadataBase","type":"string"},{"internalType":"string","name":"metadataExtension","type":"string"},{"internalType":"string","name":"newContractURI","type":"string"},{"internalType":"uint256","name":"freezeAt","type":"uint256"}],"name":"updateMetadataBaseWithDetails","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes32","name":"provenanceHash","type":"bytes32"}],"name":"updateProvenanceHash","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608080604052346015576115fb908161001b8239f35b600080fdfe6080604052600436101561001257600080fd5b60003560e01c806342495a9514610de9578063856a7ffa1461097257806391074f981461090c578063af806d561461042f578063c87b56dd146101ef578063cc1306db14610100578063de5af49b146100c65763e8a3d4851461007457600080fd5b346100c15760003660031901126100c15733600052600060205261009e60026040600020016113ff565b8051156100c1576100bd906040519182916020835260208301906114c7565b0390f35b600080fd5b346100c15760203660031901126100c1576001600160a01b036100e76112e8565b1660005260016020526020604060002054604051908152f35b346100c15760403660031901126100c1576101196112e8565b6001600160a01b03166024353382141580610181575b61016f5760207ff2e078c4022bfd6c56addd06540a4a5dd4252b6b2c424b6840c184063f48fc2791836000526001825280604060002055604051908152a2005b6040516302bd6bd160e01b8152600490fd5b50604051630935e01b60e21b8152336004820152602081602481865afa9081156101e3576000916101b4575b501561012f565b6101d6915060203d6020116101dc575b6101ce8183611334565b81019061154b565b836101ad565b503d6101c4565b6040513d6000823e3d90fd5b346100c1576020806003193601126100c15760043590336000526000815260406000206040519261021f846112fe565b610228826113ff565b8452600193600361023b600185016113ff565b9385830194855261024e600282016113ff565b60408401520154606082015251918251156100c157600091807a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008181811015610421575b5050856d04ee2d6d415b85acef810000000080841015610413575b5050662386f26fc1000080831015610404575b506305f5e100808310156103f5575b50612710808310156103e6575b5060648210156103d6575b600a809210156103cc575b9560018401968160216103186103028b611355565b9a6103106040519c8d611334565b808c52611355565b8a8a019790601f19013689378a0101905b610396575b61036388610382818a8d8b8b519160405197846103548a9651809289808a0191016114a4565b850191518093878401906114a4565b01610376825180938680850191016114a4565b01038085520183611334565b6100bd6040519282849384528301906114c7565b600019019083906f181899199a1a9b1b9c1cb0b131b232b360811b8282061a8353049182156103c757919082610329565b61032e565b92600101926102ed565b92906064600291049101926102e2565b600491949204910192876102d7565b600891949204910192876102ca565b601091949204910192876102bb565b9401939091049085886102a8565b60409550049150878061028d565b346100c15760603660031901126100c1576104486112e8565b6024356001600160401b0381116100c1576104679036906004016113a7565b6044356001600160401b0381116100c1576104869036906004016113a7565b916001600160a01b038116331415806108b1575b61016f57604051906104ab82611319565b60008252604051936104bc856112fe565b8385528260208601528060408601526000606086015260018060a01b0382166000526000602052604060002085518051906001600160401b03821161070f57819061050784546113c5565b601f8111610861575b50602090601f83116001146107fb576000926107f0575b50508160011b916000199060031b1c19161781555b60208601518051906001600160401b03821161070f57819061056160018501546113c5565b601f811161079d575b50602090601f831160011461073057600092610725575b50508160011b916000199060031b1c19161760018201555b60408601519586516001600160401b03811161070f576105bc60028401546113c5565b601f81116106c4575b506020601f821160011461063e5761062e949392826003936060936000805160206115a68339815191529b9c600092610633575b50508160011b9160001990861b1c19161760028501555b01519101556040516001600160a01b039093169592938493846114ec565b0390a2005b015190508c806105f9565b601f198216986002850160005260206000209960005b8181106106ac5750836000805160206115a68339815191529a9b60609461062e9998979460039760019510610694575b505050811b016002850155610610565b015160001983881b60f8161c191690558c8080610684565b838301518c556001909b019a60209384019301610654565b600284016000526020600020601f830160051c81019160208410610705575b601f0160051c01905b8181106106f957506105c5565b600081556001016106ec565b90915081906106e3565b634e487b7160e01b600052604160045260246000fd5b015190508880610581565b600185016000908152602081209350601f198516905b818110610785575090846001959493921061076c575b505050811b016001820155610599565b015160001960f88460031b161c1916905588808061075c565b92936020600181928786015181550195019301610746565b909150600184016000526020600020601f840160051c8101602085106107e9575b90849392915b601f830160051c820181106107da57505061056a565b600081558594506001016107c4565b50806107be565b015190508880610527565b6000858152602081209350601f198516905b8181106108495750908460019594939210610830575b505050811b01815561053c565b015160001960f88460031b161c19169055888080610823565b9293602060018192878601518155019501930161080d565b909150836000526020600020601f840160051c8101602085106108aa575b90849392915b601f830160051c8201811061089b575050610510565b60008155859450600101610885565b508061087f565b50604051630935e01b60e21b81523360048201526020816024816001600160a01b0386165afa9081156101e3576000916108ed575b501561049a565b610906915060203d6020116101dc576101ce8183611334565b846108e6565b346100c15760203660031901126100c1576001600160a01b0361092d6112e8565b1660005260006020526040600020610944816113ff565b6100bd610953600184016113ff565b926003610962600283016113ff565b910154906040519485948561152d565b346100c15760203660031901126100c1576004356001600160401b0381116100c157366023820112156100c1576109b3903690602481600401359101611370565b8051810190604081602084019303126100c15760208101516001600160401b0381116100c1578260206109e892840101611563565b916040820151916001600160401b0383116100c157610a0a9201602001611563565b9060405191610a1883611319565b6000835260405192610a29846112fe565b82845280602085015281604085015260006060850152336000526000602052604060002084518051906001600160401b03821161070f578190610a6c84546113c5565b601f8111610d99575b50602090601f8311600114610d3357600092610d28575b50508160011b916000199060031b1c19161781555b60208501518051906001600160401b03821161070f578190610ac660018501546113c5565b601f8111610cd5575b50602090601f8311600114610c6857600092610c5d575b50508160011b916000199060031b1c19161760018201555b60408501519485516001600160401b03811161070f57610b2160028401546113c5565b601f8111610c12575b506020601f8211600114610b915791816060926003946000805160206115a6833981519152999a600092610b86575b50508160011b9160001990861b1c19161760028501555b015191015561062e6040519283923396846114ec565b015190508a80610b59565b601f198216976002850160005260206000209860005b818110610bfa5750926000805160206115a68339815191529899600395936001938360609710610be2575b505050811b016002850155610b70565b015160001983881b60f8161c191690558a8080610bd2565b838301518b556001909a019960209384019301610ba7565b600284016000526020600020601f830160051c81019160208410610c53575b601f0160051c01905b818110610c475750610b2a565b60008155600101610c3a565b9091508190610c31565b015190508780610ae6565b600185016000908152602081209350601f198516905b818110610cbd5750908460019594939210610ca4575b505050811b016001820155610afe565b015160001960f88460031b161c19169055878080610c94565b92936020600181928786015181550195019301610c7e565b909150600184016000526020600020601f840160051c810160208510610d21575b90849392915b601f830160051c82018110610d12575050610acf565b60008155859450600101610cfc565b5080610cf6565b015190508780610a8c565b6000858152602081209350601f198516905b818110610d815750908460019594939210610d68575b505050811b018155610aa1565b015160001960f88460031b161c19169055878080610d5b565b92936020600181928786015181550195019301610d45565b909150836000526020600020601f840160051c810160208510610de2575b90849392915b601f830160051c82018110610dd3575050610a75565b60008155859450600101610dbd565b5080610db7565b346100c15760a03660031901126100c157610e026112e8565b6024356001600160401b0381116100c157610e219036906004016113a7565b906044356001600160401b0381116100c157610e419036906004016113a7565b906064356001600160401b0381116100c157610e619036906004016113a7565b906001600160a01b0381163314158061128d575b61016f57608435151580611282575b6112705760405193610e95856112fe565b808552836020860152826040860152608435606086015260018060a01b0382166000526000602052604060002085518051906001600160401b03821161070f578190610ee184546113c5565b601f8111611220575b50602090601f83116001146111ba576000926111af575b50508160011b916000199060031b1c19161781555b60208601518051906001600160401b03821161070f578190610f3b60018501546113c5565b601f811161115c575b50602090601f83116001146110ef576000926110e4575b50508160011b916000199060031b1c19161760018201555b60408601519586516001600160401b03811161070f57610f9660028401546113c5565b601f811161109d575b506020601f82116001146110175761062e949392826003936060936000805160206115a68339815191529b9c60009261100c575b50508160011b9160001990861b1c19161760028501555b01519101556040516001600160a01b039093169592938493608435928561152d565b015190508c80610fd3565b601f198216986002850160005260206000209960005b8181106110855750836000805160206115a68339815191529a9b60609461062e999897946003976001951061106d575b505050811b016002850155610fea565b015160001983881b60f8161c191690558c808061105d565b838301518c556001909b019a6020938401930161102d565b600284016000526020600020601f830160051c8101602084106110dd575b601f830160051c820181106110d1575050610f9f565b600081556001016110bb565b50806110bb565b015190508880610f5b565b600185016000908152602081209350601f198516905b818110611144575090846001959493921061112b575b505050811b016001820155610f73565b015160001960f88460031b161c1916905588808061111b565b92936020600181928786015181550195019301611105565b909150600184016000526020600020601f840160051c8101602085106111a8575b90849392915b601f830160051c82018110611199575050610f44565b60008155859450600101611183565b508061117d565b015190508880610f01565b6000858152602081209350601f198516905b81811061120857509084600195949392106111ef575b505050811b018155610f16565b015160001960f88460031b161c191690558880806111e2565b929360206001819287860151815501950193016111cc565b909150836000526020600020601f840160051c810160208510611269575b90849392915b601f830160051c8201811061125a575050610eea565b60008155859450600101611244565b508061123e565b60405163777821ff60e11b8152600490fd5b504260843511610e84565b50604051630935e01b60e21b81523360048201526020816024816001600160a01b0386165afa9081156101e3576000916112c9575b5015610e75565b6112e2915060203d6020116101dc576101ce8183611334565b856112c2565b600435906001600160a01b03821682036100c157565b608081019081106001600160401b0382111761070f57604052565b602081019081106001600160401b0382111761070f57604052565b90601f801991011681019081106001600160401b0382111761070f57604052565b6001600160401b03811161070f57601f01601f191660200190565b92919261137c82611355565b9161138a6040519384611334565b8294818452818301116100c1578281602093846000960137010152565b9080601f830112156100c1578160206113c293359101611370565b90565b90600182811c921680156113f5575b60208310146113df57565b634e487b7160e01b600052602260045260246000fd5b91607f16916113d4565b90604051918260008254611412816113c5565b908184526020946001916001811690816000146114825750600114611443575b50505061144192500383611334565b565b600090815285812095935091905b81831061146a5750506114419350820101388080611432565b85548884018501529485019487945091830191611451565b9250505061144194925060ff191682840152151560051b820101388080611432565b60005b8381106114b75750506000910152565b81810151838201526020016114a7565b906020916114e0815180928185528580860191016114a4565b601f01601f1916010190565b93926115289061151a60009461150c60609560808a5260808a01906114c7565b9088820360208a01526114c7565b9086820360408801526114c7565b930152565b94939261151a60609361150c6115289460808a5260808a01906114c7565b908160209103126100c1575180151581036100c15790565b81601f820112156100c157805161157981611355565b926115876040519485611334565b818452602082840101116100c1576113c291602080850191016114a456fe5eff125d5659803f33dbda215d6e8bfe0a404fd213a9ecb5e61973ee16cb17e7a2646970667358221220979a2ce5a9ba1b3e4193fa3539654e84b983b05b39d05413579f1757145ea87f64736f6c63430008190033

Deployed Bytecode

0x6080604052600436101561001257600080fd5b60003560e01c806342495a9514610de9578063856a7ffa1461097257806391074f981461090c578063af806d561461042f578063c87b56dd146101ef578063cc1306db14610100578063de5af49b146100c65763e8a3d4851461007457600080fd5b346100c15760003660031901126100c15733600052600060205261009e60026040600020016113ff565b8051156100c1576100bd906040519182916020835260208301906114c7565b0390f35b600080fd5b346100c15760203660031901126100c1576001600160a01b036100e76112e8565b1660005260016020526020604060002054604051908152f35b346100c15760403660031901126100c1576101196112e8565b6001600160a01b03166024353382141580610181575b61016f5760207ff2e078c4022bfd6c56addd06540a4a5dd4252b6b2c424b6840c184063f48fc2791836000526001825280604060002055604051908152a2005b6040516302bd6bd160e01b8152600490fd5b50604051630935e01b60e21b8152336004820152602081602481865afa9081156101e3576000916101b4575b501561012f565b6101d6915060203d6020116101dc575b6101ce8183611334565b81019061154b565b836101ad565b503d6101c4565b6040513d6000823e3d90fd5b346100c1576020806003193601126100c15760043590336000526000815260406000206040519261021f846112fe565b610228826113ff565b8452600193600361023b600185016113ff565b9385830194855261024e600282016113ff565b60408401520154606082015251918251156100c157600091807a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008181811015610421575b5050856d04ee2d6d415b85acef810000000080841015610413575b5050662386f26fc1000080831015610404575b506305f5e100808310156103f5575b50612710808310156103e6575b5060648210156103d6575b600a809210156103cc575b9560018401968160216103186103028b611355565b9a6103106040519c8d611334565b808c52611355565b8a8a019790601f19013689378a0101905b610396575b61036388610382818a8d8b8b519160405197846103548a9651809289808a0191016114a4565b850191518093878401906114a4565b01610376825180938680850191016114a4565b01038085520183611334565b6100bd6040519282849384528301906114c7565b600019019083906f181899199a1a9b1b9c1cb0b131b232b360811b8282061a8353049182156103c757919082610329565b61032e565b92600101926102ed565b92906064600291049101926102e2565b600491949204910192876102d7565b600891949204910192876102ca565b601091949204910192876102bb565b9401939091049085886102a8565b60409550049150878061028d565b346100c15760603660031901126100c1576104486112e8565b6024356001600160401b0381116100c1576104679036906004016113a7565b6044356001600160401b0381116100c1576104869036906004016113a7565b916001600160a01b038116331415806108b1575b61016f57604051906104ab82611319565b60008252604051936104bc856112fe565b8385528260208601528060408601526000606086015260018060a01b0382166000526000602052604060002085518051906001600160401b03821161070f57819061050784546113c5565b601f8111610861575b50602090601f83116001146107fb576000926107f0575b50508160011b916000199060031b1c19161781555b60208601518051906001600160401b03821161070f57819061056160018501546113c5565b601f811161079d575b50602090601f831160011461073057600092610725575b50508160011b916000199060031b1c19161760018201555b60408601519586516001600160401b03811161070f576105bc60028401546113c5565b601f81116106c4575b506020601f821160011461063e5761062e949392826003936060936000805160206115a68339815191529b9c600092610633575b50508160011b9160001990861b1c19161760028501555b01519101556040516001600160a01b039093169592938493846114ec565b0390a2005b015190508c806105f9565b601f198216986002850160005260206000209960005b8181106106ac5750836000805160206115a68339815191529a9b60609461062e9998979460039760019510610694575b505050811b016002850155610610565b015160001983881b60f8161c191690558c8080610684565b838301518c556001909b019a60209384019301610654565b600284016000526020600020601f830160051c81019160208410610705575b601f0160051c01905b8181106106f957506105c5565b600081556001016106ec565b90915081906106e3565b634e487b7160e01b600052604160045260246000fd5b015190508880610581565b600185016000908152602081209350601f198516905b818110610785575090846001959493921061076c575b505050811b016001820155610599565b015160001960f88460031b161c1916905588808061075c565b92936020600181928786015181550195019301610746565b909150600184016000526020600020601f840160051c8101602085106107e9575b90849392915b601f830160051c820181106107da57505061056a565b600081558594506001016107c4565b50806107be565b015190508880610527565b6000858152602081209350601f198516905b8181106108495750908460019594939210610830575b505050811b01815561053c565b015160001960f88460031b161c19169055888080610823565b9293602060018192878601518155019501930161080d565b909150836000526020600020601f840160051c8101602085106108aa575b90849392915b601f830160051c8201811061089b575050610510565b60008155859450600101610885565b508061087f565b50604051630935e01b60e21b81523360048201526020816024816001600160a01b0386165afa9081156101e3576000916108ed575b501561049a565b610906915060203d6020116101dc576101ce8183611334565b846108e6565b346100c15760203660031901126100c1576001600160a01b0361092d6112e8565b1660005260006020526040600020610944816113ff565b6100bd610953600184016113ff565b926003610962600283016113ff565b910154906040519485948561152d565b346100c15760203660031901126100c1576004356001600160401b0381116100c157366023820112156100c1576109b3903690602481600401359101611370565b8051810190604081602084019303126100c15760208101516001600160401b0381116100c1578260206109e892840101611563565b916040820151916001600160401b0383116100c157610a0a9201602001611563565b9060405191610a1883611319565b6000835260405192610a29846112fe565b82845280602085015281604085015260006060850152336000526000602052604060002084518051906001600160401b03821161070f578190610a6c84546113c5565b601f8111610d99575b50602090601f8311600114610d3357600092610d28575b50508160011b916000199060031b1c19161781555b60208501518051906001600160401b03821161070f578190610ac660018501546113c5565b601f8111610cd5575b50602090601f8311600114610c6857600092610c5d575b50508160011b916000199060031b1c19161760018201555b60408501519485516001600160401b03811161070f57610b2160028401546113c5565b601f8111610c12575b506020601f8211600114610b915791816060926003946000805160206115a6833981519152999a600092610b86575b50508160011b9160001990861b1c19161760028501555b015191015561062e6040519283923396846114ec565b015190508a80610b59565b601f198216976002850160005260206000209860005b818110610bfa5750926000805160206115a68339815191529899600395936001938360609710610be2575b505050811b016002850155610b70565b015160001983881b60f8161c191690558a8080610bd2565b838301518b556001909a019960209384019301610ba7565b600284016000526020600020601f830160051c81019160208410610c53575b601f0160051c01905b818110610c475750610b2a565b60008155600101610c3a565b9091508190610c31565b015190508780610ae6565b600185016000908152602081209350601f198516905b818110610cbd5750908460019594939210610ca4575b505050811b016001820155610afe565b015160001960f88460031b161c19169055878080610c94565b92936020600181928786015181550195019301610c7e565b909150600184016000526020600020601f840160051c810160208510610d21575b90849392915b601f830160051c82018110610d12575050610acf565b60008155859450600101610cfc565b5080610cf6565b015190508780610a8c565b6000858152602081209350601f198516905b818110610d815750908460019594939210610d68575b505050811b018155610aa1565b015160001960f88460031b161c19169055878080610d5b565b92936020600181928786015181550195019301610d45565b909150836000526020600020601f840160051c810160208510610de2575b90849392915b601f830160051c82018110610dd3575050610a75565b60008155859450600101610dbd565b5080610db7565b346100c15760a03660031901126100c157610e026112e8565b6024356001600160401b0381116100c157610e219036906004016113a7565b906044356001600160401b0381116100c157610e419036906004016113a7565b906064356001600160401b0381116100c157610e619036906004016113a7565b906001600160a01b0381163314158061128d575b61016f57608435151580611282575b6112705760405193610e95856112fe565b808552836020860152826040860152608435606086015260018060a01b0382166000526000602052604060002085518051906001600160401b03821161070f578190610ee184546113c5565b601f8111611220575b50602090601f83116001146111ba576000926111af575b50508160011b916000199060031b1c19161781555b60208601518051906001600160401b03821161070f578190610f3b60018501546113c5565b601f811161115c575b50602090601f83116001146110ef576000926110e4575b50508160011b916000199060031b1c19161760018201555b60408601519586516001600160401b03811161070f57610f9660028401546113c5565b601f811161109d575b506020601f82116001146110175761062e949392826003936060936000805160206115a68339815191529b9c60009261100c575b50508160011b9160001990861b1c19161760028501555b01519101556040516001600160a01b039093169592938493608435928561152d565b015190508c80610fd3565b601f198216986002850160005260206000209960005b8181106110855750836000805160206115a68339815191529a9b60609461062e999897946003976001951061106d575b505050811b016002850155610fea565b015160001983881b60f8161c191690558c808061105d565b838301518c556001909b019a6020938401930161102d565b600284016000526020600020601f830160051c8101602084106110dd575b601f830160051c820181106110d1575050610f9f565b600081556001016110bb565b50806110bb565b015190508880610f5b565b600185016000908152602081209350601f198516905b818110611144575090846001959493921061112b575b505050811b016001820155610f73565b015160001960f88460031b161c1916905588808061111b565b92936020600181928786015181550195019301611105565b909150600184016000526020600020601f840160051c8101602085106111a8575b90849392915b601f830160051c82018110611199575050610f44565b60008155859450600101611183565b508061117d565b015190508880610f01565b6000858152602081209350601f198516905b81811061120857509084600195949392106111ef575b505050811b018155610f16565b015160001960f88460031b161c191690558880806111e2565b929360206001819287860151815501950193016111cc565b909150836000526020600020601f840160051c810160208510611269575b90849392915b601f830160051c8201811061125a575050610eea565b60008155859450600101611244565b508061123e565b60405163777821ff60e11b8152600490fd5b504260843511610e84565b50604051630935e01b60e21b81523360048201526020816024816001600160a01b0386165afa9081156101e3576000916112c9575b5015610e75565b6112e2915060203d6020116101dc576101ce8183611334565b856112c2565b600435906001600160a01b03821682036100c157565b608081019081106001600160401b0382111761070f57604052565b602081019081106001600160401b0382111761070f57604052565b90601f801991011681019081106001600160401b0382111761070f57604052565b6001600160401b03811161070f57601f01601f191660200190565b92919261137c82611355565b9161138a6040519384611334565b8294818452818301116100c1578281602093846000960137010152565b9080601f830112156100c1578160206113c293359101611370565b90565b90600182811c921680156113f5575b60208310146113df57565b634e487b7160e01b600052602260045260246000fd5b91607f16916113d4565b90604051918260008254611412816113c5565b908184526020946001916001811690816000146114825750600114611443575b50505061144192500383611334565b565b600090815285812095935091905b81831061146a5750506114419350820101388080611432565b85548884018501529485019487945091830191611451565b9250505061144194925060ff191682840152151560051b820101388080611432565b60005b8381106114b75750506000910152565b81810151838201526020016114a7565b906020916114e0815180928185528580860191016114a4565b601f01601f1916010190565b93926115289061151a60009461150c60609560808a5260808a01906114c7565b9088820360208a01526114c7565b9086820360408801526114c7565b930152565b94939261151a60609361150c6115289460808a5260808a01906114c7565b908160209103126100c1575180151581036100c15790565b81601f820112156100c157805161157981611355565b926115876040519485611334565b818452602082840101116100c1576113c291602080850191016114a456fe5eff125d5659803f33dbda215d6e8bfe0a404fd213a9ecb5e61973ee16cb17e7a2646970667358221220979a2ce5a9ba1b3e4193fa3539654e84b983b05b39d05413579f1757145ea87f64736f6c63430008190033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.