ETH Price: $3,814.85 (-2.09%)
Gas: 10 Gwei

Contract

0xFfF004461b3D1BaCA004097BeDd05E926854E19D
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
Mint180369642023-08-31 20:32:59271 days ago1693513979IN
0xFfF00446...26854E19D
0.08 ETH0.0029359826.81580907
Mint179346912023-08-17 12:58:59285 days ago1692277139IN
0xFfF00446...26854E19D
0.08 ETH0.0021517319.65291548
Mint176150362023-07-03 17:51:35330 days ago1688406695IN
0xFfF00446...26854E19D
0.08 ETH0.0028004525.57800651
Mint176066002023-07-02 13:24:47331 days ago1688304287IN
0xFfF00446...26854E19D
0.00099 ETH0.0018183315.90120574
Mint175984232023-07-01 9:49:35333 days ago1688204975IN
0xFfF00446...26854E19D
0.08 ETH0.0015564214.21560141
Mint175702752023-06-27 11:00:59336 days ago1687863659IN
0xFfF00446...26854E19D
0.04 ETH0.0013753712.54524656
Mint175688152023-06-27 6:04:11337 days ago1687845851IN
0xFfF00446...26854E19D
0.04 ETH0.0014299913.04348266
Mint175669362023-06-26 23:44:35337 days ago1687823075IN
0xFfF00446...26854E19D
0.04 ETH0.0012074211.01334975
Mint175667552023-06-26 23:08:23337 days ago1687820903IN
0xFfF00446...26854E19D
0.04 ETH0.0014831513.52840072
Mint175655452023-06-26 19:03:23337 days ago1687806203IN
0xFfF00446...26854E19D
0.04 ETH0.0017812216.24719804
Mint175652842023-06-26 18:10:23337 days ago1687803023IN
0xFfF00446...26854E19D
0.04 ETH0.0021540419.64779766
Mint175597062023-06-25 23:19:23338 days ago1687735163IN
0xFfF00446...26854E19D
0.04 ETH0.0014021412.78947053
Mint175587522023-06-25 20:04:59338 days ago1687723499IN
0xFfF00446...26854E19D
0.04 ETH0.001393412.70976786
Mint175571452023-06-25 14:39:23338 days ago1687703963IN
0xFfF00446...26854E19D
0.04 ETH0.0014277713.02319414
Mint175519082023-06-24 21:00:35339 days ago1687640435IN
0xFfF00446...26854E19D
0.04 ETH0.0014493713.2202704
Mint175516332023-06-24 20:05:11339 days ago1687637111IN
0xFfF00446...26854E19D
0.04 ETH0.0012927211.79141774
Mint175495472023-06-24 13:02:11339 days ago1687611731IN
0xFfF00446...26854E19D
0.04 ETH0.0016021314.61359916
Mint175451832023-06-23 22:17:11340 days ago1687558631IN
0xFfF00446...26854E19D
0.04 ETH0.0014399313.13414045
Mint175446752023-06-23 20:33:59340 days ago1687552439IN
0xFfF00446...26854E19D
0.04 ETH0.0015329613.98269719
Mint175439242023-06-23 18:02:23340 days ago1687543343IN
0xFfF00446...26854E19D
0.04 ETH0.0019431417.72407741
Mint175417162023-06-23 10:37:23340 days ago1687516643IN
0xFfF00446...26854E19D
0.04 ETH0.002591723.63979844
Mint175381012023-06-22 22:23:23341 days ago1687472603IN
0xFfF00446...26854E19D
0.04 ETH0.001494213.62915545
Mint175377252023-06-22 21:06:59341 days ago1687468019IN
0xFfF00446...26854E19D
0.04 ETH0.0029813527.19395677
Mint175328012023-06-22 4:30:59342 days ago1687408259IN
0xFfF00446...26854E19D
0.04 ETH0.0025118222.91122824
Mint175305692023-06-21 20:59:11342 days ago1687381151IN
0xFfF00446...26854E19D
0.04 ETH0.0025309123.08537408
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To Value
180369642023-08-31 20:32:59271 days ago1693513979
0xFfF00446...26854E19D
0.08 ETH
179346912023-08-17 12:58:59285 days ago1692277139
0xFfF00446...26854E19D
0.08 ETH
176150362023-07-03 17:51:35330 days ago1688406695
0xFfF00446...26854E19D
0.08 ETH
176066002023-07-02 13:24:47331 days ago1688304287
0xFfF00446...26854E19D
0.00099 ETH
175984232023-07-01 9:49:35333 days ago1688204975
0xFfF00446...26854E19D
0.08 ETH
175702752023-06-27 11:00:59336 days ago1687863659
0xFfF00446...26854E19D
0.04 ETH
175688152023-06-27 6:04:11337 days ago1687845851
0xFfF00446...26854E19D
0.04 ETH
175669362023-06-26 23:44:35337 days ago1687823075
0xFfF00446...26854E19D
0.04 ETH
175667552023-06-26 23:08:23337 days ago1687820903
0xFfF00446...26854E19D
0.04 ETH
175655452023-06-26 19:03:23337 days ago1687806203
0xFfF00446...26854E19D
0.04 ETH
175652842023-06-26 18:10:23337 days ago1687803023
0xFfF00446...26854E19D
0.04 ETH
175597062023-06-25 23:19:23338 days ago1687735163
0xFfF00446...26854E19D
0.04 ETH
175587522023-06-25 20:04:59338 days ago1687723499
0xFfF00446...26854E19D
0.04 ETH
175571452023-06-25 14:39:23338 days ago1687703963
0xFfF00446...26854E19D
0.04 ETH
175519082023-06-24 21:00:35339 days ago1687640435
0xFfF00446...26854E19D
0.04 ETH
175516332023-06-24 20:05:11339 days ago1687637111
0xFfF00446...26854E19D
0.04 ETH
175495472023-06-24 13:02:11339 days ago1687611731
0xFfF00446...26854E19D
0.04 ETH
175451832023-06-23 22:17:11340 days ago1687558631
0xFfF00446...26854E19D
0.04 ETH
175446752023-06-23 20:33:59340 days ago1687552439
0xFfF00446...26854E19D
0.04 ETH
175439242023-06-23 18:02:23340 days ago1687543343
0xFfF00446...26854E19D
0.04 ETH
175417162023-06-23 10:37:23340 days ago1687516643
0xFfF00446...26854E19D
0.04 ETH
175381012023-06-22 22:23:23341 days ago1687472603
0xFfF00446...26854E19D
0.04 ETH
175377252023-06-22 21:06:59341 days ago1687468019
0xFfF00446...26854E19D
0.04 ETH
175328012023-06-22 4:30:59342 days ago1687408259
0xFfF00446...26854E19D
0.04 ETH
175305692023-06-21 20:59:11342 days ago1687381151
0xFfF00446...26854E19D
0.04 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
DropEngineV2

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 1000 runs

Other Settings:
default evmVersion
File 1 of 8 : DropEngineV2.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

/*

███╗   ███╗███████╗████████╗ █████╗ ██╗      █████╗ ██████╗ ███████╗██╗
████╗ ████║██╔════╝╚══██╔══╝██╔══██╗██║     ██╔══██╗██╔══██╗██╔════╝██║
██╔████╔██║█████╗     ██║   ███████║██║     ███████║██████╔╝█████╗  ██║
██║╚██╔╝██║██╔══╝     ██║   ██╔══██║██║     ██╔══██║██╔══██╗██╔══╝  ██║
██║ ╚═╝ ██║███████╗   ██║   ██║  ██║███████╗██║  ██║██████╔╝███████╗███████╗
╚═╝     ╚═╝╚══════╝   ╚═╝   ╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝╚═════╝ ╚══════╝╚══════╝


Deployed by Metalabel with 💖 as a permanent application on the Ethereum blockchain.

Metalabel is a growing universe of tools, knowledge, and resources for
metalabels and cultural collectives.

Our purpose is to establish the metalabel as key infrastructure for creative
collectives and to inspire a new culture of creative collaboration and mutual
support.

OUR SQUAD

Anna Bulbrook (Curator)
Austin Robey (Community)
Brandon Valosek (Engineer)
Ilya Yudanov (Designer)
Lauren Dorman (Engineer)
Rob Kalin (Board)
Yancey Strickler (Director)

https://metalabel.xyz

*/

import {Owned} from "@metalabel/solmate/src/auth/Owned.sol";
import {SSTORE2} from "@metalabel/solmate/src/utils/SSTORE2.sol";
import {Base64} from "@openzeppelin/contracts/utils/Base64.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {ICollection} from "../interfaces/ICollection.sol";
import {IEngine, SequenceData} from "../interfaces/IEngine.sol";
import {INodeRegistry} from "../interfaces/INodeRegistry.sol";

/// @notice Data stored engine-side for each drop.
/// - Royalty percentage is stored as basis points, eg 5% = 500
/// - If maxRecordPerTransaction is 0, there is not limit
/// - Protocol fee is written to drop data at configure-time to lock in protocol
///   fee and avoid an additional storage read at mint-time
struct DropData {
    uint96 price;
    uint16 royaltyBps;
    bool allowContractMints;
    bool randomizeMetadataVariants;
    uint8 maxRecordsPerTransaction;
    address revenueRecipient;
    uint16 primarySaleFeeBps;
    uint96 priceDecayPerDay;
    uint64 decayStopTimestamp;
    // 59 bytes total / 5 remaining for a two-word slot
}

/// @notice A single attribute of an NFT's metadata
struct NFTMetadataAttribute {
    string trait_type;
    string value;
}

/// @notice Metadata stored for a single record variant
/// @dev Storage is written via SSTORE2
struct NFTMetadata {
    string name;
    string description;
    string image;
    string external_url;
    string metalabel_record_variant_name;
    string metalabel_release_metadata_uri;
    uint16[] metalabel_record_contents;
    NFTMetadataAttribute[] attributes;
}

