ETH Price: $1,603.76 (-1.27%)
 

Overview

ETH Balance

0.0223 ETH

Eth Value

$35.76 (@ $1,603.76/ETH)

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Buy From Listing219315952025-02-26 16:06:4748 days ago1740586007IN
0x1e6C0483...9f6002F35
0.0222 ETH0.000247131.43845442
Withdraw Income218832232025-02-19 21:52:4755 days ago1740001967IN
0x1e6C0483...9f6002F35
0 ETH0.000030610.69118552
Approve Withdraw...218832222025-02-19 21:52:3555 days ago1740001955IN
0x1e6C0483...9f6002F35
0 ETH0.000033540.69700951
Revoke Role217181042025-01-27 19:59:2378 days ago1738007963IN
0x1e6C0483...9f6002F35
0 ETH0.000253158.58091122
Update Listing215884112025-01-09 17:28:3596 days ago1736443715IN
0x1e6C0483...9f6002F35
0 ETH0.000500711.30345454
Update Listing215884102025-01-09 17:28:2396 days ago1736443703IN
0x1e6C0483...9f6002F35
0 ETH0.0005037311.37173452
Update Listing215884092025-01-09 17:28:1196 days ago1736443691IN
0x1e6C0483...9f6002F35
0 ETH0.0004652410.50288156
Update Listing214653532024-12-23 13:01:59113 days ago1734958919IN
0x1e6C0483...9f6002F35
0 ETH0.000370267.49101802
Update Listing213382272024-12-05 18:57:23131 days ago1733425043IN
0x1e6C0483...9f6002F35
0 ETH0.0013269229.95528337
Update Listing213382262024-12-05 18:57:11131 days ago1733425031IN
0x1e6C0483...9f6002F35
0 ETH0.0011852326.7420151
Update Listing213379802024-12-05 18:07:35131 days ago1733422055IN
0x1e6C0483...9f6002F35
0 ETH0.0012949827.75847739
Update Listing213379792024-12-05 18:07:23131 days ago1733422043IN
0x1e6C0483...9f6002F35
0 ETH0.001319428.26737291
Update Listing213379772024-12-05 18:06:59131 days ago1733422019IN
0x1e6C0483...9f6002F35
0 ETH0.0013231128.36144906
Update Listing213379762024-12-05 18:06:47131 days ago1733422007IN
0x1e6C0483...9f6002F35
0 ETH0.0013245228.42076955
Update Listing213379752024-12-05 18:06:35131 days ago1733421995IN
0x1e6C0483...9f6002F35
0 ETH0.0013829629.67476405
Update Listing213378992024-12-05 17:51:11131 days ago1733421071IN
0x1e6C0483...9f6002F35
0 ETH0.0014577731.28001074
Update Listing213378982024-12-05 17:50:59131 days ago1733421059IN
0x1e6C0483...9f6002F35
0 ETH0.0014484231.07931379
Update Listing213378972024-12-05 17:50:47131 days ago1733421047IN
0x1e6C0483...9f6002F35
0 ETH0.0015284632.79676435
Buy From Listing212741042024-11-26 19:46:23140 days ago1732650383IN
0x1e6C0483...9f6002F35
0.05 ETH0.0023367513.40698201
Buy From Listing212722252024-11-26 13:29:23140 days ago1732627763IN
0x1e6C0483...9f6002F35
0.01 ETH0.0039804422.90940778
Update Listing212653672024-11-25 14:27:47141 days ago1732544867IN
0x1e6C0483...9f6002F35
0 ETH0.0010501823.70782215
Update Listing212653662024-11-25 14:27:35141 days ago1732544855IN
0x1e6C0483...9f6002F35
0 ETH0.0009393821.20646323
Update Listing212653642024-11-25 14:27:11141 days ago1732544831IN
0x1e6C0483...9f6002F35
0 ETH0.0010393823.46389315
Update Listing212653632024-11-25 14:26:59141 days ago1732544819IN
0x1e6C0483...9f6002F35
0 ETH0.0009845922.23917088
Update Listing212653622024-11-25 14:26:47141 days ago1732544807IN
0x1e6C0483...9f6002F35
0 ETH0.0010413423.49547809
View all transactions

Latest 12 internal transactions

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer218832232025-02-19 21:52:4755 days ago1740001967
0x1e6C0483...9f6002F35
1.282 ETH
Transfer209799382024-10-16 18:33:11181 days ago1729103591
0x1e6C0483...9f6002F35
0.033 ETH
Transfer208714032024-10-01 15:01:11196 days ago1727794871
0x1e6C0483...9f6002F35
0.066 ETH
Transfer208088642024-09-22 21:39:59205 days ago1727041199
0x1e6C0483...9f6002F35
0.165 ETH
Transfer207134562024-09-09 13:49:23218 days ago1725889763
0x1e6C0483...9f6002F35
0.033 ETH
Transfer205651862024-08-19 20:53:59239 days ago1724100839
0x1e6C0483...9f6002F35
0.018 ETH
Transfer205651772024-08-19 20:52:11239 days ago1724100731
0x1e6C0483...9f6002F35
0.018 ETH
Transfer205340022024-08-15 12:22:59243 days ago1723724579
0x1e6C0483...9f6002F35
0.08 ETH
Transfer198828102024-05-16 13:22:59334 days ago1715865779
0x1e6C0483...9f6002F35
0.16 ETH
Transfer193782622024-03-06 19:36:23405 days ago1709753783
0x1e6C0483...9f6002F35
0.81 ETH
Transfer193625522024-03-04 15:00:23407 days ago1709564423
0x1e6C0483...9f6002F35
1.53 ETH
Transfer187937922023-12-15 20:08:11487 days ago1702670891
0x1e6C0483...9f6002F35
3.249 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SykyMarket

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 300 runs

Other Settings:
paris EvmVersion
File 1 of 9 : SykyMarket.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

/// @author Syky - Nathan Rempel

/*
           @@@   @@@@@   @@@@@@@         @@@@    @@@@@@@      @@@@@     @@@@@@@        @@@@
         @@@@      @@@     @@@@@@        @@       @@@@@@       @@        @@@@@@        @@
         @@@@@      @@      @@@@@       @@        @@@@@       @            @@@@@      @@
         @@@@@@      @@      @@@@@     @@         @@@@@     @               @@@@     @@
          @@@@@@      @       @@@@@   @@          @@@@@    @                @@@@@    @
           @@@@@@@             @@@@@ @@           @@@@@  @@@                 @@@@@  @
             @@@@@@             @@@@@@            @@@@@@@@@@@                 @@@@@@
               @@@@@@           @@@@@             @@@@@  @@@@@                 @@@@@
                @@@@@@@         @@@@@             @@@@@   @@@@@                @@@@@
         @        @@@@@@        @@@@@             @@@@@    @@@@@               @@@@@
         @@        @@@@@        @@@@@             @@@@@     @@@@@              @@@@@
         @@@@      @@@@@        @@@@@             @@@@@@     @@@@@@           @@@@@@
         @@@@@@   @@@@         @@@@@@@           @@@@@@@     @@@@@@@          @@@@@@@
*/

import "../base/ProductMarket.sol";

contract SykyMarket is ProductMarket {
    /*//////////////////////////////////////////////////////////////
                            Version Info
    //////////////////////////////////////////////////////////////*/

    string public constant ENV = "MAINNET";
    string public constant VER = "1.0.1";

    /*//////////////////////////////////////////////////////////////
                            Constructor
    //////////////////////////////////////////////////////////////*/

    constructor(
        address defaultAdmin_,
        address defaultToken_,
        address vipContract_
    ) ProductMarket(defaultAdmin_, defaultToken_, vipContract_) {}
}

File 2 of 9 : IPermissions.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;

/// @author thirdweb

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IPermissions {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}

File 3 of 9 : Permissions.sol
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;

/// @author thirdweb

import "./interface/IPermissions.sol";
import "../lib/TWStrings.sol";

/**
 *  @title   Permissions
 *  @dev     This contracts provides extending-contracts with role-based access control mechanisms
 */
