ETH Price: $3,568.46 (+0.49%)
Gas: 23 Gwei

Contract

0x208D1008fA508414B6DC63738Bc8560A12Ef5279
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Value
Claim Drop167428032023-03-02 18:59:59391 days ago1677783599IN
0x208D1008...A12Ef5279
0 ETH0.0015859322
Claim Drop167380612023-03-02 2:57:11392 days ago1677725831IN
0x208D1008...A12Ef5279
0 ETH0.0017679324.52465839
Claim Drop167280542023-02-28 17:10:35393 days ago1677604235IN
0x208D1008...A12Ef5279
0 ETH0.0023404532.46667848
Claim Drop167269012023-02-28 13:17:35393 days ago1677590255IN
0x208D1008...A12Ef5279
0 ETH0.002428227.22565802
Claim Drop167264182023-02-28 11:39:59393 days ago1677584399IN
0x208D1008...A12Ef5279
0 ETH0.0012170916.8835086
Claim Drop167226942023-02-27 23:05:59394 days ago1677539159IN
0x208D1008...A12Ef5279
0 ETH0.0025381635.20931742
Set Drop URI167226352023-02-27 22:54:11394 days ago1677538451IN
0x208D1008...A12Ef5279
0 ETH0.0017290140.54150683
Claim Drop167226242023-02-27 22:51:59394 days ago1677538319IN
0x208D1008...A12Ef5279
0 ETH0.0021681730.07684989
Set Drop URI167226042023-02-27 22:47:59394 days ago1677538079IN
0x208D1008...A12Ef5279
0 ETH0.0027246928.20504653
Safe Transfer Fr...164840492023-01-25 13:11:35427 days ago1674652295IN
0x208D1008...A12Ef5279
0 ETH0.0008317716.23284689
Set Approval For...164836802023-01-25 11:57:11427 days ago1674647831IN
0x208D1008...A12Ef5279
0 ETH0.0008559518.6004549
Claim Drop163287892023-01-03 20:57:11449 days ago1672779431IN
0x208D1008...A12Ef5279
0 ETH0.0015203321.09003785
Claim Drop163163682023-01-02 3:21:35451 days ago1672629695IN
0x208D1008...A12Ef5279
0 ETH0.0010484414.54397807
Claim Drop163012752022-12-31 0:50:23453 days ago1672447823IN
0x208D1008...A12Ef5279
0 ETH0.0016537922.94128051
Claim Drop162987182022-12-30 16:16:11453 days ago1672416971IN
0x208D1008...A12Ef5279
0 ETH0.0024489733.97199347
Claim Drop162983152022-12-30 14:55:23453 days ago1672412123IN
0x208D1008...A12Ef5279
0 ETH0.0012481717.31463835
Claim Drop162967012022-12-30 9:30:11453 days ago1672392611IN
0x208D1008...A12Ef5279
0 ETH0.0010475514.53166011
Claim Drop162954452022-12-30 5:17:47454 days ago1672377467IN
0x208D1008...A12Ef5279
0 ETH0.0011607816.10500051
Claim Drop162953132022-12-30 4:51:23454 days ago1672375883IN
0x208D1008...A12Ef5279
0 ETH0.0010197814.14870319
Claim Drop162952442022-12-30 4:37:35454 days ago1672375055IN
0x208D1008...A12Ef5279
0 ETH0.0010818215.0070683
Claim Drop162951492022-12-30 4:18:35454 days ago1672373915IN
0x208D1008...A12Ef5279
0 ETH0.0010888315.10425619
Claim Drop162950102022-12-30 3:50:47454 days ago1672372247IN
0x208D1008...A12Ef5279
0 ETH0.0011450615.88427278
Set Drop URI162949272022-12-30 3:33:59454 days ago1672371239IN
0x208D1008...A12Ef5279
0 ETH0.0028253829.24742753
Claim Drop161267882022-12-06 15:56:11477 days ago1670342171IN
0x208D1008...A12Ef5279
0 ETH0.0016729718.75783829
Claim Drop161022642022-12-03 5:41:11481 days ago1670046071IN
0x208D1008...A12Ef5279
0 ETH0.0012896817.89036467
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Drops

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

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

/**

    -+#@@@@***#%%#*=.                                                           
      -@@@%      -%@@#:                                                         
      -@@@%        %@@@+     .=   .==.    :===-:        .=  :==-       :-=-.  -.
      -@@@%        -@@@@. .=%@@.=%@@@# .*@#. :%@@+   .=%@@.+@@@@@*.  -@@+::=+%@:
      -@@@%        .@@@@=.-%@@@:..#@@%:@@@-    @@@@..-%@@@=::-#@@@%  @@@*:   -@:
      -@@@%        :@@@@-  #@@@   ++- #@@@-    +@@@#  #@@@.    #@@@= *@@@@@*- :.
      -@@@%        *@@@%   #@@@       %@@@=    -@@@@  #@@@.    +@@@= .:+@@@@@@*.
      -@@@%       :@@@#    #@@@       =@@@%    :@@@*  #@@@.    %@@@..%.  :+%@@@%
      -@@@%      =@@#-     #@@@        =@@@=   =@@#   #@@@=..:#@@@: .@@=    *@@#
    -+#####****+++-      .=####+-.      .=#@#=+#+:    #@@@:*@@@%+.  .%:.+**#@%= 
                                                      #@@@.                     
    -----------------------------------------         #@@@.                     
     F R O M   S A M   K I N G   S T U D I O        .=####+-.
    -----------------------------------------

 */

import "solmate/tokens/ERC1155.sol";
import "openzeppelin/utils/cryptography/ECDSA.sol";
import "openzeppelin/utils/cryptography/draft-EIP712.sol";
import "./lib/Auth.sol";
import "./IMetadata.sol";

/**
 * @title  Drops from Sam King Studio
 * @author Sam King (samkingstudio.eth)
 * @notice
 * Allows Sam King Studio to drop NFTs to any ETH address
 *   - NFTs are ERC-1155 tokens
 *   - Can be dropped by the studio directly
 *   - Can also be claimed by an address with a valid EIP-712 signature
 * For more details and license info, check out https://drops.samking.studio
 */