/// @notice Metalabel engine that implements a multi-NFT drop.
/// - All metadata is stored onchain via SSTORE2.
/// - Price can decay over time or be constant throughout the drop.
/// - Metadata variants can be p-randomized or fixed.
/// - Enabling or disabling smart contract mints is set per-sequence.
/// - Multiple records can be minted in a single trx, configurable per-sequence.
/// - The owner of this contract can set a primary sale fee that is taken from
///   all primary sales revenue and retained by this drop engine.
contract DropEngineV2 is IEngine, Owned {
    // ---
    // Errors
    // ---

    /// @notice Invalid msg.value on purchase
    error IncorrectPaymentAmount();

    /// @notice If price or recipient is zero, they both have to be zero
    error InvalidPriceOrRecipient();

    /// @notice An invalid value was used for the royalty bps.
    error InvalidRoyaltyBps();

    /// @notice An invalid value was used for the primary sale fee.
    error InvalidPrimarySaleFee();

    /// @notice If smart contract mints are not allowed, msg.sender must be an
    /// EOA
    error MinterMustBeEOA();

    /// @notice If minting more than the max allowed per transaction
    error InvalidMintAmount();

    /// @notice An invalid price decay stop time or per day decay was used.
    error InvalidPriceDecayConfig();

    /// @notice Unable to forward ETH to the revenue recipient or unable to
    /// withdraw funds
    error CouldNotTransferEth();

    // ---
    // Events
    // ---

    /// @notice A new drop was created.
    /// @dev The collection already emits a SequenceCreated event, we're
    /// emitting the additional engine-specific data here.
    event DropCreated(address collection, uint16 sequenceId, DropData dropData);

    /// @notice The primary sale for this drop engine was set
    event PrimarySaleFeeSet(uint16 primarySaleFeeBps);

    // ---
    // Storage
    // ---

    /// @notice Drop data for a given collection + sequence ID.
    mapping(address => mapping(uint16 => DropData)) public drops;

    /// @notice The SSTORE2 contract storage address for a given sequence's list
    /// of metadata variants
    mapping(address => mapping(uint16 => address))
        public metadataStoragePointers;

    /// @notice A primary sales fee that is paid at mint time. Can be adjusted
    /// by contract owner. Fee is written into the drop's DropData structure, so
    /// fee at configure-time is locked. Fees are accumulated in the contract
    /// and can be withdrawn by the contract owner
    uint16 public primarySaleFeeBps;

    /// @notice A reference to the core protocol's node registry.
    /// @dev While this is not directly used by the engine, it is surfaced in
    /// the onchain generated JSON metadata for records as a way of creating a
    /// concrete link back to the cataloging protocol.
    INodeRegistry public immutable nodeRegistry;

    // ---
    // Constructor
    // ---

    constructor(address _contractOwner, INodeRegistry _nodeRegistry)
        Owned(_contractOwner)
    {
        nodeRegistry = _nodeRegistry;
    }

    // ---
    // Admin functionality
    // ---

    /// @notice Set the primary sale fee for all drops configured on this
    /// engine. Only callable by owner
    function setPrimarySaleFeeBps(uint16 fee) external onlyOwner {
        if (fee > 10000) revert InvalidPrimarySaleFee();
        primarySaleFeeBps = fee;
        emit PrimarySaleFeeSet(fee);
    }

    // ---
    // Permissionless functions
    // ---

    /// @notice Transfer ETH from the contract that has accumulated from fees to
    /// the owner's account. Can be called by any address.
    function transferFeesToOwner() external {
        (bool success, ) = owner.call{value: address(this).balance}("");
        if (!success) revert CouldNotTransferEth();
    }

    // ---
    // Mint functionality
    // ---

    /// @notice Mint records. Returns the first token ID minted
    function mint(
        ICollection collection,
        uint16 sequenceId,
        uint8 count
    ) external payable returns (uint256 tokenId) {
        DropData storage drop = drops[address(collection)][sequenceId];

        // block SC mints if flagged
        if (!drop.allowContractMints && msg.sender != tx.origin) {
            revert MinterMustBeEOA();
        }

        // Ensure not minting too many
        if (
            drop.maxRecordsPerTransaction > 0 &&
            count > drop.maxRecordsPerTransaction
        ) {
            revert InvalidMintAmount();
        }

        // Resolve current unit price (which may change over time if there's a
        // price decay configuration) and total order price
        uint256 unitPrice = currentPrice(collection, sequenceId);
        uint256 orderPrice = unitPrice * count;

        // Ensure correct payment was sent with the transaction. Checking less
        // than to allow sender to overpay (likely happens for all decaying
        // prices). We refund the difference below.
        if (msg.value < orderPrice) {
            revert IncorrectPaymentAmount();
        }

        for (uint256 i = 0; i < count; i++) {
            // If collection is a malicious contract, that does not impact any
            // state in the engine.  If it's a valid protocol-deployed
            // collection, then it will work as expected.
            //
            // Collection enforces max mint supply and mint window, so we're not
            // checking that here
            uint256 id = collection.mintRecord(msg.sender, sequenceId);

            // return the first minted token ID, caller can infer subsequent
            // sequential IDs
            tokenId = tokenId != 0 ? tokenId : id;
        }

        // Amount to forward to the revenue recipient is the total order price
        // minus the locked-in primary sale fee that was recorded at
        // configure-time.  The remaining ETH (after refund) will stay in this
        // contract, withdrawable by the owner at a later date via
        // transferFeesToOwner
        uint256 amountToForward = orderPrice -
            ((orderPrice * drop.primarySaleFeeBps) / 10000);

        // Amount to refund message sender is any difference in order price and
        // msg.value. This happens if the caller overpays, which will generally
        // always happen on decaying price mints
        uint256 amountToRefund = msg.value > orderPrice
            ? msg.value - orderPrice
            : 0;

        // Refund caller
        if (amountToRefund > 0) {
            (bool success, ) = msg.sender.call{value: amountToRefund}("");
            if (!success) revert CouldNotTransferEth();
        }

        // Forward ETH to the revenue recipient
        if (amountToForward > 0) {
            (bool success, ) = drop.revenueRecipient.call{
                value: amountToForward
            }("");
            if (!success) revert CouldNotTransferEth();
        }
    }

    /// @notice Get the current price of a record in a given sequence. This will
    /// return a price even if the sequence is not currently mintable (i.e. the
    /// mint window hasn't started yet or the minting window has closed).
    function currentPrice(ICollection collection, uint16 sequenceId)
        public
        view
        returns (uint256 unitPrice)
    {
        DropData storage drop = drops[address(collection)][sequenceId];

        // Compute unit price based on decay and timestamp.
        // First compute how many seconds until the decay cutoff time, after
        // which price will remain constant. Then compute the marginal increase
        // in unit price by multiplying the base price by
        //
        //   (decay per day * seconds until decay stop) / 1 day
        //

        uint64 secondsBeforeDecayStop = block.timestamp <
            drop.decayStopTimestamp
            ? drop.decayStopTimestamp - uint64(block.timestamp)
            : 0;
        uint256 inflateUnitPriceBy = (uint256(drop.priceDecayPerDay) *
            secondsBeforeDecayStop) / 1 days;
        unitPrice = drop.price + inflateUnitPriceBy;
    }

    // ---
    // IEngine setup
    // ---

    /// @inheritdoc IEngine
    /// @dev There is no access control on this function, we infer the
    /// collection from msg.sender, and use that to key all stored data. If
    /// somebody calls this function with bogus info (instead of it getting
    /// called via the collection), it just wastes storage but does not impact
    /// contract functionality
    function configureSequence(
        uint16 sequenceId,
        SequenceData calldata sequenceData,
        bytes calldata engineData
    ) external override {
        (DropData memory dropData, NFTMetadata[] memory metadatas) = abi.decode(
            engineData,
            (DropData, NFTMetadata[])
        );

        // This drop is a "free drop" if and only if the price is zero and decay
        // per day is zero
        bool isFreeDrop = dropData.price == 0 && dropData.priceDecayPerDay == 0;

        // Ensure that if this is a free drop, there's no revenue recipient, and
        // vice versa
        if ((isFreeDrop) != (dropData.revenueRecipient == address(0))) {
            revert InvalidPriceOrRecipient();
        }

        // Don't allow setting a decay stop time in the past (or before the mint
        // window opens) unless it's zero.
        if (
            dropData.decayStopTimestamp != 0 &&
            (dropData.decayStopTimestamp < block.timestamp ||
                dropData.decayStopTimestamp <
                sequenceData.sealedBeforeTimestamp)
        ) {
            revert InvalidPriceDecayConfig();
        }

        // Don't allow setting a decay stop time after the mint window closes
        if (
            sequenceData.sealedAfterTimestamp > 0 && // sealed = 0 -> no end
            dropData.decayStopTimestamp > sequenceData.sealedAfterTimestamp
        ) {
            revert InvalidPriceDecayConfig();
        }

        // Ensure that if decay stop time is set, decay per day is set, and vice
        // versa
        if (
            (dropData.decayStopTimestamp == 0) !=
            (dropData.priceDecayPerDay == 0)
        ) {
            revert InvalidPriceDecayConfig();
        }

        // Ensure royaltyBps is in range
        if (dropData.royaltyBps > 10000) revert InvalidRoyaltyBps();

        // To ensure that creators know the protocol fee they are effectively
        // agreeing to during sequence creation time, we require that they set
        // the primary sale fee correctly here. This also ensures the drop
        // engine owner cannot frontrun a fee change
        if (dropData.primarySaleFeeBps != primarySaleFeeBps) {
            revert InvalidPrimarySaleFee();
        }

        // write metadata blob to chain
        metadataStoragePointers[msg.sender][sequenceId] = SSTORE2.write(
            abi.encode(metadatas)
        );

        // Write engine data (passed through from the collection when the
        // collection admin calls `configureSequence`) to a struct in the engine
        // with all the needed info.
        drops[msg.sender][sequenceId] = dropData;
        emit DropCreated(msg.sender, sequenceId, dropData);
    }

    // ---
    // IEngine views
    // ---

    /// @inheritdoc IEngine
    /// @dev Token URI is constructed programmatically from stored metadata by
    /// creating the JSON string and base64ing it
    function getTokenURI(address collection, uint256 tokenId)
        external
        view
        override
        returns (string memory tokenURI)
    {
        uint16 sequenceId = ICollection(collection).tokenSequenceId(tokenId);
        uint80 editionNumber = ICollection(collection).tokenMintData(tokenId);
        SequenceData memory sequenceData = ICollection(collection)
            .getSequenceData(sequenceId);

        NFTMetadata memory metadata = getStoredMetadataVariant(
            collection,
            tokenId
        );

        // Construct edition string as either "1" or "1/1000" depending on if
        // this was an open edition
        string memory sEdition = sequenceData.maxSupply == 0
            ? Strings.toString(editionNumber)
            : string.concat(
                Strings.toString(editionNumber),
                "/",
                Strings.toString(sequenceData.maxSupply)
            );

        // Edition number and variant name are always included
        string memory attributesInnerJson = string.concat(
            '{"trait_type": "Record Edition", "value": "',
            sEdition,
            '"}, {"trait_type": "Record Variant", "value": "',
            metadata.metalabel_record_variant_name,
            '"}',
            metadata.attributes.length > 0 ? ", " : ""
        );

        // Additional attributes from metadata blob
        for (uint256 i = 0; i < metadata.attributes.length; i++) {
            attributesInnerJson = string.concat(
                attributesInnerJson,
                i > 0 ? ", " : "",
                '{"trait_type": "',
                metadata.attributes[i].trait_type,
                '", "value": "',
                metadata.attributes[i].value,
                '"}'
            );
        }

        // create the contents array
        string memory contentsInnerJson = "[";
        for (
            uint256 i = 0;
            i < metadata.metalabel_record_contents.length;
            i++
        ) {
            contentsInnerJson = string.concat(
                contentsInnerJson,
                Strings.toString(metadata.metalabel_record_contents[i]),
                i == metadata.metalabel_record_contents.length - 1 ? "]" : ", "
            );
        }

        // Compose the final JSON payload. Split across multiple string.concat
        // calls due to stack limitations
        string memory json = string.concat(
            '{"name":"',
            metadata.name,
            " ",
            sEdition,
            '", "description":"',
            metadata.description,
            '", "image": "',
            metadata.image,
            '", "external_url": "',
            metadata.external_url,
            '", '
        );
        json = string.concat(
            json,
            '"metalabel": { "node_registry_address": "',
            Strings.toHexString(uint256(uint160(address(nodeRegistry))), 20),
            '", "record_variant_name": "',
            metadata.metalabel_record_variant_name,
            '", "release_metadata_uri": "',
            metadata.metalabel_release_metadata_uri,
            '", "record_contents": ',
            contentsInnerJson,
            '}, "attributes": [',
            attributesInnerJson,
            "]}"
        );

        // Prepend base64 prefix + encode JSON
        tokenURI = string.concat(
            "data:application/json;base64,",
            Base64.encode(bytes(json))
        );
    }

    /// @notice Get the onchain metadata variant for a specific record
    /// @dev This is a view function that reads from SSTORE2 storage and picks
    /// the random or sequential variant, the full onchain metadata is
    /// generated in tokenURI
    function getStoredMetadataVariant(address collection, uint256 tokenId)
        public
        view
        returns (NFTMetadata memory metadata)
    {
        uint16 sequenceId = ICollection(collection).tokenSequenceId(tokenId);
        uint80 editionNumber = ICollection(collection).tokenMintData(tokenId);

        // Load all metadata variants from SSTORE2 storage
        NFTMetadata[] memory metadatas = abi.decode(
            SSTORE2.read(metadataStoragePointers[collection][sequenceId]),
            (NFTMetadata[])
        );

        // Metadata variants are default sequential, but can be pseudo-random
        // if the randomizeMetadataVariants flag is set.
        // Using (edition - 1) for sequential since edition number starts at 1
        uint256 idx = (editionNumber - 1) % metadatas.length;
        if (drops[collection][sequenceId].randomizeMetadataVariants) {
            idx =
                uint256(
                    keccak256(
                        abi.encodePacked(
                            collection,
                            sequenceId,
                            editionNumber,
                            tokenId
                        )
                    )
                ) %
                metadatas.length;
        }

        metadata = metadatas[idx];
    }

    /// @inheritdoc IEngine
    /// @dev Royalty bps and recipient is per-sequence.
    function getRoyaltyInfo(
        address collection,
        uint256 tokenId,
        uint256 salePrice
    ) external view override returns (address, uint256) {
        uint16 sequenceId = ICollection(collection).tokenSequenceId(tokenId);
        DropData storage drop = drops[collection][sequenceId];
        return (drop.revenueRecipient, (salePrice * drop.royaltyBps) / 10000);
    }
}