contract Permissions is IPermissions {
    /// @dev Map from keccak256 hash of a role => a map from address => whether address has role.
    mapping(bytes32 => mapping(address => bool)) private _hasRole;

    /// @dev Map from keccak256 hash of a role to role admin. See {getRoleAdmin}.
    mapping(bytes32 => bytes32) private _getRoleAdmin;

    /// @dev Default admin role for all roles. Only accounts with this role can grant/revoke other roles.
    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /// @dev Modifier that checks if an account has the specified role; reverts otherwise.
    modifier onlyRole(bytes32 role) {
        _checkRole(role, msg.sender);
        _;
    }

    /**
     *  @notice         Checks whether an account has a particular role.
     *  @dev            Returns `true` if `account` has been granted `role`.
     *
     *  @param role     keccak256 hash of the role. e.g. keccak256("TRANSFER_ROLE")
     *  @param account  Address of the account for which the role is being checked.
     */
    function hasRole(bytes32 role, address account) public view override returns (bool) {
        return _hasRole[role][account];
    }

    /**
     *  @notice         Checks whether an account has a particular role;
     *                  role restrictions can be swtiched on and off.
     *
     *  @dev            Returns `true` if `account` has been granted `role`.
     *                  Role restrictions can be swtiched on and off:
     *                      - If address(0) has ROLE, then the ROLE restrictions
     *                        don't apply.
     *                      - If address(0) does not have ROLE, then the ROLE
     *                        restrictions will apply.
     *
     *  @param role     keccak256 hash of the role. e.g. keccak256("TRANSFER_ROLE")
     *  @param account  Address of the account for which the role is being checked.
     */
    function hasRoleWithSwitch(bytes32 role, address account) public view returns (bool) {
        if (!_hasRole[role][address(0)]) {
            return _hasRole[role][account];
        }

        return true;
    }

    /**
     *  @notice         Returns the admin role that controls the specified role.
     *  @dev            See {grantRole} and {revokeRole}.
     *                  To change a role's admin, use {_setRoleAdmin}.
     *
     *  @param role     keccak256 hash of the role. e.g. keccak256("TRANSFER_ROLE")
     */
    function getRoleAdmin(bytes32 role) external view override returns (bytes32) {
        return _getRoleAdmin[role];
    }

    /**
     *  @notice         Grants a role to an account, if not previously granted.
     *  @dev            Caller must have admin role for the `role`.
     *                  Emits {RoleGranted Event}.
     *
     *  @param role     keccak256 hash of the role. e.g. keccak256("TRANSFER_ROLE")
     *  @param account  Address of the account to which the role is being granted.
     */
    function grantRole(bytes32 role, address account) public virtual override {
        _checkRole(_getRoleAdmin[role], msg.sender);
        if (_hasRole[role][account]) {
            revert("Can only grant to non holders");
        }
        _setupRole(role, account);
    }

    /**
     *  @notice         Revokes role from an account.
     *  @dev            Caller must have admin role for the `role`.
     *                  Emits {RoleRevoked Event}.
     *
     *  @param role     keccak256 hash of the role. e.g. keccak256("TRANSFER_ROLE")
     *  @param account  Address of the account from which the role is being revoked.
     */
    function revokeRole(bytes32 role, address account) public virtual override {
        _checkRole(_getRoleAdmin[role], msg.sender);
        _revokeRole(role, account);
    }

    /**
     *  @notice         Revokes role from the account.
     *  @dev            Caller must have the `role`, with caller being the same as `account`.
     *                  Emits {RoleRevoked Event}.
     *
     *  @param role     keccak256 hash of the role. e.g. keccak256("TRANSFER_ROLE")
     *  @param account  Address of the account from which the role is being revoked.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        if (msg.sender != account) {
            revert("Can only renounce for self");
        }
        _revokeRole(role, account);
    }

    /// @dev Sets `adminRole` as `role`'s admin role.
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = _getRoleAdmin[role];
        _getRoleAdmin[role] = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /// @dev Sets up `role` for `account`
    function _setupRole(bytes32 role, address account) internal virtual {
        _hasRole[role][account] = true;
        emit RoleGranted(role, account, msg.sender);
    }

    /// @dev Revokes `role` from `account`
    function _revokeRole(bytes32 role, address account) internal virtual {
        _checkRole(role, account);
        delete _hasRole[role][account];
        emit RoleRevoked(role, account, msg.sender);
    }

    /// @dev Checks `role` for `account`. Reverts with a message including the required role.
    function _checkRole(bytes32 role, address account) internal view virtual {
        if (!_hasRole[role][account]) {
            revert(
                string(
                    abi.encodePacked(
                        "Permissions: account ",
                        TWStrings.toHexString(uint160(account), 20),
                        " is missing role ",
                        TWStrings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /// @dev Checks `role` for `account`. Reverts with a message including the required role.
    function _checkRoleWithSwitch(bytes32 role, address account) internal view virtual {
        if (!hasRoleWithSwitch(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "Permissions: account ",
                        TWStrings.toHexString(uint160(account), 20),
                        " is missing role ",
                        TWStrings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }
}

File 4 of 9 : TWAddress.sol
// SPDX-License-Identifier: Apache 2.0
pragma solidity ^0.8.0;

/// @author thirdweb

/**
 * @dev Collection of functions related to the address type
 */
library TWAddress {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * [EIP1884](https://eips.ethereum.org/EIPS/eip-1884) increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 5 of 9 : TWStrings.sol
// SPDX-License-Identifier: Apache 2.0
pragma solidity ^0.8.0;

/// @author thirdweb

/**
 * @dev String operations.
 */
library TWStrings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

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

File 6 of 9 : IProductMarket.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

/// @author Syky - Nathan Rempel

interface IProductMarket {
    /*//////////////////////////////////////////////////////////////
                        Structs
    //////////////////////////////////////////////////////////////*/

    /**
     *  @notice A data structure to configure Product Listings
     *  @dev Should compress to 512 bytes.
     *
     *  @param productId The productId of the asset being sold.     (max 16,777,215)
     *  @param quantity The total quantity listed for sale.         (max 65,535)
     *  @param reserved The quantity availablein the VIP window.    (max 65,535)
     *  @param vipLimit The purchase limit for VIPs.                (max 65,535)
     *  @param pubLimit The purchase limit for public.              (max 65,535)
     *  @param vipPrice The price in ETH per item for VIPs.         (max 18.4467 ETH)
     *  @param pubPrice The price in ETH per item for public.       (max 18.4467 ETH)
     *  @param endTimestamp The sale end timestamp for everyone.
     *  @param vipStartTimestamp The sale start timestamp for VIPs.
     *  @param pubStartTimestamp The sale start timestamp for public.
     *  @param enabled The listing is enabled
     */
    struct ListingParams {
        uint24 productId;
        uint16 quantity;
        uint16 reserved;
        uint16 vipLimit;
        uint16 pubLimit;
        uint64 vipPrice;
        uint64 pubPrice;
        uint32 endTimestamp;
        uint32 vipStartTimestamp;
        uint32 pubStartTimestamp;
        bool enabled;
        //spare 192 bytes space capacity
        //compresses to one 256
    }

    /**
     *  @notice A data structure to store Product Listings
     *  @dev Should compress to 512 bytes.
     *
     *  @param productId The productId of the asset being sold.     (max 16,777,215)
     *  @param enabled The listing is enabled                       (value > 0 = true)
     *  @param quantity The total quantity listed for sale.         (max 65,535)
     *  @param reserved The quantity availablein the VIP window.    (max 65,535)
     *  @param vipLimit The purchase limit for VIPs.                (max 65,535)
     *  @param pubLimit The purchase limit for public.              (max 65,535)
     *  @param vipPrice The price in ETH per item for VIPs.         (max 18.4467 ETH)
     *  @param pubPrice The price in ETH per item for public.       (max 18.4467 ETH)
     *  @param endTimestamp The sale end timestamp for everyone.
     *  @param vipStartTimestamp The sale start timestamp for VIPs.
     *  @param pubStartTimestamp The sale start timestamp for public.
     *  @param resPurchased The VIP purchase quantity in the VIP window.
     *  @param vipPurchased The VIP purchase quantity of the sale in any window.
     *  @param pubPurchased The public purchase quantity of the sale.
     *  @param vipIncome The VIP purchase income of the sale.       (max 4,722.3664 ETH)
     *  @param pubIncome The public purchase income of the sale.    (max 4,722.3664 ETH)
     */
    struct Listing {
        uint24 productId;
        uint8 enabled;
        uint16 quantity;
        uint16 reserved;
        uint16 vipLimit;
        uint16 pubLimit;
        uint64 vipPrice;
        uint64 pubPrice;
        uint32 endTimestamp;
        //compresses to one 256
        uint32 vipStartTimestamp;
        uint32 pubStartTimestamp;
        uint16 resPurchased;
        uint16 vipPurchased;
        uint16 pubPurchased;
        uint72 vipIncome;
        uint72 pubIncome;
        //compresses to one 256
    }

    /// @notice A data structure to return a set of listings
    struct ListingQuery {
        uint256 listingId;
        Listing listingData;
    }

    enum AuctionStatus {
        UNSET,
        CREATED,
        COMPLETED,
        CANCELLED
    }

    struct AuctionParams {
        uint56 productId;
        uint32 startTimestamp;
        uint32 endTimestamp;
        uint64 bidBufferBps;
        uint64 timeBufferSeconds;
        uint256 minimumBidAmount;
        uint256 reserveBidAmount;
    }

    struct Auction {
        uint56 productId;
        AuctionStatus status;
        uint32 startTimestamp;
        uint32 endTimestamp;
        uint64 bidBufferBps;
        uint64 timeBufferSeconds;
        uint256 minimumBidAmount;
        uint256 reserveBidAmount;
    }

    struct AuctionQuery {
        uint256 auctionId;
        Auction auctionData;
        Bid winningBid;
    }

    struct Bid {
        uint64 auctionId;
        uint32 bidTimestamp;
        address bidder;
        uint256 bidAmount;
    }

    struct BidHistory {
        uint256 count;
        mapping(uint256 => Bid) bids;
    }

    struct ProductLookup {
        uint256 count;
        mapping(uint256 => uint256) id;
    }

    /*//////////////////////////////////////////////////////////////
                        Events
    //////////////////////////////////////////////////////////////*/

    /// @dev Emitted when a new listing is created.
    event ListingAdded(uint256 indexed listingId, Listing listing);

    /// @dev Emitted when the parameters of a listing are updated.
    event ListingUpdated(uint256 indexed listingId, Listing listing);

    /// @dev Emitted when a listing is enabled or disabled.
    event ListingEnabled(uint256 indexed listingId, bool indexed enabled);

    /// @dev Emitted when a listing token contract is updated.
    event ListingContract(uint256 indexed listingId, address indexed tokenContract);

    /// @dev Emitted when a new sale occurs for a listing.
    event NewSale(
        uint256 indexed listingId,
        address indexed buyer,
        address indexed recipient,
        uint256 productId,
        uint256 quantity,
        uint256 price
    );

    /// @dev Emitted when withdrawal recipient is approved or unapproved.
    event WithdrawalRecipientApproved(address indexed recipient, bool indexed approved);

    /// @dev Emitted when market income is withdrawn.
    event IncomeWithdrawal(
        address indexed operator,
        address indexed recipient,
        uint256 indexed amount
    );

    event AuctionAdded(uint256 indexed auctionId, Auction auction);

    event AuctionUpdated(uint256 indexed auctionId, Auction auction);

    event AuctionCancelled(uint256 indexed auctionId);

    /// @dev Emitted when a listing token contract is updated.
    event AuctionContract(uint256 indexed auctionId, address indexed tokenContract);


    event AuctionClosed(
        uint256 indexed auctionId,
        address indexed bidder,
        uint256 indexed bidAmount,
        uint256 productId,
        bool tokenAwarded,
        bool bidRefunded
    );

    event NewBid(
        uint256 indexed auctionId,
        address indexed bidder,
        uint256 indexed bidAmount,
        Auction auction
    );

    /*//////////////////////////////////////////////////////////////
                        Errors
    //////////////////////////////////////////////////////////////*/

    /// @dev Action requires the finance or admin role
    error FinanceRoleRequired();

    /// @dev Action requires the manager or admin role
    error ManagerRoleRequired();

    /// @dev VIP Sale start must be before or equal to Public Sale start
    error ListingVipStartAfterPubStart(
        uint32 vipStartTimestamp,
        uint32 pubStartTimestamp
    );

    /// @dev Public Sale start must be before sale close
    error ListingPubStartAfterEnd(uint32 pubStartTimestamp, uint32 endTimestamp);

    error ListingReserveExceedsQuantity(uint16 reserved, uint16 quantity);

    error ListingDoesNotExist();

    error ListingPurchasesExceedsQuantity(uint16 quantity, uint256 purchased);

    error ListingPurchasesExceedsReserve(uint16 reserve, uint256 purchased);

    error ListingNotEnabled();

    error ListingHasEnded();

    error ListingQueryInvalidRange();

    error ListingExpectedPriceNotEqualValue(
        uint256 expectedTotalPrice,
        uint256 transactionValue
    );

    error ListingInsufficientQuantity(
        uint256 requestedQuantity,
        uint256 availableQuantity
    );

    error ListingVipSaleNotStarted(uint64 vipStartTime, uint256 currentTimestamp);

    error ListingPublicSaleNotStarted(uint64 publicStartTime, uint256 currentTimestamp);

    error ListingVipLimitExceeded(uint256 purchases, uint256 limit);

    error ListingVipReserveExceeded(uint256 requestedQuantity, uint256 availableQuantity);

    error ListingPublicLimitExceeded(uint256 purchases, uint256 limit);

    error ListingVipExpectedPriceInvalid(
        uint256 expectedTotalPrice,
        uint256 actualTotalPrice
    );

    error ListingPublicExpectedPriceInvalid(
        uint256 expectedTotalPrice,
        uint256 actualTotalPrice
    );

    error AuctionQueryInvalidRange();

    error AuctionStartAfterEnd(uint32 startTimestamp, uint32 endTimestamp);

    error AuctionBufferBpsExceedsMax();

    error AuctionDoesNotExist();

    error AuctionNotActive();

    error AuctionNotEnded(uint32 endTimestamp, uint256 currentTimestamp);

    error AuctionHasBids(uint256 numberOfBids);

    error AuctionHasNoBids();

    error AuctionReserveNotMet(uint256 highestBidAmount, uint256 reserveBidAmount);

    error AuctionReserveWasMet(uint256 highestBidAmount, uint256 reserveBidAmount);

    error AuctionPreviousBidRefundRejected();

    error AuctionNotStarted(uint32 startTimestamp, uint256 currentTimestamp);

    error AuctionHasEnded();

    error AuctionBidAmountZero();

    error AuctionBidBelowMinimum(uint256 bidAmount, uint256 minimumBidAmount);

    error AuctionBidAmountNotEqualValue(uint256 bidAmount, uint256 transactionValue);

    error AuctionBidAmountInsufficient(uint256 bidAmount, uint256 requiredBidAmount);

    error WithdrawalRecipientNotApproved();

    error WithdrawalRecipientRejectedTransfer();

    error WithdrawalInsufficientBalance(uint256 requested, uint256 available);
}

File 7 of 9 : IProductToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

/// @author Syky - Nathan Rempel

interface IProductToken {
    /*//////////////////////////////////////////////////////////////
                        Methods
    //////////////////////////////////////////////////////////////*/

    /// @notice Lets an authorized address mint single NFTs to a recipient.
    function mintTo(address _to, uint256 _productId) external;

    function mintTo(address _to, uint256 _productId, bytes memory _data) external;

    function mintTo(
        address _to,
        uint256 _productId,
        string calldata _uri,
        bytes memory _data
    ) external;

    /// @notice Lets an authorized address mint multiple NFTs at once to a recipient.
    function batchMintTo(address _to, uint256 _productId, uint256 _quantity) external;

    function batchMintTo(
        address _to,
        uint256 _productId,
        uint256 _quantity,
        bytes memory _data
    ) external;

    function batchMintTo(
        address _to,
        uint256 _productId,
        uint256 _quantity,
        string[] calldata _uris,
        bytes memory _data
    ) external;

    /*//////////////////////////////////////////////////////////////
                        Events
    //////////////////////////////////////////////////////////////*/

    /// @dev Emitted when all minting is enabled or disabled
    event GlobalMintingRestricted(bool restricted);

    /// @dev Emitted when all transfers are enabled or disabled
    event GlobalTransfersRestricted(bool restricted);

    /// @dev Emitted when all burning is enabled or disabled
    event GlobalBurningRestricted(bool restricted);

    /*//////////////////////////////////////////////////////////////
                        Errors
    //////////////////////////////////////////////////////////////*/

    /// @dev URIs array length for batch mint must match _quantity
    error BatchMintURICountMismatch();

    /// @dev Action requires the manager or admin role
    error ManagerRoleRequired();

    /// @dev Action requires the minting or admin role
    error MintingRoleRequired();

    /// @dev Minting has been disabled via address(0) role
    error GlobalMintingDisabled();

    /// @dev Transfers have been disabled via address(0) role
    error GlobalTransfersDisabled();

    /// @dev Burning has been disabled via address(0) role
    error GlobalBurningDisabled();
}

File 8 of 9 : IVipManager.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

/// @author Syky - Nathan Rempel

interface IVipManager {
    struct VipConditions {
        GroupConditions groupConditions;
        ProductConditions[] productConditions;
        ERC721Conditions[] erc721Conditions;
        ERC1155Conditions[] erc1155Conditions;
    }

    struct VipConditionsData {
        uint256 productLength;
        uint256 erc721Length;
        uint256 erc1155Length;
        GroupConditions groupConditions;
        mapping(uint256 => ERC721Conditions) erc721Conditions;
        mapping(uint256 => ERC1155ConditionsData) erc1155Conditions;
        mapping(uint256 => ProductConditionsData) productConditions;
    }

    struct GroupConditions {
        address groupContract;
        uint256 groupId;
    }

    struct ERC721Conditions {
        address tokenContract;
    }

    struct ProductConditions {
        address tokenContract;
        uint256[] productIds;
    }

    struct ERC1155Conditions {
        address tokenContract;
        uint256[] tokenIds;
    }

    struct ERC1155ConditionsData {
        address tokenContract;
        uint96 length;
        mapping(uint256 => uint256) tokenIds;
    }

    struct ProductConditionsData {
        address tokenContract;
        uint96 length;
        mapping(uint256 => uint256) productIds;
    }

    function isVip(uint256 _selectorId, address _member) external view returns (bool);

    error ManagerRoleRequired();

    event VipSelectorConditionsUpdated(
        uint256 indexed selectorId,
        uint256 indexed conditionsId
    );

    event VipConditionsUpdated(uint256 indexed conditionsId, VipConditions conditions);
}

File 9 of 9 : ProductMarket.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

/// @author Syky - Nathan Rempel

import "./interface/IProductMarket.sol";
import "./interface/IProductToken.sol";
import "./interface/IVipManager.sol";

import "@thirdweb-dev/contracts/extension/Permissions.sol";
import "@thirdweb-dev/contracts/lib/TWAddress.sol";

contract ProductMarket is IProductMarket, Permissions {
    using TWAddress for address;

    /*//////////////////////////////////////////////////////////////
                            Constants
    //////////////////////////////////////////////////////////////*/

    bytes32 public constant FINANCE_ROLE = keccak256("FINANCE_ROLE");
    bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE");

    /// @dev The max bps of the contract. So, 10_000 == 100 %
    uint64 private constant MAX_BPS = 10_000;

    /*//////////////////////////////////////////////////////////////
                            Mappings
    //////////////////////////////////////////////////////////////*/

    address private _vipContract;

    //counter for total listings created
    uint256 private _totalListings;

    //counter for total auctions created
    uint256 private _totalAuctions;

    //mapping of sale parameters to listingId
    mapping(uint256 => Listing) private _listings;

    //reverse lookup of listings by productId
    mapping(uint256 => ProductLookup) private _productListings;

    //mapping of product token address to listingId
    mapping(uint256 => address) private _listingContracts;

    //mapping of purchases made by an address to listingId
    mapping(uint256 => mapping(address => uint256)) private _listingPurchases;

    //mapping of auction parameters to auctionId
    mapping(uint256 => Auction) private _auctions;

    //reverse lookup of auctions by productId
    mapping(uint256 => ProductLookup) private _productAuctions;

    //mapping of product token address to auctionId
    mapping(uint256 => address) private _auctionContracts;

    //mapping of auction bids to auctionId
    mapping(uint256 => BidHistory) private _auctionBids;

    //mapping of auction bids to address
    mapping(address => BidHistory) private _addressBids;

    //mapping of approved withdrawal addresses
    mapping(address => bool) private _withdrawalApproved;

    /*//////////////////////////////////////////////////////////////
                            Constructor
    //////////////////////////////////////////////////////////////*/

    constructor(address defaultAdmin_, address defaultToken_, address vipContract_) {
        _listingContracts[0] = defaultToken_;
        _auctionContracts[0] = defaultToken_;
        _vipContract = vipContract_;
        _setupRole(DEFAULT_ADMIN_ROLE, defaultAdmin_);
        _setRoleAdmin(FINANCE_ROLE, DEFAULT_ADMIN_ROLE);
        _setRoleAdmin(MANAGER_ROLE, DEFAULT_ADMIN_ROLE);
    }

    /*//////////////////////////////////////////////////////////////
                        Admin functions
    //////////////////////////////////////////////////////////////*/

    function setVipContract(address _vipContract_) external onlyManager {
        _vipContract = _vipContract_;
    }

    function createListing(
        ListingParams calldata _params
    ) external onlyManager returns (uint256 listingId) {
        // overflow is impossible short of 2**256-1 listings being created
        unchecked {
            listingId = ++_totalListings;
        }

        Listing storage listing = _listings[listingId];

        if (_params.pubStartTimestamp < _params.vipStartTimestamp)
            revert ListingVipStartAfterPubStart(
                _params.vipStartTimestamp,
                _params.pubStartTimestamp
            );
        if (_params.endTimestamp <= _params.pubStartTimestamp)
            revert ListingPubStartAfterEnd(
                _params.pubStartTimestamp,
                _params.endTimestamp
            );
        if (_params.quantity < _params.reserved)
            revert ListingReserveExceedsQuantity(_params.reserved, _params.quantity);

        listing.productId = _params.productId;
        listing.enabled = _params.enabled ? 1 : 0;
        listing.quantity = _params.quantity;
        listing.reserved = _params.reserved;
        listing.vipLimit = _params.vipLimit;
        listing.pubLimit = _params.pubLimit;
        listing.vipPrice = _params.vipPrice;
        listing.pubPrice = _params.pubPrice;
        listing.endTimestamp = _params.endTimestamp;
        listing.vipStartTimestamp = _params.vipStartTimestamp;
        listing.pubStartTimestamp = _params.pubStartTimestamp;

        //reverse lookup
        unchecked {
            uint256 reverseIdx = _productListings[_params.productId].count++;
            _productListings[_params.productId].id[reverseIdx] = listingId;
        }

        emit ListingAdded(listingId, listing);
    }

    function updateListing(
        uint256 _listingId,
        ListingParams calldata _params
    ) external onlyManager {
        Listing storage listing = _listings[_listingId];

        if (listing.productId == 0) revert ListingDoesNotExist();
        if (_params.pubStartTimestamp < _params.vipStartTimestamp)
            revert ListingVipStartAfterPubStart(
                _params.vipStartTimestamp,
                _params.pubStartTimestamp
            );
        if (_params.endTimestamp <= _params.pubStartTimestamp)
            revert ListingPubStartAfterEnd(
                _params.pubStartTimestamp,
                _params.endTimestamp
            );
        if (_params.quantity < _params.reserved)
            revert ListingReserveExceedsQuantity(_params.reserved, _params.quantity);

        unchecked {
            uint256 totalPurchased = listing.vipPurchased + listing.pubPurchased;

            if (_params.quantity < totalPurchased)
                revert ListingPurchasesExceedsQuantity(_params.quantity, totalPurchased);
            if (_params.reserved < listing.resPurchased)
                revert ListingPurchasesExceedsReserve(
                    _params.reserved,
                    listing.resPurchased
                );
        }

        listing.enabled = _params.enabled ? 1 : 0;
        listing.quantity = _params.quantity;
        listing.reserved = _params.reserved;
        listing.vipLimit = _params.vipLimit;
        listing.pubLimit = _params.pubLimit;
        listing.vipPrice = _params.vipPrice;
        listing.pubPrice = _params.pubPrice;
        listing.endTimestamp = _params.endTimestamp;
        listing.vipStartTimestamp = _params.vipStartTimestamp;
        listing.pubStartTimestamp = _params.pubStartTimestamp;

        emit ListingUpdated(_listingId, listing);
    }

    function enableListing(uint256 _listingId, bool _enabled) external onlyManager {
        _listings[_listingId].enabled = _enabled ? 1 : 0;
        emit ListingEnabled(_listingId, _enabled);
    }

    function setListingContract(
        uint256 _listingId,
        address _tokenContract
    ) external onlyManager {
        _listingContracts[_listingId] = _tokenContract;
        emit ListingContract(_listingId, _tokenContract);
    }

    function setAuctionContract(
        uint256 _auctionId,
        address _tokenContract
    ) external onlyManager {
        _auctionContracts[_auctionId] = _tokenContract;
        emit AuctionContract(_auctionId, _tokenContract);
    }

    function createAuction(
        AuctionParams calldata _params
    ) external onlyManager returns (uint256 auctionId) {
        unchecked {
            auctionId = ++_totalAuctions;
        }

        Auction storage auction = _auctions[auctionId];

        if (_params.endTimestamp <= _params.startTimestamp)
            revert AuctionStartAfterEnd(_params.startTimestamp, _params.endTimestamp);
        if (MAX_BPS < _params.bidBufferBps) revert AuctionBufferBpsExceedsMax();

        auction.productId = _params.productId;
        auction.status = AuctionStatus.CREATED;
        auction.startTimestamp = _params.startTimestamp;
        auction.endTimestamp = _params.endTimestamp;
        auction.bidBufferBps = _params.bidBufferBps;
        auction.timeBufferSeconds = _params.timeBufferSeconds;
        auction.minimumBidAmount = _params.minimumBidAmount;
        auction.reserveBidAmount = _params.reserveBidAmount;

        unchecked {
            uint256 reverseIdx = _productAuctions[_params.productId].count++;
            _productAuctions[_params.productId].id[reverseIdx] = auctionId;
        }

        emit AuctionAdded(auctionId, auction);
    }

    function updateAuction(
        uint256 _auctionId,
        AuctionParams calldata _params
    ) external onlyManager {
        Auction storage auction = _auctions[_auctionId];

        if (auction.status == AuctionStatus.UNSET) revert AuctionDoesNotExist();
        if (auction.status != AuctionStatus.CREATED) revert AuctionNotActive();
        if (_params.endTimestamp <= _params.startTimestamp)
            revert AuctionStartAfterEnd(_params.startTimestamp, _params.endTimestamp);
        if (MAX_BPS < _params.bidBufferBps) revert AuctionBufferBpsExceedsMax();

        auction.startTimestamp = _params.startTimestamp;
        auction.endTimestamp = _params.endTimestamp;
        auction.bidBufferBps = _params.bidBufferBps;
        auction.timeBufferSeconds = _params.timeBufferSeconds;
        auction.minimumBidAmount = _params.minimumBidAmount;
        auction.reserveBidAmount = _params.reserveBidAmount;

        emit AuctionUpdated(_auctionId, auction);
    }

    function cancelAuction(uint256 _auctionId) external onlyManager {
        Auction storage auction = _auctions[_auctionId];

        if (auction.status == AuctionStatus.UNSET) revert AuctionDoesNotExist();
        if (auction.status != AuctionStatus.CREATED) revert AuctionNotActive();
        if (_auctionBids[_auctionId].count != 0)
            revert AuctionHasBids(_auctionBids[_auctionId].count);

        auction.status = AuctionStatus.CANCELLED;

        emit AuctionCancelled(_auctionId);
    }

    function rewardAuction(
        uint256 _auctionId,
        bool _allowUnmetReserve
    ) external onlyManager {
        Auction storage auction = _auctions[_auctionId];

        if (auction.status == AuctionStatus.UNSET) revert AuctionDoesNotExist();
        if (auction.status != AuctionStatus.CREATED) revert AuctionNotActive();
        if (block.timestamp < auction.endTimestamp)
            revert AuctionNotEnded(auction.endTimestamp, block.timestamp);

        uint256 numberOfBids = _auctionBids[_auctionId].count;
        if (numberOfBids == 0) revert AuctionHasNoBids();

        Bid memory winningBid = _auctionBids[_auctionId].bids[numberOfBids - 1];
        if (winningBid.bidAmount < auction.reserveBidAmount && !_allowUnmetReserve)
            revert AuctionReserveNotMet(winningBid.bidAmount, auction.reserveBidAmount);

        //reentrancy protection
        auction.status = AuctionStatus.COMPLETED;

        IProductToken(getAuctionContract(_auctionId)).mintTo(
            winningBid.bidder,
            auction.productId
        );

        emit AuctionClosed(
            _auctionId,
            winningBid.bidder,
            winningBid.bidAmount,
            auction.productId,
            true,
            false
        );
    }

    function closeAuction(uint256 _auctionId) external onlyManager {
        Auction storage auction = _auctions[_auctionId];

        if (auction.status == AuctionStatus.UNSET) revert AuctionDoesNotExist();
        if (auction.status != AuctionStatus.CREATED) revert AuctionNotActive();
        if (block.timestamp < auction.endTimestamp)
            revert AuctionNotEnded(auction.endTimestamp, block.timestamp);

        uint256 numberOfBids = _auctionBids[_auctionId].count;
        if (numberOfBids == 0) revert AuctionHasNoBids();

        Bid memory winningBid = _auctionBids[_auctionId].bids[numberOfBids - 1];
        if (auction.reserveBidAmount <= winningBid.bidAmount)
            revert AuctionReserveWasMet(winningBid.bidAmount, auction.reserveBidAmount);

        //reentrancy protection
        auction.status = AuctionStatus.COMPLETED;

        (bool success, ) = winningBid.bidder.call{value: winningBid.bidAmount}("");
        if (!success) revert AuctionPreviousBidRefundRejected();

        emit AuctionClosed(
            _auctionId,
            winningBid.bidder,
            winningBid.bidAmount,
            auction.productId,
            false,
            true
        );
    }

    /// @dev Sets `_recipient` as `_approved` for withdrawing income.
    function approveWithdrawalRecipient(
        address _recipient,
        bool _approved
    ) external onlyFinance {
        _withdrawalApproved[_recipient] = _approved;

        emit WithdrawalRecipientApproved(_recipient, _approved);
    }

    /// @dev Transfers `_amount` of native token to `_account`. `_account` must be approved.
    function withdrawIncome(
        address payable _recipient,
        uint256 _amount
    ) external onlyFinance {
        if (address(this).balance < _amount)
            revert WithdrawalInsufficientBalance(_amount, address(this).balance);
        if (!_withdrawalApproved[_recipient]) revert WithdrawalRecipientNotApproved();

        (bool success, ) = _recipient.call{value: _amount}("");
        if (!success) revert WithdrawalRecipientRejectedTransfer();

        emit IncomeWithdrawal(msg.sender, _recipient, _amount);
    }

    /*//////////////////////////////////////////////////////////////
                        Public functions
    //////////////////////////////////////////////////////////////*/

    function buyFromListing(
        uint256 _listingId,
        address _buyFor,
        uint256 _quantity,
        uint256 _expectedTotalPrice
    ) external payable {
        Listing storage listing = _listings[_listingId];

        if (listing.productId == 0) revert ListingDoesNotExist();
        if (listing.enabled == 0) revert ListingNotEnabled();
        if (_expectedTotalPrice != msg.value)
            revert ListingExpectedPriceNotEqualValue(_expectedTotalPrice, msg.value);
        if (listing.endTimestamp < block.timestamp) revert ListingHasEnded();
        unchecked {
            uint256 availableQuantity = listing.quantity -
                (listing.vipPurchased + listing.pubPurchased);

            if (availableQuantity < _quantity)
                revert ListingInsufficientQuantity(_quantity, availableQuantity);
        }

        uint256 listingPurchases = _listingPurchases[_listingId][msg.sender] + _quantity;

        //usually prefer non-duplicate code but this allows for custom messages and less memory use
        if (_checkListingVip(_listingId, msg.sender)) {
            if (block.timestamp < listing.vipStartTimestamp)
                revert ListingVipSaleNotStarted(
                    listing.vipStartTimestamp,
                    block.timestamp
                );
            if (listing.vipLimit < listingPurchases)
                revert ListingVipLimitExceeded(listingPurchases, listing.vipLimit);

            uint256 actualTotalPrice = listing.vipPrice * _quantity;
            if (actualTotalPrice != _expectedTotalPrice)
                revert ListingVipExpectedPriceInvalid(
                    _expectedTotalPrice,
                    actualTotalPrice
                );

            unchecked {
                //if VIP purchases are occuring BEFORE the external window, use the reserve
                if (block.timestamp < listing.pubStartTimestamp) {
                    //not allowed in creation or update to exceed
                    uint256 reserveAvailable = listing.reserved - listing.resPurchased;
                    if (reserveAvailable < _quantity)
                        revert ListingVipReserveExceeded(_quantity, reserveAvailable);
                    listing.resPurchased += uint16(_quantity);
                }

                listing.vipPurchased += uint16(_quantity);
                listing.vipIncome += uint72(_expectedTotalPrice);
            }
        } else {
            if (block.timestamp < listing.pubStartTimestamp)
                revert ListingPublicSaleNotStarted(
                    listing.pubStartTimestamp,
                    block.timestamp
                );
            if (listing.pubLimit < listingPurchases)
                revert ListingPublicLimitExceeded(listingPurchases, listing.pubLimit);

            uint256 actualTotalPrice = listing.pubPrice * _quantity;
            if (actualTotalPrice != _expectedTotalPrice)
                revert ListingPublicExpectedPriceInvalid(
                    _expectedTotalPrice,
                    actualTotalPrice
                );

            unchecked {
                listing.pubPurchased += uint16(_quantity);
                listing.pubIncome += uint72(_expectedTotalPrice);
            }
        }

        //perform updates before transfer to avoid re-entrancy
        _listingPurchases[_listingId][msg.sender] = listingPurchases;

        IProductToken(getListingContract(_listingId)).batchMintTo(
            _buyFor,
            listing.productId,
            _quantity
        );

        emit NewSale(
            _listingId,
            msg.sender,
            _buyFor,
            listing.productId,
            _quantity,
            _expectedTotalPrice
        );
    }

    function bidInAuction(uint256 _auctionId, uint256 _bidAmount) external payable {
        Auction memory auction = _auctions[_auctionId];

        if (auction.status == AuctionStatus.UNSET) revert AuctionDoesNotExist();
        if (auction.status != AuctionStatus.CREATED) revert AuctionNotActive();
        if (block.timestamp < auction.startTimestamp)
            revert AuctionNotStarted(auction.startTimestamp, block.timestamp);
        if (auction.endTimestamp < block.timestamp) revert AuctionHasEnded();
        if (_bidAmount == 0) revert AuctionBidAmountZero();
        if (_bidAmount < auction.minimumBidAmount)
            revert AuctionBidBelowMinimum(_bidAmount, auction.minimumBidAmount);
        if (_bidAmount != msg.value)
            revert AuctionBidAmountNotEqualValue(_bidAmount, msg.value);

        uint256 numberOfBids = _auctionBids[_auctionId].count;
        if (numberOfBids > 0) {
            Bid memory previousBid = _auctionBids[_auctionId].bids[numberOfBids - 1];

            unchecked {
                uint256 requiredBidAmount = previousBid.bidAmount +
                    ((previousBid.bidAmount * auction.bidBufferBps) / MAX_BPS);

                if (_bidAmount < requiredBidAmount)
                    revert AuctionBidAmountInsufficient(_bidAmount, requiredBidAmount);
            }
            (bool success, ) = previousBid.bidder.call{value: previousBid.bidAmount}("");
            if (!success) revert AuctionPreviousBidRefundRejected();

            // Reentrancy protection
            if (_auctionBids[_auctionId].count != numberOfBids) revert();
        }

        unchecked {
            ++_auctionBids[_auctionId].count;
        }

        Bid memory newBid = Bid({
            auctionId: uint64(_auctionId),
            bidTimestamp: uint32(block.timestamp),
            bidder: msg.sender,
            bidAmount: _bidAmount
        });

        _auctionBids[_auctionId].bids[numberOfBids] = newBid;

        unchecked {
            uint256 addressBids = _addressBids[msg.sender].count++;

            _addressBids[msg.sender].bids[addressBids] = newBid;
        }

        if (auction.endTimestamp - block.timestamp <= auction.timeBufferSeconds) {
            unchecked {
                auction.endTimestamp += uint32(auction.timeBufferSeconds);
            }
            _auctions[_auctionId] = auction;
        }

        emit NewBid(_auctionId, msg.sender, _bidAmount, auction);
    }

    /*//////////////////////////////////////////////////////////////
                        Public getters
    //////////////////////////////////////////////////////////////*/

    function getVipContract() external view returns (address) {
        return _vipContract;
    }

    function totalListings() external view returns (uint256) {
        return _totalListings;
    }

    function getListingContract(uint256 _listingId) public view returns (address) {
        if (_listingContracts[_listingId] == address(0)) {
            return _listingContracts[0];
        } else {
            return _listingContracts[_listingId];
        }
    }

    function getListing(
        uint256 _listingId
    ) external view returns (ListingQuery memory _listing) {
        return ListingQuery({listingId: _listingId, listingData: _listings[_listingId]});
    }

    function getAllProductListings(
        uint256 _productId
    ) external view returns (ListingQuery[] memory _allListings) {
        ProductLookup storage productLookup = _productListings[_productId];
        uint256 count = productLookup.count;
        _allListings = new ListingQuery[](count);
        for (uint256 i; i < count; ) {
            uint256 listingId = productLookup.id[i];
            _allListings[i] = ListingQuery({
                listingId: listingId,
                listingData: _listings[listingId]
            });
            unchecked {
                ++i;
            }
        }
    }

    function getAllListings(
        uint256 _startId,
        uint256 _endId
    ) external view returns (ListingQuery[] memory _allListings) {
        if (_startId == 0 || _endId < _startId) revert ListingQueryInvalidRange();
        unchecked {
            uint256 maxId = (_endId > _totalListings ? _totalListings : _endId) + 1;

            _allListings = new ListingQuery[](maxId - _startId);

            for (uint256 i = _startId; i < maxId; ) {
                _allListings[i - _startId] = ListingQuery({
                    listingId: i,
                    listingData: _listings[i]
                });
                ++i;
            }
        }
    }

    function getWithdrawalApproved(address _recipient) external view returns (bool) {
        return _withdrawalApproved[_recipient];
    }

    function totalAuctions() external view returns (uint256) {
        return _totalAuctions;
    }

    function getAuctionContract(uint256 _auctionId) public view returns (address) {
        if (_auctionContracts[_auctionId] == address(0)) {
            return _auctionContracts[0];
        } else {
            return _auctionContracts[_auctionId];
        }
    }

    function getAuction(
        uint256 _auctionId
    ) external view returns (AuctionQuery memory _auction) {
        unchecked {
            uint256 numberOfBids = _auctionBids[_auctionId].count;

            return
                AuctionQuery({
                    auctionId: _auctionId,
                    auctionData: _auctions[_auctionId],
                    winningBid: _auctionBids[_auctionId].bids[
                        numberOfBids > 0 ? numberOfBids - 1 : 0
                    ]
                });
        }
    }

    function getAllProductAuctions(
        uint256 _productId
    ) external view returns (AuctionQuery[] memory _allAuctions) {
        ProductLookup storage productLookup = _productAuctions[_productId];
        uint256 count = productLookup.count;
        _allAuctions = new AuctionQuery[](count);
        for (uint256 i; i < count; ) {
            uint256 auctionId = productLookup.id[i];
            uint256 numberOfBids = _auctionBids[i].count;
            unchecked {
                _allAuctions[i] = AuctionQuery({
                    auctionId: auctionId,
                    auctionData: _auctions[auctionId],
                    winningBid: _auctionBids[auctionId].bids[
                        numberOfBids > 0 ? numberOfBids - 1 : 0
                    ]
                });
                ++i;
            }
        }
    }

    function getAllAuctions(
        uint256 _startId,
        uint256 _endId
    ) external view returns (AuctionQuery[] memory _allAuctions) {
        if (_startId == 0 || _endId < _startId) revert AuctionQueryInvalidRange();
        unchecked {
            uint256 maxId = (_endId > _totalAuctions ? _totalAuctions : _endId) + 1;

            _allAuctions = new AuctionQuery[](maxId - _startId);

            for (uint256 i = _startId; i < maxId; ) {
                uint256 numberOfBids = _auctionBids[i].count;

                _allAuctions[i - _startId] = AuctionQuery({
                    auctionId: i,
                    auctionData: _auctions[i],
                    winningBid: _auctionBids[i].bids[
                        numberOfBids > 0 ? numberOfBids - 1 : 0
                    ]
                });

                ++i;
            }
        }
    }

    function getAuctionBids(
        uint256 _auctionId
    ) external view returns (Bid[] memory _bids) {
        uint256 numberOfBids = _auctionBids[_auctionId].count;
        _bids = new Bid[](numberOfBids);
        for (uint256 i; i < numberOfBids; ) {
            _bids[i] = _auctionBids[_auctionId].bids[i];
            unchecked {
                ++i;
            }
        }
    }

    function getAddressBids(address _bidder) external view returns (Bid[] memory _bids) {
        uint256 numberOfBids = _addressBids[_bidder].count;
        _bids = new Bid[](numberOfBids);
        for (uint256 i; i < numberOfBids; ) {
            _bids[i] = _addressBids[_bidder].bids[i];
            unchecked {
                ++i;
            }
        }
    }

    function getWinningBidAmount(uint256 _auctionId) external view returns (uint256) {
        Auction memory auction = _auctions[_auctionId];
        if (auction.status == AuctionStatus.UNSET) revert AuctionDoesNotExist();

        uint256 numberOfBids = _auctionBids[_auctionId].count;
        if (numberOfBids > 0) {
            unchecked {
                Bid memory previousBid = _auctionBids[_auctionId].bids[numberOfBids - 1];
                return
                    previousBid.bidAmount +
                    ((previousBid.bidAmount * auction.bidBufferBps) / MAX_BPS);
            }
        }

        return auction.minimumBidAmount;
    }

    /*//////////////////////////////////////////////////////////////
                            Modifiers
    //////////////////////////////////////////////////////////////*/

    /// @dev Modifier that checks if an account has admin or finance role; reverts otherwise.
    modifier onlyFinance() {
        _checkFinanceAdmin();
        _;
    }

    /// @dev Modifier that checks if an account has admin or manager role; reverts otherwise.
    modifier onlyManager() {
        _checkManagerAdmin();
        _;
    }

    /*//////////////////////////////////////////////////////////////
                        Internal functions
    //////////////////////////////////////////////////////////////*/

    /// @dev Function that checks if an account has admin or finance role; reverts otherwise.
    function _checkFinanceAdmin() internal view {
        if (
            !hasRole(DEFAULT_ADMIN_ROLE, msg.sender) && !hasRole(FINANCE_ROLE, msg.sender)
        ) {
            revert FinanceRoleRequired();
        }
    }

    /// @dev Function that checks if an account has admin or manager role; reverts otherwise.
    function _checkManagerAdmin() internal view {
        if (
            !hasRole(DEFAULT_ADMIN_ROLE, msg.sender) && !hasRole(MANAGER_ROLE, msg.sender)
        ) {
            revert ManagerRoleRequired();
        }
    }

    function _checkListingVip(
        uint256 _listingId,
        address _member
    ) internal view returns (bool) {
        if (_vipContract != address(0))
            return IVipManager(_vipContract).isVip(_listingId, _member);
        return false;
    }
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"defaultAdmin_","type":"address"},{"internalType":"address","name":"defaultToken_","type":"address"},{"internalType":"address","name":"vipContract_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"bidAmount","type":"uint256"},{"internalType":"uint256","name":"requiredBidAmount","type":"uint256"}],"name":"AuctionBidAmountInsufficient","type":"error"},{"inputs":[{"internalType":"uint256","name":"bidAmount","type":"uint256"},{"internalType":"uint256","name":"transactionValue","type":"uint256"}],"name":"AuctionBidAmountNotEqualValue","type":"error"},{"inputs":[],"name":"AuctionBidAmountZero","type":"error"},{"inputs":[{"internalType":"uint256","name":"bidAmount","type":"uint256"},{"internalType":"uint256","name":"minimumBidAmount","type":"uint256"}],"name":"AuctionBidBelowMinimum","type":"error"},{"inputs":[],"name":"AuctionBufferBpsExceedsMax","type":"error"},{"inputs":[],"name":"AuctionDoesNotExist","type":"error"},{"inputs":[{"internalType":"uint256","name":"numberOfBids","type":"uint256"}],"name":"AuctionHasBids","type":"error"},{"inputs":[],"name":"AuctionHasEnded","type":"error"},{"inputs":[],"name":"AuctionHasNoBids","type":"error"},{"inputs":[],"name":"AuctionNotActive","type":"error"},{"inputs":[{"internalType":"uint32","name":"endTimestamp","type":"uint32"},{"internalType":"uint256","name":"currentTimestamp","type":"uint256"}],"name":"AuctionNotEnded","type":"error"},{"inputs":[{"internalType":"uint32","name":"startTimestamp","type":"uint32"},{"internalType":"uint256","name":"currentTimestamp","type":"uint256"}],"name":"AuctionNotStarted","type":"error"},{"inputs":[],"name":"AuctionPreviousBidRefundRejected","type":"error"},{"inputs":[],"name":"AuctionQueryInvalidRange","type":"error"},{"inputs":[{"internalType":"uint256","name":"highestBidAmount","type":"uint256"},{"internalType":"uint256","name":"reserveBidAmount","type":"uint256"}],"name":"AuctionReserveNotMet","type":"error"},{"inputs":[{"internalType":"uint256","name":"highestBidAmount","type":"uint256"},{"internalType":"uint256","name":"reserveBidAmount","type":"uint256"}],"name":"AuctionReserveWasMet","type":"error"},{"inputs":[{"internalType":"uint32","name":"startTimestamp","type":"uint32"},{"internalType":"uint32","name":"endTimestamp","type":"uint32"}],"name":"AuctionStartAfterEnd","type":"error"},{"inputs":[],"name":"FinanceRoleRequired","type":"error"},{"inputs":[],"name":"ListingDoesNotExist","type":"error"},{"inputs":[{"internalType":"uint256","name":"expectedTotalPrice","type":"uint256"},{"internalType":"uint256","name":"transactionValue","type":"uint256"}],"name":"ListingExpectedPriceNotEqualValue","type":"error"},{"inputs":[],"name":"ListingHasEnded","type":"error"},{"inputs":[{"internalType":"uint256","name":"requestedQuantity","type":"uint256"},{"internalType":"uint256","name":"availableQuantity","type":"uint256"}],"name":"ListingInsufficientQuantity","type":"error"},{"inputs":[],"name":"ListingNotEnabled","type":"error"},{"inputs":[{"internalType":"uint32","name":"pubStartTimestamp","type":"uint32"},{"internalType":"uint32","name":"endTimestamp","type":"uint32"}],"name":"ListingPubStartAfterEnd","type":"error"},{"inputs":[{"internalType":"uint256","name":"expectedTotalPrice","type":"uint256"},{"internalType":"uint256","name":"actualTotalPrice","type":"uint256"}],"name":"ListingPublicExpectedPriceInvalid","type":"error"},{"inputs":[{"internalType":"uint256","name":"purchases","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"ListingPublicLimitExceeded","type":"error"},{"inputs":[{"internalType":"uint64","name":"publicStartTime","type":"uint64"},{"internalType":"uint256","name":"currentTimestamp","type":"uint256"}],"name":"ListingPublicSaleNotStarted","type":"error"},{"inputs":[{"internalType":"uint16","name":"quantity","type":"uint16"},{"internalType":"uint256","name":"purchased","type":"uint256"}],"name":"ListingPurchasesExceedsQuantity","type":"error"},{"inputs":[{"internalType":"uint16","name":"reserve","type":"uint16"},{"internalType":"uint256","name":"purchased","type":"uint256"}],"name":"ListingPurchasesExceedsReserve","type":"error"},{"inputs":[],"name":"ListingQueryInvalidRange","type":"error"},{"inputs":[{"internalType":"uint16","name":"reserved","type":"uint16"},{"internalType":"uint16","name":"quantity","type":"uint16"}],"name":"ListingReserveExceedsQuantity","type":"error"},{"inputs":[{"internalType":"uint256","name":"expectedTotalPrice","type":"uint256"},{"internalType":"uint256","name":"actualTotalPrice","type":"uint256"}],"name":"ListingVipExpectedPriceInvalid","type":"error"},{"inputs":[{"internalType":"uint256","name":"purchases","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"ListingVipLimitExceeded","type":"error"},{"inputs":[{"internalType":"uint256","name":"requestedQuantity","type":"uint256"},{"internalType":"uint256","name":"availableQuantity","type":"uint256"}],"name":"ListingVipReserveExceeded","type":"error"},{"inputs":[{"internalType":"uint64","name":"vipStartTime","type":"uint64"},{"internalType":"uint256","name":"currentTimestamp","type":"uint256"}],"name":"ListingVipSaleNotStarted","type":"error"},{"inputs":[{"internalType":"uint32","name":"vipStartTimestamp","type":"uint32"},{"internalType":"uint32","name":"pubStartTimestamp","type":"uint32"}],"name":"ListingVipStartAfterPubStart","type":"error"},{"inputs":[],"name":"ManagerRoleRequired","type":"error"},{"inputs":[{"internalType":"uint256","name":"requested","type":"uint256"},{"internalType":"uint256","name":"available","type":"uint256"}],"name":"WithdrawalInsufficientBalance","type":"error"},{"inputs":[],"name":"WithdrawalRecipientNotApproved","type":"error"},{"inputs":[],"name":"WithdrawalRecipientRejectedTransfer","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"auctionId","type":"uint256"},{"components":[{"internalType":"uint56","name":"productId","type":"uint56"},{"internalType":"enum IProductMarket.AuctionStatus","name":"status","type":"uint8"},{"internalType":"uint32","name":"startTimestamp","type":"uint32"},{"internalType":"uint32","name":"endTimestamp","type":"uint32"},{"internalType":"uint64","name":"bidBufferBps","type":"uint64"},{"internalType":"uint64","name":"timeBufferSeconds","type":"uint64"},{"internalType":"uint256","name":"minimumBidAmount","type":"uint256"},{"internalType":"uint256","name":"reserveBidAmount","type":"uint256"}],"indexed":false,"internalType":"struct IProductMarket.Auction","name":"auction","type":"tuple"}],"name":"AuctionAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"auctionId","type":"uint256"}],"name":"AuctionCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"auctionId","type":"uint256"},{"indexed":true,"internalType":"address","name":"bidder","type":"address"},{"indexed":true,"internalType":"uint256","name":"bidAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"productId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"tokenAwarded","type":"bool"},{"indexed":false,"internalType":"bool","name":"bidRefunded","type":"bool"}],"name":"AuctionClosed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"auctionId","type":"uint256"},{"indexed":true,"internalType":"address","name":"tokenContract","type":"address"}],"name":"AuctionContract","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"auctionId","type":"uint256"},{"components":[{"internalType":"uint56","name":"productId","type":"uint56"},{"internalType":"enum IProductMarket.AuctionStatus","name":"status","type":"uint8"},{"internalType":"uint32","name":"startTimestamp","type":"uint32"},{"internalType":"uint32","name":"endTimestamp","type":"uint32"},{"internalType":"uint64","name":"bidBufferBps","type":"uint64"},{"internalType":"uint64","name":"timeBufferSeconds","type":"uint64"},{"internalType":"uint256","name":"minimumBidAmount","type":"uint256"},{"internalType":"uint256","name":"reserveBidAmount","type":"uint256"}],"indexed":false,"internalType":"struct IProductMarket.Auction","name":"auction","type":"tuple"}],"name":"AuctionUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"IncomeWithdrawal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"listingId","type":"uint256"},{"components":[{"internalType":"uint24","name":"productId","type":"uint24"},{"internalType":"uint8","name":"enabled","type":"uint8"},{"internalType":"uint16","name":"quantity","type":"uint16"},{"internalType":"uint16","name":"reserved","type":"uint16"},{"internalType":"uint16","name":"vipLimit","type":"uint16"},{"internalType":"uint16","name":"pubLimit","type":"uint16"},{"internalType":"uint64","name":"vipPrice","type":"uint64"},{"internalType":"uint64","name":"pubPrice","type":"uint64"},{"internalType":"uint32","name":"endTimestamp","type":"uint32"},{"internalType":"uint32","name":"vipStartTimestamp","type":"uint32"},{"internalType":"uint32","name":"pubStartTimestamp","type":"uint32"},{"internalType":"uint16","name":"resPurchased","type":"uint16"},{"internalType":"uint16","name":"vipPurchased","type":"uint16"},{"internalType":"uint16","name":"pubPurchased","type":"uint16"},{"internalType":"uint72","name":"vipIncome","type":"uint72"},{"internalType":"uint72","name":"pubIncome","type":"uint72"}],"indexed":false,"internalType":"struct IProductMarket.Listing","name":"listing","type":"tuple"}],"name":"ListingAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"listingId","type":"uint256"},{"indexed":true,"internalType":"address","name":"tokenContract","type":"address"}],"name":"ListingContract","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"listingId","type":"uint256"},{"indexed":true,"internalType":"bool","name":"enabled","type":"bool"}],"name":"ListingEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"listingId","type":"uint256"},{"components":[{"internalType":"uint24","name":"productId","type":"uint24"},{"internalType":"uint8","name":"enabled","type":"uint8"},{"internalType":"uint16","name":"quantity","type":"uint16"},{"internalType":"uint16","name":"reserved","type":"uint16"},{"internalType":"uint16","name":"vipLimit","type":"uint16"},{"internalType":"uint16","name":"pubLimit","type":"uint16"},{"internalType":"uint64","name":"vipPrice","type":"uint64"},{"internalType":"uint64","name":"pubPrice","type":"uint64"},{"internalType":"uint32","name":"endTimestamp","type":"uint32"},{"internalType":"uint32","name":"vipStartTimestamp","type":"uint32"},{"internalType":"uint32","name":"pubStartTimestamp","type":"uint32"},{"internalType":"uint16","name":"resPurchased","type":"uint16"},{"internalType":"uint16","name":"vipPurchased","type":"uint16"},{"internalType":"uint16","name":"pubPurchased","type":"uint16"},{"internalType":"uint72","name":"vipIncome","type":"uint72"},{"internalType":"uint72","name":"pubIncome","type":"uint72"}],"indexed":false,"internalType":"struct IProductMarket.Listing","name":"listing","type":"tuple"}],"name":"ListingUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"auctionId","type":"uint256"},{"indexed":true,"internalType":"address","name":"bidder","type":"address"},{"indexed":true,"internalType":"uint256","name":"bidAmount","type":"uint256"},{"components":[{"internalType":"uint56","name":"productId","type":"uint56"},{"internalType":"enum IProductMarket.AuctionStatus","name":"status","type":"uint8"},{"internalType":"uint32","name":"startTimestamp","type":"uint32"},{"internalType":"uint32","name":"endTimestamp","type":"uint32"},{"internalType":"uint64","name":"bidBufferBps","type":"uint64"},{"internalType":"uint64","name":"timeBufferSeconds","type":"uint64"},{"internalType":"uint256","name":"minimumBidAmount","type":"uint256"},{"internalType":"uint256","name":"reserveBidAmount","type":"uint256"}],"indexed":false,"internalType":"struct IProductMarket.Auction","name":"auction","type":"tuple"}],"name":"NewBid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"listingId","type":"uint256"},{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"productId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"quantity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"NewSale","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":true,"internalType":"bool","name":"approved","type":"bool"}],"name":"WithdrawalRecipientApproved","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ENV","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FINANCE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VER","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"bool","name":"_approved","type":"bool"}],"name":"approveWithdrawalRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_auctionId","type":"uint256"},{"internalType":"uint256","name":"_bidAmount","type":"uint256"}],"name":"bidInAuction","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_listingId","type":"uint256"},{"internalType":"address","name":"_buyFor","type":"address"},{"internalType":"uint256","name":"_quantity","type":"uint256"},{"internalType":"uint256","name":"_expectedTotalPrice","type":"uint256"}],"name":"buyFromListing","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_auctionId","type":"uint256"}],"name":"cancelAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_auctionId","type":"uint256"}],"name":"closeAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint56","name":"productId","type":"uint56"},{"internalType":"uint32","name":"startTimestamp","type":"uint32"},{"internalType":"uint32","name":"endTimestamp","type":"uint32"},{"internalType":"uint64","name":"bidBufferBps","type":"uint64"},{"internalType":"uint64","name":"timeBufferSeconds","type":"uint64"},{"internalType":"uint256","name":"minimumBidAmount","type":"uint256"},{"internalType":"uint256","name":"reserveBidAmount","type":"uint256"}],"internalType":"struct IProductMarket.AuctionParams","name":"_params","type":"tuple"}],"name":"createAuction","outputs":[{"internalType":"uint256","name":"auctionId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint24","name":"productId","type":"uint24"},{"internalType":"uint16","name":"quantity","type":"uint16"},{"internalType":"uint16","name":"reserved","type":"uint16"},{"internalType":"uint16","name":"vipLimit","type":"uint16"},{"internalType":"uint16","name":"pubLimit","type":"uint16"},{"internalType":"uint64","name":"vipPrice","type":"uint64"},{"internalType":"uint64","name":"pubPrice","type":"uint64"},{"internalType":"uint32","name":"endTimestamp","type":"uint32"},{"internalType":"uint32","name":"vipStartTimestamp","type":"uint32"},{"internalType":"uint32","name":"pubStartTimestamp","type":"uint32"},{"internalType":"bool","name":"enabled","type":"bool"}],"internalType":"struct IProductMarket.ListingParams","name":"_params","type":"tuple"}],"name":"createListing","outputs":[{"internalType":"uint256","name":"listingId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_listingId","type":"uint256"},{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"enableListing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_bidder","type":"address"}],"name":"getAddressBids","outputs":[{"components":[{"internalType":"uint64","name":"auctionId","type":"uint64"},{"internalType":"uint32","name":"bidTimestamp","type":"uint32"},{"internalType":"address","name":"bidder","type":"address"},{"internalType":"uint256","name":"bidAmount","type":"uint256"}],"internalType":"struct IProductMarket.Bid[]","name":"_bids","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_startId","type":"uint256"},{"internalType":"uint256","name":"_endId","type":"uint256"}],"name":"getAllAuctions","outputs":[{"components":[{"internalType":"uint256","name":"auctionId","type":"uint256"},{"components":[{"internalType":"uint56","name":"productId","type":"uint56"},{"internalType":"enum IProductMarket.AuctionStatus","name":"status","type":"uint8"},{"internalType":"uint32","name":"startTimestamp","type":"uint32"},{"internalType":"uint32","name":"endTimestamp","type":"uint32"},{"internalType":"uint64","name":"bidBufferBps","type":"uint64"},{"internalType":"uint64","name":"timeBufferSeconds","type":"uint64"},{"internalType":"uint256","name":"minimumBidAmount","type":"uint256"},{"internalType":"uint256","name":"reserveBidAmount","type":"uint256"}],"internalType":"struct IProductMarket.Auction","name":"auctionData","type":"tuple"},{"components":[{"internalType":"uint64","name":"auctionId","type":"uint64"},{"internalType":"uint32","name":"bidTimestamp","type":"uint32"},{"internalType":"address","name":"bidder","type":"address"},{"internalType":"uint256","name":"bidAmount","type":"uint256"}],"internalType":"struct IProductMarket.Bid","name":"winningBid","type":"tuple"}],"internalType":"struct IProductMarket.AuctionQuery[]","name":"_allAuctions","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_startId","type":"uint256"},{"internalType":"uint256","name":"_endId","type":"uint256"}],"name":"getAllListings","outputs":[{"components":[{"internalType":"uint256","name":"listingId","type":"uint256"},{"components":[{"internalType":"uint24","name":"productId","type":"uint24"},{"internalType":"uint8","name":"enabled","type":"uint8"},{"internalType":"uint16","name":"quantity","type":"uint16"},{"internalType":"uint16","name":"reserved","type":"uint16"},{"internalType":"uint16","name":"vipLimit","type":"uint16"},{"internalType":"uint16","name":"pubLimit","type":"uint16"},{"internalType":"uint64","name":"vipPrice","type":"uint64"},{"internalType":"uint64","name":"pubPrice","type":"uint64"},{"internalType":"uint32","name":"endTimestamp","type":"uint32"},{"internalType":"uint32","name":"vipStartTimestamp","type":"uint32"},{"internalType":"uint32","name":"pubStartTimestamp","type":"uint32"},{"internalType":"uint16","name":"resPurchased","type":"uint16"},{"internalType":"uint16","name":"vipPurchased","type":"uint16"},{"internalType":"uint16","name":"pubPurchased","type":"uint16"},{"internalType":"uint72","name":"vipIncome","type":"uint72"},{"internalType":"uint72","name":"pubIncome","type":"uint72"}],"internalType":"struct IProductMarket.Listing","name":"listingData","type":"tuple"}],"internalType":"struct IProductMarket.ListingQuery[]","name":"_allListings","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_productId","type":"uint256"}],"name":"getAllProductAuctions","outputs":[{"components":[{"internalType":"uint256","name":"auctionId","type":"uint256"},{"components":[{"internalType":"uint56","name":"productId","type":"uint56"},{"internalType":"enum IProductMarket.AuctionStatus","name":"status","type":"uint8"},{"internalType":"uint32","name":"startTimestamp","type":"uint32"},{"internalType":"uint32","name":"endTimestamp","type":"uint32"},{"internalType":"uint64","name":"bidBufferBps","type":"uint64"},{"internalType":"uint64","name":"timeBufferSeconds","type":"uint64"},{"internalType":"uint256","name":"minimumBidAmount","type":"uint256"},{"internalType":"uint256","name":"reserveBidAmount","type":"uint256"}],"internalType":"struct IProductMarket.Auction","name":"auctionData","type":"tuple"},{"components":[{"internalType":"uint64","name":"auctionId","type":"uint64"},{"internalType":"uint32","name":"bidTimestamp","type":"uint32"},{"internalType":"address","name":"bidder","type":"address"},{"internalType":"uint256","name":"bidAmount","type":"uint256"}],"internalType":"struct IProductMarket.Bid","name":"winningBid","type":"tuple"}],"internalType":"struct IProductMarket.AuctionQuery[]","name":"_allAuctions","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_productId","type":"uint256"}],"name":"getAllProductListings","outputs":[{"components":[{"internalType":"uint256","name":"listingId","type":"uint256"},{"components":[{"internalType":"uint24","name":"productId","type":"uint24"},{"internalType":"uint8","name":"enabled","type":"uint8"},{"internalType":"uint16","name":"quantity","type":"uint16"},{"internalType":"uint16","name":"reserved","type":"uint16"},{"internalType":"uint16","name":"vipLimit","type":"uint16"},{"internalType":"uint16","name":"pubLimit","type":"uint16"},{"internalType":"uint64","name":"vipPrice","type":"uint64"},{"internalType":"uint64","name":"pubPrice","type":"uint64"},{"internalType":"uint32","name":"endTimestamp","type":"uint32"},{"internalType":"uint32","name":"vipStartTimestamp","type":"uint32"},{"internalType":"uint32","name":"pubStartTimestamp","type":"uint32"},{"internalType":"uint16","name":"resPurchased","type":"uint16"},{"internalType":"uint16","name":"vipPurchased","type":"uint16"},{"internalType":"uint16","name":"pubPurchased","type":"uint16"},{"internalType":"uint72","name":"vipIncome","type":"uint72"},{"internalType":"uint72","name":"pubIncome","type":"uint72"}],"internalType":"struct IProductMarket.Listing","name":"listingData","type":"tuple"}],"internalType":"struct IProductMarket.ListingQuery[]","name":"_allListings","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_auctionId","type":"uint256"}],"name":"getAuction","outputs":[{"components":[{"internalType":"uint256","name":"auctionId","type":"uint256"},{"components":[{"internalType":"uint56","name":"productId","type":"uint56"},{"internalType":"enum IProductMarket.AuctionStatus","name":"status","type":"uint8"},{"internalType":"uint32","name":"startTimestamp","type":"uint32"},{"internalType":"uint32","name":"endTimestamp","type":"uint32"},{"internalType":"uint64","name":"bidBufferBps","type":"uint64"},{"internalType":"uint64","name":"timeBufferSeconds","type":"uint64"},{"internalType":"uint256","name":"minimumBidAmount","type":"uint256"},{"internalType":"uint256","name":"reserveBidAmount","type":"uint256"}],"internalType":"struct IProductMarket.Auction","name":"auctionData","type":"tuple"},{"components":[{"internalType":"uint64","name":"auctionId","type":"uint64"},{"internalType":"uint32","name":"bidTimestamp","type":"uint32"},{"internalType":"address","name":"bidder","type":"address"},{"internalType":"uint256","name":"bidAmount","type":"uint256"}],"internalType":"struct IProductMarket.Bid","name":"winningBid","type":"tuple"}],"internalType":"struct IProductMarket.AuctionQuery","name":"_auction","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_auctionId","type":"uint256"}],"name":"getAuctionBids","outputs":[{"components":[{"internalType":"uint64","name":"auctionId","type":"uint64"},{"internalType":"uint32","name":"bidTimestamp","type":"uint32"},{"internalType":"address","name":"bidder","type":"address"},{"internalType":"uint256","name":"bidAmount","type":"uint256"}],"internalType":"struct IProductMarket.Bid[]","name":"_bids","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_auctionId","type":"uint256"}],"name":"getAuctionContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_listingId","type":"uint256"}],"name":"getListing","outputs":[{"components":[{"internalType":"uint256","name":"listingId","type":"uint256"},{"components":[{"internalType":"uint24","name":"productId","type":"uint24"},{"internalType":"uint8","name":"enabled","type":"uint8"},{"internalType":"uint16","name":"quantity","type":"uint16"},{"internalType":"uint16","name":"reserved","type":"uint16"},{"internalType":"uint16","name":"vipLimit","type":"uint16"},{"internalType":"uint16","name":"pubLimit","type":"uint16"},{"internalType":"uint64","name":"vipPrice","type":"uint64"},{"internalType":"uint64","name":"pubPrice","type":"uint64"},{"internalType":"uint32","name":"endTimestamp","type":"uint32"},{"internalType":"uint32","name":"vipStartTimestamp","type":"uint32"},{"internalType":"uint32","name":"pubStartTimestamp","type":"uint32"},{"internalType":"uint16","name":"resPurchased","type":"uint16"},{"internalType":"uint16","name":"vipPurchased","type":"uint16"},{"internalType":"uint16","name":"pubPurchased","type":"uint16"},{"internalType":"uint72","name":"vipIncome","type":"uint72"},{"internalType":"uint72","name":"pubIncome","type":"uint72"}],"internalType":"struct IProductMarket.Listing","name":"listingData","type":"tuple"}],"internalType":"struct IProductMarket.ListingQuery","name":"_listing","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_listingId","type":"uint256"}],"name":"getListingContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVipContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_auctionId","type":"uint256"}],"name":"getWinningBidAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"}],"name":"getWithdrawalApproved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRoleWithSwitch","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_auctionId","type":"uint256"},{"internalType":"bool","name":"_allowUnmetReserve","type":"bool"}],"name":"rewardAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_auctionId","type":"uint256"},{"internalType":"address","name":"_tokenContract","type":"address"}],"name":"setAuctionContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_listingId","type":"uint256"},{"internalType":"address","name":"_tokenContract","type":"address"}],"name":"setListingContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vipContract_","type":"address"}],"name":"setVipContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalAuctions","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalListings","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_auctionId","type":"uint256"},{"components":[{"internalType":"uint56","name":"productId","type":"uint56"},{"internalType":"uint32","name":"startTimestamp","type":"uint32"},{"internalType":"uint32","name":"endTimestamp","type":"uint32"},{"internalType":"uint64","name":"bidBufferBps","type":"uint64"},{"internalType":"uint64","name":"timeBufferSeconds","type":"uint64"},{"internalType":"uint256","name":"minimumBidAmount","type":"uint256"},{"internalType":"uint256","name":"reserveBidAmount","type":"uint256"}],"internalType":"struct IProductMarket.AuctionParams","name":"_params","type":"tuple"}],"name":"updateAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_listingId","type":"uint256"},{"components":[{"internalType":"uint24","name":"productId","type":"uint24"},{"internalType":"uint16","name":"quantity","type":"uint16"},{"internalType":"uint16","name":"reserved","type":"uint16"},{"internalType":"uint16","name":"vipLimit","type":"uint16"},{"internalType":"uint16","name":"pubLimit","type":"uint16"},{"internalType":"uint64","name":"vipPrice","type":"uint64"},{"internalType":"uint64","name":"pubPrice","type":"uint64"},{"internalType":"uint32","name":"endTimestamp","type":"uint32"},{"internalType":"uint32","name":"vipStartTimestamp","type":"uint32"},{"internalType":"uint32","name":"pubStartTimestamp","type":"uint32"},{"internalType":"bool","name":"enabled","type":"bool"}],"internalType":"struct IProductMarket.ListingParams","name":"_params","type":"tuple"}],"name":"updateListing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawIncome","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b5060405162004e7038038062004e708339810160408190526200003491620001ee565b60008080527f6d5257204ebe7d88fd91ae87941cb2dd9d8062b64ae5a2bd2d28ec40b9fbf6df80546001600160a01b03199081166001600160a01b03868116918217909355600b6020527fdf7de25b7f1fd6d0b5205f0e18f1f35bd7b8d84cce336588d184533ce43a6f7680548316909117905560028054909116918416919091179055839083908390620000ca908462000130565b620000f77f940d6b1946ff1d2b5a9f1909219c3c81a370804b5ba0f91ec0828c99a2e6a681600062000189565b620001247f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b08600062000189565b50505050505062000238565b6000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916600117905551339285917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a45050565b600082815260016020526040808220805490849055905190918391839186917fbd79b86ffe0ab8e8776151514217cd7cacd52c909f66475c3af44e129f0b00ff9190a4505050565b80516001600160a01b0381168114620001e957600080fd5b919050565b6000806000606084860312156200020457600080fd5b6200020f84620001d1565b92506200021f60208501620001d1565b91506200022f60408501620001d1565b90509250925092565b614c2880620002486000396000f3fe6080604052600436106102565760003560e01c8063802c3a3a11610149578063c291537c116100c6578063d9ea95491161008a578063ec87621c11610064578063ec87621c146107d4578063f10f537a14610808578063fc9b5fc81461081b57600080fd5b8063d9ea95491461075b578063e403a2511461077b578063e506dfbe146107b457600080fd5b8063c291537c146106c6578063c5275fb0146106e6578063c78b616c14610706578063c821ec001461071b578063d547741f1461073b57600080fd5b80639c5204711161010d5780639c52047114610633578063a217fddf14610651578063a32fa5b314610666578063a3c8fdd814610686578063b7792b26146106a657600080fd5b8063802c3a3a1461055e57806383f7f09d1461059657806391d14854146105b65780639258d45d146105e657806396b5a7551461061357600080fd5b806331964156116101d7578063499e145a1161019b578063499e145a14610484578063567441f8146104a457806370b4768e146104d157806378bd7935146104fe5780637c6285a11461052b57600080fd5b806331964156146103b2578063349b5954146103d257806336568abe146104065780633c4de40f1461042657806341896c541461046457600080fd5b8063216fd1f51161021e578063216fd1f514610305578063218ddb5714610325578063236ed8f314610345578063248a9ca3146103655780632f2ff15d1461039257600080fd5b80630858e5ad1461025b5780630c269b0b14610270578063107a274a1461029057806316002f4a146102c65780631fcc5b8a146102e5575b600080fd5b61026e610269366004614211565b61083b565b005b34801561027c57600080fd5b5061026e61028b36600461424c565b610f6e565b34801561029c57600080fd5b506102b06102ab36600461427a565b611434565b6040516102bd91906143fa565b60405180910390f35b3480156102d257600080fd5b506004545b6040519081526020016102bd565b3480156102f157600080fd5b5061026e610300366004614421565b611561565b34801561031157600080fd5b5061026e61032036600461444c565b61158b565b34801561033157600080fd5b5061026e610340366004614485565b6115e7565b34801561035157600080fd5b5061026e61036036600461427a565b61165b565b34801561037157600080fd5b506102d761038036600461427a565b60009081526001602052604090205490565b34801561039e57600080fd5b5061026e6103ad3660046144aa565b61190f565b3480156103be57600080fd5b5061026e6103cd3660046144aa565b6119a7565b3480156103de57600080fd5b506102d77f940d6b1946ff1d2b5a9f1909219c3c81a370804b5ba0f91ec0828c99a2e6a68181565b34801561041257600080fd5b5061026e6104213660046144aa565b611a08565b34801561043257600080fd5b5061045760405180604001604052806005815260200164312e302e3160d81b81525081565b6040516102bd91906144f3565b34801561047057600080fd5b5061026e61047f366004614538565b611a6a565b34801561049057600080fd5b506102d761049f36600461455d565b611cbd565b3480156104b057600080fd5b506104c46104bf36600461427a565b6120a5565b6040516102bd919061457a565b3480156104dd57600080fd5b506104f16104ec36600461427a565b61227e565b6040516102bd91906145c9565b34801561050a57600080fd5b5061051e61051936600461427a565b6123a0565b6040516102bd9190614756565b34801561053757600080fd5b50610457604051806040016040528060078152602001661350525393915560ca1b81525081565b34801561056a57600080fd5b5061057e61057936600461427a565b61251a565b6040516001600160a01b0390911681526020016102bd565b3480156105a257600080fd5b5061026e6105b1366004614485565b61258b565b3480156105c257600080fd5b506105d66105d13660046144aa565b61284b565b60405190151581526020016102bd565b3480156105f257600080fd5b5061060661060136600461427a565b612876565b6040516102bd9190614765565b34801561061f57600080fd5b5061026e61062e36600461427a565b612a8a565b34801561063f57600080fd5b506002546001600160a01b031661057e565b34801561065d57600080fd5b506102d7600081565b34801561067257600080fd5b506105d66106813660046144aa565b612b9e565b34801561069257600080fd5b506102d76106a136600461427a565b612bf0565b3480156106b257600080fd5b5061026e6106c13660046147a8565b612d88565b3480156106d257600080fd5b506106066106e1366004614211565b612ea4565b3480156106f257600080fd5b506104c4610701366004614211565b6130e7565b34801561071257600080fd5b506003546102d7565b34801561072757600080fd5b506102d76107363660046147d4565b6132d9565b34801561074757600080fd5b5061026e6107563660046144aa565b613546565b34801561076757600080fd5b506104f1610776366004614421565b61355f565b34801561078757600080fd5b506105d6610796366004614421565b6001600160a01b03166000908152600e602052604090205460ff1690565b3480156107c057600080fd5b5061057e6107cf36600461427a565b613685565b3480156107e057600080fd5b506102d77f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b0881565b61026e6108163660046147f0565b6136f6565b34801561082757600080fd5b5061026e6108363660046144aa565b613c6a565b600082815260096020908152604080832081516101008101909252805466ffffffffffffff811683529192909190830190600160381b900460ff16600381111561088757610887614644565b600381111561089857610898614644565b8152815463ffffffff600160401b820481166020840152600160601b82041660408301526001600160401b03600160801b820481166060840152600160c01b909104166080820152600182015460a082015260029091015460c090910152905060008160200151600381111561091057610910614644565b0361092e5760405163e6759c6760e01b815260040160405180910390fd5b60018160200151600381111561094657610946614644565b14610964576040516334dc687f60e11b815260040160405180910390fd5b806040015163ffffffff164210156109a857604080820151905163ad4db47b60e01b815263ffffffff90911660048201524260248201526044015b60405180910390fd5b42816060015163ffffffff1610156109d35760405163dda144a560e01b815260040160405180910390fd5b816000036109f457604051630d5a8f9960e11b815260040160405180910390fd5b8060c00151821015610a295760c081015160405163013542db60e31b815261099f918491600401918252602082015260400190565b348214610a52576040516334cb937b60e21b81526004810183905234602482015260440161099f565b6000838152600c60205260409020548015610bc2576000848152600c602052604081206001908101908290610a879085614843565b8152602080820192909252604090810160002081516080808201845282546001600160401b038082168452600160401b820463ffffffff1696840196909652600160601b90046001600160a01b031693820193909352600190910154606082018190529186015190935061271092168102919091040180851015610b2857604051631711707760e31b8152600481018690526024810182905260440161099f565b50600081604001516001600160a01b0316826060015160405160006040518083038185875af1925050503d8060008114610b7e576040519150601f19603f3d011682016040523d82523d6000602084013e610b83565b606091505b5050905080610ba557604051634412abcb60e01b815260040160405180910390fd5b6000868152600c60205260409020548314610bbf57600080fd5b50505b600c6000858152602001908152602001600020600001600081546001019190508190555060006040518060800160405280866001600160401b031681526020014263ffffffff168152602001336001600160a01b0316815260200185815250905080600c6000878152602001908152602001600020600101600084815260200190815260200160002060008201518160000160006101000a8154816001600160401b0302191690836001600160401b0316021790555060208201518160000160086101000a81548163ffffffff021916908363ffffffff160217905550604082015181600001600c6101000a8154816001600160a01b0302191690836001600160a01b03160217905550606082015181600101559050506000600d6000336001600160a01b03166001600160a01b03168152602001908152602001600020600001600081548092919060010191905055905081600d6000336001600160a01b03166001600160a01b03168152602001908152602001600020600101600083815260200190815260200160002060008201518160000160006101000a8154816001600160401b0302191690836001600160401b0316021790555060208201518160000160086101000a81548163ffffffff021916908363ffffffff160217905550604082015181600001600c6101000a8154816001600160a01b0302191690836001600160a01b0316021790555060608201518160010155905050508260a001516001600160401b031642846060015163ffffffff16610e019190614843565b11610f245760a083015160608401805190910163ffffffff16905260008581526009602090815260409091208451815466ffffffffffffff19811666ffffffffffffff90921691821783559286015186939091839167ffffffffffffffff191617600160381b836003811115610e7957610e79614644565b0217905550604082015181546060840151608085015160a08601516fffffffffffffffff000000000000000019909316600160401b63ffffffff9586160263ffffffff60601b191617600160601b9490921693909302176fffffffffffffffffffffffffffffffff16600160801b6001600160401b03938416026001600160c01b031617600160c01b929091169190910217815560c0820151600182015560e0909101516002909101555b83336001600160a01b0316867f81b76daaaa20e11a350a2cbf4c8e7c229b6b0bb852585e708b3f6ca5dc25046686604051610f5f9190614856565b60405180910390a45050505050565b610f76613ccb565b60008281526005602052604081208054909162ffffff9091169003610fae576040516335aacf6560e11b815260040160405180910390fd5b610fc061012083016101008401614865565b63ffffffff16610fd861014084016101208501614865565b63ffffffff16101561103157610ff661012083016101008401614865565b61100861014084016101208501614865565b6040516322e2aba560e21b815263ffffffff92831660048201529116602482015260440161099f565b61104361014083016101208401614865565b63ffffffff1661105a610100840160e08501614865565b63ffffffff16116110b15761107761014083016101208401614865565b611088610100840160e08501614865565b604051637a423a8560e01b815263ffffffff92831660048201529116602482015260440161099f565b6110c1606083016040840161488b565b61ffff166110d5604084016020850161488b565b61ffff161015611126576110ef606083016040840161488b565b6110ff604084016020850161488b565b604051635789d79160e11b815261ffff92831660048201529116602482015260440161099f565b6001810154600160501b810461ffff908116600160601b9092048116919091011680611158604085016020860161488b565b61ffff16101561119957611172604084016020850161488b565b60405163721750bd60e11b815261ffff90911660048201526024810182905260440161099f565b6001820154600160401b900461ffff166111b9606085016040860161488b565b61ffff161015611208576111d3606084016040850161488b565b600183015460405163db50aaff60e01b815261ffff9283166004820152600160401b909104909116602482015260440161099f565b5061121b610160830161014084016148af565b611226576000611229565b60015b815460ff9190911663010000000263ff00000019909116178155611253604083016020840161488b565b815461ffff91909116600160201b0265ffff0000000019909116178155611280606083016040840161488b565b815461ffff91909116600160301b0267ffff000000000000199091161781556112af608083016060840161488b565b815461ffff91909116600160401b0261ffff60401b199091161781556112db60a083016080840161488b565b815461ffff91909116600160501b0261ffff60501b1990911617815561130760c0830160a084016148cc565b81546001600160401b0391909116600160601b0267ffffffffffffffff60601b1990911617815561133e60e0830160c084016148cc565b81546001600160401b0391909116600160a01b0267ffffffffffffffff60a01b19909116178155611376610100830160e08401614865565b815463ffffffff91909116600160e01b026001600160e01b039091161781556113a761012083016101008401614865565b60018201805463ffffffff191663ffffffff929092169190911790556113d561014083016101208401614865565b8160010160046101000a81548163ffffffff021916908363ffffffff160217905550827fec7aa23b1f28f22e8d710a736df8f4b309ee41f3f210a4091c67dad2ee3e6bf58260405161142791906148f5565b60405180910390a2505050565b61143c6140f8565b5060408051808201825282815260009283526005602090815292829020825161020081018452815462ffffff811682526301000000810460ff1682870152600160201b80820461ffff90811696840196909652600160301b820486166060840152600160401b80830487166080850152600160501b808404881660a0860152600160601b8085046001600160401b0390811660c0880152600160a01b86041660e0870152600160e01b90940463ffffffff90811661010087015260019096015480871661012087015292830490951661014085015281048616610160840152928304851661018083015282049093166101a0840152600160701b810468ffffffffffffffffff9081166101c0850152600160b81b909104166101e08301529182015290565b611569613ccb565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b611593613d2a565b6001600160a01b0382166000818152600e6020526040808220805460ff191685151590811790915590519092917f215f66273fb517a22736277e280b3ea8a0b7db6ed54f2edb25b1cbd87e3c28ca91a35050565b6115ef613ccb565b806115fb5760006115fe565b60015b600083815260056020526040808220805460ff9490941663010000000263ff000000199094169390931790925590518215159184917f3f3590113b880e5ffacda884287cb609f87652a7522ba040e52d072f9179e9b09190a35050565b611663613ccb565b6000818152600960205260408120908154600160381b900460ff16600381111561168f5761168f614644565b036116ad5760405163e6759c6760e01b815260040160405180910390fd5b60018154600160381b900460ff1660038111156116cc576116cc614644565b146116ea576040516334dc687f60e11b815260040160405180910390fd5b8054600160601b900463ffffffff164210156117305780546040516336cc6d4f60e21b8152600160601b90910463ffffffff16600482015242602482015260440161099f565b6000828152600c602052604081205490819003611760576040516359a67b3d60e01b815260040160405180910390fd5b6000838152600c6020526040812060019081019082906117809085614843565b81526020808201929092526040908101600020815160808101835281546001600160401b0381168252600160401b810463ffffffff1694820194909452600160601b9093046001600160a01b03169183019190915260010154606082018190526002850154919250106118195760608101516002840154604051637e4b9d7d60e01b81526004810192909252602482015260440161099f565b825460ff60381b1916670200000000000000178355604081810151606083015191516000926001600160a01b0390921691908381818185875af1925050503d8060008114611883576040519150601f19603f3d011682016040523d82523d6000602084013e611888565b606091505b50509050806118aa57604051634412abcb60e01b815260040160405180910390fd5b6060828101516040808501518754825166ffffffffffffff90911681526000602082015260019281019290925291926001600160a01b039092169188917f46b848163e03f83edace353ba36892b6d49697bebcbe7aea9f837c69cd5851479101610f5f565b6000828152600160205260409020546119289033613d86565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16156119995760405162461bcd60e51b815260206004820152601d60248201527f43616e206f6e6c79206772616e7420746f206e6f6e20686f6c64657273000000604482015260640161099f565b6119a38282613e04565b5050565b6119af613ccb565b60008281526007602052604080822080546001600160a01b0319166001600160a01b0385169081179091559051909184917f7bda5ebb0c6f5079561a878d9b8fa1fd8e2443210022b1e25de894fea02509479190a35050565b336001600160a01b03821614611a605760405162461bcd60e51b815260206004820152601a60248201527f43616e206f6e6c792072656e6f756e636520666f722073656c66000000000000604482015260640161099f565b6119a38282613e5d565b611a72613ccb565b6000828152600960205260408120908154600160381b900460ff166003811115611a9e57611a9e614644565b03611abc5760405163e6759c6760e01b815260040160405180910390fd5b60018154600160381b900460ff166003811115611adb57611adb614644565b14611af9576040516334dc687f60e11b815260040160405180910390fd5b611b096040830160208401614865565b63ffffffff16611b1f6060840160408501614865565b63ffffffff1611611b7357611b3a6040830160208401614865565b611b4a6060840160408501614865565b6040516377acf3f160e11b815263ffffffff92831660048201529116602482015260440161099f565b611b8360808301606084016148cc565b6001600160401b03166127101015611bae57604051631594b46760e21b815260040160405180910390fd5b611bbe6040830160208401614865565b815463ffffffff91909116600160401b0263ffffffff60401b19909116178155611bee6060830160408401614865565b815463ffffffff91909116600160601b0263ffffffff60601b19909116178155611c1e60808301606084016148cc565b81546001600160401b0391909116600160801b0267ffffffffffffffff60801b19909116178155611c5560a08301608084016148cc565b81546001600160401b0391909116600160c01b026001600160c01b0390911617815560a0820135600182015560c0820135600282015560405183907f719a0c86470e9c93a183ded6bca73369f7e28afe0beec0a19f90763aae17323b90611427908490614a13565b6000611cc7613ccb565b5060038054600101908190556000818152600560205260409020611cf361012084016101008501614865565b63ffffffff16611d0b61014085016101208601614865565b63ffffffff161015611d3b57611d2961012084016101008501614865565b61100861014085016101208601614865565b611d4d61014084016101208501614865565b63ffffffff16611d64610100850160e08601614865565b63ffffffff1611611d9257611d8161014084016101208501614865565b611088610100850160e08601614865565b611da2606084016040850161488b565b61ffff16611db6604085016020860161488b565b61ffff161015611de057611dd0606084016040850161488b565b6110ff604085016020860161488b565b611ded6020840184614aa5565b815462ffffff191662ffffff91909116178155611e12610160840161014085016148af565b611e1d576000611e20565b60015b815460ff9190911663010000000263ff00000019909116178155611e4a604084016020850161488b565b815461ffff91909116600160201b0265ffff0000000019909116178155611e77606084016040850161488b565b815461ffff91909116600160301b0267ffff00000000000019909116178155611ea6608084016060850161488b565b815461ffff91909116600160401b0261ffff60401b19909116178155611ed260a084016080850161488b565b815461ffff91909116600160501b0261ffff60501b19909116178155611efe60c0840160a085016148cc565b81546001600160401b0391909116600160601b0267ffffffffffffffff60601b19909116178155611f3560e0840160c085016148cc565b81546001600160401b0391909116600160a01b0267ffffffffffffffff60a01b19909116178155611f6d610100840160e08501614865565b815463ffffffff91909116600160e01b026001600160e01b03909116178155611f9e61012084016101008501614865565b60018201805463ffffffff191663ffffffff92909216919091179055611fcc61014084016101208501614865565b60018201805463ffffffff92909216600160201b0267ffffffff000000001990921691909117905560006006816120066020870187614aa5565b62ffffff1681526020808201929092526040016000908120805460018101909155925084916006919061203b90880188614aa5565b62ffffff16815260200190815260200160002060010160008381526020019081526020016000208190555050817f7efa901ffa0a63f7fe1fda3e997b815c85bd90c454df0cc44818c4ba326d81fb8260405161209791906148f5565b60405180910390a250919050565b6000818152600660205260409020805460609190806001600160401b038111156120d1576120d1614aca565b60405190808252806020026020018201604052801561210a57816020015b6120f76140f8565b8152602001906001900390816120ef5790505b50925060005b8181101561227657600081815260018085016020908152604080842054815180830183528181528186526005845294829020825161020081018452815462ffffff8116825260ff63010000008204168287015261ffff600160201b808304821696840196909652600160301b820481166060840152600160401b80830482166080850152600160501b808404831660a08601526001600160401b03600160601b808604821660c0880152600160a01b860490911660e087015263ffffffff600160e01b90950485166101008701529590990154808416610120860152968704909216610140840152908504811661016083015295840486166101808201529083049094166101a085015268ffffffffffffffffff600160701b830481166101c0860152600160b81b9092049091166101e084015290830191909152855190919086908490811061226257612262614ae0565b602090810291909101015250600101612110565b505050919050565b6000818152600c6020526040902054606090806001600160401b038111156122a8576122a8614aca565b6040519080825280602002602001820160405280156122fa57816020015b6040805160808101825260008082526020808301829052928201819052606082015282526000199092019101816122c65790505b50915060005b81811015612399576000848152600c602090815260408083208484526001908101835292819020815160808101835281546001600160401b0381168252600160401b810463ffffffff1694820194909452600160601b9093046001600160a01b031691830191909152909101546060820152835184908390811061238657612386614ae0565b6020908102919091010152600101612300565b5050919050565b6123a861418c565b6000828152600c60209081526040808320548151606081018352868152868552600984529382902082516101008101909352805466ffffffffffffff81168452919493848101939290830190600160381b900460ff16600381111561240f5761240f614644565b600381111561242057612420614644565b8152815463ffffffff600160401b82048116602080850191909152600160601b83049091166040808501919091526001600160401b03600160801b840481166060860152600160c01b909304909216608084015260018085015460a085015260029094015460c0909301929092529284526000888152600c82529283209301920190846124ae5760006124b3565b600185035b81526020808201929092526040908101600020815160808101835281546001600160401b0381168252600160401b810463ffffffff1694820194909452600160601b9093046001600160a01b03169183019190915260010154606082015290529392505050565b6000818152600760205260408120546001600160a01b031661256f5750506000805260076020527f6d5257204ebe7d88fd91ae87941cb2dd9d8062b64ae5a2bd2d28ec40b9fbf6df546001600160a01b031690565b506000908152600760205260409020546001600160a01b031690565b612593613ccb565b6000828152600960205260408120908154600160381b900460ff1660038111156125bf576125bf614644565b036125dd5760405163e6759c6760e01b815260040160405180910390fd5b60018154600160381b900460ff1660038111156125fc576125fc614644565b1461261a576040516334dc687f60e11b815260040160405180910390fd5b8054600160601b900463ffffffff164210156126605780546040516336cc6d4f60e21b8152600160601b90910463ffffffff16600482015242602482015260440161099f565b6000838152600c602052604081205490819003612690576040516359a67b3d60e01b815260040160405180910390fd5b6000848152600c6020526040812060019081019082906126b09085614843565b81526020808201929092526040908101600020815160808101835281546001600160401b0381168252600160401b810463ffffffff1694820194909452600160601b9093046001600160a01b03169183019190915260010154606082018190526002850154919250108015612723575083155b156127545760608101516002840154604051635cf8b88960e11b81526004810192909252602482015260440161099f565b825460ff60381b191667020000000000000017835561277285613685565b604082810151855491516308934a5f60e31b81526001600160a01b03918216600482015266ffffffffffffff9092166024830152919091169063449a52f890604401600060405180830381600087803b1580156127ce57600080fd5b505af11580156127e2573d6000803e3d6000fd5b505050506060818101516040808401518654825166ffffffffffffff90911681526001602082015260009281019290925291926001600160a01b039092169188917f46b848163e03f83edace353ba36892b6d49697bebcbe7aea9f837c69cd5851479101610f5f565b6000828152602081815260408083206001600160a01b038516845290915290205460ff165b92915050565b6000818152600a60205260409020805460609190806001600160401b038111156128a2576128a2614aca565b6040519080825280602002602001820160405280156128db57816020015b6128c861418c565b8152602001906001900390816128c05790505b50925060005b81811015612276576000818152600184016020908152604080832054600c8352818420548251606081018452828152828652600985529483902083516101008101909452805466ffffffffffffff81168552929591949193848301939092830190600160381b900460ff16600381111561295d5761295d614644565b600381111561296e5761296e614644565b8152815463ffffffff600160401b82048116602080850191909152600160601b83049091166040808501919091526001600160401b03600160801b840481166060860152600160c01b909304909216608084015260018085015460a085015260029094015460c0909301929092529284526000878152600c82529283209301920190846129fc576000612a01565b600185035b81526020808201929092526040908101600020815160808101835281546001600160401b0381168252600160401b810463ffffffff1694820194909452600160601b9093046001600160a01b03169183019190915260010154606082015290528651879085908110612a7557612a75614ae0565b602090810291909101015250506001016128e1565b612a92613ccb565b6000818152600960205260408120908154600160381b900460ff166003811115612abe57612abe614644565b03612adc5760405163e6759c6760e01b815260040160405180910390fd5b60018154600160381b900460ff166003811115612afb57612afb614644565b14612b19576040516334dc687f60e11b815260040160405180910390fd5b6000828152600c602052604090205415612b5a576000828152600c602052604090819020549051636761e76160e11b8152600481019190915260240161099f565b805460ff60381b191667030000000000000017815560405182907f2809c7e17bf978fbc7194c0a694b638c4215e9140cacc6c38ca36010b45697df90600090a25050565b60008281526020818152604080832083805290915281205460ff16612be757506000828152602081815260408083206001600160a01b038516845290915290205460ff16612870565b50600192915050565b600081815260096020908152604080832081516101008101909252805466ffffffffffffff811683528493830190600160381b900460ff166003811115612c3957612c39614644565b6003811115612c4a57612c4a614644565b8152815463ffffffff600160401b820481166020840152600160601b82041660408301526001600160401b03600160801b820481166060840152600160c01b909104166080820152600182015460a082015260029091015460c0909101529050600081602001516003811115612cc257612cc2614644565b03612ce05760405163e6759c6760e01b815260040160405180910390fd5b6000838152600c60205260409020548015612d7d576000938452600c60209081526040808620600019939093018652600192830182529485902085516080808201885282546001600160401b038082168452600160401b820463ffffffff1695840195909552600160601b90046001600160a01b031697820197909752920154606090920182905291909301516127109116830204909101919050565b5060c0015192915050565b612d90613d2a565b80471015612dba57604051635f938ce560e11b81526004810182905247602482015260440161099f565b6001600160a01b0382166000908152600e602052604090205460ff16612df35760405163b13347ad60e01b815260040160405180910390fd5b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612e40576040519150601f19603f3d011682016040523d82523d6000602084013e612e45565b606091505b5050905080612e675760405163df108a3b60e01b815260040160405180910390fd5b60405182906001600160a01b0385169033907fd1b078762514fc24641f0f647e92ba3f15f4cb8e732e84ce1d2686f15542837190600090a4505050565b6060821580612eb257508282105b15612ed0576040516304d8557760e31b815260040160405180910390fd5b60006004548311612ee15782612ee5565b6004545b60010190508381036001600160401b03811115612f0457612f04614aca565b604051908082528060200260200182016040528015612f3d57816020015b612f2a61418c565b815260200190600190039081612f225790505b509150835b818110156130df576000818152600c60209081526040808320548151606081018352858152858552600984529382902082516101008101909352805466ffffffffffffff81168452919493848101939290830190600160381b900460ff166003811115612fb157612fb1614644565b6003811115612fc257612fc2614644565b8152815463ffffffff600160401b82048116602080850191909152600160601b83049091166040808501919091526001600160401b03600160801b840481166060860152600160c01b909304909216608084015260018085015460a085015260029094015460c0909301929092529284526000878152600c8252928320930192019084613050576000613055565b600185035b81526020808201929092526040908101600020815160808101835281546001600160401b0381168252600160401b810463ffffffff1694820194909452600160601b9093046001600160a01b0316918301919091526001015460608201529052845185908885039081106130cb576130cb614ae0565b602090810291909101015250600101612f42565b505092915050565b60608215806130f557508282105b15613113576040516313e95aa760e21b815260040160405180910390fd5b600060035483116131245782613128565b6003545b60010190508381036001600160401b0381111561314757613147614aca565b60405190808252806020026020018201604052801561318057816020015b61316d6140f8565b8152602001906001900390816131655790505b509150835b818110156130df5760408051808201825282815260008381526005602090815290839020835161020081018552815462ffffff811682526301000000810460ff1682850152600160201b80820461ffff90811697840197909752600160301b820487166060840152600160401b80830488166080850152600160501b808404891660a0860152600160601b8085046001600160401b0390811660c0880152600160a01b86041660e0870152600160e01b90940463ffffffff90811661010087015260019096015480871661012087015292830490951661014085015281048716610160840152928304861661018083015282049094166101a0850152600160701b810468ffffffffffffffffff9081166101c0860152600160b81b909104166101e0840152810191909152835184908784039081106132c6576132c6614ae0565b6020908102919091010152600101613185565b60006132e3613ccb565b5060048054600101908190556000818152600960209081526040918290209161331191908501908501614865565b63ffffffff166133276060850160408601614865565b63ffffffff1611613352576133426040840160208501614865565b611b4a6060850160408601614865565b61336260808401606085016148cc565b6001600160401b0316612710101561338d57604051631594b46760e21b815260040160405180910390fd5b61339a6020840184614af6565b815466ffffffffffffff9190911667ffffffffffffffff1990911617600160381b1781556133ce6040840160208501614865565b815463ffffffff91909116600160401b0263ffffffff60401b199091161781556133fe6060840160408501614865565b815463ffffffff91909116600160601b0263ffffffff60601b1990911617815561342e60808401606085016148cc565b81546001600160401b0391909116600160801b0267ffffffffffffffff60801b1990911617815561346560a08401608085016148cc565b81546001600160401b0391909116600160c01b026001600160c01b0390911617815560a0830135600182015560c083013560028201556000600a816134ad6020870187614af6565b66ffffffffffffff168152602080820192909252604001600090812080546001810190915592508491600a91906134e690880188614af6565b66ffffffffffffff16815260200190815260200160002060010160008381526020019081526020016000208190555050817f6ecb6e63f6645ff9293c33fc77c67f1bc05beff9ff71806d5c759647b3d2d402826040516120979190614a13565b600082815260016020526040902054611a609033613d86565b6001600160a01b0381166000908152600d6020526040902054606090806001600160401b0381111561359357613593614aca565b6040519080825280602002602001820160405280156135e557816020015b6040805160808101825260008082526020808301829052928201819052606082015282526000199092019101816135b15790505b50915060005b81811015612399576001600160a01b038085166000908152600d602090815260408083208584526001908101835292819020815160808101835281546001600160401b038116825263ffffffff600160401b82041694820194909452600160601b909304909416908201529101546060820152835184908390811061367257613672614ae0565b60209081029190910101526001016135eb565b6000818152600b60205260408120546001600160a01b03166136da57505060008052600b6020527fdf7de25b7f1fd6d0b5205f0e18f1f35bd7b8d84cce336588d184533ce43a6f76546001600160a01b031690565b506000908152600b60205260409020546001600160a01b031690565b60008481526005602052604081208054909162ffffff909116900361372e576040516335aacf6560e11b815260040160405180910390fd5b80546301000000900460ff1660000361375a57604051635acda82f60e01b815260040160405180910390fd5b34821461378357604051631162ee2d60e21b81526004810183905234602482015260440161099f565b805442600160e01b90910463ffffffff1610156137b3576040516389d4186960e01b815260040160405180910390fd5b60018101548154600160501b820461ffff908116600160601b909304811692909201600160201b909104821603168381101561380c57604051630d27c2b960e41b8152600481018590526024810182905260440161099f565b506000858152600860209081526040808320338452909152812054613832908590614b1f565b905061383e8633613ebd565b15613a1557600182015463ffffffff16421015613882576001820154604051637283b3fb60e01b815263ffffffff909116600482015242602482015260440161099f565b8154600160401b900461ffff168111156138c5578154604051632fda893760e21b815260048101839052600160401b90910461ffff16602482015260440161099f565b81546000906138e5908690600160601b90046001600160401b0316614b32565b905083811461391157604051630bf76b4560e41b8152600481018590526024810182905260440161099f565b6001830154600160201b900463ffffffff1642101561399d576001830154835461ffff600160401b9092048216600160301b909104821603168581101561397557604051631386b05760e01b8152600481018790526024810182905260440161099f565b5060018301805461ffff600160401b808304821689019091160261ffff60401b199091161790555b5060018201805468ffffffffffffffffff600160701b61ffff600160501b80850482168a019091160261ffff60501b1984168117829004831688019092160268ffffffffffffffffff60701b1990911676ffffffffffffffffff0000ffff000000000000000000001990921691909117179055613b76565b6001820154600160201b900463ffffffff16421015613a615760018201546040516381c5e80b60e01b8152600160201b90910463ffffffff16600482015242602482015260440161099f565b8154600160501b900461ffff16811115613aa457815460405163180da9c560e31b815260048101839052600160501b90910461ffff16602482015260440161099f565b8154600090613ac4908690600160a01b90046001600160401b0316614b32565b9050838114613af0576040516396e80d5560e01b8152600481018590526024810182905260440161099f565b5060018201805468ffffffffffffffffff600160b81b61ffff600160601b80850482168a01909116026dffff0000000000000000000000001984168117829004831688019092160276ffffffffffffffffffffffffffffffffffffffffffffff90911676ffffffffffffffffff0000ffffffffffffffffffffffff909216919091171790555b60008681526008602090815260408083203384529091529020819055613b9b8661251a565b8254604051632c7ef07760e01b81526001600160a01b03888116600483015262ffffff909216602482015260448101879052911690632c7ef07790606401600060405180830381600087803b158015613bf357600080fd5b505af1158015613c07573d6000803e3d6000fd5b505083546040805162ffffff90921682526020820188905281018690526001600160a01b038816925033915088907f964be453e8b19c8fc2d856baaaeb5c6db9607b1f52fdff3f0a1e6cef6ac3bd019060600160405180910390a4505050505050565b613c72613ccb565b6000828152600b602052604080822080546001600160a01b0319166001600160a01b0385169081179091559051909184917f8829ff1f8d6f20e53e317d9e72d94b852e0d669afb69b39a2b7d1923da57f5c09190a35050565b613cd660003361284b565b158015613d0a5750613d087f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b083361284b565b155b15613d28576040516349349c6360e11b815260040160405180910390fd5b565b613d3560003361284b565b158015613d695750613d677f940d6b1946ff1d2b5a9f1909219c3c81a370804b5ba0f91ec0828c99a2e6a6813361284b565b155b15613d285760405162afd36160e01b815260040160405180910390fd5b6000828152602081815260408083206001600160a01b038516845290915290205460ff166119a357613dc2816001600160a01b03166014613f56565b613dcd836020613f56565b604051602001613dde929190614b49565b60408051601f198184030181529082905262461bcd60e51b825261099f916004016144f3565b6000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916600117905551339285917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a45050565b613e678282613d86565b6000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6002546000906001600160a01b031615613f4d57600254604051636c096c6d60e11b8152600481018590526001600160a01b0384811660248301529091169063d812d8da90604401602060405180830381865afa158015613f22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f469190614bbe565b9050612870565b50600092915050565b60606000613f65836002614b32565b613f70906002614b1f565b6001600160401b03811115613f8757613f87614aca565b6040519080825280601f01601f191660200182016040528015613fb1576020820181803683370190505b509050600360fc1b81600081518110613fcc57613fcc614ae0565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613ffb57613ffb614ae0565b60200101906001600160f81b031916908160001a905350600061401f846002614b32565b61402a906001614b1f565b90505b60018111156140a2576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061405e5761405e614ae0565b1a60f81b82828151811061407457614074614ae0565b60200101906001600160f81b031916908160001a90535060049490941c9361409b81614bdb565b905061402d565b5083156140f15760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161099f565b9392505050565b60408051808201825260008082528251610200810184528181526020818101839052938101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e0810191909152909182015290565b6040518060600160405280600081526020016141e760408051610100810190915260008082526020820190815260006020820181905260408201819052606082018190526080820181905260a0820181905260c09091015290565b81526040805160808101825260008082526020828101829052928201819052606082015291015290565b6000806040838503121561422457600080fd5b50508035926020909101359150565b6000610160828403121561424657600080fd5b50919050565b600080610180838503121561426057600080fd5b823591506142718460208501614233565b90509250929050565b60006020828403121561428c57600080fd5b5035919050565b8051825260208101516142ae60208401825162ffffff169052565b602081015160ff8116604085015250604081015161ffff8116606085015250606081015161ffff8116608085015250608081015161ffff811660a08501525060a081015161ffff811660c08501525060c08101516001600160401b03811660e08501525060e081015161010061432e818601836001600160401b03169052565b82015190506101206143478582018363ffffffff169052565b82015190506101406143608582018363ffffffff169052565b82015190506101606143798582018363ffffffff169052565b82015190506101806143908582018361ffff169052565b82015190506101a06143a78582018361ffff169052565b82015190506101c06143be8582018361ffff169052565b82015190506101e06143dc8582018368ffffffffffffffffff169052565b919091015168ffffffffffffffffff81166102008501529050505050565b61022081016128708284614293565b6001600160a01b038116811461441e57600080fd5b50565b60006020828403121561443357600080fd5b81356140f181614409565b801515811461441e57600080fd5b6000806040838503121561445f57600080fd5b823561446a81614409565b9150602083013561447a8161443e565b809150509250929050565b6000806040838503121561449857600080fd5b82359150602083013561447a8161443e565b600080604083850312156144bd57600080fd5b82359150602083013561447a81614409565b60005b838110156144ea5781810151838201526020016144d2565b50506000910152565b60208152600082518060208401526145128160408501602087016144cf565b601f01601f19169190910160400192915050565b600060e0828403121561424657600080fd5b600080610100838503121561454c57600080fd5b823591506142718460208501614526565b6000610160828403121561457057600080fd5b6140f18383614233565b6020808252825182820181905260009190848201906040850190845b818110156145bd576145a9838551614293565b928401926102209290920191600101614596565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156145bd576146318385516001600160401b03815116825263ffffffff60208201511660208301526001600160a01b036040820151166040830152606081015160608301525050565b92840192608092909201916001016145e5565b634e487b7160e01b600052602160045260246000fd5b6004811061467857634e487b7160e01b600052602160045260246000fd5b9052565b66ffffffffffffff8151168252602081015161469b602084018261465a565b50604081015163ffffffff8082166040850152806060840151166060850152505060808101516001600160401b0380821660808501528060a08401511660a0850152505060c081015160c083015260e081015160e08301525050565b80518252602081015161470d602084018261467c565b5060409081015180516001600160401b0316610120840152602081015163ffffffff16610140840152908101516001600160a01b03166101608301526060015161018090910152565b6101a0810161287082846146f7565b6020808252825182820181905260009190848201906040850190845b818110156145bd576147948385516146f7565b928401926101a09290920191600101614781565b600080604083850312156147bb57600080fd5b82356147c681614409565b946020939093013593505050565b600060e082840312156147e657600080fd5b6140f18383614526565b6000806000806080858703121561480657600080fd5b84359350602085013561481881614409565b93969395505050506040820135916060013590565b634e487b7160e01b600052601160045260246000fd5b818103818111156128705761287061482d565b6101008101612870828461467c565b60006020828403121561487757600080fd5b813563ffffffff811681146140f157600080fd5b60006020828403121561489d57600080fd5b813561ffff811681146140f157600080fd5b6000602082840312156148c157600080fd5b81356140f18161443e565b6000602082840312156148de57600080fd5b81356001600160401b03811681146140f157600080fd5b815462ffffff81168252610200820190601881901c60ff16602084015261ffff602082901c8116604085015261493660608501828460301c1661ffff169052565b61494b60808501828460401c1661ffff169052565b61496060a08501828460501c1661ffff169052565b6001600160401b03606083901c811660c086015260a083901c1660e0808601919091529190911c610100840152600184015463ffffffff808216610120860152602082901c16610140850152604081901c821661ffff16610160850152906149d46101808501828460501c1661ffff169052565b6149ea6101a08501828460601c1661ffff169052565b50607081901c68ffffffffffffffffff166101c084015260b881901c6101e08401525092915050565b815466ffffffffffffff81168252610100820190614a3b60208401603883901c60ff1661465a565b63ffffffff614a5760408501828460401c1663ffffffff169052565b614a6e60608501828460601c1663ffffffff169052565b50608081811c6001600160401b03169084015260c081901c60a084015250600183015460c083015260029092015460e09091015290565b600060208284031215614ab757600080fd5b813562ffffff811681146140f157600080fd5b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600060208284031215614b0857600080fd5b813566ffffffffffffff811681146140f157600080fd5b808201808211156128705761287061482d565b80820281158282048414176128705761287061482d565b7f5065726d697373696f6e733a206163636f756e74200000000000000000000000815260008351614b818160158501602088016144cf565b7001034b99036b4b9b9b4b733903937b6329607d1b6015918401918201528351614bb28160268401602088016144cf565b01602601949350505050565b600060208284031215614bd057600080fd5b81516140f18161443e565b600081614bea57614bea61482d565b50600019019056fea2646970667358221220153d524a6e1ce05d14f48032db91f4dad727d222682e46d6b1fda4f6e9ca026964736f6c63430008140033000000000000000000000000f9e30ba8df802eef5a0fb239d59dee05f18b2e49000000000000000000000000a1cf615003464ab30c1c6a7c926f52788e64077d00000000000000000000000099a2b56d146bfca762e8fa86e04a7b63483e1f57