contract Drops is ERC1155, EIP712, Auth {
    /* ------------------------------------------------------------------------
       S T O R A G E
    ------------------------------------------------------------------------ */

    string public name = "Drops from Sam King Studio";
    string public symbol = "SKSDRP";

    /// @dev EIP-712 signing domain
    string public constant SIGNING_DOMAIN = "SamKingStudioDrops";

    /// @dev EIP-712 signature version
    string public constant SIGNATURE_VERSION = "1";

    /// @dev EIP-712 signed data type hash for claiming drops
    bytes32 public constant CLAIM_DROP_TYPEHASH =
        keccak256("ClaimDropData(uint256 dropId,uint256 amount,address to,uint256 nonce)");

    /// @dev EIP-712 signed data struct for claiming drops
    struct ClaimDropData {
        uint256 dropId;
        uint256 amount;
        address to;
        uint256 nonce;
        bytes signature;
    }

    /// @dev Approved signer public addresses
    mapping(address => bool) public approvedSigners;

    /// @dev Nonce management to avoid signature replay attacks
    mapping(address => uint256) public nonces;

    /// @notice Set a token metadata URI per drop
    mapping(uint256 => string) public dropURI;

    /// @notice Optional token metadata contract per drop
    mapping(uint256 => address) public dropMetadataAddress;

    /* ------------------------------------------------------------------------
       I N I T
    ------------------------------------------------------------------------ */

    event Initialised();

    /**
     * @notice Init the contract
     * @param owner_ The owner of the contract. Can use drops.
     * @param admin_ The initial admin of the contract. Can use drops.
     * @param signer_ An initial EIP-712 signing address
     */
    constructor(
        address owner_,
        address admin_,
        address signer_
    ) EIP712(SIGNING_DOMAIN, SIGNATURE_VERSION) Auth(owner_, admin_) {
        approvedSigners[signer_] = true;
        emit SignerAdded(signer_);
        emit Initialised();
    }

    /* ------------------------------------------------------------------------
       M O D I F I E R S
    ------------------------------------------------------------------------ */

    /**
     * @dev
     * Only allows the function to be called when a URI or metadata address has been
     * set for the particular drop
     *
     * @param dropId The id of the drop to check
     */
    modifier onlyWhenDropIsReady(uint256 dropId) {
        // If there's no metadata address, then check if there's a uri set
        if (dropMetadataAddress[dropId] == address(0)) {
            bytes memory dropUri = bytes(dropURI[dropId]);
            require(dropUri.length > 0, "DROP_NOT_READY");
        }
        _;
    }

    /* ------------------------------------------------------------------------
       D R O P S
    ------------------------------------------------------------------------ */

    /// @dev Emitted when an admin has called any of the drop functions
    event Dropped(uint256 indexed dropId);

    /**
     * @notice Mints one token from the specified drop to each recipient
     *
     * @param dropId The id of the drop
     * @param recipients The list of address to mint tokens to
     */
    function drop(uint256 dropId, address[] calldata recipients)
        external
        onlyWhenDropIsReady(dropId)
        onlyOwnerOrAdmin
    {
        for (uint256 i = 0; i < recipients.length; i++) {
            _mint(recipients[i], dropId, 1, "");
        }
        emit Dropped(dropId);
    }

    /**
     * @notice Mints multiple tokens from the specified drop to each recipient
     *
     * @param dropId The id of the drop
     * @param recipients The list of address to mint tokens to
     * @param amount The amount of tokens to mint to each recipient
     */
    function drop(
        uint256 dropId,
        address[] calldata recipients,
        uint256 amount
    ) external onlyWhenDropIsReady(dropId) onlyOwnerOrAdmin {
        if (amount > 0) {
            for (uint256 i = 0; i < recipients.length; i++) {
                _mint(recipients[i], dropId, amount, "");
            }
        }
        emit Dropped(dropId);
    }

    /**
     * @notice Mints multiple tokens from the specified drop to each recipient
     *
     * @param dropId The id of the drop
     * @param recipients The list of address to mint tokens to
     * @param amounts The amount of tokens to mint per recipient
     */
    function drop(
        uint256 dropId,
        address[] calldata recipients,
        uint256[] calldata amounts
    ) external onlyWhenDropIsReady(dropId) onlyOwnerOrAdmin {
        require(recipients.length == amounts.length, "LENGTH_MISMATCH");
        for (uint256 i = 0; i < recipients.length; i++) {
            if (amounts[i] > 0) {
                _mint(recipients[i], dropId, amounts[i], "");
            }
        }
        emit Dropped(dropId);
    }

    /**
     * @notice Mints tokens from the specified drop to a specific address,
     * usually the Sam King Studio or owner address.
     *
     * @param dropId The id of the drop
     * @param to The list of address to mint tokens to
     * @param amount The amount of tokens to mint per recipient
     */
    function studioMint(
        uint256 dropId,
        address to,
        uint256 amount
    ) external onlyWhenDropIsReady(dropId) onlyOwnerOrAdmin {
        _mint(to, dropId, amount, "");
        emit Dropped(dropId);
    }

    /// @dev Emitted when a drop is claimed using EIP-712
    event DropClaimed(uint256 indexed dropId, address indexed by, uint256 indexed amount);

    /**
     * @notice Claims a drop using an EIP-712 signature. Caller pays gas to claim
     * instead of being airdropped by Sam King Studio.
     *
     * @param dropId The id of the drop
     * @param amount The amount of tokens to mint
     * @param signature A valid EIP-712 signature
     */
    function claimDrop(
        uint256 dropId,
        uint256 amount,
        bytes calldata signature
    ) external onlyWhenDropIsReady(dropId) {
        // Reconstruct the signed data on-chain
        ClaimDropData memory data = ClaimDropData({
            dropId: dropId,
            amount: amount,
            to: msg.sender,
            nonce: nonces[msg.sender],
            signature: signature
        });

        // Hash the data for verification
        bytes32 digest = _hashTypedDataV4(
            keccak256(
                abi.encode(
                    CLAIM_DROP_TYPEHASH,
                    data.dropId,
                    data.amount,
                    data.to,
                    nonces[data.to]++
                )
            )
        );

        // Verifiy signature is ok
        address addr = ECDSA.recover(digest, data.signature);
        require(approvedSigners[addr] && addr != address(0), "INVALID_SIGNATURE");

        // Claim the drop
        if (data.amount > 0) {
            _mint(data.to, data.dropId, data.amount, "");
            emit DropClaimed(data.dropId, data.to, data.amount);
        }
    }

    /* ------------------------------------------------------------------------
       A D M I N
    ------------------------------------------------------------------------ */

    /**
     * @notice Admin function to set the URI for a particular drop
     * @dev Emits the URI event from ERC1155
     *
     * @param dropId The id of the drop to set the URI for
     * @param uri_ The new URI
     */
    function setDropURI(uint256 dropId, string calldata uri_) external onlyOwnerOrAdmin {
        dropURI[dropId] = uri_;
        emit URI(uri_, dropId);
    }

    /**
     * @notice Admin function to set the URI for a particular drop
     * @dev Emits the URI event from ERC1155
     *
     * @param dropId The id of the drop to set the URI for
     * @param metadata The new metadata contract address
     */
    function setDropMetadataAddress(uint256 dropId, address metadata) external onlyOwnerOrAdmin {
        dropMetadataAddress[dropId] = metadata;
        emit URI(IMetadata(metadata).uri(dropId), dropId);
    }

    /// @dev Emitted when a new signer is added to this contract
    event SignerAdded(address indexed signer);

    /**
     * @notice Admin function to add a new EIP-712 signer address
     * @dev Emits the SignerAdded event
     *
     * @param signer The address of the new signer
     */
    function addSigner(address signer) external onlyOwnerOrAdmin {
        approvedSigners[signer] = true;
        emit SignerAdded(signer);
    }

    /// @dev Emitted when an existing signer is removed from this contract
    event SignerRemoved(address indexed signer);

    /**
     * @notice Admin function to remove an existing EIP-712 signer address
     * @dev Emits the SignerRemoved event
     *
     * @param signer The address of the signer to remove
     */
    function removeSigner(address signer) external onlyOwnerOrAdmin {
        approvedSigners[signer] = false;
        emit SignerRemoved(signer);
    }

    /* ------------------------------------------------------------------------
       M E T A D A T A
    ------------------------------------------------------------------------ */

    /**
     * @notice ERC1155 token URI
     * @param id The token id to get token metadata for
     * @return metadata The token metadata URI or Base64 encoded JSON token metadata
     */
    function uri(uint256 id) public view override returns (string memory) {
        address metadata = dropMetadataAddress[id];
        if (metadata != address(0)) return IMetadata(metadata).uri(id);
        return dropURI[id];
    }
}

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

/// @notice Minimalist and gas efficient standard ERC1155 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol)
abstract contract ERC1155 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event TransferSingle(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256 id,
        uint256 amount
    );

    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] amounts
    );

    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    event URI(string value, uint256 indexed id);

    /*//////////////////////////////////////////////////////////////
                             ERC1155 STORAGE
    //////////////////////////////////////////////////////////////*/

    mapping(address => mapping(uint256 => uint256)) public balanceOf;

    mapping(address => mapping(address => bool)) public isApprovedForAll;

    /*//////////////////////////////////////////////////////////////
                             METADATA LOGIC
    //////////////////////////////////////////////////////////////*/

    function uri(uint256 id) public view virtual returns (string memory);

    /*//////////////////////////////////////////////////////////////
                              ERC1155 LOGIC
    //////////////////////////////////////////////////////////////*/

    function setApprovalForAll(address operator, bool approved) public virtual {
        isApprovedForAll[msg.sender][operator] = approved;

        emit ApprovalForAll(msg.sender, operator, approved);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) public virtual {
        require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED");

        balanceOf[from][id] -= amount;
        balanceOf[to][id] += amount;

        emit TransferSingle(msg.sender, from, to, id, amount);

        require(
            to.code.length == 0
                ? to != address(0)
                : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, from, id, amount, data) ==
                    ERC1155TokenReceiver.onERC1155Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) public virtual {
        require(ids.length == amounts.length, "LENGTH_MISMATCH");

        require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED");

        // Storing these outside the loop saves ~15 gas per iteration.
        uint256 id;
        uint256 amount;

        for (uint256 i = 0; i < ids.length; ) {
            id = ids[i];
            amount = amounts[i];

            balanceOf[from][id] -= amount;
            balanceOf[to][id] += amount;

            // An array can't have a total length
            // larger than the max uint256 value.
            unchecked {
                ++i;
            }
        }

        emit TransferBatch(msg.sender, from, to, ids, amounts);

        require(
            to.code.length == 0
                ? to != address(0)
                : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, from, ids, amounts, data) ==
                    ERC1155TokenReceiver.onERC1155BatchReceived.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function balanceOfBatch(address[] calldata owners, uint256[] calldata ids)
        public
        view
        virtual
        returns (uint256[] memory balances)
    {
        require(owners.length == ids.length, "LENGTH_MISMATCH");

        balances = new uint256[](owners.length);

        // Unchecked because the only math done is incrementing
        // the array index counter which cannot possibly overflow.
        unchecked {
            for (uint256 i = 0; i < owners.length; ++i) {
                balances[i] = balanceOf[owners[i]][ids[i]];
            }
        }
    }

    /*//////////////////////////////////////////////////////////////
                              ERC165 LOGIC
    //////////////////////////////////////////////////////////////*/

    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return
            interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
            interfaceId == 0xd9b67a26 || // ERC165 Interface ID for ERC1155
            interfaceId == 0x0e89341c; // ERC165 Interface ID for ERC1155MetadataURI
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        balanceOf[to][id] += amount;

        emit TransferSingle(msg.sender, address(0), to, id, amount);

        require(
            to.code.length == 0
                ? to != address(0)
                : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, address(0), id, amount, data) ==
                    ERC1155TokenReceiver.onERC1155Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function _batchMint(
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        uint256 idsLength = ids.length; // Saves MLOADs.

        require(idsLength == amounts.length, "LENGTH_MISMATCH");

        for (uint256 i = 0; i < idsLength; ) {
            balanceOf[to][ids[i]] += amounts[i];

            // An array can't have a total length
            // larger than the max uint256 value.
            unchecked {
                ++i;
            }
        }

        emit TransferBatch(msg.sender, address(0), to, ids, amounts);

        require(
            to.code.length == 0
                ? to != address(0)
                : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, address(0), ids, amounts, data) ==
                    ERC1155TokenReceiver.onERC1155BatchReceived.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function _batchBurn(
        address from,
        uint256[] memory ids,
        uint256[] memory amounts
    ) internal virtual {
        uint256 idsLength = ids.length; // Saves MLOADs.

        require(idsLength == amounts.length, "LENGTH_MISMATCH");

        for (uint256 i = 0; i < idsLength; ) {
            balanceOf[from][ids[i]] -= amounts[i];

            // An array can't have a total length
            // larger than the max uint256 value.
            unchecked {
                ++i;
            }
        }

        emit TransferBatch(msg.sender, from, address(0), ids, amounts);
    }

    function _burn(
        address from,
        uint256 id,
        uint256 amount
    ) internal virtual {
        balanceOf[from][id] -= amount;

        emit TransferSingle(msg.sender, from, address(0), id, amount);
    }
}

/// @notice A generic interface for a contract which properly accepts ERC1155 tokens.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC1155.sol)
abstract contract ERC1155TokenReceiver {
    function onERC1155Received(
        address,
        address,
        uint256,
        uint256,
        bytes calldata
    ) external virtual returns (bytes4) {
        return ERC1155TokenReceiver.onERC1155Received.selector;
    }

    function onERC1155BatchReceived(
        address,
        address,
        uint256[] calldata,
        uint256[] calldata,
        bytes calldata
    ) external virtual returns (bytes4) {
        return ERC1155TokenReceiver.onERC1155BatchReceived.selector;
    }
}

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

pragma solidity ^0.8.0;

import "../Strings.sol";

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV // Deprecated in v4.8
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 27);
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