File 2 of 8 : Owned.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event OwnershipTransferred(address indexed user, address indexed newOwner);

    /*//////////////////////////////////////////////////////////////
                            OWNERSHIP STORAGE
    //////////////////////////////////////////////////////////////*/

    address public owner;

    modifier onlyOwner() virtual {
        require(msg.sender == owner, "UNAUTHORIZED");

        _;
    }

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(address _owner) {
        owner = _owner;

        emit OwnershipTransferred(address(0), _owner);
    }

    /*//////////////////////////////////////////////////////////////
                             OWNERSHIP LOGIC
    //////////////////////////////////////////////////////////////*/

    function transferOwnership(address newOwner) public virtual onlyOwner {
        owner = newOwner;

        emit OwnershipTransferred(msg.sender, newOwner);
    }
}

File 3 of 8 : SSTORE2.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Read and write to persistent storage at a fraction of the cost.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SSTORE2.sol)
/// @author Modified from 0xSequence (https://github.com/0xSequence/sstore2/blob/master/contracts/SSTORE2.sol)
library SSTORE2 {
    uint256 internal constant DATA_OFFSET = 1; // We skip the first byte as it's a STOP opcode to ensure the contract can't be called.

    /*//////////////////////////////////////////////////////////////
                               WRITE LOGIC
    //////////////////////////////////////////////////////////////*/

    function write(bytes memory data) internal returns (address pointer) {
        // Prefix the bytecode with a STOP opcode to ensure it cannot be called.
        bytes memory runtimeCode = abi.encodePacked(hex"00", data);

        bytes memory creationCode = abi.encodePacked(
            //---------------------------------------------------------------------------------------------------------------//
            // Opcode  | Opcode + Arguments  | Description  | Stack View                                                     //
            //---------------------------------------------------------------------------------------------------------------//
            // 0x60    |  0x600B             | PUSH1 11     | codeOffset                                                     //
            // 0x59    |  0x59               | MSIZE        | 0 codeOffset                                                   //
            // 0x81    |  0x81               | DUP2         | codeOffset 0 codeOffset                                        //
            // 0x38    |  0x38               | CODESIZE     | codeSize codeOffset 0 codeOffset                               //
            // 0x03    |  0x03               | SUB          | (codeSize - codeOffset) 0 codeOffset                           //
            // 0x80    |  0x80               | DUP          | (codeSize - codeOffset) (codeSize - codeOffset) 0 codeOffset   //
            // 0x92    |  0x92               | SWAP3        | codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset)   //
            // 0x59    |  0x59               | MSIZE        | 0 codeOffset (codeSize - codeOffset) 0 (codeSize - codeOffset) //
            // 0x39    |  0x39               | CODECOPY     | 0 (codeSize - codeOffset)                                      //
            // 0xf3    |  0xf3               | RETURN       |                                                                //
            //---------------------------------------------------------------------------------------------------------------//
            hex"60_0B_59_81_38_03_80_92_59_39_F3", // Returns all code in the contract except for the first 11 (0B in hex) bytes.
            runtimeCode // The bytecode we want the contract to have after deployment. Capped at 1 byte less than the code size limit.
        );

        assembly {
            // Deploy a new contract with the generated creation code.
            // We start 32 bytes into the code to avoid copying the byte length.
            pointer := create(0, add(creationCode, 32), mload(creationCode))
        }

        require(pointer != address(0), "DEPLOYMENT_FAILED");
    }

    /*//////////////////////////////////////////////////////////////
                               READ LOGIC
    //////////////////////////////////////////////////////////////*/

    function read(address pointer) internal view returns (bytes memory) {
        return readBytecode(pointer, DATA_OFFSET, pointer.code.length - DATA_OFFSET);
    }

    function read(address pointer, uint256 start) internal view returns (bytes memory) {
        start += DATA_OFFSET;

        return readBytecode(pointer, start, pointer.code.length - start);
    }

    function read(
        address pointer,
        uint256 start,
        uint256 end
    ) internal view returns (bytes memory) {
        start += DATA_OFFSET;
        end += DATA_OFFSET;

        require(pointer.code.length >= end, "OUT_OF_BOUNDS");

        return readBytecode(pointer, start, end - start);
    }

    /*//////////////////////////////////////////////////////////////
                          INTERNAL HELPER LOGIC
    //////////////////////////////////////////////////////////////*/

    function readBytecode(
        address pointer,
        uint256 start,
        uint256 size
    ) private view returns (bytes memory data) {
        assembly {
            // Get a pointer to some free memory.
            data := mload(0x40)

            // Update the free memory pointer to prevent overriding our data.
            // We use and(x, not(31)) as a cheaper equivalent to sub(x, mod(x, 32)).
            // Adding 31 to size and running the result through the logic above ensures
            // the memory pointer remains word-aligned, following the Solidity convention.
            mstore(0x40, add(data, and(add(add(size, 32), 31), not(31))))

            // Store the size of the data in the first 32 byte chunk of free memory.
            mstore(data, size)

            // Copy the code into memory right after the 32 bytes we used to store the size.
            extcodecopy(pointer, add(data, 32), start, size)
        }
    }
}

File 4 of 8 : Base64.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides a set of functions to operate with Base64 strings.
 *
 * _Available since v4.5._
 */
library Base64 {
    /**
     * @dev Base64 Encoding/Decoding Table
     */
    string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    /**
     * @dev Converts a `bytes` to its Bytes64 `string` representation.
     */
    function encode(bytes memory data) internal pure returns (string memory) {
        /**
         * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence
         * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol
         */
        if (data.length == 0) return "";

        // Loads the table into memory
        string memory table = _TABLE;

        // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter
        // and split into 4 numbers of 6 bits.
        // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up
        // - `data.length + 2`  -> Round up
        // - `/ 3`              -> Number of 3-bytes chunks
        // - `4 *`              -> 4 characters for each chunk
        string memory result = new string(4 * ((data.length + 2) / 3));

        /// @solidity memory-safe-assembly
        assembly {
            // Prepare the lookup table (skip the first "length" byte)
            let tablePtr := add(table, 1)

            // Prepare result pointer, jump over length
            let resultPtr := add(result, 32)

            // Run over the input, 3 bytes at a time
            for {
                let dataPtr := data
                let endPtr := add(data, mload(data))
            } lt(dataPtr, endPtr) {

            } {
                // Advance 3 bytes
                dataPtr := add(dataPtr, 3)
                let input := mload(dataPtr)

                // To write each character, shift the 3 bytes (18 bits) chunk
                // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)
                // and apply logical AND with 0x3F which is the number of
                // the previous character in the ASCII table prior to the Base64 Table
                // The result is then added to the table to get the character to write,
                // and finally write it in the result pointer but with a left shift
                // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits

                mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance
            }

            // When data `bytes` is not exactly 3 bytes long
            // it is padded with `=` characters at the end
            switch mod(mload(data), 3)
            case 1 {
                mstore8(sub(resultPtr, 1), 0x3d)
                mstore8(sub(resultPtr, 2), 0x3d)
            }
            case 2 {
                mstore8(sub(resultPtr, 1), 0x3d)
            }
        }

        return result;
    }
}

File 5 of 8 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_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) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @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] = _HEX_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);
    }
}

File 7 of 8 : ICollection.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import {SequenceData} from "./IEngine.sol";

/// @notice Collections are ERC721 contracts that contain records.
interface ICollection {
    /// @notice Mint a new record with custom immutable token data. Only
    /// callable by the sequence-specific engine.
    function mintRecord(
        address to,
        uint16 sequenceId,
        uint80 tokenData
    ) external returns (uint256 tokenId);

    /// @notice Mint a new record with the edition number of the sequence
    /// written to the immutable token data. Only callable by the
    /// sequence-specific engine.
    function mintRecord(address to, uint16 sequenceId)
        external
        returns (uint256 tokenId);

    /// @notice Get the sequence ID for a given token.
    function tokenSequenceId(uint256 tokenId)
        external
        view
        returns (uint16 sequenceId);

    /// @notice Get the immutable mint data for a given token.
    function tokenMintData(uint256 tokenId) external view returns (uint80 data);

    /// @notice Get the sequence data for a given sequence ID.
    function getSequenceData(uint16 sequenceId)
        external
        view
        returns (SequenceData memory);
}

File 8 of 8 : IEngine.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

/// @notice Data stored in the collection for each sequence.
/// @dev We could use smaller ints for timestamps and supply, but we'd still be
/// stuck with a 2-word storage layout. engine + dropNodeId is 28 bytes, leaving
/// us with only 4 bytes for the remaining parameters.
struct SequenceData {
    uint64 sealedBeforeTimestamp;
    uint64 sealedAfterTimestamp;
    uint64 maxSupply;
    uint64 minted;
    // ^ 1 word
    IEngine engine;
    uint64 dropNodeId;
    // 4 bytes remaining
}

/// @notice An engine contract implements record minting mechanics, tokenURI
/// computation, and royalty computation.
interface IEngine {
    /// @notice Called by the collection when a new sequence is configured.
    /// @dev An arbitrary bytes buffer engineData is forwarded from the
    /// collection that can be used to pass setup and configuration data
    function configureSequence(
        uint16 sequenceId,
        SequenceData calldata sequence,
        bytes calldata engineData
    ) external;

    /// @notice Called by the collection to resolve tokenURI.
    function getTokenURI(address collection, uint256 tokenId)
        external
        view
        returns (string memory);

    /// @notice Called by the collection to resolve royalties.
    function getRoyaltyInfo(
        address collection,
        uint256 tokenId,
        uint256 salePrice
    ) external view returns (address receiver, uint256 royaltyAmount);
}

File 9 of 8 : INodeRegistry.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

enum NodeType {
    INVALID_NODE_TYPE,
    METALABEL,
    RELEASE
}

/// @notice Data stored per node.
struct NodeData {
    NodeType nodeType;
    uint64 owner;
    uint64 parent;
    uint64 groupNode;
    // 7 bytes remaining
}