Deployed Bytecode

0x6080604052600436106102565760003560e01c8063802c3a3a11610149578063c291537c116100c6578063d9ea95491161008a578063ec87621c11610064578063ec87621c146107d4578063f10f537a14610808578063fc9b5fc81461081b57600080fd5b8063d9ea95491461075b578063e403a2511461077b578063e506dfbe146107b457600080fd5b8063c291537c146106c6578063c5275fb0146106e6578063c78b616c14610706578063c821ec001461071b578063d547741f1461073b57600080fd5b80639c5204711161010d5780639c52047114610633578063a217fddf14610651578063a32fa5b314610666578063a3c8fdd814610686578063b7792b26146106a657600080fd5b8063802c3a3a1461055e57806383f7f09d1461059657806391d14854146105b65780639258d45d146105e657806396b5a7551461061357600080fd5b806331964156116101d7578063499e145a1161019b578063499e145a14610484578063567441f8146104a457806370b4768e146104d157806378bd7935146104fe5780637c6285a11461052b57600080fd5b806331964156146103b2578063349b5954146103d257806336568abe146104065780633c4de40f1461042657806341896c541461046457600080fd5b8063216fd1f51161021e578063216fd1f514610305578063218ddb5714610325578063236ed8f314610345578063248a9ca3146103655780632f2ff15d1461039257600080fd5b80630858e5ad1461025b5780630c269b0b14610270578063107a274a1461029057806316002f4a146102c65780631fcc5b8a146102e5575b600080fd5b61026e610269366004614211565b61083b565b005b34801561027c57600080fd5b5061026e61028b36600461424c565b610f6e565b34801561029c57600080fd5b506102b06102ab36600461427a565b611434565b6040516102bd91906143fa565b60405180910390f35b3480156102d257600080fd5b506004545b6040519081526020016102bd565b3480156102f157600080fd5b5061026e610300366004614421565b611561565b34801561031157600080fd5b5061026e61032036600461444c565b61158b565b34801561033157600080fd5b5061026e610340366004614485565b6115e7565b34801561035157600080fd5b5061026e61036036600461427a565b61165b565b34801561037157600080fd5b506102d761038036600461427a565b60009081526001602052604090205490565b34801561039e57600080fd5b5061026e6103ad3660046144aa565b61190f565b3480156103be57600080fd5b5061026e6103cd3660046144aa565b6119a7565b3480156103de57600080fd5b506102d77f940d6b1946ff1d2b5a9f1909219c3c81a370804b5ba0f91ec0828c99a2e6a68181565b34801561041257600080fd5b5061026e6104213660046144aa565b611a08565b34801561043257600080fd5b5061045760405180604001604052806005815260200164312e302e3160d81b81525081565b6040516102bd91906144f3565b34801561047057600080fd5b5061026e61047f366004614538565b611a6a565b34801561049057600080fd5b506102d761049f36600461455d565b611cbd565b3480156104b057600080fd5b506104c46104bf36600461427a565b6120a5565b6040516102bd919061457a565b3480156104dd57600080fd5b506104f16104ec36600461427a565b61227e565b6040516102bd91906145c9565b34801561050a57600080fd5b5061051e61051936600461427a565b6123a0565b6040516102bd9190614756565b34801561053757600080fd5b50610457604051806040016040528060078152602001661350525393915560ca1b81525081565b34801561056a57600080fd5b5061057e61057936600461427a565b61251a565b6040516001600160a01b0390911681526020016102bd565b3480156105a257600080fd5b5061026e6105b1366004614485565b61258b565b3480156105c257600080fd5b506105d66105d13660046144aa565b61284b565b60405190151581526020016102bd565b3480156105f257600080fd5b5061060661060136600461427a565b612876565b6040516102bd9190614765565b34801561061f57600080fd5b5061026e61062e36600461427a565b612a8a565b34801561063f57600080fd5b506002546001600160a01b031661057e565b34801561065d57600080fd5b506102d7600081565b34801561067257600080fd5b506105d66106813660046144aa565b612b9e565b34801561069257600080fd5b506102d76106a136600461427a565b612bf0565b3480156106b257600080fd5b5061026e6106c13660046147a8565b612d88565b3480156106d257600080fd5b506106066106e1366004614211565b612ea4565b3480156106f257600080fd5b506104c4610701366004614211565b6130e7565b34801561071257600080fd5b506003546102d7565b34801561072757600080fd5b506102d76107363660046147d4565b6132d9565b34801561074757600080fd5b5061026e6107563660046144aa565b613546565b34801561076757600080fd5b506104f1610776366004614421565b61355f565b34801561078757600080fd5b506105d6610796366004614421565b6001600160a01b03166000908152600e602052604090205460ff1690565b3480156107c057600080fd5b5061057e6107cf36600461427a565b613685565b3480156107e057600080fd5b506102d77f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b0881565b61026e6108163660046147f0565b6136f6565b34801561082757600080fd5b5061026e6108363660046144aa565b613c6a565b600082815260096020908152604080832081516101008101909252805466ffffffffffffff811683529192909190830190600160381b900460ff16600381111561088757610887614644565b600381111561089857610898614644565b8152815463ffffffff600160401b820481166020840152600160601b82041660408301526001600160401b03600160801b820481166060840152600160c01b909104166080820152600182015460a082015260029091015460c090910152905060008160200151600381111561091057610910614644565b0361092e5760405163e6759c6760e01b815260040160405180910390fd5b60018160200151600381111561094657610946614644565b14610964576040516334dc687f60e11b815260040160405180910390fd5b806040015163ffffffff164210156109a857604080820151905163ad4db47b60e01b815263ffffffff90911660048201524260248201526044015b60405180910390fd5b42816060015163ffffffff1610156109d35760405163dda144a560e01b815260040160405180910390fd5b816000036109f457604051630d5a8f9960e11b815260040160405180910390fd5b8060c00151821015610a295760c081015160405163013542db60e31b815261099f918491600401918252602082015260400190565b348214610a52576040516334cb937b60e21b81526004810183905234602482015260440161099f565b6000838152600c60205260409020548015610bc2576000848152600c602052604081206001908101908290610a879085614843565b8152602080820192909252604090810160002081516080808201845282546001600160401b038082168452600160401b820463ffffffff1696840196909652600160601b90046001600160a01b031693820193909352600190910154606082018190529186015190935061271092168102919091040180851015610b2857604051631711707760e31b8152600481018690526024810182905260440161099f565b50600081604001516001600160a01b0316826060015160405160006040518083038185875af1925050503d8060008114610b7e576040519150601f19603f3d011682016040523d82523d6000602084013e610b83565b606091505b5050905080610ba557604051634412abcb60e01b815260040160405180910390fd5b6000868152600c60205260409020548314610bbf57600080fd5b50505b600c6000858152602001908152602001600020600001600081546001019190508190555060006040518060800160405280866001600160401b031681526020014263ffffffff168152602001336001600160a01b0316815260200185815250905080600c6000878152602001908152602001600020600101600084815260200190815260200160002060008201518160000160006101000a8154816001600160401b0302191690836001600160401b0316021790555060208201518160000160086101000a81548163ffffffff021916908363ffffffff160217905550604082015181600001600c6101000a8154816001600160a01b0302191690836001600160a01b03160217905550606082015181600101559050506000600d6000336001600160a01b03166001600160a01b03168152602001908152602001600020600001600081548092919060010191905055905081600d6000336001600160a01b03166001600160a01b03168152602001908152602001600020600101600083815260200190815260200160002060008201518160000160006101000a8154816001600160401b0302191690836001600160401b0316021790555060208201518160000160086101000a81548163ffffffff021916908363ffffffff160217905550604082015181600001600c6101000a8154816001600160a01b0302191690836001600160a01b0316021790555060608201518160010155905050508260a001516001600160401b031642846060015163ffffffff16610e019190614843565b11610f245760a083015160608401805190910163ffffffff16905260008581526009602090815260409091208451815466ffffffffffffff19811666ffffffffffffff90921691821783559286015186939091839167ffffffffffffffff191617600160381b836003811115610e7957610e79614644565b0217905550604082015181546060840151608085015160a08601516fffffffffffffffff000000000000000019909316600160401b63ffffffff9586160263ffffffff60601b191617600160601b9490921693909302176fffffffffffffffffffffffffffffffff16600160801b6001600160401b03938416026001600160c01b031617600160c01b929091169190910217815560c0820151600182015560e0909101516002909101555b83336001600160a01b0316867f81b76daaaa20e11a350a2cbf4c8e7c229b6b0bb852585e708b3f6ca5dc25046686604051610f5f9190614856565b60405180910390a45050505050565b610f76613ccb565b60008281526005602052604081208054909162ffffff9091169003610fae576040516335aacf6560e11b815260040160405180910390fd5b610fc061012083016101008401614865565b63ffffffff16610fd861014084016101208501614865565b63ffffffff16101561103157610ff661012083016101008401614865565b61100861014084016101208501614865565b6040516322e2aba560e21b815263ffffffff92831660048201529116602482015260440161099f565b61104361014083016101208401614865565b63ffffffff1661105a610100840160e08501614865565b63ffffffff16116110b15761107761014083016101208401614865565b611088610100840160e08501614865565b604051637a423a8560e01b815263ffffffff92831660048201529116602482015260440161099f565b6110c1606083016040840161488b565b61ffff166110d5604084016020850161488b565b61ffff161015611126576110ef606083016040840161488b565b6110ff604084016020850161488b565b604051635789d79160e11b815261ffff92831660048201529116602482015260440161099f565b6001810154600160501b810461ffff908116600160601b9092048116919091011680611158604085016020860161488b565b61ffff16101561119957611172604084016020850161488b565b60405163721750bd60e11b815261ffff90911660048201526024810182905260440161099f565b6001820154600160401b900461ffff166111b9606085016040860161488b565b61ffff161015611208576111d3606084016040850161488b565b600183015460405163db50aaff60e01b815261ffff9283166004820152600160401b909104909116602482015260440161099f565b5061121b610160830161014084016148af565b611226576000611229565b60015b815460ff9190911663010000000263ff00000019909116178155611253604083016020840161488b565b815461ffff91909116600160201b0265ffff0000000019909116178155611280606083016040840161488b565b815461ffff91909116600160301b0267ffff000000000000199091161781556112af608083016060840161488b565b815461ffff91909116600160401b0261ffff60401b199091161781556112db60a083016080840161488b565b815461ffff91909116600160501b0261ffff60501b1990911617815561130760c0830160a084016148cc565b81546001600160401b0391909116600160601b0267ffffffffffffffff60601b1990911617815561133e60e0830160c084016148cc565b81546001600160401b0391909116600160a01b0267ffffffffffffffff60a01b19909116178155611376610100830160e08401614865565b815463ffffffff91909116600160e01b026001600160e01b039091161781556113a761012083016101008401614865565b60018201805463ffffffff191663ffffffff929092169190911790556113d561014083016101208401614865565b8160010160046101000a81548163ffffffff021916908363ffffffff160217905550827fec7aa23b1f28f22e8d710a736df8f4b309ee41f3f210a4091c67dad2ee3e6bf58260405161142791906148f5565b60405180910390a2505050565b61143c6140f8565b5060408051808201825282815260009283526005602090815292829020825161020081018452815462ffffff811682526301000000810460ff1682870152600160201b80820461ffff90811696840196909652600160301b820486166060840152600160401b80830487166080850152600160501b808404881660a0860152600160601b8085046001600160401b0390811660c0880152600160a01b86041660e0870152600160e01b90940463ffffffff90811661010087015260019096015480871661012087015292830490951661014085015281048616610160840152928304851661018083015282049093166101a0840152600160701b810468ffffffffffffffffff9081166101c0850152600160b81b909104166101e08301529182015290565b611569613ccb565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b611593613d2a565b6001600160a01b0382166000818152600e6020526040808220805460ff191685151590811790915590519092917f215f66273fb517a22736277e280b3ea8a0b7db6ed54f2edb25b1cbd87e3c28ca91a35050565b6115ef613ccb565b806115fb5760006115fe565b60015b600083815260056020526040808220805460ff9490941663010000000263ff000000199094169390931790925590518215159184917f3f3590113b880e5ffacda884287cb609f87652a7522ba040e52d072f9179e9b09190a35050565b611663613ccb565b6000818152600960205260408120908154600160381b900460ff16600381111561168f5761168f614644565b036116ad5760405163e6759c6760e01b815260040160405180910390fd5b60018154600160381b900460ff1660038111156116cc576116cc614644565b146116ea576040516334dc687f60e11b815260040160405180910390fd5b8054600160601b900463ffffffff164210156117305780546040516336cc6d4f60e21b8152600160601b90910463ffffffff16600482015242602482015260440161099f565b6000828152600c602052604081205490819003611760576040516359a67b3d60e01b815260040160405180910390fd5b6000838152600c6020526040812060019081019082906117809085614843565b81526020808201929092526040908101600020815160808101835281546001600160401b0381168252600160401b810463ffffffff1694820194909452600160601b9093046001600160a01b03169183019190915260010154606082018190526002850154919250106118195760608101516002840154604051637e4b9d7d60e01b81526004810192909252602482015260440161099f565b825460ff60381b1916670200000000000000178355604081810151606083015191516000926001600160a01b0390921691908381818185875af1925050503d8060008114611883576040519150601f19603f3d011682016040523d82523d6000602084013e611888565b606091505b50509050806118aa57604051634412abcb60e01b815260040160405180910390fd5b6060828101516040808501518754825166ffffffffffffff90911681526000602082015260019281019290925291926001600160a01b039092169188917f46b848163e03f83edace353ba36892b6d49697bebcbe7aea9f837c69cd5851479101610f5f565b6000828152600160205260409020546119289033613d86565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16156119995760405162461bcd60e51b815260206004820152601d60248201527f43616e206f6e6c79206772616e7420746f206e6f6e20686f6c64657273000000604482015260640161099f565b6119a38282613e04565b5050565b6119af613ccb565b60008281526007602052604080822080546001600160a01b0319166001600160a01b0385169081179091559051909184917f7bda5ebb0c6f5079561a878d9b8fa1fd8e2443210022b1e25de894fea02509479190a35050565b336001600160a01b03821614611a605760405162461bcd60e51b815260206004820152601a60248201527f43616e206f6e6c792072656e6f756e636520666f722073656c66000000000000604482015260640161099f565b6119a38282613e5d565b611a72613ccb565b6000828152600960205260408120908154600160381b900460ff166003811115611a9e57611a9e614644565b03611abc5760405163e6759c6760e01b815260040160405180910390fd5b60018154600160381b900460ff166003811115611adb57611adb614644565b14611af9576040516334dc687f60e11b815260040160405180910390fd5b611b096040830160208401614865565b63ffffffff16611b1f6060840160408501614865565b63ffffffff1611611b7357611b3a6040830160208401614865565b611b4a6060840160408501614865565b6040516377acf3f160e11b815263ffffffff92831660048201529116602482015260440161099f565b611b8360808301606084016148cc565b6001600160401b03166127101015611bae57604051631594b46760e21b815260040160405180910390fd5b611bbe6040830160208401614865565b815463ffffffff91909116600160401b0263ffffffff60401b19909116178155611bee6060830160408401614865565b815463ffffffff91909116600160601b0263ffffffff60601b19909116178155611c1e60808301606084016148cc565b81546001600160401b0391909116600160801b0267ffffffffffffffff60801b19909116178155611c5560a08301608084016148cc565b81546001600160401b0391909116600160c01b026001600160c01b0390911617815560a0820135600182015560c0820135600282015560405183907f719a0c86470e9c93a183ded6bca73369f7e28afe0beec0a19f90763aae17323b90611427908490614a13565b6000611cc7613ccb565b5060038054600101908190556000818152600560205260409020611cf361012084016101008501614865565b63ffffffff16611d0b61014085016101208601614865565b63ffffffff161015611d3b57611d2961012084016101008501614865565b61100861014085016101208601614865565b611d4d61014084016101208501614865565b63ffffffff16611d64610100850160e08601614865565b63ffffffff1611611d9257611d8161014084016101208501614865565b611088610100850160e08601614865565b611da2606084016040850161488b565b61ffff16611db6604085016020860161488b565b61ffff161015611de057611dd0606084016040850161488b565b6110ff604085016020860161488b565b611ded6020840184614aa5565b815462ffffff191662ffffff91909116178155611e12610160840161014085016148af565b611e1d576000611e20565b60015b815460ff9190911663010000000263ff00000019909116178155611e4a604084016020850161488b565b815461ffff91909116600160201b0265ffff0000000019909116178155611e77606084016040850161488b565b815461ffff91909116600160301b0267ffff00000000000019909116178155611ea6608084016060850161488b565b815461ffff91909116600160401b0261ffff60401b19909116178155611ed260a084016080850161488b565b815461ffff91909116600160501b0261ffff60501b19909116178155611efe60c0840160a085016148cc565b81546001600160401b0391909116600160601b0267ffffffffffffffff60601b19909116178155611f3560e0840160c085016148cc565b81546001600160401b0391909116600160a01b0267ffffffffffffffff60a01b19909116178155611f6d610100840160e08501614865565b815463ffffffff91909116600160e01b026001600160e01b03909116178155611f9e61012084016101008501614865565b60018201805463ffffffff191663ffffffff92909216919091179055611fcc61014084016101208501614865565b60018201805463ffffffff92909216600160201b0267ffffffff000000001990921691909117905560006006816120066020870187614aa5565b62ffffff1681526020808201929092526040016000908120805460018101909155925084916006919061203b90880188614aa5565b62ffffff16815260200190815260200160002060010160008381526020019081526020016000208190555050817f7efa901ffa0a63f7fe1fda3e997b815c85bd90c454df0cc44818c4ba326d81fb8260405161209791906148f5565b60405180910390a250919050565b6000818152600660205260409020805460609190806001600160401b038111156120d1576120d1614aca565b60405190808252806020026020018201604052801561210a57816020015b6120f76140f8565b8152602001906001900390816120ef5790505b50925060005b8181101561227657600081815260018085016020908152604080842054815180830183528181528186526005845294829020825161020081018452815462ffffff8116825260ff63010000008204168287015261ffff600160201b808304821696840196909652600160301b820481166060840152600160401b80830482166080850152600160501b808404831660a08601526001600160401b03600160601b808604821660c0880152600160a01b860490911660e087015263ffffffff600160e01b90950485166101008701529590990154808416610120860152968704909216610140840152908504811661016083015295840486166101808201529083049094166101a085015268ffffffffffffffffff600160701b830481166101c0860152600160b81b9092049091166101e084015290830191909152855190919086908490811061226257612262614ae0565b602090810291909101015250600101612110565b505050919050565b6000818152600c6020526040902054606090806001600160401b038111156122a8576122a8614aca565b6040519080825280602002602001820160405280156122fa57816020015b6040805160808101825260008082526020808301829052928201819052606082015282526000199092019101816122c65790505b50915060005b81811015612399576000848152600c602090815260408083208484526001908101835292819020815160808101835281546001600160401b0381168252600160401b810463ffffffff1694820194909452600160601b9093046001600160a01b031691830191909152909101546060820152835184908390811061238657612386614ae0565b6020908102919091010152600101612300565b5050919050565b6123a861418c565b6000828152600c60209081526040808320548151606081018352868152868552600984529382902082516101008101909352805466ffffffffffffff81168452919493848101939290830190600160381b900460ff16600381111561240f5761240f614644565b600381111561242057612420614644565b8152815463ffffffff600160401b82048116602080850191909152600160601b83049091166040808501919091526001600160401b03600160801b840481166060860152600160c01b909304909216608084015260018085015460a085015260029094015460c0909301929092529284526000888152600c82529283209301920190846124ae5760006124b3565b600185035b81526020808201929092526040908101600020815160808101835281546001600160401b0381168252600160401b810463ffffffff1694820194909452600160601b9093046001600160a01b03169183019190915260010154606082015290529392505050565b6000818152600760205260408120546001600160a01b031661256f5750506000805260076020527f6d5257204ebe7d88fd91ae87941cb2dd9d8062b64ae5a2bd2d28ec40b9fbf6df546001600160a01b031690565b506000908152600760205260409020546001600160a01b031690565b612593613ccb565b6000828152600960205260408120908154600160381b900460ff1660038111156125bf576125bf614644565b036125dd5760405163e6759c6760e01b815260040160405180910390fd5b60018154600160381b900460ff1660038111156125fc576125fc614644565b1461261a576040516334dc687f60e11b815260040160405180910390fd5b8054600160601b900463ffffffff164210156126605780546040516336cc6d4f60e21b8152600160601b90910463ffffffff16600482015242602482015260440161099f565b6000838152600c602052604081205490819003612690576040516359a67b3d60e01b815260040160405180910390fd5b6000848152600c6020526040812060019081019082906126b09085614843565b81526020808201929092526040908101600020815160808101835281546001600160401b0381168252600160401b810463ffffffff1694820194909452600160601b9093046001600160a01b03169183019190915260010154606082018190526002850154919250108015612723575083155b156127545760608101516002840154604051635cf8b88960e11b81526004810192909252602482015260440161099f565b825460ff60381b191667020000000000000017835561277285613685565b604082810151855491516308934a5f60e31b81526001600160a01b03918216600482015266ffffffffffffff9092166024830152919091169063449a52f890604401600060405180830381600087803b1580156127ce57600080fd5b505af11580156127e2573d6000803e3d6000fd5b505050506060818101516040808401518654825166ffffffffffffff90911681526001602082015260009281019290925291926001600160a01b039092169188917f46b848163e03f83edace353ba36892b6d49697bebcbe7aea9f837c69cd5851479101610f5f565b6000828152602081815260408083206001600160a01b038516845290915290205460ff165b92915050565b6000818152600a60205260409020805460609190806001600160401b038111156128a2576128a2614aca565b6040519080825280602002602001820160405280156128db57816020015b6128c861418c565b8152602001906001900390816128c05790505b50925060005b81811015612276576000818152600184016020908152604080832054600c8352818420548251606081018452828152828652600985529483902083516101008101909452805466ffffffffffffff81168552929591949193848301939092830190600160381b900460ff16600381111561295d5761295d614644565b600381111561296e5761296e614644565b8152815463ffffffff600160401b82048116602080850191909152600160601b83049091166040808501919091526001600160401b03600160801b840481166060860152600160c01b909304909216608084015260018085015460a085015260029094015460c0909301929092529284526000878152600c82529283209301920190846129fc576000612a01565b600185035b81526020808201929092526040908101600020815160808101835281546001600160401b0381168252600160401b810463ffffffff1694820194909452600160601b9093046001600160a01b03169183019190915260010154606082015290528651879085908110612a7557612a75614ae0565b602090810291909101015250506001016128e1565b612a92613ccb565b6000818152600960205260408120908154600160381b900460ff166003811115612abe57612abe614644565b03612adc5760405163e6759c6760e01b815260040160405180910390fd5b60018154600160381b900460ff166003811115612afb57612afb614644565b14612b19576040516334dc687f60e11b815260040160405180910390fd5b6000828152600c602052604090205415612b5a576000828152600c602052604090819020549051636761e76160e11b8152600481019190915260240161099f565b805460ff60381b191667030000000000000017815560405182907f2809c7e17bf978fbc7194c0a694b638c4215e9140cacc6c38ca36010b45697df90600090a25050565b60008281526020818152604080832083805290915281205460ff16612be757506000828152602081815260408083206001600160a01b038516845290915290205460ff16612870565b50600192915050565b600081815260096020908152604080832081516101008101909252805466ffffffffffffff811683528493830190600160381b900460ff166003811115612c3957612c39614644565b6003811115612c4a57612c4a614644565b8152815463ffffffff600160401b820481166020840152600160601b82041660408301526001600160401b03600160801b820481166060840152600160c01b909104166080820152600182015460a082015260029091015460c0909101529050600081602001516003811115612cc257612cc2614644565b03612ce05760405163e6759c6760e01b815260040160405180910390fd5b6000838152600c60205260409020548015612d7d576000938452600c60209081526040808620600019939093018652600192830182529485902085516080808201885282546001600160401b038082168452600160401b820463ffffffff1695840195909552600160601b90046001600160a01b031697820197909752920154606090920182905291909301516127109116830204909101919050565b5060c0015192915050565b612d90613d2a565b80471015612dba57604051635f938ce560e11b81526004810182905247602482015260440161099f565b6001600160a01b0382166000908152600e602052604090205460ff16612df35760405163b13347ad60e01b815260040160405180910390fd5b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612e40576040519150601f19603f3d011682016040523d82523d6000602084013e612e45565b606091505b5050905080612e675760405163df108a3b60e01b815260040160405180910390fd5b60405182906001600160a01b0385169033907fd1b078762514fc24641f0f647e92ba3f15f4cb8e732e84ce1d2686f15542837190600090a4505050565b6060821580612eb257508282105b15612ed0576040516304d8557760e31b815260040160405180910390fd5b60006004548311612ee15782612ee5565b6004545b60010190508381036001600160401b03811115612f0457612f04614aca565b604051908082528060200260200182016040528015612f3d57816020015b612f2a61418c565b815260200190600190039081612f225790505b509150835b818110156130df576000818152600c60209081526040808320548151606081018352858152858552600984529382902082516101008101909352805466ffffffffffffff81168452919493848101939290830190600160381b900460ff166003811115612fb157612fb1614644565b6003811115612fc257612fc2614644565b8152815463ffffffff600160401b82048116602080850191909152600160601b83049091166040808501919091526001600160401b03600160801b840481166060860152600160c01b909304909216608084015260018085015460a085015260029094015460c0909301929092529284526000878152600c8252928320930192019084613050576000613055565b600185035b81526020808201929092526040908101600020815160808101835281546001600160401b0381168252600160401b810463ffffffff1694820194909452600160601b9093046001600160a01b0316918301919091526001015460608201529052845185908885039081106130cb576130cb614ae0565b602090810291909101015250600101612f42565b505092915050565b60608215806130f557508282105b15613113576040516313e95aa760e21b815260040160405180910390fd5b600060035483116131245782613128565b6003545b60010190508381036001600160401b0381111561314757613147614aca565b60405190808252806020026020018201604052801561318057816020015b61316d6140f8565b8152602001906001900390816131655790505b509150835b818110156130df5760408051808201825282815260008381526005602090815290839020835161020081018552815462ffffff811682526301000000810460ff1682850152600160201b80820461ffff90811697840197909752600160301b820487166060840152600160401b80830488166080850152600160501b808404891660a0860152600160601b8085046001600160401b0390811660c0880152600160a01b86041660e0870152600160e01b90940463ffffffff90811661010087015260019096015480871661012087015292830490951661014085015281048716610160840152928304861661018083015282049094166101a0850152600160701b810468ffffffffffffffffff9081166101c0860152600160b81b909104166101e0840152810191909152835184908784039081106132c6576132c6614ae0565b6020908102919091010152600101613185565b60006132e3613ccb565b5060048054600101908190556000818152600960209081526040918290209161331191908501908501614865565b63ffffffff166133276060850160408601614865565b63ffffffff1611613352576133426040840160208501614865565b611b4a6060850160408601614865565b61336260808401606085016148cc565b6001600160401b0316612710101561338d57604051631594b46760e21b815260040160405180910390fd5b61339a6020840184614af6565b815466ffffffffffffff9190911667ffffffffffffffff1990911617600160381b1781556133ce6040840160208501614865565b815463ffffffff91909116600160401b0263ffffffff60401b199091161781556133fe6060840160408501614865565b815463ffffffff91909116600160601b0263ffffffff60601b1990911617815561342e60808401606085016148cc565b81546001600160401b0391909116600160801b0267ffffffffffffffff60801b1990911617815561346560a08401608085016148cc565b81546001600160401b0391909116600160c01b026001600160c01b0390911617815560a0830135600182015560c083013560028201556000600a816134ad6020870187614af6565b66ffffffffffffff168152602080820192909252604001600090812080546001810190915592508491600a91906134e690880188614af6565b66ffffffffffffff16815260200190815260200160002060010160008381526020019081526020016000208190555050817f6ecb6e63f6645ff9293c33fc77c67f1bc05beff9ff71806d5c759647b3d2d402826040516120979190614a13565b600082815260016020526040902054611a609033613d86565b6001600160a01b0381166000908152600d6020526040902054606090806001600160401b0381111561359357613593614aca565b6040519080825280602002602001820160405280156135e557816020015b6040805160808101825260008082526020808301829052928201819052606082015282526000199092019101816135b15790505b50915060005b81811015612399576001600160a01b038085166000908152600d602090815260408083208584526001908101835292819020815160808101835281546001600160401b038116825263ffffffff600160401b82041694820194909452600160601b909304909416908201529101546060820152835184908390811061367257613672614ae0565b60209081029190910101526001016135eb565b6000818152600b60205260408120546001600160a01b03166136da57505060008052600b6020527fdf7de25b7f1fd6d0b5205f0e18f1f35bd7b8d84cce336588d184533ce43a6f76546001600160a01b031690565b506000908152600b60205260409020546001600160a01b031690565b60008481526005602052604081208054909162ffffff909116900361372e576040516335aacf6560e11b815260040160405180910390fd5b80546301000000900460ff1660000361375a57604051635acda82f60e01b815260040160405180910390fd5b34821461378357604051631162ee2d60e21b81526004810183905234602482015260440161099f565b805442600160e01b90910463ffffffff1610156137b3576040516389d4186960e01b815260040160405180910390fd5b60018101548154600160501b820461ffff908116600160601b909304811692909201600160201b909104821603168381101561380c57604051630d27c2b960e41b8152600481018590526024810182905260440161099f565b506000858152600860209081526040808320338452909152812054613832908590614b1f565b905061383e8633613ebd565b15613a1557600182015463ffffffff16421015613882576001820154604051637283b3fb60e01b815263ffffffff909116600482015242602482015260440161099f565b8154600160401b900461ffff168111156138c5578154604051632fda893760e21b815260048101839052600160401b90910461ffff16602482015260440161099f565b81546000906138e5908690600160601b90046001600160401b0316614b32565b905083811461391157604051630bf76b4560e41b8152600481018590526024810182905260440161099f565b6001830154600160201b900463ffffffff1642101561399d576001830154835461ffff600160401b9092048216600160301b909104821603168581101561397557604051631386b05760e01b8152600481018790526024810182905260440161099f565b5060018301805461ffff600160401b808304821689019091160261ffff60401b199091161790555b5060018201805468ffffffffffffffffff600160701b61ffff600160501b80850482168a019091160261ffff60501b1984168117829004831688019092160268ffffffffffffffffff60701b1990911676ffffffffffffffffff0000ffff000000000000000000001990921691909117179055613b76565b6001820154600160201b900463ffffffff16421015613a615760018201546040516381c5e80b60e01b8152600160201b90910463ffffffff16600482015242602482015260440161099f565b8154600160501b900461ffff16811115613aa457815460405163180da9c560e31b815260048101839052600160501b90910461ffff16602482015260440161099f565b8154600090613ac4908690600160a01b90046001600160401b0316614b32565b9050838114613af0576040516396e80d5560e01b8152600481018590526024810182905260440161099f565b5060018201805468ffffffffffffffffff600160b81b61ffff600160601b80850482168a01909116026dffff0000000000000000000000001984168117829004831688019092160276ffffffffffffffffffffffffffffffffffffffffffffff90911676ffffffffffffffffff0000ffffffffffffffffffffffff909216919091171790555b60008681526008602090815260408083203384529091529020819055613b9b8661251a565b8254604051632c7ef07760e01b81526001600160a01b03888116600483015262ffffff909216602482015260448101879052911690632c7ef07790606401600060405180830381600087803b158015613bf357600080fd5b505af1158015613c07573d6000803e3d6000fd5b505083546040805162ffffff90921682526020820188905281018690526001600160a01b038816925033915088907f964be453e8b19c8fc2d856baaaeb5c6db9607b1f52fdff3f0a1e6cef6ac3bd019060600160405180910390a4505050505050565b613c72613ccb565b6000828152600b602052604080822080546001600160a01b0319166001600160a01b0385169081179091559051909184917f8829ff1f8d6f20e53e317d9e72d94b852e0d669afb69b39a2b7d1923da57f5c09190a35050565b613cd660003361284b565b158015613d0a5750613d087f241ecf16d79d0f8dbfb92cbc07fe17840425976cf0667f022fe9877caa831b083361284b565b155b15613d28576040516349349c6360e11b815260040160405180910390fd5b565b613d3560003361284b565b158015613d695750613d677f940d6b1946ff1d2b5a9f1909219c3c81a370804b5ba0f91ec0828c99a2e6a6813361284b565b155b15613d285760405162afd36160e01b815260040160405180910390fd5b6000828152602081815260408083206001600160a01b038516845290915290205460ff166119a357613dc2816001600160a01b03166014613f56565b613dcd836020613f56565b604051602001613dde929190614b49565b60408051601f198184030181529082905262461bcd60e51b825261099f916004016144f3565b6000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916600117905551339285917f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9190a45050565b613e678282613d86565b6000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6002546000906001600160a01b031615613f4d57600254604051636c096c6d60e11b8152600481018590526001600160a01b0384811660248301529091169063d812d8da90604401602060405180830381865afa158015613f22573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f469190614bbe565b9050612870565b50600092915050565b60606000613f65836002614b32565b613f70906002614b1f565b6001600160401b03811115613f8757613f87614aca565b6040519080825280601f01601f191660200182016040528015613fb1576020820181803683370190505b509050600360fc1b81600081518110613fcc57613fcc614ae0565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613ffb57613ffb614ae0565b60200101906001600160f81b031916908160001a905350600061401f846002614b32565b61402a906001614b1f565b90505b60018111156140a2576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061405e5761405e614ae0565b1a60f81b82828151811061407457614074614ae0565b60200101906001600160f81b031916908160001a90535060049490941c9361409b81614bdb565b905061402d565b5083156140f15760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e74604482015260640161099f565b9392505050565b60408051808201825260008082528251610200810184528181526020818101839052938101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101829052610160810182905261018081018290526101a081018290526101c081018290526101e0810191909152909182015290565b6040518060600160405280600081526020016141e760408051610100810190915260008082526020820190815260006020820181905260408201819052606082018190526080820181905260a0820181905260c09091015290565b81526040805160808101825260008082526020828101829052928201819052606082015291015290565b6000806040838503121561422457600080fd5b50508035926020909101359150565b6000610160828403121561424657600080fd5b50919050565b600080610180838503121561426057600080fd5b823591506142718460208501614233565b90509250929050565b60006020828403121561428c57600080fd5b5035919050565b8051825260208101516142ae60208401825162ffffff169052565b602081015160ff8116604085015250604081015161ffff8116606085015250606081015161ffff8116608085015250608081015161ffff811660a08501525060a081015161ffff811660c08501525060c08101516001600160401b03811660e08501525060e081015161010061432e818601836001600160401b03169052565b82015190506101206143478582018363ffffffff169052565b82015190506101406143608582018363ffffffff169052565b82015190506101606143798582018363ffffffff169052565b82015190506101806143908582018361ffff169052565b82015190506101a06143a78582018361ffff169052565b82015190506101c06143be8582018361ffff169052565b82015190506101e06143dc8582018368ffffffffffffffffff169052565b919091015168ffffffffffffffffff81166102008501529050505050565b61022081016128708284614293565b6001600160a01b038116811461441e57600080fd5b50565b60006020828403121561443357600080fd5b81356140f181614409565b801515811461441e57600080fd5b6000806040838503121561445f57600080fd5b823561446a81614409565b9150602083013561447a8161443e565b809150509250929050565b6000806040838503121561449857600080fd5b82359150602083013561447a8161443e565b600080604083850312156144bd57600080fd5b82359150602083013561447a81614409565b60005b838110156144ea5781810151838201526020016144d2565b50506000910152565b60208152600082518060208401526145128160408501602087016144cf565b601f01601f19169190910160400192915050565b600060e0828403121561424657600080fd5b600080610100838503121561454c57600080fd5b823591506142718460208501614526565b6000610160828403121561457057600080fd5b6140f18383614233565b6020808252825182820181905260009190848201906040850190845b818110156145bd576145a9838551614293565b928401926102209290920191600101614596565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156145bd576146318385516001600160401b03815116825263ffffffff60208201511660208301526001600160a01b036040820151166040830152606081015160608301525050565b92840192608092909201916001016145e5565b634e487b7160e01b600052602160045260246000fd5b6004811061467857634e487b7160e01b600052602160045260246000fd5b9052565b66ffffffffffffff8151168252602081015161469b602084018261465a565b50604081015163ffffffff8082166040850152806060840151166060850152505060808101516001600160401b0380821660808501528060a08401511660a0850152505060c081015160c083015260e081015160e08301525050565b80518252602081015161470d602084018261467c565b5060409081015180516001600160401b0316610120840152602081015163ffffffff16610140840152908101516001600160a01b03166101608301526060015161018090910152565b6101a0810161287082846146f7565b6020808252825182820181905260009190848201906040850190845b818110156145bd576147948385516146f7565b928401926101a09290920191600101614781565b600080604083850312156147bb57600080fd5b82356147c681614409565b946020939093013593505050565b600060e082840312156147e657600080fd5b6140f18383614526565b6000806000806080858703121561480657600080fd5b84359350602085013561481881614409565b93969395505050506040820135916060013590565b634e487b7160e01b600052601160045260246000fd5b818103818111156128705761287061482d565b6101008101612870828461467c565b60006020828403121561487757600080fd5b813563ffffffff811681146140f157600080fd5b60006020828403121561489d57600080fd5b813561ffff811681146140f157600080fd5b6000602082840312156148c157600080fd5b81356140f18161443e565b6000602082840312156148de57600080fd5b81356001600160401b03811681146140f157600080fd5b815462ffffff81168252610200820190601881901c60ff16602084015261ffff602082901c8116604085015261493660608501828460301c1661ffff169052565b61494b60808501828460401c1661ffff169052565b61496060a08501828460501c1661ffff169052565b6001600160401b03606083901c811660c086015260a083901c1660e0808601919091529190911c610100840152600184015463ffffffff808216610120860152602082901c16610140850152604081901c821661ffff16610160850152906149d46101808501828460501c1661ffff169052565b6149ea6101a08501828460601c1661ffff169052565b50607081901c68ffffffffffffffffff166101c084015260b881901c6101e08401525092915050565b815466ffffffffffffff81168252610100820190614a3b60208401603883901c60ff1661465a565b63ffffffff614a5760408501828460401c1663ffffffff169052565b614a6e60608501828460601c1663ffffffff169052565b50608081811c6001600160401b03169084015260c081901c60a084015250600183015460c083015260029092015460e09091015290565b600060208284031215614ab757600080fd5b813562ffffff811681146140f157600080fd5b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600060208284031215614b0857600080fd5b813566ffffffffffffff811681146140f157600080fd5b808201808211156128705761287061482d565b80820281158282048414176128705761287061482d565b7f5065726d697373696f6e733a206163636f756e74200000000000000000000000815260008351614b818160158501602088016144cf565b7001034b99036b4b9b9b4b733903937b6329607d1b6015918401918201528351614bb28160268401602088016144cf565b01602601949350505050565b600060208284031215614bd057600080fd5b81516140f18161443e565b600081614bea57614bea61482d565b50600019019056fea2646970667358221220153d524a6e1ce05d14f48032db91f4dad727d222682e46d6b1fda4f6e9ca026964736f6c63430008140033

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

000000000000000000000000f9e30ba8df802eef5a0fb239d59dee05f18b2e49000000000000000000000000a1cf615003464ab30c1c6a7c926f52788e64077d00000000000000000000000099a2b56d146bfca762e8fa86e04a7b63483e1f57

-----Decoded View---------------
Arg [0] : defaultAdmin_ (address): 0xf9E30Ba8Df802EeF5A0fb239d59dee05f18B2e49
Arg [1] : defaultToken_ (address): 0xa1cF615003464Ab30c1c6A7c926f52788E64077d
Arg [2] : vipContract_ (address): 0x99a2b56D146Bfca762e8fa86e04A7B63483e1f57

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000f9e30ba8df802eef5a0fb239d59dee05f18b2e49
Arg [1] : 000000000000000000000000a1cf615003464ab30c1c6a7c926f52788e64077d
Arg [2] : 00000000000000000000000099a2b56d146bfca762e8fa86e04a7b63483e1f57


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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