File 4 of 8 : draft-EIP712.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

// EIP-712 is Final as of 2022-08-11. This file is deprecated.

import "./EIP712.sol";

File 5 of 8 : Auth.sol
// SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.17;

/**
 * @author Sam King (samkingstudio.eth)
 * @title  Simple owner and admin authentication
 * @notice Allows the management of a contract by using simple ownership and admin modifiers.
 */
abstract contract Auth {
    /* ------------------------------------------------------------------------
       S T O R A G E
    ------------------------------------------------------------------------ */

    /// @notice Current owner of the contract
    address public owner;

    /// @notice Current admins of the contract
    mapping(address => bool) public admins;

    /* ------------------------------------------------------------------------
       E V E N T S
    ------------------------------------------------------------------------ */

    /**
     * @notice When the contract owner is updated
     * @param user The account that updated the new owner
     * @param newOwner The new owner of the contract
     */
    event OwnerUpdated(address indexed user, address indexed newOwner);

    /**
     * @notice When an admin is added to the contract
     * @param user The account that added the new admin
     * @param newAdmin The admin that was added
     */
    event AdminAdded(address indexed user, address indexed newAdmin);

    /**
     * @notice When an admin is removed from the contract
     * @param user The account that removed an admin
     * @param prevAdmin The admin that got removed
     */
    event AdminRemoved(address indexed user, address indexed prevAdmin);

    /* ------------------------------------------------------------------------
       M O D I F I E R S
    ------------------------------------------------------------------------ */

    /**
     * @dev Only the owner can call
     */
    modifier onlyOwner() {
        require(msg.sender == owner, "UNAUTHORIZED");
        _;
    }

    /**
     * @dev Only an admin can call
     */
    modifier onlyAdmin() {
        require(admins[msg.sender], "UNAUTHORIZED");
        _;
    }

    /**
     * @dev Only the owner or an admin can call
     */
    modifier onlyOwnerOrAdmin() {
        require((msg.sender == owner || admins[msg.sender]), "UNAUTHORIZED");
        _;
    }

    /* ------------------------------------------------------------------------
       I N I T
    ------------------------------------------------------------------------ */

    /**
     * @dev Sets the initial owner and a first admin upon creation.
     * @param owner_ The initial owner of the contract
     * @param admin_ An initial admin of the contract
     */
    constructor(address owner_, address admin_) {
        owner = owner_;
        emit OwnerUpdated(address(0), owner_);

        admins[admin_] = true;
        emit AdminAdded(address(0), admin_);
    }

    /* ------------------------------------------------------------------------
       A D M I N
    ------------------------------------------------------------------------ */

    /**
     * @notice Transfers ownership of the contract to `newOwner`
     * @dev Can only be called by the current owner or an admin
     * @param newOwner The new owner of the contract
     */
    function setOwner(address newOwner) public virtual onlyOwnerOrAdmin {
        owner = newOwner;
        emit OwnerUpdated(msg.sender, newOwner);
    }

    /**
     * @notice Adds `newAdmin` as an amdin of the contract
     * @dev Can only be called by the current owner or an admin
     * @param newAdmin A new admin of the contract
     */
    function addAdmin(address newAdmin) public virtual onlyOwnerOrAdmin {
        admins[newAdmin] = true;
        emit AdminAdded(address(0), newAdmin);
    }

    /**
     * @notice Removes `prevAdmin` as an amdin of the contract
     * @dev Can only be called by the current owner or an admin
     * @param prevAdmin The admin to remove
     */
    function removeAdmin(address prevAdmin) public virtual onlyOwnerOrAdmin {
        admins[prevAdmin] = false;
        emit AdminRemoved(address(0), prevAdmin);
    }
}

File 6 of 8 : IMetadata.sol
// SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.17;

interface IMetadata {
    function uri(uint256 id) external view returns (string memory);
}

File 7 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 8 of 8 : EIP712.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./ECDSA.sol";

/**
 * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
 *
 * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
 * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
 * they need in their contracts using a combination of `abi.encode` and `keccak256`.
 *
 * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
 * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
 * ({_hashTypedDataV4}).
 *
 * The implementation of the domain separator was designed to be as efficient as possible while still properly updating
 * the chain id to protect against replay attacks on an eventual fork of the chain.
 *
 * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
 * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
 *
 * _Available since v3.4._
 */
abstract contract EIP712 {
    /* solhint-disable var-name-mixedcase */
    // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to
    // invalidate the cached domain separator if the chain id changes.
    bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;
    uint256 private immutable _CACHED_CHAIN_ID;
    address private immutable _CACHED_THIS;

    bytes32 private immutable _HASHED_NAME;
    bytes32 private immutable _HASHED_VERSION;
    bytes32 private immutable _TYPE_HASH;

    /* solhint-enable var-name-mixedcase */

    /**
     * @dev Initializes the domain separator and parameter caches.
     *
     * The meaning of `name` and `version` is specified in
     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
     *
     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
     * - `version`: the current major version of the signing domain.
     *
     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
     * contract upgrade].
     */
    constructor(string memory name, string memory version) {
        bytes32 hashedName = keccak256(bytes(name));
        bytes32 hashedVersion = keccak256(bytes(version));
        bytes32 typeHash = keccak256(
            "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
        );
        _HASHED_NAME = hashedName;
        _HASHED_VERSION = hashedVersion;
        _CACHED_CHAIN_ID = block.chainid;
        _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);
        _CACHED_THIS = address(this);
        _TYPE_HASH = typeHash;
    }

    /**
     * @dev Returns the domain separator for the current chain.
     */
    function _domainSeparatorV4() internal view returns (bytes32) {
        if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {
            return _CACHED_DOMAIN_SEPARATOR;
        } else {
            return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
        }
    }

    function _buildDomainSeparator(
        bytes32 typeHash,
        bytes32 nameHash,
        bytes32 versionHash
    ) private view returns (bytes32) {
        return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));
    }

    /**
     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
     * function returns the hash of the fully encoded EIP712 message for this domain.
     *
     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
     *
     * ```solidity
     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
     *     keccak256("Mail(address to,string contents)"),
     *     mailTo,
     *     keccak256(bytes(mailContents))
     * )));
     * address signer = ECDSA.recover(digest, signature);
     * ```
     */
    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
        return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);
    }
}