/// @notice The node registry maintains a tree of ownable nodes that are used to
/// catalog logical entities and manage access control in the Metalabel
/// universe.
interface INodeRegistry {
    /// @notice Create a new node. Child nodes can specify an group node that
    /// will be used to determine ownership, and a separate logical parent that
    /// expresses the entity relationship.  Child nodes can only be created if
    /// msg.sender is an authorized manager of the parent node.
    function createNode(
        NodeType nodeType,
        uint64 owner,
        uint64 parent,
        uint64 groupNode,
        address[] memory initialControllers,
        string memory metadata
    ) external returns (uint64 id);

    /// @notice Determine if an address is authorized to manage a node.
    /// A node can be managed by an address if any of the following conditions
    /// are true:
    ///   - The address's account is the owner of the node
    ///   - The address's account is the owner of the node's group node
    ///   - The address is an authorized controller of the node
    ///   - The address is an authorized controller of the node's group node
    function isAuthorizedAddressForNode(uint64 node, address subject)
        external
        view
        returns (bool isAuthorized);

    /// @notice Resolve node owner account.
    function ownerOf(uint64 id) external view returns (uint64);
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 1000
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_contractOwner","type":"address"},{"internalType":"contract INodeRegistry","name":"_nodeRegistry","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CouldNotTransferEth","type":"error"},{"inputs":[],"name":"IncorrectPaymentAmount","type":"error"},{"inputs":[],"name":"InvalidMintAmount","type":"error"},{"inputs":[],"name":"InvalidPriceDecayConfig","type":"error"},{"inputs":[],"name":"InvalidPriceOrRecipient","type":"error"},{"inputs":[],"name":"InvalidPrimarySaleFee","type":"error"},{"inputs":[],"name":"InvalidRoyaltyBps","type":"error"},{"inputs":[],"name":"MinterMustBeEOA","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"collection","type":"address"},{"indexed":false,"internalType":"uint16","name":"sequenceId","type":"uint16"},{"components":[{"internalType":"uint96","name":"price","type":"uint96"},{"internalType":"uint16","name":"royaltyBps","type":"uint16"},{"internalType":"bool","name":"allowContractMints","type":"bool"},{"internalType":"bool","name":"randomizeMetadataVariants","type":"bool"},{"internalType":"uint8","name":"maxRecordsPerTransaction","type":"uint8"},{"internalType":"address","name":"revenueRecipient","type":"address"},{"internalType":"uint16","name":"primarySaleFeeBps","type":"uint16"},{"internalType":"uint96","name":"priceDecayPerDay","type":"uint96"},{"internalType":"uint64","name":"decayStopTimestamp","type":"uint64"}],"indexed":false,"internalType":"struct DropData","name":"dropData","type":"tuple"}],"name":"DropCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"primarySaleFeeBps","type":"uint16"}],"name":"PrimarySaleFeeSet","type":"event"},{"inputs":[{"internalType":"uint16","name":"sequenceId","type":"uint16"},{"components":[{"internalType":"uint64","name":"sealedBeforeTimestamp","type":"uint64"},{"internalType":"uint64","name":"sealedAfterTimestamp","type":"uint64"},{"internalType":"uint64","name":"maxSupply","type":"uint64"},{"internalType":"uint64","name":"minted","type":"uint64"},{"internalType":"contract IEngine","name":"engine","type":"address"},{"internalType":"uint64","name":"dropNodeId","type":"uint64"}],"internalType":"struct SequenceData","name":"sequenceData","type":"tuple"},{"internalType":"bytes","name":"engineData","type":"bytes"}],"name":"configureSequence","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ICollection","name":"collection","type":"address"},{"internalType":"uint16","name":"sequenceId","type":"uint16"}],"name":"currentPrice","outputs":[{"internalType":"uint256","name":"unitPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint16","name":"","type":"uint16"}],"name":"drops","outputs":[{"internalType":"uint96","name":"price","type":"uint96"},{"internalType":"uint16","name":"royaltyBps","type":"uint16"},{"internalType":"bool","name":"allowContractMints","type":"bool"},{"internalType":"bool","name":"randomizeMetadataVariants","type":"bool"},{"internalType":"uint8","name":"maxRecordsPerTransaction","type":"uint8"},{"internalType":"address","name":"revenueRecipient","type":"address"},{"internalType":"uint16","name":"primarySaleFeeBps","type":"uint16"},{"internalType":"uint96","name":"priceDecayPerDay","type":"uint96"},{"internalType":"uint64","name":"decayStopTimestamp","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"getRoyaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getStoredMetadataVariant","outputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"string","name":"image","type":"string"},{"internalType":"string","name":"external_url","type":"string"},{"internalType":"string","name":"metalabel_record_variant_name","type":"string"},{"internalType":"string","name":"metalabel_release_metadata_uri","type":"string"},{"internalType":"uint16[]","name":"metalabel_record_contents","type":"uint16[]"},{"components":[{"internalType":"string","name":"trait_type","type":"string"},{"internalType":"string","name":"value","type":"string"}],"internalType":"struct NFTMetadataAttribute[]","name":"attributes","type":"tuple[]"}],"internalType":"struct NFTMetadata","name":"metadata","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"collection","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getTokenURI","outputs":[{"internalType":"string","name":"tokenURI","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint16","name":"","type":"uint16"}],"name":"metadataStoragePointers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ICollection","name":"collection","type":"address"},{"internalType":"uint16","name":"sequenceId","type":"uint16"},{"internalType":"uint8","name":"count","type":"uint8"}],"name":"mint","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"nodeRegistry","outputs":[{"internalType":"contract INodeRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"primarySaleFeeBps","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"fee","type":"uint16"}],"name":"setPrimarySaleFeeBps","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"transferFeesToOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a06040523480156200001157600080fd5b50604051620034c5380380620034c58339810160408190526200003491620000a9565b600080546001600160a01b0319166001600160a01b03841690811782556040518492907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506001600160a01b031660805250620000e8565b6001600160a01b0381168114620000a657600080fd5b50565b60008060408385031215620000bd57600080fd5b8251620000ca8162000090565b6020840151909250620000dd8162000090565b809150509250929050565b6080516133ba6200010b6000396000818161029501526108c401526133ba6000f3fe6080604052600436106100dd5760003560e01c8063b1e8d9701161007f578063e289208711610059578063e2892087146102b7578063f11c801c146102e4578063f2fde38b146102f7578063f746f01f1461031757600080fd5b8063b1e8d9701461024e578063cfd88a3614610263578063d9b5c4a51461028357600080fd5b806322a5c8d0116100bb57806322a5c8d01461019f57806336de9742146101c1578063502493c1146102005780638da5cb5b1461022e57600080fd5b80630b63fd62146100e25780630c8caf9a146101185780631618229314610171575b600080fd5b3480156100ee57600080fd5b506101026100fd366004611ca0565b610445565b60405161010f9190611d1c565b60405180910390f35b34801561012457600080fd5b50610159610133366004611d51565b60026020908152600092835260408084209091529082529020546001600160a01b031681565b6040516001600160a01b03909116815260200161010f565b34801561017d57600080fd5b5060035461018c9061ffff1681565b60405161ffff909116815260200161010f565b3480156101ab57600080fd5b506101bf6101ba366004611d8a565b61095d565b005b3480156101cd57600080fd5b506101e16101dc366004611e27565b610de9565b604080516001600160a01b03909316835260208301919091520161010f565b34801561020c57600080fd5b5061022061021b366004611d51565b610ec2565b60405190815260200161010f565b34801561023a57600080fd5b50600054610159906001600160a01b031681565b34801561025a57600080fd5b506101bf610f8a565b34801561026f57600080fd5b506101bf61027e366004611e5c565b611001565b34801561028f57600080fd5b506101597f000000000000000000000000000000000000000000000000000000000000000081565b3480156102c357600080fd5b506102d76102d2366004611ca0565b6110c0565b60405161010f9190612008565b6102206102f236600461202c565b611366565b34801561030357600080fd5b506101bf610312366004612073565b6116b5565b34801561032357600080fd5b506103d4610332366004611d51565b600160208181526000938452604080852090915291835291208054918101546002909101546001600160601b038084169361ffff600160601b80830482169560ff6e01000000000000000000000000000085048116966f010000000000000000000000000000008604821696600160801b909604909116946001600160a01b03831694600160a01b909304909216929181169167ffffffffffffffff91041689565b604080516001600160601b039a8b16815261ffff998a16602082015297151590880152941515606087015260ff9390931660808601526001600160a01b039190911660a085015290931660c08301529190921660e083015267ffffffffffffffff166101008201526101200161010f565b6040516305b5acb960e31b8152600481018290526060906000906001600160a01b03851690632dad65c890602401602060405180830381865afa158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b49190612090565b604051633aa9eee560e21b8152600481018590529091506000906001600160a01b0386169063eaa7bb9490602401602060405180830381865afa1580156104ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052391906120ad565b6040517fef65403c00000000000000000000000000000000000000000000000000000000815261ffff841660048201529091506000906001600160a01b0387169063ef65403c9060240160c060405180830381865afa15801561058a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ae91906121a7565b905060006105bc87876110c0565b90506000826040015167ffffffffffffffff16600014610627576105eb8469ffffffffffffffffffff16611761565b610602846040015167ffffffffffffffff16611761565b60405160200161061392919061226e565b60405160208183030381529060405261063c565b61063c8469ffffffffffffffffffff16611761565b9050600081836080015160008560e0015151116106685760405180602001604052806000815250610684565b60405180604001604052806002815260200161016160f51b8152505b604051602001610696939291906122c6565b604051602081830303815290604052905060005b8360e001515181101561076c5781600082116106d557604051806020016040528060008152506106f1565b60405180604001604052806002815260200161016160f51b8152505b8560e001518381518110610707576107076123b7565b6020026020010151600001518660e001518481518110610729576107296123b7565b60200260200101516020015160405160200161074894939291906123cd565b604051602081830303815290604052915080806107649061249d565b9150506106aa565b5060408051808201909152600181527f5b00000000000000000000000000000000000000000000000000000000000000602082015260005b8460c001515181101561088157816107dc8660c0015183815181106107cb576107cb6123b7565b602002602001015161ffff16611761565b60018760c00151516107ee91906124b6565b83146108145760405180604001604052806002815260200161016160f51b81525061084b565b6040518060400160405280600181526020017f5d000000000000000000000000000000000000000000000000000000000000008152505b60405160200161085d939291906124c9565b604051602081830303815290604052915080806108799061249d565b9150506107a4565b5060008460000151848660200151876040015188606001516040516020016108ad95949392919061250c565b6040516020818303038152906040529050806108f37f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316601461186a565b86608001518760a00151858760405160200161091496959493929190612676565b604051602081830303815290604052905061092e81611a38565b60405160200161093e9190612804565b6040516020818303038152906040529850505050505050505092915050565b60008061096c83850185612c3e565b815191935091506000906001600160601b0316158015610997575060e08301516001600160601b0316155b60a08401519091506001600160a01b031615811515146109e3576040517ff1c970d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015167ffffffffffffffff1615801590610a3d57504283610100015167ffffffffffffffff161080610a3d5750610a216020870187612d32565b67ffffffffffffffff1683610100015167ffffffffffffffff16105b15610a5b5760405163564646d560e11b815260040160405180910390fd5b6000610a6d6040880160208901612d32565b67ffffffffffffffff16118015610aab5750610a8f6040870160208801612d32565b67ffffffffffffffff1683610100015167ffffffffffffffff16115b15610ac95760405163564646d560e11b815260040160405180910390fd5b60e083015161010084015167ffffffffffffffff16156001600160601b039091161514610b095760405163564646d560e11b815260040160405180910390fd5b612710836020015161ffff161115610b4d576040517f2568952000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60035460c084015161ffff908116911614610b7b576040516362ce3dcd60e01b815260040160405180910390fd5b610ba382604051602001610b8f9190612d4f565b604051602081830303815290604052611b8b565b60026000336001600160a01b03166001600160a01b0316815260200190815260200160002060008961ffff1661ffff16815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508260016000336001600160a01b03166001600160a01b0316815260200190815260200160002060008961ffff1661ffff16815260200190815260200160002060008201518160000160006101000a8154816001600160601b0302191690836001600160601b03160217905550602082015181600001600c6101000a81548161ffff021916908361ffff160217905550604082015181600001600e6101000a81548160ff021916908315150217905550606082015181600001600f6101000a81548160ff02191690831515021790555060808201518160000160106101000a81548160ff021916908360ff16021790555060a08201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060c08201518160010160146101000a81548161ffff021916908361ffff16021790555060e08201518160020160006101000a8154816001600160601b0302191690836001600160601b0316021790555061010082015181600201600c6101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055509050507fc64b0f1a277fb0efdf2ed63e3c5a529f5c80920863464b9b44695ad9c041fa0a338885604051610dd893929190612db1565b60405180910390a150505050505050565b6000806000856001600160a01b0316632dad65c8866040518263ffffffff1660e01b8152600401610e1c91815260200190565b602060405180830381865afa158015610e39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e5d9190612090565b6001600160a01b03808816600090815260016020818152604080842061ffff80881686529252909220908101548154949550909392169161271091610eaa91600160601b90041688612e7e565b610eb49190612eab565b935093505050935093915050565b6001600160a01b038216600090815260016020908152604080832061ffff85168452909152812060028101548290600160601b900467ffffffffffffffff164210610f0e576000610f2f565b6002820154610f2f904290600160601b900467ffffffffffffffff16612ebf565b60028301549091506000906201518090610f5d9067ffffffffffffffff8516906001600160601b0316612e7e565b610f679190612eab565b8354909150610f809082906001600160601b0316612ee7565b9695505050505050565b600080546040516001600160a01b039091169047908381818185875af1925050503d8060008114610fd7576040519150601f19603f3d011682016040523d82523d6000602084013e610fdc565b606091505b5050905080610ffe57604051634917cec360e11b815260040160405180910390fd5b50565b6000546001600160a01b0316331461104f5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b60448201526064015b60405180910390fd5b6127108161ffff161115611076576040516362ce3dcd60e01b815260040160405180910390fd5b6003805461ffff191661ffff83169081179091556040519081527fc26f8db1267f65723040652d335ca099d7f37fb82ee03cb67ee19bc815b5fd959060200160405180910390a150565b61110860405180610100016040528060608152602001606081526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b6040516305b5acb960e31b8152600481018390526000906001600160a01b03851690632dad65c890602401602060405180830381865afa158015611150573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111749190612090565b604051633aa9eee560e21b8152600481018590529091506000906001600160a01b0386169063eaa7bb9490602401602060405180830381865afa1580156111bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e391906120ad565b6001600160a01b03808716600090815260026020908152604080832061ffff881684529091528120549293509161121a9116611c3c565b80602001905181019061122d9190613082565b9050600081516001846112409190613272565b69ffffffffffffffffffff166112569190613295565b6001600160a01b038816600090815260016020908152604080832061ffff891684529091529020549091506f01000000000000000000000000000000900460ff16156113405781516040805160608a811b6bffffffffffffffffffffffff1916602083015260f088901b7fffff00000000000000000000000000000000000000000000000000000000000016603483015260b087901b7fffffffffffffffffffff00000000000000000000000000000000000000000000166036830152918101899052016040516020818303038152906040528051906020012060001c61133d9190613295565b90505b818181518110611352576113526123b7565b602002602001015194505050505092915050565b6001600160a01b038316600090815260016020908152604080832061ffff86168452909152812080546e010000000000000000000000000000900460ff161580156113b15750333214155b156113e8576040517ff000bcf600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8054600160801b900460ff16158015906114105750805460ff600160801b9091048116908416115b15611447576040517fccfad01800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006114538686610ec2565b9050600061146460ff861683612e7e565b9050803410156114a0576040517f6992e1ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8560ff16811015611566576040517f6342747b00000000000000000000000000000000000000000000000000000000815233600482015261ffff881660248201526000906001600160a01b038a1690636342747b906044016020604051808303816000875af115801561151a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061153e91906132a9565b90508560000361154e5780611550565b855b955050808061155e9061249d565b9150506114a3565b5060018301546000906127109061158890600160a01b900461ffff1684612e7e565b6115929190612eab565b61159c90836124b6565b905060008234116115ae5760006115b8565b6115b883346124b6565b9050801561162b57604051600090339083908381818185875af1925050503d8060008114611602576040519150601f19603f3d011682016040523d82523d6000602084013e611607565b606091505b505090508061162957604051634917cec360e11b815260040160405180910390fd5b505b81156116a95760018501546040516000916001600160a01b03169084908381818185875af1925050503d8060008114611680576040519150601f19603f3d011682016040523d82523d6000602084013e611685565b606091505b50509050806116a757604051634917cec360e11b815260040160405180910390fd5b505b50505050509392505050565b6000546001600160a01b031633146116fe5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401611046565b600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b6060816000036117885750506040805180820190915260018152600360fc1b602082015290565b8160005b81156117b2578061179c8161249d565b91506117ab9050600a83612eab565b915061178c565b60008167ffffffffffffffff8111156117cd576117cd6120d9565b6040519080825280601f01601f1916602001820160405280156117f7576020820181803683370190505b5090505b84156118625761180c6001836124b6565b9150611819600a86613295565b611824906030612ee7565b60f81b818381518110611839576118396123b7565b60200101906001600160f81b031916908160001a90535061185b600a86612eab565b94506117fb565b949350505050565b60606000611879836002612e7e565b611884906002612ee7565b67ffffffffffffffff81111561189c5761189c6120d9565b6040519080825280601f01601f1916602001820160405280156118c6576020820181803683370190505b509050600360fc1b816000815181106118e1576118e16123b7565b60200101906001600160f81b031916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061192c5761192c6123b7565b60200101906001600160f81b031916908160001a9053506000611950846002612e7e565b61195b906001612ee7565b90505b60018111156119e0577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061199c5761199c6123b7565b1a60f81b8282815181106119b2576119b26123b7565b60200101906001600160f81b031916908160001a90535060049490941c936119d9816132c2565b905061195e565b508315611a2f5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401611046565b90505b92915050565b60608151600003611a5757505060408051602081019091526000815290565b60006040518060600160405280604081526020016133456040913990506000600384516002611a869190612ee7565b611a909190612eab565b611a9b906004612e7e565b67ffffffffffffffff811115611ab357611ab36120d9565b6040519080825280601f01601f191660200182016040528015611add576020820181803683370190505b509050600182016020820185865187015b80821015611b49576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250611aee565b5050600386510660018114611b655760028114611b7857611b80565b603d6001830353603d6002830353611b80565b603d60018303535b509195945050505050565b60008082604051602001611b9f91906132d9565b6040516020818303038152906040529050600081604051602001611bc391906132ff565b60405160208183030381529060405290508051602082016000f092506001600160a01b038316611c355760405162461bcd60e51b815260206004820152601160248201527f4445504c4f594d454e545f4641494c45440000000000000000000000000000006044820152606401611046565b5050919050565b6060611a32826001611c58816001600160a01b0384163b6124b6565b60408051603f8301601f19168101909152818152818360208301863c9392505050565b6001600160a01b0381168114610ffe57600080fd5b8035611c9b81611c7b565b919050565b60008060408385031215611cb357600080fd5b8235611cbe81611c7b565b946020939093013593505050565b60005b83811015611ce7578181015183820152602001611ccf565b50506000910152565b60008151808452611d08816020860160208601611ccc565b601f01601f19169290920160200192915050565b602081526000611d2f6020830184611cf0565b9392505050565b61ffff81168114610ffe57600080fd5b8035611c9b81611d36565b60008060408385031215611d6457600080fd5b8235611d6f81611c7b565b91506020830135611d7f81611d36565b809150509250929050565b600080600080848603610100811215611da257600080fd5b8535611dad81611d36565b945060c0601f1982011215611dc157600080fd5b5060208501925060e085013567ffffffffffffffff80821115611de357600080fd5b818701915087601f830112611df757600080fd5b813581811115611e0657600080fd5b886020828501011115611e1857600080fd5b95989497505060200194505050565b600080600060608486031215611e3c57600080fd5b8335611e4781611c7b565b95602085013595506040909401359392505050565b600060208284031215611e6e57600080fd5b8135611a2f81611d36565b600081518084526020808501945080840160005b83811015611ead57815161ffff1687529582019590820190600101611e8d565b509495945050505050565b600081518084526020808501808196508360051b8101915082860160005b85811015611f26578284038952815160408151818752611ef882880182611cf0565b91505086820151915085810387870152611f128183611cf0565b9a87019a9550505090840190600101611ed6565b5091979650505050505050565b60006101008251818552611f4982860182611cf0565b91505060208301518482036020860152611f638282611cf0565b91505060408301518482036040860152611f7d8282611cf0565b91505060608301518482036060860152611f978282611cf0565b91505060808301518482036080860152611fb18282611cf0565b91505060a083015184820360a0860152611fcb8282611cf0565b91505060c083015184820360c0860152611fe58282611e79565b91505060e083015184820360e0860152611fff8282611eb8565b95945050505050565b602081526000611d2f6020830184611f33565b803560ff81168114611c9b57600080fd5b60008060006060848603121561204157600080fd5b833561204c81611c7b565b9250602084013561205c81611d36565b915061206a6040850161201b565b90509250925092565b60006020828403121561208557600080fd5b8135611a2f81611c7b565b6000602082840312156120a257600080fd5b8151611a2f81611d36565b6000602082840312156120bf57600080fd5b815169ffffffffffffffffffff81168114611a2f57600080fd5b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715612112576121126120d9565b60405290565b604051610100810167ffffffffffffffff81118282101715612112576121126120d9565b604051610120810167ffffffffffffffff81118282101715612112576121126120d9565b604051601f8201601f1916810167ffffffffffffffff81118282101715612189576121896120d9565b604052919050565b67ffffffffffffffff81168114610ffe57600080fd5b600060c082840312156121b957600080fd5b60405160c0810181811067ffffffffffffffff821117156121dc576121dc6120d9565b60405282516121ea81612191565b815260208301516121fa81612191565b6020820152604083015161220d81612191565b6040820152606083015161222081612191565b6060820152608083015161223381611c7b565b608082015260a083015161224681612191565b60a08201529392505050565b60008151612264818560208601611ccc565b9290920192915050565b60008351612280818460208801611ccc565b7f2f0000000000000000000000000000000000000000000000000000000000000090830190815283516122ba816001840160208801611ccc565b01600101949350505050565b7f7b2274726169745f74797065223a20225265636f72642045646974696f6e222c81527f202276616c7565223a202200000000000000000000000000000000000000000060208201526000845161232481602b850160208901611ccc565b7f227d2c207b2274726169745f74797065223a20225265636f7264205661726961602b918401918201527f6e74222c202276616c7565223a20220000000000000000000000000000000000604b820152845161238781605a840160208901611ccc565b61227d60f01b605a929091019182015283516123aa81605c840160208801611ccc565b01605c0195945050505050565b634e487b7160e01b600052603260045260246000fd5b600085516123df818460208a01611ccc565b8551908301906123f3818360208a01611ccc565b7f7b2274726169745f74797065223a2022000000000000000000000000000000009101908152845161242c816010840160208901611ccc565b7f222c202276616c7565223a20220000000000000000000000000000000000000060109290910191820152835161246a81601d840160208801611ccc565b61227d60f01b601d9290910191820152601f019695505050505050565b634e487b7160e01b600052601160045260246000fd5b6000600182016124af576124af612487565b5060010190565b81810381811115611a3257611a32612487565b600084516124db818460208901611ccc565b8451908301906124ef818360208901611ccc565b8451910190612502818360208801611ccc565b0195945050505050565b7f7b226e616d65223a220000000000000000000000000000000000000000000000815260008651612544816009850160208b01611ccc565b7f2000000000000000000000000000000000000000000000000000000000000000600991840191820152865161258181600a840160208b01611ccc565b7f222c20226465736372697074696f6e223a220000000000000000000000000000600a929091019182015285516125bf81601c840160208a01611ccc565b7f222c2022696d616765223a202200000000000000000000000000000000000000601c929091019182015284516125fd816029840160208901611ccc565b7f222c202265787465726e616c5f75726c223a202200000000000000000000000060299290910191820152835161263b81603d840160208801611ccc565b01612668603d82017f222c2000000000000000000000000000000000000000000000000000000000009052565b604001979650505050505050565b60008751612688818460208c01611ccc565b80830190507f226d6574616c6162656c223a207b20226e6f64655f72656769737472795f616481527f6472657373223a20220000000000000000000000000000000000000000000000602082015287516126e9816029840160208c01611ccc565b7f222c20227265636f72645f76617269616e745f6e616d65223a20220000000000602992909101918201528651612727816044840160208b01611ccc565b7f222c202272656c656173655f6d657461646174615f757269223a202200000000604492909101918201528551612765816060840160208a01611ccc565b01612792606082017f222c20227265636f72645f636f6e74656e7473223a20000000000000000000009052565b61279f6076820186612252565b7f7d2c202261747472696275746573223a205b0000000000000000000000000000815290506127d16012820185612252565b7f5d7d00000000000000000000000000000000000000000000000000000000000081526002019998505050505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161283c81601d850160208701611ccc565b91909101601d0192915050565b80356001600160601b0381168114611c9b57600080fd5b80358015158114611c9b57600080fd5b8035611c9b81612191565b600067ffffffffffffffff821115612895576128956120d9565b5060051b60200190565b600067ffffffffffffffff8211156128b9576128b96120d9565b50601f01601f191660200190565b600082601f8301126128d857600080fd5b81356128eb6128e68261289f565b612160565b81815284602083860101111561290057600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261292e57600080fd5b8135602061293e6128e68361287b565b82815260059290921b8401810191818101908684111561295d57600080fd5b8286015b8481101561298157803561297481611d36565b8352918301918301612961565b509695505050505050565b600082601f83011261299d57600080fd5b813560206129ad6128e68361287b565b82815260059290921b840181019181810190868411156129cc57600080fd5b8286015b8481101561298157803567ffffffffffffffff808211156129f15760008081fd5b908801906040828b03601f1901811315612a0b5760008081fd5b612a136120ef565b8784013583811115612a255760008081fd5b612a338d8a838801016128c7565b825250908301359082821115612a495760008081fd5b612a578c89848701016128c7565b8189015286525050509183019183016129d0565b600082601f830112612a7c57600080fd5b81356020612a8c6128e68361287b565b82815260059290921b84018101918181019086841115612aab57600080fd5b8286015b8481101561298157803567ffffffffffffffff80821115612ad05760008081fd5b90880190610100828b03601f1901811315612aeb5760008081fd5b612af3612118565b8784013583811115612b055760008081fd5b612b138d8a838801016128c7565b82525060408085013584811115612b2a5760008081fd5b612b388e8b838901016128c7565b8a8401525060608086013585811115612b515760008081fd5b612b5f8f8c838a01016128c7565b8385015250608091508186013585811115612b7a5760008081fd5b612b888f8c838a01016128c7565b82850152505060a08086013585811115612ba25760008081fd5b612bb08f8c838a01016128c7565b838501525060c091508186013585811115612bcb5760008081fd5b612bd98f8c838a01016128c7565b82850152505060e08086013585811115612bf35760008081fd5b612c018f8c838a010161291d565b8484015250928501359284841115612c1b57600091508182fd5b612c298e8b8689010161298c565b90830152508652505050918301918301612aaf565b600080828403610140811215612c5357600080fd5b61012080821215612c6357600080fd5b612c6b61213c565b9150612c7685612849565b8252612c8460208601611d46565b6020830152612c9560408601612860565b6040830152612ca660608601612860565b6060830152612cb76080860161201b565b6080830152612cc860a08601611c90565b60a0830152612cd960c08601611d46565b60c0830152612cea60e08601612849565b60e0830152610100612cfd818701612870565b9083015290925083013567ffffffffffffffff811115612d1c57600080fd5b612d2885828601612a6b565b9150509250929050565b600060208284031215612d4457600080fd5b8135611a2f81612191565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015612da457603f19888603018452612d92858351611f33565b94509285019290850190600101612d76565b5092979650505050505050565b6000610160820190506001600160a01b038516825261ffff80851660208401526001600160601b038451166040840152806020850151166060840152506040830151612e01608084018215159052565b50606083015180151560a084015250608083015160ff811660c08401525060a08301516001600160a01b03811660e08401525060c0830151610100612e4b8185018361ffff169052565b60e08501516001600160601b03166101208501529093015167ffffffffffffffff16610140909201919091529392505050565b8082028115828204841417611a3257611a32612487565b634e487b7160e01b600052601260045260246000fd5b600082612eba57612eba612e95565b500490565b67ffffffffffffffff828116828216039080821115612ee057612ee0612487565b5092915050565b80820180821115611a3257611a32612487565b600082601f830112612f0b57600080fd5b8151612f196128e68261289f565b818152846020838601011115612f2e57600080fd5b611862826020830160208701611ccc565b600082601f830112612f5057600080fd5b81516020612f606128e68361287b565b82815260059290921b84018101918181019086841115612f7f57600080fd5b8286015b84811015612981578051612f9681611d36565b8352918301918301612f83565b600082601f830112612fb457600080fd5b81516020612fc46128e68361287b565b82815260059290921b84018101918181019086841115612fe357600080fd5b8286015b8481101561298157805167ffffffffffffffff808211156130085760008081fd5b908801906040828b03601f19018113156130225760008081fd5b61302a6120ef565b878401518381111561303c5760008081fd5b61304a8d8a83880101612efa565b8252509083015190828211156130605760008081fd5b61306e8c8984870101612efa565b818901528652505050918301918301612fe7565b6000602080838503121561309557600080fd5b825167ffffffffffffffff808211156130ad57600080fd5b818501915085601f8301126130c157600080fd5b81516130cf6128e68261287b565b81815260059190911b830184019084810190888311156130ee57600080fd5b8585015b838110156132655780518581111561310957600080fd5b8601610100818c03601f190181131561312157600080fd5b613129612118565b898301518881111561313a57600080fd5b6131488e8c83870101612efa565b82525060408301518881111561315d57600080fd5b61316b8e8c83870101612efa565b8b8301525060608301518881111561318257600080fd5b6131908e8c83870101612efa565b6040830152506080830151888111156131a857600080fd5b6131b68e8c83870101612efa565b60608301525060a0830151888111156131ce57600080fd5b6131dc8e8c83870101612efa565b60808301525060c0830151888111156131f55760008081fd5b6132038e8c83870101612efa565b60a08301525060e0808401518981111561321d5760008081fd5b61322b8f8d83880101612f3f565b60c0840152509183015191888311156132445760008081fd5b6132528e8c85870101612fa3565b90820152855250509186019186016130f2565b5098975050505050505050565b69ffffffffffffffffffff828116828216039080821115612ee057612ee0612487565b6000826132a4576132a4612e95565b500690565b6000602082840312156132bb57600080fd5b5051919050565b6000816132d1576132d1612487565b506000190190565b60008152600082516132f2816001850160208701611ccc565b9190910160010192915050565b7f600b5981380380925939f300000000000000000000000000000000000000000081526000825161333781600b850160208701611ccc565b91909101600b019291505056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa26469706673582212208934fa935e84c77cfb46ced08e7d8d91c71d95c38dd544f9b81c2bf86d6972c064736f6c63430008110033000000000000000000000000118355e0991d163220e79311c5cb97e5f21dfb9100000000000000000000000072373101e2d85807fd46d460c7e0603dca709b86