Settings
{
  "remappings": [
    "ds-test/=packages/contracts/lib/ds-test/src/",
    "forge-std/=packages/contracts/lib/forge-std/src/",
    "openzeppelin-contracts/=packages/contracts/lib/openzeppelin-contracts/",
    "openzeppelin/=packages/contracts/lib/openzeppelin-contracts/contracts/",
    "solmate/=packages/contracts/lib/solmate/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "bytecodeHash": "none"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"admin_","type":"address"},{"internalType":"address","name":"signer_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"prevAdmin","type":"address"}],"name":"AdminRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"dropId","type":"uint256"},{"indexed":true,"internalType":"address","name":"by","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DropClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"dropId","type":"uint256"}],"name":"Dropped","type":"event"},{"anonymous":false,"inputs":[],"name":"Initialised","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"signer","type":"address"}],"name":"SignerAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"signer","type":"address"}],"name":"SignerRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[],"name":"CLAIM_DROP_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SIGNATURE_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SIGNING_DOMAIN","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newAdmin","type":"address"}],"name":"addAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"addSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"admins","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"approvedSigners","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"owners","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"balances","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"dropId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"claimDrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"dropId","type":"uint256"},{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"drop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"dropId","type":"uint256"},{"internalType":"address[]","name":"recipients","type":"address[]"}],"name":"drop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"dropId","type":"uint256"},{"internalType":"address[]","name":"recipients","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"drop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"dropMetadataAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"dropURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"prevAdmin","type":"address"}],"name":"removeAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"removeSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"dropId","type":"uint256"},{"internalType":"address","name":"metadata","type":"address"}],"name":"setDropMetadataAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"dropId","type":"uint256"},{"internalType":"string","name":"uri_","type":"string"}],"name":"setDropURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"dropId","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"studioMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]

610180604052601a6101409081527f44726f70732066726f6d2053616d204b696e672053747564696f0000000000006101605260049062000041908262000337565b506040805180820190915260068152650534b534452560d41b60208201526005906200006e908262000337565b503480156200007c57600080fd5b5060405162003017380380620030178339810160408190526200009f9162000420565b604080518082018252601281527153616d4b696e6753747564696f44726f707360701b60208083019182528351808501855260018152603160f81b908201529151902060e08190527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66101008190524660a081815285517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818701819052818801959095526060810193909352608080840192909252308382018190528651808503909201825260c0938401968790528151919095012090529190915261012052600280546001600160a01b0319166001600160a01b03861690811790915584918491906000907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d76908290a36001600160a01b038116600081815260036020526040808220805460ff19166001179055517fbf3f493c772c8c283fd124432c2d0f539ab343faa04258fe88e52912d36b102b908290a350506001600160a01b038116600081815260066020526040808220805460ff19166001179055517f47d1c22a25bb3a5d4e481b9b1e6944c2eade3181a0a20b495ed61d35b5323f249190a26040517f09dfb9099a2610601d58030170fde7ae9db3e1bcb751c3d6800216cbe3b499b590600090a15050506200046a565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620002bd57607f821691505b602082108103620002de57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200033257600081815260208120601f850160051c810160208610156200030d5750805b601f850160051c820191505b818110156200032e5782815560010162000319565b5050505b505050565b81516001600160401b0381111562000353576200035362000292565b6200036b81620003648454620002a8565b84620002e4565b602080601f831160018114620003a357600084156200038a5750858301515b600019600386901b1c1916600185901b1785556200032e565b600085815260208120601f198616915b82811015620003d457888601518255948401946001909101908401620003b3565b5085821015620003f35787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b80516001600160a01b03811681146200041b57600080fd5b919050565b6000806000606084860312156200043657600080fd5b620004418462000403565b9250620004516020850162000403565b9150620004616040850162000403565b90509250925092565b60805160a05160c05160e0516101005161012051612b5d620004ba6000396000611d9e01526000611ded01526000611dc801526000611d2101526000611d4b01526000611d750152612b5d6000f3fe608060405234801561001057600080fd5b50600436106101e45760003560e01c80634e1273f41161010f578063a22cb465116100a2578063e3faad9411610071578063e3faad94146104a4578063e985e9c5146104d5578063eb12d61e14610503578063f242432a1461051657600080fd5b8063a22cb4651461044b578063a41572961461045e578063d3c2a2c81461047e578063e3f3e7271461049157600080fd5b80638da5cb5b116100de5780638da5cb5b146103dc57806395d89b41146104075780639f390a361461040f5780639f9839fa1461042257600080fd5b80634e1273f41461036657806370480275146103865780637ecebe00146103995780638a875512146103b957600080fd5b806313af4035116101875780633099c549116101565780633099c549146102f6578063361e9e7c146103095780633c03f11214610330578063429b62e51461034357600080fd5b806313af4035146102aa5780631785f53c146102bd5780631c7d1b37146102d05780632eb2c2d6146102e357600080fd5b80630a971087116101c35780630a9710871461025c5780630e316ab7146102715780630e89341c14610284578063120f6e081461029757600080fd5b8062fdd58e146101e957806301ffc9a71461022457806306fdde0314610247575b600080fd5b6102116101f73660046120ad565b600060208181529281526040808220909352908152205481565b6040519081526020015b60405180910390f35b6102376102323660046120ed565b610529565b604051901515815260200161021b565b61024f61057b565b60405161021b919061215a565b61026f61026a3660046121b1565b610609565b005b61026f61027f366004612203565b6107b6565b61024f61029236600461221e565b610843565b61024f6102a536600461221e565b610977565b61026f6102b8366004612203565b610990565b61026f6102cb366004612203565b610a20565b61026f6102de366004612278565b610aae565b61026f6102f13660046122ca565b610d9d565b61026f610304366004612384565b61101e565b6102117f778ae2d713762caf7cf7089c6a0794596dd24a29c9630e2749991c98ea9ea01b81565b61026f61033e3660046123cf565b6110bb565b610237610351366004612203565b60036020526000908152604090205460ff1681565b610379610374366004612404565b611213565b60405161021b9190612463565b61026f610394366004612203565b611325565b6102116103a7366004612203565b60076020526000908152604090205481565b6102376103c7366004612203565b60066020526000908152604090205460ff1681565b6002546103ef906001600160a01b031681565b6040516001600160a01b03909116815260200161021b565b61024f6113b6565b61026f61041d3660046124a7565b6113c3565b6103ef61043036600461221e565b6009602052600090815260409020546001600160a01b031681565b61026f6104593660046124e5565b611560565b61024f604051806040016040528060018152602001603160f81b81525081565b61026f61048c366004612521565b6115cc565b61026f61049f36600461254d565b6116da565b61024f6040518060400160405280601281526020017153616d4b696e6753747564696f44726f707360701b81525081565b6102376104e33660046125c6565b600160209081526000928352604080842090915290825290205460ff1681565b61026f610511366004612203565b6118d0565b61026f6105243660046125f0565b611960565b60006301ffc9a760e01b6001600160e01b03198316148061055a5750636cdb3d1360e11b6001600160e01b03198316145b8061057557506303a24d0760e21b6001600160e01b03198316145b92915050565b6004805461058890612667565b80601f01602080910402602001604051908101604052809291908181526020018280546105b490612667565b80156106015780601f106105d657610100808354040283529160200191610601565b820191906000526020600020905b8154815290600101906020018083116105e457829003601f168201915b505050505081565b60008481526009602052604090205484906001600160a01b03166106ec576000818152600860205260408120805461064090612667565b80601f016020809104026020016040519081016040528092919081815260200182805461066c90612667565b80156106b95780601f1061068e576101008083540402835291602001916106b9565b820191906000526020600020905b81548152906001019060200180831161069c57829003601f168201915b5050505050905060008151116106ea5760405162461bcd60e51b81526004016106e1906126a1565b60405180910390fd5b505b6002546001600160a01b031633148061071457503360009081526003602052604090205460ff165b6107305760405162461bcd60e51b81526004016106e1906126c9565b81156107965760005b8381101561079457610782858583818110610756576107566126ef565b905060200201602081019061076b9190612203565b878560405180602001604052806000815250611b5a565b8061078c8161271b565b915050610739565b505b6040518590600080516020612b3183398151915290600090a25050505050565b6002546001600160a01b03163314806107de57503360009081526003602052604090205460ff165b6107fa5760405162461bcd60e51b81526004016106e1906126c9565b6001600160a01b038116600081815260066020526040808220805460ff19169055517f3525e22824a8a7df2c9a6029941c824cf95b6447f1e13d5128fd3826d35afe8b9190a250565b6000818152600960205260409020546060906001600160a01b031680156108d8576040516303a24d0760e21b8152600481018490526001600160a01b03821690630e89341c90602401600060405180830381865afa1580156108a9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108d1919081019061274a565b9392505050565b600083815260086020526040902080546108f190612667565b80601f016020809104026020016040519081016040528092919081815260200182805461091d90612667565b801561096a5780601f1061093f5761010080835404028352916020019161096a565b820191906000526020600020905b81548152906001019060200180831161094d57829003601f168201915b5050505050915050919050565b6008602052600090815260409020805461058890612667565b6002546001600160a01b03163314806109b857503360009081526003602052604090205460ff165b6109d45760405162461bcd60e51b81526004016106e1906126c9565b600280546001600160a01b0319166001600160a01b03831690811790915560405133907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7690600090a350565b6002546001600160a01b0316331480610a4857503360009081526003602052604090205460ff165b610a645760405162461bcd60e51b81526004016106e1906126c9565b6001600160a01b038116600081815260036020526040808220805460ff19169055517fdb9d5d31320daf5bc7181d565b6da4d12e30f0f4d5aa324a992426c14a1d19ce908290a350565b60008481526009602052604090205484906001600160a01b0316610b885760008181526008602052604081208054610ae590612667565b80601f0160208091040260200160405190810160405280929190818152602001828054610b1190612667565b8015610b5e5780601f10610b3357610100808354040283529160200191610b5e565b820191906000526020600020905b815481529060010190602001808311610b4157829003601f168201915b505050505090506000815111610b865760405162461bcd60e51b81526004016106e1906126a1565b505b6040805160a0810182528681526020808201879052338284018190526000908152600782528381205460608401528351601f87018390048302810183019094528584529260808301918790879081908401838280828437600092018290525093909452505082516020808501516040808701516001600160a01b03811686526007909352842080549697509395610c9895507f778ae2d713762caf7cf7089c6a0794596dd24a29c9630e2749991c98ea9ea01b9491929187610c498361271b565b9091555060408051602081019690965285019390935260608401919091526001600160a01b0316608083015260a082015260c00160405160208183030381529060405280519060200120611ca2565b90506000610caa828460800151611cf0565b6001600160a01b03811660009081526006602052604090205490915060ff168015610cdd57506001600160a01b03811615155b610d1d5760405162461bcd60e51b8152602060048201526011602482015270494e56414c49445f5349474e415455524560781b60448201526064016106e1565b602083015115610d9357610d4e83604001518460000151856020015160405180602001604052806000815250611b5a565b826020015183604001516001600160a01b031684600001517f2b93fe25f6eb77d6c3e44244241ad4193572e76d3b3e9e2f834a11e9404e856e60405160405180910390a45b5050505050505050565b848314610dbc5760405162461bcd60e51b81526004016106e1906127f6565b336001600160a01b0389161480610df657506001600160a01b038816600090815260016020908152604080832033845290915290205460ff165b610e335760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064016106e1565b60008060005b87811015610eee57888882818110610e5357610e536126ef565b905060200201359250868682818110610e6e57610e6e6126ef565b6001600160a01b038e1660009081526020818152604080832089845282528220805493909102949094013595508593925090610eab90849061281f565b90915550506001600160a01b038a1660009081526020818152604080832086845290915281208054849290610ee1908490612832565b9091555050600101610e39565b50886001600160a01b03168a6001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8b8b8b8b604051610f429493929190612877565b60405180910390a46001600160a01b0389163b15610fe95760405163bc197c8160e01b808252906001600160a01b038b169063bc197c8190610f969033908f908e908e908e908e908e908e906004016128c7565b6020604051808303816000875af1158015610fb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd9919061292b565b6001600160e01b03191614610ff6565b6001600160a01b03891615155b6110125760405162461bcd60e51b81526004016106e190612948565b50505050505050505050565b6002546001600160a01b031633148061104657503360009081526003602052604090205460ff165b6110625760405162461bcd60e51b81526004016106e1906126c9565b600083815260086020526040902061107b8284836129bd565b50827f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b83836040516110ae929190612a7d565b60405180910390a2505050565b60008381526009602052604090205483906001600160a01b031661119557600081815260086020526040812080546110f290612667565b80601f016020809104026020016040519081016040528092919081815260200182805461111e90612667565b801561116b5780601f106111405761010080835404028352916020019161116b565b820191906000526020600020905b81548152906001019060200180831161114e57829003601f168201915b5050505050905060008151116111935760405162461bcd60e51b81526004016106e1906126a1565b505b6002546001600160a01b03163314806111bd57503360009081526003602052604090205460ff165b6111d95760405162461bcd60e51b81526004016106e1906126c9565b6111f483858460405180602001604052806000815250611b5a565b6040518490600080516020612b3183398151915290600090a250505050565b60608382146112345760405162461bcd60e51b81526004016106e1906127f6565b836001600160401b0381111561124c5761124c612734565b604051908082528060200260200182016040528015611275578160200160208202803683370190505b50905060005b8481101561131c57600080878784818110611298576112986126ef565b90506020020160208101906112ad9190612203565b6001600160a01b03166001600160a01b0316815260200190815260200160002060008585848181106112e1576112e16126ef565b90506020020135815260200190815260200160002054828281518110611309576113096126ef565b602090810291909101015260010161127b565b50949350505050565b6002546001600160a01b031633148061134d57503360009081526003602052604090205460ff165b6113695760405162461bcd60e51b81526004016106e1906126c9565b6001600160a01b038116600081815260036020526040808220805460ff19166001179055517fbf3f493c772c8c283fd124432c2d0f539ab343faa04258fe88e52912d36b102b908290a350565b6005805461058890612667565b60008381526009602052604090205483906001600160a01b031661149d57600081815260086020526040812080546113fa90612667565b80601f016020809104026020016040519081016040528092919081815260200182805461142690612667565b80156114735780601f1061144857610100808354040283529160200191611473565b820191906000526020600020905b81548152906001019060200180831161145657829003601f168201915b50505050509050600081511161149b5760405162461bcd60e51b81526004016106e1906126a1565b505b6002546001600160a01b03163314806114c557503360009081526003602052604090205460ff165b6114e15760405162461bcd60e51b81526004016106e1906126c9565b60005b828110156115405761152e848483818110611501576115016126ef565b90506020020160208101906115169190612203565b86600160405180602001604052806000815250611b5a565b806115388161271b565b9150506114e4565b506040518490600080516020612b3183398151915290600090a250505050565b3360008181526001602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6002546001600160a01b03163314806115f457503360009081526003602052604090205460ff165b6116105760405162461bcd60e51b81526004016106e1906126c9565b6000828152600960205260409081902080546001600160a01b0319166001600160a01b03841690811790915590516303a24d0760e21b81526004810184905283917f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b91630e89341c90602401600060405180830381865afa158015611699573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526116c1919081019061274a565b6040516116ce919061215a565b60405180910390a25050565b60008581526009602052604090205485906001600160a01b03166117b4576000818152600860205260408120805461171190612667565b80601f016020809104026020016040519081016040528092919081815260200182805461173d90612667565b801561178a5780601f1061175f5761010080835404028352916020019161178a565b820191906000526020600020905b81548152906001019060200180831161176d57829003601f168201915b5050505050905060008151116117b25760405162461bcd60e51b81526004016106e1906126a1565b505b6002546001600160a01b03163314806117dc57503360009081526003602052604090205460ff165b6117f85760405162461bcd60e51b81526004016106e1906126c9565b8382146118175760405162461bcd60e51b81526004016106e1906127f6565b60005b848110156118ae576000848483818110611836576118366126ef565b90506020020135111561189c5761189c868683818110611858576118586126ef565b905060200201602081019061186d9190612203565b88868685818110611880576118806126ef565b9050602002013560405180602001604052806000815250611b5a565b806118a68161271b565b91505061181a565b506040518690600080516020612b3183398151915290600090a2505050505050565b6002546001600160a01b03163314806118f857503360009081526003602052604090205460ff165b6119145760405162461bcd60e51b81526004016106e1906126c9565b6001600160a01b038116600081815260066020526040808220805460ff19166001179055517f47d1c22a25bb3a5d4e481b9b1e6944c2eade3181a0a20b495ed61d35b5323f249190a250565b336001600160a01b038716148061199a57506001600160a01b038616600090815260016020908152604080832033845290915290205460ff165b6119d75760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064016106e1565b6001600160a01b03861660009081526020818152604080832087845290915281208054859290611a0890849061281f565b90915550506001600160a01b03851660009081526020818152604080832087845290915281208054859290611a3e908490612832565b909155505060408051858152602081018590526001600160a01b03808816929089169133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46001600160a01b0385163b15611b295760405163f23a6e6160e01b808252906001600160a01b0387169063f23a6e6190611ad69033908b908a908a908a908a90600401612a99565b6020604051808303816000875af1158015611af5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b19919061292b565b6001600160e01b03191614611b36565b6001600160a01b03851615155b611b525760405162461bcd60e51b81526004016106e190612948565b505050505050565b6001600160a01b03841660009081526020818152604080832086845290915281208054849290611b8b908490612832565b909155505060408051848152602081018490526001600160a01b0386169160009133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46001600160a01b0384163b15611c735760405163f23a6e6160e01b808252906001600160a01b0386169063f23a6e6190611c20903390600090899089908990600401612ae0565b6020604051808303816000875af1158015611c3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c63919061292b565b6001600160e01b03191614611c80565b6001600160a01b03841615155b611c9c5760405162461bcd60e51b81526004016106e190612948565b50505050565b6000610575611caf611d14565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b6000806000611cff8585611e3b565b91509150611d0c81611e80565b509392505050565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016148015611d6d57507f000000000000000000000000000000000000000000000000000000000000000046145b15611d9757507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b6000808251604103611e715760208301516040840151606085015160001a611e6587828585611fcd565b94509450505050611e79565b506000905060025b9250929050565b6000816004811115611e9457611e94612b1a565b03611e9c5750565b6001816004811115611eb057611eb0612b1a565b03611efd5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016106e1565b6002816004811115611f1157611f11612b1a565b03611f5e5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016106e1565b6003816004811115611f7257611f72612b1a565b03611fca5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016106e1565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156120045750600090506003612088565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612058573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661208157600060019250925050612088565b9150600090505b94509492505050565b80356001600160a01b03811681146120a857600080fd5b919050565b600080604083850312156120c057600080fd5b6120c983612091565b946020939093013593505050565b6001600160e01b031981168114611fca57600080fd5b6000602082840312156120ff57600080fd5b81356108d1816120d7565b60005b8381101561212557818101518382015260200161210d565b50506000910152565b6000815180845261214681602086016020860161210a565b601f01601f19169290920160200192915050565b6020815260006108d1602083018461212e565b60008083601f84011261217f57600080fd5b5081356001600160401b0381111561219657600080fd5b6020830191508360208260051b8501011115611e7957600080fd5b600080600080606085870312156121c757600080fd5b8435935060208501356001600160401b038111156121e457600080fd5b6121f08782880161216d565b9598909750949560400135949350505050565b60006020828403121561221557600080fd5b6108d182612091565b60006020828403121561223057600080fd5b5035919050565b60008083601f84011261224957600080fd5b5081356001600160401b0381111561226057600080fd5b602083019150836020828501011115611e7957600080fd5b6000806000806060858703121561228e57600080fd5b843593506020850135925060408501356001600160401b038111156122b257600080fd5b6122be87828801612237565b95989497509550505050565b60008060008060008060008060a0898b0312156122e657600080fd5b6122ef89612091565b97506122fd60208a01612091565b965060408901356001600160401b038082111561231957600080fd5b6123258c838d0161216d565b909850965060608b013591508082111561233e57600080fd5b61234a8c838d0161216d565b909650945060808b013591508082111561236357600080fd5b506123708b828c01612237565b999c989b5096995094979396929594505050565b60008060006040848603121561239957600080fd5b8335925060208401356001600160401b038111156123b657600080fd5b6123c286828701612237565b9497909650939450505050565b6000806000606084860312156123e457600080fd5b833592506123f460208501612091565b9150604084013590509250925092565b6000806000806040858703121561241a57600080fd5b84356001600160401b038082111561243157600080fd5b61243d8883890161216d565b9096509450602087013591508082111561245657600080fd5b506122be8782880161216d565b6020808252825182820181905260009190848201906040850190845b8181101561249b5783518352928401929184019160010161247f565b50909695505050505050565b6000806000604084860312156124bc57600080fd5b8335925060208401356001600160401b038111156124d957600080fd5b6123c28682870161216d565b600080604083850312156124f857600080fd5b61250183612091565b91506020830135801515811461251657600080fd5b809150509250929050565b6000806040838503121561253457600080fd5b8235915061254460208401612091565b90509250929050565b60008060008060006060868803121561256557600080fd5b8535945060208601356001600160401b038082111561258357600080fd5b61258f89838a0161216d565b909650945060408801359150808211156125a857600080fd5b506125b58882890161216d565b969995985093965092949392505050565b600080604083850312156125d957600080fd5b6125e283612091565b915061254460208401612091565b60008060008060008060a0878903121561260957600080fd5b61261287612091565b955061262060208801612091565b9450604087013593506060870135925060808701356001600160401b0381111561264957600080fd5b61265589828a01612237565b979a9699509497509295939492505050565b600181811c9082168061267b57607f821691505b60208210810361269b57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600e908201526d44524f505f4e4f545f524541445960901b604082015260600190565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161272d5761272d612705565b5060010190565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561275c57600080fd5b81516001600160401b038082111561277357600080fd5b818401915084601f83011261278757600080fd5b81518181111561279957612799612734565b604051601f8201601f19908116603f011681019083821181831017156127c1576127c1612734565b816040528281528760208487010111156127da57600080fd5b6127eb83602083016020880161210a565b979650505050505050565b6020808252600f908201526e0988a9c8ea890be9a92a69a82a8869608b1b604082015260600190565b8181038181111561057557610575612705565b8082018082111561057557610575612705565b81835260006001600160fb1b0383111561285e57600080fd5b8260051b80836020870137939093016020019392505050565b60408152600061288b604083018688612845565b82810360208401526127eb818587612845565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b0389811682528816602082015260a0604082018190526000906128f4908301888a612845565b8281036060840152612907818789612845565b9050828103608084015261291c81858761289e565b9b9a5050505050505050505050565b60006020828403121561293d57600080fd5b81516108d1816120d7565b60208082526010908201526f155394d0519157d49150d2541251539560821b604082015260600190565b601f8211156129b857600081815260208120601f850160051c810160208610156129995750805b601f850160051c820191505b81811015611b52578281556001016129a5565b505050565b6001600160401b038311156129d4576129d4612734565b6129e8836129e28354612667565b83612972565b6000601f841160018114612a1c5760008515612a045750838201355b600019600387901b1c1916600186901b178355612a76565b600083815260209020601f19861690835b82811015612a4d5786850135825560209485019460019092019101612a2d565b5086821015612a6a5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b602081526000612a9160208301848661289e565b949350505050565b6001600160a01b03878116825286166020820152604081018590526060810184905260a060808201819052600090612ad4908301848661289e565b98975050505050505050565b6001600160a01b03868116825285166020820152604081018490526060810183905260a0608082018190526000906127eb9083018461212e565b634e487b7160e01b600052602160045260246000fdfe95a00f343edb771ffa3d5bda50afe8c6354c35baae5ab282c4d27b38271c561da164736f6c6343000811000a00000000000000000000000027676d628ab0979754f01af51074680dfa38d3e9000000000000000000000000d633d5bc9fd1250ac203de798508340dfa989b6b000000000000000000000000aa6bf8f3a77f9a71a778204e3f4049a416dbb72a

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101e45760003560e01c80634e1273f41161010f578063a22cb465116100a2578063e3faad9411610071578063e3faad94146104a4578063e985e9c5146104d5578063eb12d61e14610503578063f242432a1461051657600080fd5b8063a22cb4651461044b578063a41572961461045e578063d3c2a2c81461047e578063e3f3e7271461049157600080fd5b80638da5cb5b116100de5780638da5cb5b146103dc57806395d89b41146104075780639f390a361461040f5780639f9839fa1461042257600080fd5b80634e1273f41461036657806370480275146103865780637ecebe00146103995780638a875512146103b957600080fd5b806313af4035116101875780633099c549116101565780633099c549146102f6578063361e9e7c146103095780633c03f11214610330578063429b62e51461034357600080fd5b806313af4035146102aa5780631785f53c146102bd5780631c7d1b37146102d05780632eb2c2d6146102e357600080fd5b80630a971087116101c35780630a9710871461025c5780630e316ab7146102715780630e89341c14610284578063120f6e081461029757600080fd5b8062fdd58e146101e957806301ffc9a71461022457806306fdde0314610247575b600080fd5b6102116101f73660046120ad565b600060208181529281526040808220909352908152205481565b6040519081526020015b60405180910390f35b6102376102323660046120ed565b610529565b604051901515815260200161021b565b61024f61057b565b60405161021b919061215a565b61026f61026a3660046121b1565b610609565b005b61026f61027f366004612203565b6107b6565b61024f61029236600461221e565b610843565b61024f6102a536600461221e565b610977565b61026f6102b8366004612203565b610990565b61026f6102cb366004612203565b610a20565b61026f6102de366004612278565b610aae565b61026f6102f13660046122ca565b610d9d565b61026f610304366004612384565b61101e565b6102117f778ae2d713762caf7cf7089c6a0794596dd24a29c9630e2749991c98ea9ea01b81565b61026f61033e3660046123cf565b6110bb565b610237610351366004612203565b60036020526000908152604090205460ff1681565b610379610374366004612404565b611213565b60405161021b9190612463565b61026f610394366004612203565b611325565b6102116103a7366004612203565b60076020526000908152604090205481565b6102376103c7366004612203565b60066020526000908152604090205460ff1681565b6002546103ef906001600160a01b031681565b6040516001600160a01b03909116815260200161021b565b61024f6113b6565b61026f61041d3660046124a7565b6113c3565b6103ef61043036600461221e565b6009602052600090815260409020546001600160a01b031681565b61026f6104593660046124e5565b611560565b61024f604051806040016040528060018152602001603160f81b81525081565b61026f61048c366004612521565b6115cc565b61026f61049f36600461254d565b6116da565b61024f6040518060400160405280601281526020017153616d4b696e6753747564696f44726f707360701b81525081565b6102376104e33660046125c6565b600160209081526000928352604080842090915290825290205460ff1681565b61026f610511366004612203565b6118d0565b61026f6105243660046125f0565b611960565b60006301ffc9a760e01b6001600160e01b03198316148061055a5750636cdb3d1360e11b6001600160e01b03198316145b8061057557506303a24d0760e21b6001600160e01b03198316145b92915050565b6004805461058890612667565b80601f01602080910402602001604051908101604052809291908181526020018280546105b490612667565b80156106015780601f106105d657610100808354040283529160200191610601565b820191906000526020600020905b8154815290600101906020018083116105e457829003601f168201915b505050505081565b60008481526009602052604090205484906001600160a01b03166106ec576000818152600860205260408120805461064090612667565b80601f016020809104026020016040519081016040528092919081815260200182805461066c90612667565b80156106b95780601f1061068e576101008083540402835291602001916106b9565b820191906000526020600020905b81548152906001019060200180831161069c57829003601f168201915b5050505050905060008151116106ea5760405162461bcd60e51b81526004016106e1906126a1565b60405180910390fd5b505b6002546001600160a01b031633148061071457503360009081526003602052604090205460ff165b6107305760405162461bcd60e51b81526004016106e1906126c9565b81156107965760005b8381101561079457610782858583818110610756576107566126ef565b905060200201602081019061076b9190612203565b878560405180602001604052806000815250611b5a565b8061078c8161271b565b915050610739565b505b6040518590600080516020612b3183398151915290600090a25050505050565b6002546001600160a01b03163314806107de57503360009081526003602052604090205460ff165b6107fa5760405162461bcd60e51b81526004016106e1906126c9565b6001600160a01b038116600081815260066020526040808220805460ff19169055517f3525e22824a8a7df2c9a6029941c824cf95b6447f1e13d5128fd3826d35afe8b9190a250565b6000818152600960205260409020546060906001600160a01b031680156108d8576040516303a24d0760e21b8152600481018490526001600160a01b03821690630e89341c90602401600060405180830381865afa1580156108a9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526108d1919081019061274a565b9392505050565b600083815260086020526040902080546108f190612667565b80601f016020809104026020016040519081016040528092919081815260200182805461091d90612667565b801561096a5780601f1061093f5761010080835404028352916020019161096a565b820191906000526020600020905b81548152906001019060200180831161094d57829003601f168201915b5050505050915050919050565b6008602052600090815260409020805461058890612667565b6002546001600160a01b03163314806109b857503360009081526003602052604090205460ff165b6109d45760405162461bcd60e51b81526004016106e1906126c9565b600280546001600160a01b0319166001600160a01b03831690811790915560405133907f8292fce18fa69edf4db7b94ea2e58241df0ae57f97e0a6c9b29067028bf92d7690600090a350565b6002546001600160a01b0316331480610a4857503360009081526003602052604090205460ff165b610a645760405162461bcd60e51b81526004016106e1906126c9565b6001600160a01b038116600081815260036020526040808220805460ff19169055517fdb9d5d31320daf5bc7181d565b6da4d12e30f0f4d5aa324a992426c14a1d19ce908290a350565b60008481526009602052604090205484906001600160a01b0316610b885760008181526008602052604081208054610ae590612667565b80601f0160208091040260200160405190810160405280929190818152602001828054610b1190612667565b8015610b5e5780601f10610b3357610100808354040283529160200191610b5e565b820191906000526020600020905b815481529060010190602001808311610b4157829003601f168201915b505050505090506000815111610b865760405162461bcd60e51b81526004016106e1906126a1565b505b6040805160a0810182528681526020808201879052338284018190526000908152600782528381205460608401528351601f87018390048302810183019094528584529260808301918790879081908401838280828437600092018290525093909452505082516020808501516040808701516001600160a01b03811686526007909352842080549697509395610c9895507f778ae2d713762caf7cf7089c6a0794596dd24a29c9630e2749991c98ea9ea01b9491929187610c498361271b565b9091555060408051602081019690965285019390935260608401919091526001600160a01b0316608083015260a082015260c00160405160208183030381529060405280519060200120611ca2565b90506000610caa828460800151611cf0565b6001600160a01b03811660009081526006602052604090205490915060ff168015610cdd57506001600160a01b03811615155b610d1d5760405162461bcd60e51b8152602060048201526011602482015270494e56414c49445f5349474e415455524560781b60448201526064016106e1565b602083015115610d9357610d4e83604001518460000151856020015160405180602001604052806000815250611b5a565b826020015183604001516001600160a01b031684600001517f2b93fe25f6eb77d6c3e44244241ad4193572e76d3b3e9e2f834a11e9404e856e60405160405180910390a45b5050505050505050565b848314610dbc5760405162461bcd60e51b81526004016106e1906127f6565b336001600160a01b0389161480610df657506001600160a01b038816600090815260016020908152604080832033845290915290205460ff165b610e335760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064016106e1565b60008060005b87811015610eee57888882818110610e5357610e536126ef565b905060200201359250868682818110610e6e57610e6e6126ef565b6001600160a01b038e1660009081526020818152604080832089845282528220805493909102949094013595508593925090610eab90849061281f565b90915550506001600160a01b038a1660009081526020818152604080832086845290915281208054849290610ee1908490612832565b9091555050600101610e39565b50886001600160a01b03168a6001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8b8b8b8b604051610f429493929190612877565b60405180910390a46001600160a01b0389163b15610fe95760405163bc197c8160e01b808252906001600160a01b038b169063bc197c8190610f969033908f908e908e908e908e908e908e906004016128c7565b6020604051808303816000875af1158015610fb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd9919061292b565b6001600160e01b03191614610ff6565b6001600160a01b03891615155b6110125760405162461bcd60e51b81526004016106e190612948565b50505050505050505050565b6002546001600160a01b031633148061104657503360009081526003602052604090205460ff165b6110625760405162461bcd60e51b81526004016106e1906126c9565b600083815260086020526040902061107b8284836129bd565b50827f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b83836040516110ae929190612a7d565b60405180910390a2505050565b60008381526009602052604090205483906001600160a01b031661119557600081815260086020526040812080546110f290612667565b80601f016020809104026020016040519081016040528092919081815260200182805461111e90612667565b801561116b5780601f106111405761010080835404028352916020019161116b565b820191906000526020600020905b81548152906001019060200180831161114e57829003601f168201915b5050505050905060008151116111935760405162461bcd60e51b81526004016106e1906126a1565b505b6002546001600160a01b03163314806111bd57503360009081526003602052604090205460ff165b6111d95760405162461bcd60e51b81526004016106e1906126c9565b6111f483858460405180602001604052806000815250611b5a565b6040518490600080516020612b3183398151915290600090a250505050565b60608382146112345760405162461bcd60e51b81526004016106e1906127f6565b836001600160401b0381111561124c5761124c612734565b604051908082528060200260200182016040528015611275578160200160208202803683370190505b50905060005b8481101561131c57600080878784818110611298576112986126ef565b90506020020160208101906112ad9190612203565b6001600160a01b03166001600160a01b0316815260200190815260200160002060008585848181106112e1576112e16126ef565b90506020020135815260200190815260200160002054828281518110611309576113096126ef565b602090810291909101015260010161127b565b50949350505050565b6002546001600160a01b031633148061134d57503360009081526003602052604090205460ff165b6113695760405162461bcd60e51b81526004016106e1906126c9565b6001600160a01b038116600081815260036020526040808220805460ff19166001179055517fbf3f493c772c8c283fd124432c2d0f539ab343faa04258fe88e52912d36b102b908290a350565b6005805461058890612667565b60008381526009602052604090205483906001600160a01b031661149d57600081815260086020526040812080546113fa90612667565b80601f016020809104026020016040519081016040528092919081815260200182805461142690612667565b80156114735780601f1061144857610100808354040283529160200191611473565b820191906000526020600020905b81548152906001019060200180831161145657829003601f168201915b50505050509050600081511161149b5760405162461bcd60e51b81526004016106e1906126a1565b505b6002546001600160a01b03163314806114c557503360009081526003602052604090205460ff165b6114e15760405162461bcd60e51b81526004016106e1906126c9565b60005b828110156115405761152e848483818110611501576115016126ef565b90506020020160208101906115169190612203565b86600160405180602001604052806000815250611b5a565b806115388161271b565b9150506114e4565b506040518490600080516020612b3183398151915290600090a250505050565b3360008181526001602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6002546001600160a01b03163314806115f457503360009081526003602052604090205460ff165b6116105760405162461bcd60e51b81526004016106e1906126c9565b6000828152600960205260409081902080546001600160a01b0319166001600160a01b03841690811790915590516303a24d0760e21b81526004810184905283917f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b91630e89341c90602401600060405180830381865afa158015611699573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526116c1919081019061274a565b6040516116ce919061215a565b60405180910390a25050565b60008581526009602052604090205485906001600160a01b03166117b4576000818152600860205260408120805461171190612667565b80601f016020809104026020016040519081016040528092919081815260200182805461173d90612667565b801561178a5780601f1061175f5761010080835404028352916020019161178a565b820191906000526020600020905b81548152906001019060200180831161176d57829003601f168201915b5050505050905060008151116117b25760405162461bcd60e51b81526004016106e1906126a1565b505b6002546001600160a01b03163314806117dc57503360009081526003602052604090205460ff165b6117f85760405162461bcd60e51b81526004016106e1906126c9565b8382146118175760405162461bcd60e51b81526004016106e1906127f6565b60005b848110156118ae576000848483818110611836576118366126ef565b90506020020135111561189c5761189c868683818110611858576118586126ef565b905060200201602081019061186d9190612203565b88868685818110611880576118806126ef565b9050602002013560405180602001604052806000815250611b5a565b806118a68161271b565b91505061181a565b506040518690600080516020612b3183398151915290600090a2505050505050565b6002546001600160a01b03163314806118f857503360009081526003602052604090205460ff165b6119145760405162461bcd60e51b81526004016106e1906126c9565b6001600160a01b038116600081815260066020526040808220805460ff19166001179055517f47d1c22a25bb3a5d4e481b9b1e6944c2eade3181a0a20b495ed61d35b5323f249190a250565b336001600160a01b038716148061199a57506001600160a01b038616600090815260016020908152604080832033845290915290205460ff165b6119d75760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064016106e1565b6001600160a01b03861660009081526020818152604080832087845290915281208054859290611a0890849061281f565b90915550506001600160a01b03851660009081526020818152604080832087845290915281208054859290611a3e908490612832565b909155505060408051858152602081018590526001600160a01b03808816929089169133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46001600160a01b0385163b15611b295760405163f23a6e6160e01b808252906001600160a01b0387169063f23a6e6190611ad69033908b908a908a908a908a90600401612a99565b6020604051808303816000875af1158015611af5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b19919061292b565b6001600160e01b03191614611b36565b6001600160a01b03851615155b611b525760405162461bcd60e51b81526004016106e190612948565b505050505050565b6001600160a01b03841660009081526020818152604080832086845290915281208054849290611b8b908490612832565b909155505060408051848152602081018490526001600160a01b0386169160009133917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46001600160a01b0384163b15611c735760405163f23a6e6160e01b808252906001600160a01b0386169063f23a6e6190611c20903390600090899089908990600401612ae0565b6020604051808303816000875af1158015611c3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c63919061292b565b6001600160e01b03191614611c80565b6001600160a01b03841615155b611c9c5760405162461bcd60e51b81526004016106e190612948565b50505050565b6000610575611caf611d14565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b6000806000611cff8585611e3b565b91509150611d0c81611e80565b509392505050565b6000306001600160a01b037f000000000000000000000000208d1008fa508414b6dc63738bc8560a12ef527916148015611d6d57507f000000000000000000000000000000000000000000000000000000000000000146145b15611d9757507f6d8d6a9bfcdac5713f347dfd98a88b02bd1f5d719e87beb58f4c80abe5c12db090565b50604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6020808301919091527f23f09aaf7a35db8147a6c2a52fd383a65ba2ade2f6d49cc26551426e5f1c8012828401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b6000808251604103611e715760208301516040840151606085015160001a611e6587828585611fcd565b94509450505050611e79565b506000905060025b9250929050565b6000816004811115611e9457611e94612b1a565b03611e9c5750565b6001816004811115611eb057611eb0612b1a565b03611efd5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016106e1565b6002816004811115611f1157611f11612b1a565b03611f5e5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016106e1565b6003816004811115611f7257611f72612b1a565b03611fca5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016106e1565b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156120045750600090506003612088565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612058573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661208157600060019250925050612088565b9150600090505b94509492505050565b80356001600160a01b03811681146120a857600080fd5b919050565b600080604083850312156120c057600080fd5b6120c983612091565b946020939093013593505050565b6001600160e01b031981168114611fca57600080fd5b6000602082840312156120ff57600080fd5b81356108d1816120d7565b60005b8381101561212557818101518382015260200161210d565b50506000910152565b6000815180845261214681602086016020860161210a565b601f01601f19169290920160200192915050565b6020815260006108d1602083018461212e565b60008083601f84011261217f57600080fd5b5081356001600160401b0381111561219657600080fd5b6020830191508360208260051b8501011115611e7957600080fd5b600080600080606085870312156121c757600080fd5b8435935060208501356001600160401b038111156121e457600080fd5b6121f08782880161216d565b9598909750949560400135949350505050565b60006020828403121561221557600080fd5b6108d182612091565b60006020828403121561223057600080fd5b5035919050565b60008083601f84011261224957600080fd5b5081356001600160401b0381111561226057600080fd5b602083019150836020828501011115611e7957600080fd5b6000806000806060858703121561228e57600080fd5b843593506020850135925060408501356001600160401b038111156122b257600080fd5b6122be87828801612237565b95989497509550505050565b60008060008060008060008060a0898b0312156122e657600080fd5b6122ef89612091565b97506122fd60208a01612091565b965060408901356001600160401b038082111561231957600080fd5b6123258c838d0161216d565b909850965060608b013591508082111561233e57600080fd5b61234a8c838d0161216d565b909650945060808b013591508082111561236357600080fd5b506123708b828c01612237565b999c989b5096995094979396929594505050565b60008060006040848603121561239957600080fd5b8335925060208401356001600160401b038111156123b657600080fd5b6123c286828701612237565b9497909650939450505050565b6000806000606084860312156123e457600080fd5b833592506123f460208501612091565b9150604084013590509250925092565b6000806000806040858703121561241a57600080fd5b84356001600160401b038082111561243157600080fd5b61243d8883890161216d565b9096509450602087013591508082111561245657600080fd5b506122be8782880161216d565b6020808252825182820181905260009190848201906040850190845b8181101561249b5783518352928401929184019160010161247f565b50909695505050505050565b6000806000604084860312156124bc57600080fd5b8335925060208401356001600160401b038111156124d957600080fd5b6123c28682870161216d565b600080604083850312156124f857600080fd5b61250183612091565b91506020830135801515811461251657600080fd5b809150509250929050565b6000806040838503121561253457600080fd5b8235915061254460208401612091565b90509250929050565b60008060008060006060868803121561256557600080fd5b8535945060208601356001600160401b038082111561258357600080fd5b61258f89838a0161216d565b909650945060408801359150808211156125a857600080fd5b506125b58882890161216d565b969995985093965092949392505050565b600080604083850312156125d957600080fd5b6125e283612091565b915061254460208401612091565b60008060008060008060a0878903121561260957600080fd5b61261287612091565b955061262060208801612091565b9450604087013593506060870135925060808701356001600160401b0381111561264957600080fd5b61265589828a01612237565b979a9699509497509295939492505050565b600181811c9082168061267b57607f821691505b60208210810361269b57634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600e908201526d44524f505f4e4f545f524541445960901b604082015260600190565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161272d5761272d612705565b5060010190565b634e487b7160e01b600052604160045260246000fd5b60006020828403121561275c57600080fd5b81516001600160401b038082111561277357600080fd5b818401915084601f83011261278757600080fd5b81518181111561279957612799612734565b604051601f8201601f19908116603f011681019083821181831017156127c1576127c1612734565b816040528281528760208487010111156127da57600080fd5b6127eb83602083016020880161210a565b979650505050505050565b6020808252600f908201526e0988a9c8ea890be9a92a69a82a8869608b1b604082015260600190565b8181038181111561057557610575612705565b8082018082111561057557610575612705565b81835260006001600160fb1b0383111561285e57600080fd5b8260051b80836020870137939093016020019392505050565b60408152600061288b604083018688612845565b82810360208401526127eb818587612845565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b0389811682528816602082015260a0604082018190526000906128f4908301888a612845565b8281036060840152612907818789612845565b9050828103608084015261291c81858761289e565b9b9a5050505050505050505050565b60006020828403121561293d57600080fd5b81516108d1816120d7565b60208082526010908201526f155394d0519157d49150d2541251539560821b604082015260600190565b601f8211156129b857600081815260208120601f850160051c810160208610156129995750805b601f850160051c820191505b81811015611b52578281556001016129a5565b505050565b6001600160401b038311156129d4576129d4612734565b6129e8836129e28354612667565b83612972565b6000601f841160018114612a1c5760008515612a045750838201355b600019600387901b1c1916600186901b178355612a76565b600083815260209020601f19861690835b82811015612a4d5786850135825560209485019460019092019101612a2d565b5086821015612a6a5760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b602081526000612a9160208301848661289e565b949350505050565b6001600160a01b03878116825286166020820152604081018590526060810184905260a060808201819052600090612ad4908301848661289e565b98975050505050505050565b6001600160a01b03868116825285166020820152604081018490526060810183905260a0608082018190526000906127eb9083018461212e565b634e487b7160e01b600052602160045260246000fdfe95a00f343edb771ffa3d5bda50afe8c6354c35baae5ab282c4d27b38271c561da164736f6c6343000811000a

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

00000000000000000000000027676d628ab0979754f01af51074680dfa38d3e9000000000000000000000000d633d5bc9fd1250ac203de798508340dfa989b6b000000000000000000000000aa6bf8f3a77f9a71a778204e3f4049a416dbb72a

-----Decoded View---------------
Arg [0] : owner_ (address): 0x27676d628ab0979754F01aF51074680DfA38D3e9
Arg [1] : admin_ (address): 0xD633d5bc9Fd1250aC203dE798508340dFA989B6B
Arg [2] : signer_ (address): 0xAa6BF8F3A77F9A71A778204E3f4049a416DbB72a

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 00000000000000000000000027676d628ab0979754f01af51074680dfa38d3e9
Arg [1] : 000000000000000000000000d633d5bc9fd1250ac203de798508340dfa989b6b
Arg [2] : 000000000000000000000000aa6bf8f3a77f9a71a778204e3f4049a416dbb72a


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

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

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