Deployed Bytecode

0x6080604052600436106100dd5760003560e01c8063b1e8d9701161007f578063e289208711610059578063e2892087146102b7578063f11c801c146102e4578063f2fde38b146102f7578063f746f01f1461031757600080fd5b8063b1e8d9701461024e578063cfd88a3614610263578063d9b5c4a51461028357600080fd5b806322a5c8d0116100bb57806322a5c8d01461019f57806336de9742146101c1578063502493c1146102005780638da5cb5b1461022e57600080fd5b80630b63fd62146100e25780630c8caf9a146101185780631618229314610171575b600080fd5b3480156100ee57600080fd5b506101026100fd366004611ca0565b610445565b60405161010f9190611d1c565b60405180910390f35b34801561012457600080fd5b50610159610133366004611d51565b60026020908152600092835260408084209091529082529020546001600160a01b031681565b6040516001600160a01b03909116815260200161010f565b34801561017d57600080fd5b5060035461018c9061ffff1681565b60405161ffff909116815260200161010f565b3480156101ab57600080fd5b506101bf6101ba366004611d8a565b61095d565b005b3480156101cd57600080fd5b506101e16101dc366004611e27565b610de9565b604080516001600160a01b03909316835260208301919091520161010f565b34801561020c57600080fd5b5061022061021b366004611d51565b610ec2565b60405190815260200161010f565b34801561023a57600080fd5b50600054610159906001600160a01b031681565b34801561025a57600080fd5b506101bf610f8a565b34801561026f57600080fd5b506101bf61027e366004611e5c565b611001565b34801561028f57600080fd5b506101597f00000000000000000000000072373101e2d85807fd46d460c7e0603dca709b8681565b3480156102c357600080fd5b506102d76102d2366004611ca0565b6110c0565b60405161010f9190612008565b6102206102f236600461202c565b611366565b34801561030357600080fd5b506101bf610312366004612073565b6116b5565b34801561032357600080fd5b506103d4610332366004611d51565b600160208181526000938452604080852090915291835291208054918101546002909101546001600160601b038084169361ffff600160601b80830482169560ff6e01000000000000000000000000000085048116966f010000000000000000000000000000008604821696600160801b909604909116946001600160a01b03831694600160a01b909304909216929181169167ffffffffffffffff91041689565b604080516001600160601b039a8b16815261ffff998a16602082015297151590880152941515606087015260ff9390931660808601526001600160a01b039190911660a085015290931660c08301529190921660e083015267ffffffffffffffff166101008201526101200161010f565b6040516305b5acb960e31b8152600481018290526060906000906001600160a01b03851690632dad65c890602401602060405180830381865afa158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b49190612090565b604051633aa9eee560e21b8152600481018590529091506000906001600160a01b0386169063eaa7bb9490602401602060405180830381865afa1580156104ff573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061052391906120ad565b6040517fef65403c00000000000000000000000000000000000000000000000000000000815261ffff841660048201529091506000906001600160a01b0387169063ef65403c9060240160c060405180830381865afa15801561058a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105ae91906121a7565b905060006105bc87876110c0565b90506000826040015167ffffffffffffffff16600014610627576105eb8469ffffffffffffffffffff16611761565b610602846040015167ffffffffffffffff16611761565b60405160200161061392919061226e565b60405160208183030381529060405261063c565b61063c8469ffffffffffffffffffff16611761565b9050600081836080015160008560e0015151116106685760405180602001604052806000815250610684565b60405180604001604052806002815260200161016160f51b8152505b604051602001610696939291906122c6565b604051602081830303815290604052905060005b8360e001515181101561076c5781600082116106d557604051806020016040528060008152506106f1565b60405180604001604052806002815260200161016160f51b8152505b8560e001518381518110610707576107076123b7565b6020026020010151600001518660e001518481518110610729576107296123b7565b60200260200101516020015160405160200161074894939291906123cd565b604051602081830303815290604052915080806107649061249d565b9150506106aa565b5060408051808201909152600181527f5b00000000000000000000000000000000000000000000000000000000000000602082015260005b8460c001515181101561088157816107dc8660c0015183815181106107cb576107cb6123b7565b602002602001015161ffff16611761565b60018760c00151516107ee91906124b6565b83146108145760405180604001604052806002815260200161016160f51b81525061084b565b6040518060400160405280600181526020017f5d000000000000000000000000000000000000000000000000000000000000008152505b60405160200161085d939291906124c9565b604051602081830303815290604052915080806108799061249d565b9150506107a4565b5060008460000151848660200151876040015188606001516040516020016108ad95949392919061250c565b6040516020818303038152906040529050806108f37f00000000000000000000000072373101e2d85807fd46d460c7e0603dca709b866001600160a01b0316601461186a565b86608001518760a00151858760405160200161091496959493929190612676565b604051602081830303815290604052905061092e81611a38565b60405160200161093e9190612804565b6040516020818303038152906040529850505050505050505092915050565b60008061096c83850185612c3e565b815191935091506000906001600160601b0316158015610997575060e08301516001600160601b0316155b60a08401519091506001600160a01b031615811515146109e3576040517ff1c970d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61010083015167ffffffffffffffff1615801590610a3d57504283610100015167ffffffffffffffff161080610a3d5750610a216020870187612d32565b67ffffffffffffffff1683610100015167ffffffffffffffff16105b15610a5b5760405163564646d560e11b815260040160405180910390fd5b6000610a6d6040880160208901612d32565b67ffffffffffffffff16118015610aab5750610a8f6040870160208801612d32565b67ffffffffffffffff1683610100015167ffffffffffffffff16115b15610ac95760405163564646d560e11b815260040160405180910390fd5b60e083015161010084015167ffffffffffffffff16156001600160601b039091161514610b095760405163564646d560e11b815260040160405180910390fd5b612710836020015161ffff161115610b4d576040517f2568952000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60035460c084015161ffff908116911614610b7b576040516362ce3dcd60e01b815260040160405180910390fd5b610ba382604051602001610b8f9190612d4f565b604051602081830303815290604052611b8b565b60026000336001600160a01b03166001600160a01b0316815260200190815260200160002060008961ffff1661ffff16815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508260016000336001600160a01b03166001600160a01b0316815260200190815260200160002060008961ffff1661ffff16815260200190815260200160002060008201518160000160006101000a8154816001600160601b0302191690836001600160601b03160217905550602082015181600001600c6101000a81548161ffff021916908361ffff160217905550604082015181600001600e6101000a81548160ff021916908315150217905550606082015181600001600f6101000a81548160ff02191690831515021790555060808201518160000160106101000a81548160ff021916908360ff16021790555060a08201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060c08201518160010160146101000a81548161ffff021916908361ffff16021790555060e08201518160020160006101000a8154816001600160601b0302191690836001600160601b0316021790555061010082015181600201600c6101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055509050507fc64b0f1a277fb0efdf2ed63e3c5a529f5c80920863464b9b44695ad9c041fa0a338885604051610dd893929190612db1565b60405180910390a150505050505050565b6000806000856001600160a01b0316632dad65c8866040518263ffffffff1660e01b8152600401610e1c91815260200190565b602060405180830381865afa158015610e39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e5d9190612090565b6001600160a01b03808816600090815260016020818152604080842061ffff80881686529252909220908101548154949550909392169161271091610eaa91600160601b90041688612e7e565b610eb49190612eab565b935093505050935093915050565b6001600160a01b038216600090815260016020908152604080832061ffff85168452909152812060028101548290600160601b900467ffffffffffffffff164210610f0e576000610f2f565b6002820154610f2f904290600160601b900467ffffffffffffffff16612ebf565b60028301549091506000906201518090610f5d9067ffffffffffffffff8516906001600160601b0316612e7e565b610f679190612eab565b8354909150610f809082906001600160601b0316612ee7565b9695505050505050565b600080546040516001600160a01b039091169047908381818185875af1925050503d8060008114610fd7576040519150601f19603f3d011682016040523d82523d6000602084013e610fdc565b606091505b5050905080610ffe57604051634917cec360e11b815260040160405180910390fd5b50565b6000546001600160a01b0316331461104f5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b60448201526064015b60405180910390fd5b6127108161ffff161115611076576040516362ce3dcd60e01b815260040160405180910390fd5b6003805461ffff191661ffff83169081179091556040519081527fc26f8db1267f65723040652d335ca099d7f37fb82ee03cb67ee19bc815b5fd959060200160405180910390a150565b61110860405180610100016040528060608152602001606081526020016060815260200160608152602001606081526020016060815260200160608152602001606081525090565b6040516305b5acb960e31b8152600481018390526000906001600160a01b03851690632dad65c890602401602060405180830381865afa158015611150573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111749190612090565b604051633aa9eee560e21b8152600481018590529091506000906001600160a01b0386169063eaa7bb9490602401602060405180830381865afa1580156111bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e391906120ad565b6001600160a01b03808716600090815260026020908152604080832061ffff881684529091528120549293509161121a9116611c3c565b80602001905181019061122d9190613082565b9050600081516001846112409190613272565b69ffffffffffffffffffff166112569190613295565b6001600160a01b038816600090815260016020908152604080832061ffff891684529091529020549091506f01000000000000000000000000000000900460ff16156113405781516040805160608a811b6bffffffffffffffffffffffff1916602083015260f088901b7fffff00000000000000000000000000000000000000000000000000000000000016603483015260b087901b7fffffffffffffffffffff00000000000000000000000000000000000000000000166036830152918101899052016040516020818303038152906040528051906020012060001c61133d9190613295565b90505b818181518110611352576113526123b7565b602002602001015194505050505092915050565b6001600160a01b038316600090815260016020908152604080832061ffff86168452909152812080546e010000000000000000000000000000900460ff161580156113b15750333214155b156113e8576040517ff000bcf600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8054600160801b900460ff16158015906114105750805460ff600160801b9091048116908416115b15611447576040517fccfad01800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006114538686610ec2565b9050600061146460ff861683612e7e565b9050803410156114a0576040517f6992e1ff00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b8560ff16811015611566576040517f6342747b00000000000000000000000000000000000000000000000000000000815233600482015261ffff881660248201526000906001600160a01b038a1690636342747b906044016020604051808303816000875af115801561151a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061153e91906132a9565b90508560000361154e5780611550565b855b955050808061155e9061249d565b9150506114a3565b5060018301546000906127109061158890600160a01b900461ffff1684612e7e565b6115929190612eab565b61159c90836124b6565b905060008234116115ae5760006115b8565b6115b883346124b6565b9050801561162b57604051600090339083908381818185875af1925050503d8060008114611602576040519150601f19603f3d011682016040523d82523d6000602084013e611607565b606091505b505090508061162957604051634917cec360e11b815260040160405180910390fd5b505b81156116a95760018501546040516000916001600160a01b03169084908381818185875af1925050503d8060008114611680576040519150601f19603f3d011682016040523d82523d6000602084013e611685565b606091505b50509050806116a757604051634917cec360e11b815260040160405180910390fd5b505b50505050509392505050565b6000546001600160a01b031633146116fe5760405162461bcd60e51b815260206004820152600c60248201526b15539055551213d49256915160a21b6044820152606401611046565b600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b6060816000036117885750506040805180820190915260018152600360fc1b602082015290565b8160005b81156117b2578061179c8161249d565b91506117ab9050600a83612eab565b915061178c565b60008167ffffffffffffffff8111156117cd576117cd6120d9565b6040519080825280601f01601f1916602001820160405280156117f7576020820181803683370190505b5090505b84156118625761180c6001836124b6565b9150611819600a86613295565b611824906030612ee7565b60f81b818381518110611839576118396123b7565b60200101906001600160f81b031916908160001a90535061185b600a86612eab565b94506117fb565b949350505050565b60606000611879836002612e7e565b611884906002612ee7565b67ffffffffffffffff81111561189c5761189c6120d9565b6040519080825280601f01601f1916602001820160405280156118c6576020820181803683370190505b509050600360fc1b816000815181106118e1576118e16123b7565b60200101906001600160f81b031916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061192c5761192c6123b7565b60200101906001600160f81b031916908160001a9053506000611950846002612e7e565b61195b906001612ee7565b90505b60018111156119e0577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061199c5761199c6123b7565b1a60f81b8282815181106119b2576119b26123b7565b60200101906001600160f81b031916908160001a90535060049490941c936119d9816132c2565b905061195e565b508315611a2f5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401611046565b90505b92915050565b60608151600003611a5757505060408051602081019091526000815290565b60006040518060600160405280604081526020016133456040913990506000600384516002611a869190612ee7565b611a909190612eab565b611a9b906004612e7e565b67ffffffffffffffff811115611ab357611ab36120d9565b6040519080825280601f01601f191660200182016040528015611add576020820181803683370190505b509050600182016020820185865187015b80821015611b49576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845350600183019250611aee565b5050600386510660018114611b655760028114611b7857611b80565b603d6001830353603d6002830353611b80565b603d60018303535b509195945050505050565b60008082604051602001611b9f91906132d9565b6040516020818303038152906040529050600081604051602001611bc391906132ff565b60405160208183030381529060405290508051602082016000f092506001600160a01b038316611c355760405162461bcd60e51b815260206004820152601160248201527f4445504c4f594d454e545f4641494c45440000000000000000000000000000006044820152606401611046565b5050919050565b6060611a32826001611c58816001600160a01b0384163b6124b6565b60408051603f8301601f19168101909152818152818360208301863c9392505050565b6001600160a01b0381168114610ffe57600080fd5b8035611c9b81611c7b565b919050565b60008060408385031215611cb357600080fd5b8235611cbe81611c7b565b946020939093013593505050565b60005b83811015611ce7578181015183820152602001611ccf565b50506000910152565b60008151808452611d08816020860160208601611ccc565b601f01601f19169290920160200192915050565b602081526000611d2f6020830184611cf0565b9392505050565b61ffff81168114610ffe57600080fd5b8035611c9b81611d36565b60008060408385031215611d6457600080fd5b8235611d6f81611c7b565b91506020830135611d7f81611d36565b809150509250929050565b600080600080848603610100811215611da257600080fd5b8535611dad81611d36565b945060c0601f1982011215611dc157600080fd5b5060208501925060e085013567ffffffffffffffff80821115611de357600080fd5b818701915087601f830112611df757600080fd5b813581811115611e0657600080fd5b886020828501011115611e1857600080fd5b95989497505060200194505050565b600080600060608486031215611e3c57600080fd5b8335611e4781611c7b565b95602085013595506040909401359392505050565b600060208284031215611e6e57600080fd5b8135611a2f81611d36565b600081518084526020808501945080840160005b83811015611ead57815161ffff1687529582019590820190600101611e8d565b509495945050505050565b600081518084526020808501808196508360051b8101915082860160005b85811015611f26578284038952815160408151818752611ef882880182611cf0565b91505086820151915085810387870152611f128183611cf0565b9a87019a9550505090840190600101611ed6565b5091979650505050505050565b60006101008251818552611f4982860182611cf0565b91505060208301518482036020860152611f638282611cf0565b91505060408301518482036040860152611f7d8282611cf0565b91505060608301518482036060860152611f978282611cf0565b91505060808301518482036080860152611fb18282611cf0565b91505060a083015184820360a0860152611fcb8282611cf0565b91505060c083015184820360c0860152611fe58282611e79565b91505060e083015184820360e0860152611fff8282611eb8565b95945050505050565b602081526000611d2f6020830184611f33565b803560ff81168114611c9b57600080fd5b60008060006060848603121561204157600080fd5b833561204c81611c7b565b9250602084013561205c81611d36565b915061206a6040850161201b565b90509250925092565b60006020828403121561208557600080fd5b8135611a2f81611c7b565b6000602082840312156120a257600080fd5b8151611a2f81611d36565b6000602082840312156120bf57600080fd5b815169ffffffffffffffffffff81168114611a2f57600080fd5b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715612112576121126120d9565b60405290565b604051610100810167ffffffffffffffff81118282101715612112576121126120d9565b604051610120810167ffffffffffffffff81118282101715612112576121126120d9565b604051601f8201601f1916810167ffffffffffffffff81118282101715612189576121896120d9565b604052919050565b67ffffffffffffffff81168114610ffe57600080fd5b600060c082840312156121b957600080fd5b60405160c0810181811067ffffffffffffffff821117156121dc576121dc6120d9565b60405282516121ea81612191565b815260208301516121fa81612191565b6020820152604083015161220d81612191565b6040820152606083015161222081612191565b6060820152608083015161223381611c7b565b608082015260a083015161224681612191565b60a08201529392505050565b60008151612264818560208601611ccc565b9290920192915050565b60008351612280818460208801611ccc565b7f2f0000000000000000000000000000000000000000000000000000000000000090830190815283516122ba816001840160208801611ccc565b01600101949350505050565b7f7b2274726169745f74797065223a20225265636f72642045646974696f6e222c81527f202276616c7565223a202200000000000000000000000000000000000000000060208201526000845161232481602b850160208901611ccc565b7f227d2c207b2274726169745f74797065223a20225265636f7264205661726961602b918401918201527f6e74222c202276616c7565223a20220000000000000000000000000000000000604b820152845161238781605a840160208901611ccc565b61227d60f01b605a929091019182015283516123aa81605c840160208801611ccc565b01605c0195945050505050565b634e487b7160e01b600052603260045260246000fd5b600085516123df818460208a01611ccc565b8551908301906123f3818360208a01611ccc565b7f7b2274726169745f74797065223a2022000000000000000000000000000000009101908152845161242c816010840160208901611ccc565b7f222c202276616c7565223a20220000000000000000000000000000000000000060109290910191820152835161246a81601d840160208801611ccc565b61227d60f01b601d9290910191820152601f019695505050505050565b634e487b7160e01b600052601160045260246000fd5b6000600182016124af576124af612487565b5060010190565b81810381811115611a3257611a32612487565b600084516124db818460208901611ccc565b8451908301906124ef818360208901611ccc565b8451910190612502818360208801611ccc565b0195945050505050565b7f7b226e616d65223a220000000000000000000000000000000000000000000000815260008651612544816009850160208b01611ccc565b7f2000000000000000000000000000000000000000000000000000000000000000600991840191820152865161258181600a840160208b01611ccc565b7f222c20226465736372697074696f6e223a220000000000000000000000000000600a929091019182015285516125bf81601c840160208a01611ccc565b7f222c2022696d616765223a202200000000000000000000000000000000000000601c929091019182015284516125fd816029840160208901611ccc565b7f222c202265787465726e616c5f75726c223a202200000000000000000000000060299290910191820152835161263b81603d840160208801611ccc565b01612668603d82017f222c2000000000000000000000000000000000000000000000000000000000009052565b604001979650505050505050565b60008751612688818460208c01611ccc565b80830190507f226d6574616c6162656c223a207b20226e6f64655f72656769737472795f616481527f6472657373223a20220000000000000000000000000000000000000000000000602082015287516126e9816029840160208c01611ccc565b7f222c20227265636f72645f76617269616e745f6e616d65223a20220000000000602992909101918201528651612727816044840160208b01611ccc565b7f222c202272656c656173655f6d657461646174615f757269223a202200000000604492909101918201528551612765816060840160208a01611ccc565b01612792606082017f222c20227265636f72645f636f6e74656e7473223a20000000000000000000009052565b61279f6076820186612252565b7f7d2c202261747472696275746573223a205b0000000000000000000000000000815290506127d16012820185612252565b7f5d7d00000000000000000000000000000000000000000000000000000000000081526002019998505050505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161283c81601d850160208701611ccc565b91909101601d0192915050565b80356001600160601b0381168114611c9b57600080fd5b80358015158114611c9b57600080fd5b8035611c9b81612191565b600067ffffffffffffffff821115612895576128956120d9565b5060051b60200190565b600067ffffffffffffffff8211156128b9576128b96120d9565b50601f01601f191660200190565b600082601f8301126128d857600080fd5b81356128eb6128e68261289f565b612160565b81815284602083860101111561290057600080fd5b816020850160208301376000918101602001919091529392505050565b600082601f83011261292e57600080fd5b8135602061293e6128e68361287b565b82815260059290921b8401810191818101908684111561295d57600080fd5b8286015b8481101561298157803561297481611d36565b8352918301918301612961565b509695505050505050565b600082601f83011261299d57600080fd5b813560206129ad6128e68361287b565b82815260059290921b840181019181810190868411156129cc57600080fd5b8286015b8481101561298157803567ffffffffffffffff808211156129f15760008081fd5b908801906040828b03601f1901811315612a0b5760008081fd5b612a136120ef565b8784013583811115612a255760008081fd5b612a338d8a838801016128c7565b825250908301359082821115612a495760008081fd5b612a578c89848701016128c7565b8189015286525050509183019183016129d0565b600082601f830112612a7c57600080fd5b81356020612a8c6128e68361287b565b82815260059290921b84018101918181019086841115612aab57600080fd5b8286015b8481101561298157803567ffffffffffffffff80821115612ad05760008081fd5b90880190610100828b03601f1901811315612aeb5760008081fd5b612af3612118565b8784013583811115612b055760008081fd5b612b138d8a838801016128c7565b82525060408085013584811115612b2a5760008081fd5b612b388e8b838901016128c7565b8a8401525060608086013585811115612b515760008081fd5b612b5f8f8c838a01016128c7565b8385015250608091508186013585811115612b7a5760008081fd5b612b888f8c838a01016128c7565b82850152505060a08086013585811115612ba25760008081fd5b612bb08f8c838a01016128c7565b838501525060c091508186013585811115612bcb5760008081fd5b612bd98f8c838a01016128c7565b82850152505060e08086013585811115612bf35760008081fd5b612c018f8c838a010161291d565b8484015250928501359284841115612c1b57600091508182fd5b612c298e8b8689010161298c565b90830152508652505050918301918301612aaf565b600080828403610140811215612c5357600080fd5b61012080821215612c6357600080fd5b612c6b61213c565b9150612c7685612849565b8252612c8460208601611d46565b6020830152612c9560408601612860565b6040830152612ca660608601612860565b6060830152612cb76080860161201b565b6080830152612cc860a08601611c90565b60a0830152612cd960c08601611d46565b60c0830152612cea60e08601612849565b60e0830152610100612cfd818701612870565b9083015290925083013567ffffffffffffffff811115612d1c57600080fd5b612d2885828601612a6b565b9150509250929050565b600060208284031215612d4457600080fd5b8135611a2f81612191565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015612da457603f19888603018452612d92858351611f33565b94509285019290850190600101612d76565b5092979650505050505050565b6000610160820190506001600160a01b038516825261ffff80851660208401526001600160601b038451166040840152806020850151166060840152506040830151612e01608084018215159052565b50606083015180151560a084015250608083015160ff811660c08401525060a08301516001600160a01b03811660e08401525060c0830151610100612e4b8185018361ffff169052565b60e08501516001600160601b03166101208501529093015167ffffffffffffffff16610140909201919091529392505050565b8082028115828204841417611a3257611a32612487565b634e487b7160e01b600052601260045260246000fd5b600082612eba57612eba612e95565b500490565b67ffffffffffffffff828116828216039080821115612ee057612ee0612487565b5092915050565b80820180821115611a3257611a32612487565b600082601f830112612f0b57600080fd5b8151612f196128e68261289f565b818152846020838601011115612f2e57600080fd5b611862826020830160208701611ccc565b600082601f830112612f5057600080fd5b81516020612f606128e68361287b565b82815260059290921b84018101918181019086841115612f7f57600080fd5b8286015b84811015612981578051612f9681611d36565b8352918301918301612f83565b600082601f830112612fb457600080fd5b81516020612fc46128e68361287b565b82815260059290921b84018101918181019086841115612fe357600080fd5b8286015b8481101561298157805167ffffffffffffffff808211156130085760008081fd5b908801906040828b03601f19018113156130225760008081fd5b61302a6120ef565b878401518381111561303c5760008081fd5b61304a8d8a83880101612efa565b8252509083015190828211156130605760008081fd5b61306e8c8984870101612efa565b818901528652505050918301918301612fe7565b6000602080838503121561309557600080fd5b825167ffffffffffffffff808211156130ad57600080fd5b818501915085601f8301126130c157600080fd5b81516130cf6128e68261287b565b81815260059190911b830184019084810190888311156130ee57600080fd5b8585015b838110156132655780518581111561310957600080fd5b8601610100818c03601f190181131561312157600080fd5b613129612118565b898301518881111561313a57600080fd5b6131488e8c83870101612efa565b82525060408301518881111561315d57600080fd5b61316b8e8c83870101612efa565b8b8301525060608301518881111561318257600080fd5b6131908e8c83870101612efa565b6040830152506080830151888111156131a857600080fd5b6131b68e8c83870101612efa565b60608301525060a0830151888111156131ce57600080fd5b6131dc8e8c83870101612efa565b60808301525060c0830151888111156131f55760008081fd5b6132038e8c83870101612efa565b60a08301525060e0808401518981111561321d5760008081fd5b61322b8f8d83880101612f3f565b60c0840152509183015191888311156132445760008081fd5b6132528e8c85870101612fa3565b90820152855250509186019186016130f2565b5098975050505050505050565b69ffffffffffffffffffff828116828216039080821115612ee057612ee0612487565b6000826132a4576132a4612e95565b500690565b6000602082840312156132bb57600080fd5b5051919050565b6000816132d1576132d1612487565b506000190190565b60008152600082516132f2816001850160208701611ccc565b9190910160010192915050565b7f600b5981380380925939f300000000000000000000000000000000000000000081526000825161333781600b850160208701611ccc565b91909101600b019291505056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa26469706673582212208934fa935e84c77cfb46ced08e7d8d91c71d95c38dd544f9b81c2bf86d6972c064736f6c63430008110033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000118355e0991d163220e79311c5cb97e5f21dfb9100000000000000000000000072373101e2d85807fd46d460c7e0603dca709b86

-----Decoded View---------------
Arg [0] : _contractOwner (address): 0x118355e0991d163220E79311C5Cb97e5f21dFb91
Arg [1] : _nodeRegistry (address): 0x72373101e2D85807FD46D460c7E0603DCa709b86

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000118355e0991d163220e79311c5cb97e5f21dfb91
Arg [1] : 00000000000000000000000072373101e2d85807fd46d460c7e0603dca709b86


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
Loading...
Loading
[ Download: CSV Export  ]
[ 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.