Contract 0x1ed46a7436e5ff19d7dd8fbe7ee825c7f1395459

Contract Overview

Balance:
0 AVAX

AVAX Value:
$0.00

Token:
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x8517f8a18f20247c5f9cbde6ed07b42ca8747744ba59b0bde5af412aefa4447cCreate Auction167100232022-06-30 10:08:4550 mins ago0xee3b7c9c7f75af723b8f85f25e01fd99f45597e8 IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.0141089575 27.5
0x0c90d4625f35e10608289d2e804c6175a657a3927ca95119774b97203eb4d95fPlace Bid167090542022-06-30 9:36:251 hr 22 mins ago0x1eba6fbc603468fcef1ae0f4634eb62dfb67f3ab IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.01152788577 26.41
0xb118666ef166e624d517bdd7e8d23a972bb4baa30f8859ae99de2670746ea645Place Bid167085102022-06-30 9:18:291 hr 40 mins ago0x6c4e606157958b420e9334d8f972ae18ad6d763b IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.0124739175 27.5
0xb62915a2e7f0934118faf47188a184d51a9c0a79272024ff39470c3f5f0c5532Place Bid167083822022-06-30 9:14:121 hr 45 mins ago0x6c4e606157958b420e9334d8f972ae18ad6d763b IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.012582427635 27.739955324
0x17756d0ede3e04bdc036031cdf2c6f917f2a2b754c668bee61afad2d4ce3680aPlace Bid167078042022-06-30 8:55:122 hrs 4 mins ago0x7bffa72ef790fec4eca1033a4eb06bf6ab6b2320 IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.0129441675 27.5
0x3a6ed10311146e5e11bbfd5cace60a16467c0c02fb3cc523f59251cf5cd13b68Cancel Auction167074712022-06-30 8:44:062 hrs 15 mins ago0xd04de5e2e40af45f80dfad89a700d99232091c54 IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.00408928 26
0x2e9f4d3c10c30dcdf3c38001196aebcce04809505580acc809e37d567b4236b5Place Bid167074342022-06-30 8:42:472 hrs 16 mins ago0x6c4e606157958b420e9334d8f972ae18ad6d763b IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.013553000653 28.793471497
0xa2e175a55deab5bd0f5e893aa3d2f8b722a30ee241840bcfabe25557f2aa8e3ePlace Bid167073222022-06-30 8:39:042 hrs 20 mins ago0x6c4e606157958b420e9334d8f972ae18ad6d763b IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.011353815 27.5
0x74dfdacf2f7b2ccdf26bbc657bf91afdd074e3c5edee72c05f520d380058864ePlace Bid167071272022-06-30 8:32:322 hrs 26 mins ago0x6c4e606157958b420e9334d8f972ae18ad6d763b IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.011824065 27.5
0x80012659f2a020740a95171174d6e84ca9a40a01f729068daa8b44eb4483afc7Place Bid167070852022-06-30 8:30:592 hrs 28 mins ago0x6c4e606157958b420e9334d8f972ae18ad6d763b IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.012294315 27.5
0x827087e2ad1c9b9e49638ff985bc38bf311cba9957e143945a890c9724a5284dCreate Auction167067812022-06-30 8:20:512 hrs 38 mins ago0xc367421e987a37a3aefb7f801bf30049ec77e17d IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.0136387075 27.5
0x092205956c1358eb940082fea2fb7028b527950d14523d1136a35627692b50f4Create Auction167067162022-06-30 8:18:422 hrs 40 mins ago0xc367421e987a37a3aefb7f801bf30049ec77e17d IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.0141089575 27.5
0x1151cf6c687635a1e97d6f12df68d4b2e4bf39ef1e4d5f13380ed494d8ef8876Place Bid167059332022-06-30 7:53:023 hrs 6 mins ago0xcdbbf63e09e5b4149daf57b57a99b68879b699c1 IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.01201439153927.101985639
0xf8b75dc3f0c05398331d41f5ff80d3c06411564c1f325c5562f076e2e9f5451fCreate Auction166994152022-06-30 4:15:306 hrs 43 mins ago0xd04de5e2e40af45f80dfad89a700d99232091c54 IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.00835681 27.5
0xfd34a0f4b28f715da01c93312dbdb73f01ebc4ea1d2530e7000dded8859f1b19Cancel Auction166993812022-06-30 4:14:226 hrs 44 mins ago0xd04de5e2e40af45f80dfad89a700d99232091c54 IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.0043252 27.5
0xee473f8d01ae84e89452f31c123a7c934ce5bd270bfbcb17deab8969a918c37dPlace Bid166956362022-06-30 2:09:148 hrs 50 mins ago0xe9abf508d93875d7065633717dca1bed48e67165 IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.0129438375 27.5
0x449d971a2afccfb106d1c2a99bac07faffd7cc32cafc580d68648a40667fe4d0Cancel Auction166836752022-06-29 19:30:0715 hrs 29 mins ago0xa7e93fb95d278dc075c8032f823e4c58cd9ddcf6 IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.00479545 27.5
0xf25d8c6974208d06ddbe58773d7e10d9b5f90768779655d933df241989ff4469Create Auction166812572022-06-29 18:09:1316 hrs 50 mins ago0xd04de5e2e40af45f80dfad89a700d99232091c54 IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.007900984 26
0x40e30649a6bdacbb4051a4866ac63f2085d3050a2b2258629d19b1cb7aee72aeCancel Auction166812282022-06-29 18:08:1516 hrs 51 mins ago0xd04de5e2e40af45f80dfad89a700d99232091c54 IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.0041537648 26.41
0x6cbbcf8ef6047cf4de2f870e4d94447ea1b7375df11abfdb7ddd553a09c16f8dCreate Auction166766182022-06-29 15:34:1819 hrs 25 mins ago0x6c1259b31dd391a54a30f9e17218dc429f99ed5d IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.00835681 27.5
0x02e389dae6632be74ee3930c77a1b072b290d49fb21aacae0e8ce1e51a0edfbaCancel Auction166765842022-06-29 15:33:1019 hrs 26 mins ago0x6c1259b31dd391a54a30f9e17218dc429f99ed5d IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.0043252 27.5
0x49b9f4beb9b6bcda95f3fd59aa6027965816ce9dfc71ba502a35a296fd2b6b3bCreate Auction166756862022-06-29 15:03:1219 hrs 56 mins ago0x17b9087455e4813f2df87f420b20fd07170c339b IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.0145792075 27.5
0x27fc846a62baf5274452a2ae08be3b8bdadf2c8b0d01a98d10fdbbd3d20855aeCreate Auction166735942022-06-29 13:53:3321 hrs 5 mins ago0x6c1259b31dd391a54a30f9e17218dc429f99ed5d IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.01234981 27.5
0x5f18ae3aa522707baa55e687cbfd57ede4eacd88e48a221870a174f75e051163Place Bid166717912022-06-29 12:53:3322 hrs 5 mins ago0x463977d86eee5f51db368f7aa2c70ab6048e8814 IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.011353815 27.5
0xe20350861c2e0294c964656c392feb5194d2080e5ff09bc9417fedaa71e3cd3ePlace Bid166716912022-06-29 12:50:1322 hrs 9 mins ago0x463977d86eee5f51db368f7aa2c70ab6048e8814 IN  0x1ed46a7436e5ff19d7dd8fbe7ee825c7f13954590 AVAX0.012294315 27.5
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
AuctionManagerCustomToken

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at snowtrace.io on 2022-04-19
*/

// SPDX-License-Identifier: MIT
pragma solidity 0.8.4;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @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.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] 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);
            }
        }
    }
}

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

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

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
}

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

contract AuctionManagerCustomToken is Ownable {
    using SafeMath for uint256;
    using SafeMath for uint;
    using SafeERC20 for IERC20;
    uint _auctionIdCounter; // auction Id counter

    enum AuctionState { 
        OPEN,
        CANCELLED,
        ENDED,
        DIRECT_BUY
    }

    struct Bid { // A bid on an auction
        address sender;
        uint256 bid;
    }

    struct Auction {
        address creator; // The address of the auction creator
        uint256 startPrice; // The starting price of the auction
        uint256 maxBid; // The highest bid of the auction
        address maxBidder; // The address of the highest bidder
        uint256 directBuyPrice; // The direct buy price of the auction
        uint256 minIncrement; // The minimum increment of the auction
        bool isDirectBuy; // Whether the auction is ended by a direct buy
        bool isCancelled; // Whether the auction is cancelled
        uint256 endTime; // The end time of the auction
        address nftAddress; // The address of the NFT contract
        uint256 tokenId; // The token id of the auction
        uint256 feeRatio; // The fee ratio of the auction
        uint256 auctionId;
    }

    mapping(uint => Auction) public auctions; // auctions
    mapping(uint => bool) public isClaimed;
    mapping(address => bool) public nftContracts; // Allowed NFT addresses
    address[] public nftContractsList; // Allowed NFT addresses
    mapping(address => mapping(uint256 => Auction)) public nftContractAuctions; // NFT contract tokenId to Auction mapping
    mapping(uint256 => Bid[]) private bids; // NFT contract auctionId to Bid mapping
    IERC20 private bidToken;
    uint256 private feeRatio;
    mapping(address => uint256) private userClaimableBids;
    mapping(address => uint256) private userClaimableNfts;

    constructor(address _bidToken, uint256 _feeRatio) {
        bidToken = IERC20(_bidToken);
        feeRatio = _feeRatio;
    }

    function getBidToken() public view returns(address) {
        return address(bidToken);
    }

    function addNewContract(address _newNFTAddress) external onlyOwner {
        nftContracts[_newNFTAddress] = true;
        nftContractsList.push(_newNFTAddress);
    }

    function setFeeRatio(uint256 newFeeRatio) public onlyOwner {
        feeRatio = newFeeRatio;
    }

    function getFeeRatio() public view returns(uint256) {
        return feeRatio;
    }

    function getNFTList() external view returns(address[] memory) {
        return nftContractsList;
    }

    function getUserTokenIds(address _nftContract) external view returns(uint256[] memory) {
        IERC721 _nft = IERC721(_nftContract);
        uint256 _balance = _nft.balanceOf(msg.sender);
        uint256[] memory _tokenIds = new uint256[](_balance);
        uint256 _index = 0;

        for(uint i = 0; _index < _balance; i++) {
            if(_nft.ownerOf(i) == msg.sender) {
                _tokenIds[_index] = i;
                _index++;
            }
        }
        return _tokenIds;
    }
    
    // create an auction
    function createAuction(uint _endTime, uint _minIncrement, uint _directBuyPrice,uint _startPrice,address _nftAddress,uint _tokenId) external returns (bool) {
        //require(_directBuyPrice > 0, "Direct buy price must be greater than 0!"); // direct buy price must be greater than 0
        if(_directBuyPrice > 0) {
            require(_startPrice < _directBuyPrice,"Start price is smaller than direct buy price!"); // start price is smaller than direct buy price
        }
        require(_minIncrement >= 10 ** 16, "Minimum increment must be greater or equal to 0.01!"); // minimum increment must be greater than 0
        require(_endTime > 1 minutes, "End time must be greater than 1 minutes!"); // end time must be greater than 5 minutes (setting it to 5 minutes for testing you can set it to 1 days or anything you would like)
        require(nftContracts[_nftAddress], "NFT is not a part of HeC Collections."); // the nft contract must be added to the auction manager

        uint auctionId = _auctionIdCounter; // get the current value of the counter
        _auctionIdCounter++; // increment the counter
        
        //Auction _auction = new Auction(msg.sender, _endTime, _minIncrement, _directBuyPrice, _startPrice, _nftAddress, _tokenId, bidToken, owner(), feeRatio); // create the auction
        
        Auction memory _auction = Auction(
            msg.sender, 
            _startPrice, 
            0, 
            payable(msg.sender), 
            _directBuyPrice, 
            _minIncrement, 
            false, 
            false, 
            block.timestamp +  _endTime, 
            _nftAddress, 
            _tokenId, 
            feeRatio,
            auctionId); // create the auction
        
        IERC721 _nftToken = IERC721(_nftAddress); // get the nft token
        _nftToken.transferFrom(msg.sender, address(this), _tokenId); // transfer the token to the auction
        userClaimableBids[msg.sender] += 1; // add one to the user's claimable bid count
        userClaimableNfts[msg.sender] += 1; // Check the case for no bidders
        auctions[auctionId] = _auction; // add the auction to the map
        nftContractAuctions[_nftAddress][_tokenId] = _auction; // add the auction to the nft contract auction map
        return true;
    }

    function getAuctionNumber() public view returns(uint) {
        return _auctionIdCounter;
    }

    // Return the information of each auction address
    function getAuctionInfo(uint256 _lastNumber)
        external
        view
        returns (
            uint256[] memory directBuy,
            address[] memory owner,
            uint256[] memory highestBid,
            address[] memory highestBidder,
            uint256[] memory tokenIds,
            uint256[] memory endTime,
            uint256[] memory startPrice,
            uint256[] memory auctionStates,
            address[] memory auctionNFTAddress,
            uint256[] memory auctionIds
        )
    {
        if(_lastNumber > _auctionIdCounter) {
            _lastNumber = _auctionIdCounter;
        }
        directBuy = new uint256[](_lastNumber); // create an array of size equal to the length of the passed array
        owner = new address[](_lastNumber); // create an array of size equal to the length of the passed array
        highestBid = new uint256[](_lastNumber);
        highestBidder = new address[](_lastNumber);
        tokenIds = new uint256[](_lastNumber);
        endTime = new uint256[](_lastNumber);
        startPrice = new uint256[](_lastNumber);
        auctionStates = new uint256[](_lastNumber);
        auctionNFTAddress = new address[](_lastNumber);
        auctionIds = new uint256[](_lastNumber);


        for (uint256 i = 0; i < _lastNumber; i++) { // for each auction
            directBuy[i] = auctions[_auctionIdCounter - i - 1].directBuyPrice; // get the direct buy price
            owner[i] = auctions[_auctionIdCounter - i - 1].creator; // get the owner of the auction
            highestBid[i] = auctions[_auctionIdCounter - i - 1].maxBid; // get the highest bid
            highestBidder[i] = auctions[_auctionIdCounter - i - 1].maxBidder;
            tokenIds[i] = auctions[_auctionIdCounter - i - 1].tokenId; // get the token id
            endTime[i] = auctions[_auctionIdCounter - i - 1].endTime; // get the end time
            startPrice[i] = auctions[_auctionIdCounter - i - 1].startPrice; // get the start price
            auctionStates[i] = uint256(getAuctionState(auctions[_auctionIdCounter - i - 1].auctionId)); // get the auction state
            auctionNFTAddress[i] = auctions[_auctionIdCounter - i - 1].nftAddress;
            auctionIds[i] = auctions[_auctionIdCounter - i - 1].auctionId;
        }
        
        return ( // return the arrays
            directBuy,
            owner,
            highestBid,
            highestBidder,
            tokenIds,
            endTime,
            startPrice,
            auctionStates,
            auctionNFTAddress,
            auctionIds
        );
    }

    function getClaimableBids(uint256 _lastNumber)
        external
        view
        returns (
            uint256[] memory highestBid,
            uint256[] memory tokenIds,
            address[] memory auctionNFTAddress,
            uint256[] memory auctionIds
        )
    {
        if(_lastNumber > _auctionIdCounter) {
            _lastNumber = _auctionIdCounter;
        }
        address _auctionOwner;
        uint256 _auctionState;
        address _highestBidder;
        uint256 _highestBid;
        uint256 _index = 0;

        highestBid = new uint256[](userClaimableBids[msg.sender]);
        tokenIds = new uint256[](userClaimableBids[msg.sender]);
        auctionNFTAddress = new address[](userClaimableBids[msg.sender]);
        auctionIds = new uint256[](userClaimableBids[msg.sender]);

        for (uint256 i = 0; i < _lastNumber; i++) { // for each auction
            _auctionState = uint256(getAuctionState(auctions[_auctionIdCounter - i - 1].auctionId));
            if(_auctionState == 2 || _auctionState == 3) {
                _auctionOwner = auctions[_auctionIdCounter - i - 1].creator; // get the owner of the auction
                _highestBidder = auctions[_auctionIdCounter - i - 1].maxBidder;
                _highestBid = auctions[_auctionIdCounter - i - 1].maxBid;
                if(msg.sender == _auctionOwner && !isClaimed[auctions[_auctionIdCounter - i - 1].auctionId]) {
                    highestBid[_index] = _highestBid;
                    tokenIds[_index] = auctions[_auctionIdCounter - i - 1].tokenId; // get the token id
                    auctionNFTAddress[_index] = auctions[_auctionIdCounter - i - 1].nftAddress;
                    auctionIds[_index] = auctions[_auctionIdCounter - i - 1].auctionId;
                    _index++;
                }
            }
        }
        
        return ( // return the arrays
            highestBid,
            tokenIds,
            auctionNFTAddress,
            auctionIds
        );
    }

    // Return the information of each auction address
    function getClaimableNFTs(uint256 _lastNumber)
        external
        view
        returns (
            uint256[] memory tokenIds,
            address[] memory auctionNFTAddress,
            uint256[] memory auctionIds
        )
    {
        if(_lastNumber > _auctionIdCounter) {
            _lastNumber = _auctionIdCounter;
        }
        address _auctionOwner;
        uint256 _auctionState;
        address _highestBidder;
        uint256 _highestBid;
        uint256 _index = 0;

        tokenIds = new uint256[](userClaimableNfts[msg.sender]);
        auctionNFTAddress = new address[](userClaimableNfts[msg.sender]);
        auctionIds = new uint256[](userClaimableNfts[msg.sender]);

        for (uint256 i = 0; i < _lastNumber; i++) { // for each auction
            _auctionState = uint256(getAuctionState(auctions[_auctionIdCounter - i - 1].auctionId));
            if(_auctionState == 2 || _auctionState == 3) {
                _auctionOwner = auctions[_auctionIdCounter - i - 1].creator; // get the owner of the auction
                _highestBidder = auctions[_auctionIdCounter - i - 1].maxBidder;
                _highestBid = auctions[_auctionIdCounter - i - 1].maxBid;
                if(msg.sender == _highestBidder && !isClaimed[auctions[_auctionIdCounter - i - 1].auctionId]) {
                    tokenIds[_index] = auctions[_auctionIdCounter - i - 1].tokenId; // get the token id
                    auctionNFTAddress[_index] = auctions[_auctionIdCounter - i - 1].nftAddress;
                    auctionIds[_index] = auctions[_auctionIdCounter - i - 1].auctionId;
                    _index++;
                }
            }
        }
        
        return ( // return the arrays
            tokenIds,
            auctionNFTAddress,
            auctionIds
        );
    }

    function getUserAuctions(uint256 _lastNumber)
        external
        view
        returns (
            uint256[] memory tokenIds,
            address[] memory auctionNFTAddress,
            uint256[] memory auctionIds
        )
    {
        if(_lastNumber > _auctionIdCounter) {
            _lastNumber = _auctionIdCounter;
        }
        address _auctionOwner;
        uint256 _auctionState;
        uint256 _index = 0;

        tokenIds = new uint256[](userClaimableBids[msg.sender]);
        auctionNFTAddress = new address[](userClaimableBids[msg.sender]);
        auctionIds = new uint256[](userClaimableBids[msg.sender]);

        for (uint256 i = 0; i < _lastNumber; i++) { // for each auction
            _auctionState = uint256(getAuctionState(auctions[_auctionIdCounter - i - 1].auctionId));
            if(_auctionState == 0) {
                _auctionOwner = auctions[_auctionIdCounter - i - 1].creator; // get the owner of the auction
                if(msg.sender == _auctionOwner && !isClaimed[auctions[_auctionIdCounter - i - 1].auctionId]) {
                    tokenIds[_index] = auctions[_auctionIdCounter - i - 1].tokenId; // get the token id
                    auctionNFTAddress[_index] = auctions[_auctionIdCounter - i - 1].nftAddress;
                    auctionIds[_index] = auctions[_auctionIdCounter - i - 1].auctionId;
                    _index++;
                }
            }
        }
        
        return ( // return the arrays
            tokenIds,
            auctionNFTAddress,
            auctionIds
        );
    }

    // Returns a list of all bids and addresses
    function allBids(uint256 _auctionId)
        external
        view
        returns (address[] memory, uint256[] memory)
    {
        uint256 _maxReturn = 10;
        Bid[] memory _bids = bids[_auctionId]; // get the bids of the auction
        if(_bids.length < _maxReturn) {
            _maxReturn = _bids.length;
        }
        address[] memory addrs = new address[](_maxReturn);
        uint256[] memory bidPrice = new uint256[](_maxReturn);
        for (uint256 i = 0; i < _maxReturn; i++) {
            addrs[i] = _bids[_bids.length - 1 - i].sender;
            bidPrice[i] = _bids[_bids.length - 1 - i].bid;
        }
        return (addrs, bidPrice);
    }


    // Place a bid on the auction
    function placeBid(address _nftContract, uint256 _tokenId, uint256 _bidValue) external returns(bool) {
        require(nftContracts[_nftContract], "NFT is not a part of HeC Collections."); // the nft contract must be added to the auction manager
        Auction storage _auction = nftContractAuctions[_nftContract][_tokenId]; // get the auction


        require(msg.sender != _auction.creator, "You cannot bid on your own auction. Consider cancelling."); // The auction creator can not place a bid
        require(getAuctionState(_auction.auctionId) == AuctionState.OPEN, "Auction is closed."); // The auction must be open
        require(_bidValue >= _auction.startPrice, "The bid must be higher than the starting price"); // The bid must be higher than the starting price
        require(_bidValue >= _auction.maxBid + _auction.minIncrement || _bidValue == _auction.directBuyPrice, "The bid must be higher or equal to the current bid + the minimum increment"); // The bid must be higher than the current bid + the minimum increment
        
        if(_bidValue > _auction.directBuyPrice && _auction.directBuyPrice > 0) { // If the bid is higher than the direct buy price
            _bidValue = _auction.directBuyPrice;
        }
        bidToken.safeTransferFrom(msg.sender, address(this), _bidValue);
        userClaimableNfts[msg.sender] += 1;

        address payable lastHightestBidder = payable(_auction.maxBidder); // The address of the last highest bidder
        uint256 lastHighestBid = _auction.maxBid; // The last highest bid
        _auction.maxBid = _bidValue; // The new highest bid
        _auction.maxBidder = payable(msg.sender); // The address of the new highest bidder

        nftContractAuctions[_nftContract][_tokenId] = _auction; // update the auction
        auctions[_auction.auctionId] = _auction;

        if(_bidValue >= _auction.directBuyPrice && _auction.directBuyPrice > 0) { // If the bid is higher than the direct buy price
            _auction.isDirectBuy = true; // The auction has ended
            nftContractAuctions[_nftContract][_tokenId] = _auction; // update the auction
            auctions[_auction.auctionId] = _auction;
            exchangeAssets(_nftContract, _tokenId); // Withdraw the token
        }
        bids[_auction.auctionId].push(Bid(msg.sender, _bidValue)); // Add the new bid to the list of bids

        if(lastHighestBid != 0){ // if there is a bid
            bidToken.safeTransfer(lastHightestBidder, lastHighestBid); // refund the previous bid to the previous highest bidder
        }
        userClaimableNfts[lastHightestBidder] -= 1; // remove the claimable nft from the user

        emit NewBid(msg.sender, _bidValue, _nftContract, _tokenId); // emit a new bid event
        return true; // The bid was placed successfully
    }

    function exchangeAssets(address _nftContract, uint256 _tokenId) public returns(bool) {
        require(nftContracts[_nftContract], "NFT is not a part of HeC Collections."); // the nft contract must be added to the auction manager
        Auction memory _auction = nftContractAuctions[_nftContract][_tokenId]; // get the auction
        IERC721 _nft = IERC721(_nftContract); // get the nft contract

        require(getAuctionState(_auction.auctionId) == AuctionState.ENDED || getAuctionState(_auction.auctionId) == AuctionState.DIRECT_BUY, "The auction must be ended by either a direct buy or timeout");
        require(msg.sender == _auction.creator || msg.sender == _auction.maxBidder, "You do not have the right to claim the funds.");
        require(!isClaimed[_auction.auctionId], "Rewards already claimed.");

        _nft.transferFrom(address(this), _auction.maxBidder, _tokenId); // Transfer the token to the highest bidder
        emit WithdrawToken(_auction.maxBidder, _nftContract, _tokenId); // Emit a withdraw token event

        uint256 fee = (_auction.maxBid * _auction.feeRatio) / 100;
        bidToken.safeTransfer(owner(), fee); // sends fee to marketplace 
        bidToken.safeTransfer(_auction.creator, _auction.maxBid - fee); // Transfers funds to the creator
        emit WithdrawFunds(msg.sender, _auction.maxBid, _nftContract, _tokenId); // Emit a withdraw funds event

        isClaimed[_auction.auctionId] = true;
        auctions[_auction.auctionId] = _auction;
        nftContractAuctions[_nftContract][_tokenId] = _auction;

        userClaimableBids[_auction.creator] -= 1;
        userClaimableNfts[_auction.maxBidder] -= 1;
        return true;
    }

    function cancelAuction(address _nftContract, uint256 _tokenId) external returns(bool){ // Cancel the auction
        require(nftContracts[_nftContract], "NFT is not a part of HeC Collections."); // the nft contract must be added to the auction manager
        Auction memory _auction = nftContractAuctions[_nftContract][_tokenId]; // get the auction
        IERC721 _nft = IERC721(_nftContract); // get the nft contract

        require(msg.sender == _auction.creator, "You must be the owner of the auction to cancel."); // Only the auction creator can cancel the auction
        require(getAuctionState(_auction.auctionId) == AuctionState.OPEN, "Auction is already closed."); // The auction must be open
        require(_auction.maxBid == 0, "There is already a bid, cannot cancel auction."); // The auction must not be cancelled if there is a bid
        _auction.isCancelled = true; // The auction has been cancelled
        _nft.transferFrom(address(this), _auction.creator, _auction.tokenId); // Transfer the NFT token to the auction creator

        nftContractAuctions[_nftContract][_tokenId] = _auction; // update the auction
        auctions[_auction.auctionId] = _auction;
        userClaimableBids[msg.sender] -= 1;
        emit AuctionCanceled(_nftContract, _tokenId); // Emit Auction Canceled event
        return true;
    } 

    // Get the auction state
    function getAuctionState(uint256 _auctionId) public view returns(AuctionState) {
        Auction memory _auction = auctions[_auctionId]; // get the auction

        if(_auction.isCancelled) return AuctionState.CANCELLED; // If the auction is cancelled return CANCELLED
        if(_auction.isDirectBuy) return AuctionState.DIRECT_BUY; // If the auction is ended by a direct buy return DIRECT_BUY
        if(block.timestamp >= _auction.endTime) return AuctionState.ENDED; // The auction is over if the block timestamp is greater than the end timestamp, return ENDED
        return AuctionState.OPEN; // Otherwise return OPEN
    } 

    event NewBid(address bidder, uint bid, address nftContract, uint256 tokenId); // A new bid was placed
    event WithdrawToken(address withdrawer, address nftContract, uint256 tokenId); // The auction winner withdrawed the token
    event WithdrawFunds(address withdrawer, uint256 amount, address nftContract, uint256 tokenId); // The auction owner withdrawed the funds
    event AuctionCanceled(address nftContract, uint256 tokenId); // The auction was cancelled
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"_bidToken","type":"address"},{"internalType":"uint256","name":"_feeRatio","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"nftContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"AuctionCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"bidder","type":"address"},{"indexed":false,"internalType":"uint256","name":"bid","type":"uint256"},{"indexed":false,"internalType":"address","name":"nftContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"NewBid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"withdrawer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"nftContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"WithdrawFunds","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"withdrawer","type":"address"},{"indexed":false,"internalType":"address","name":"nftContract","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"WithdrawToken","type":"event"},{"inputs":[{"internalType":"address","name":"_newNFTAddress","type":"address"}],"name":"addNewContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_auctionId","type":"uint256"}],"name":"allBids","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"auctions","outputs":[{"internalType":"address","name":"creator","type":"address"},{"internalType":"uint256","name":"startPrice","type":"uint256"},{"internalType":"uint256","name":"maxBid","type":"uint256"},{"internalType":"address","name":"maxBidder","type":"address"},{"internalType":"uint256","name":"directBuyPrice","type":"uint256"},{"internalType":"uint256","name":"minIncrement","type":"uint256"},{"internalType":"bool","name":"isDirectBuy","type":"bool"},{"internalType":"bool","name":"isCancelled","type":"bool"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"address","name":"nftAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"feeRatio","type":"uint256"},{"internalType":"uint256","name":"auctionId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nftContract","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"cancelAuction","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_endTime","type":"uint256"},{"internalType":"uint256","name":"_minIncrement","type":"uint256"},{"internalType":"uint256","name":"_directBuyPrice","type":"uint256"},{"internalType":"uint256","name":"_startPrice","type":"uint256"},{"internalType":"address","name":"_nftAddress","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"createAuction","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nftContract","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"exchangeAssets","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lastNumber","type":"uint256"}],"name":"getAuctionInfo","outputs":[{"internalType":"uint256[]","name":"directBuy","type":"uint256[]"},{"internalType":"address[]","name":"owner","type":"address[]"},{"internalType":"uint256[]","name":"highestBid","type":"uint256[]"},{"internalType":"address[]","name":"highestBidder","type":"address[]"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"endTime","type":"uint256[]"},{"internalType":"uint256[]","name":"startPrice","type":"uint256[]"},{"internalType":"uint256[]","name":"auctionStates","type":"uint256[]"},{"internalType":"address[]","name":"auctionNFTAddress","type":"address[]"},{"internalType":"uint256[]","name":"auctionIds","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAuctionNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_auctionId","type":"uint256"}],"name":"getAuctionState","outputs":[{"internalType":"enum AuctionManagerCustomToken.AuctionState","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBidToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lastNumber","type":"uint256"}],"name":"getClaimableBids","outputs":[{"internalType":"uint256[]","name":"highestBid","type":"uint256[]"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"address[]","name":"auctionNFTAddress","type":"address[]"},{"internalType":"uint256[]","name":"auctionIds","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lastNumber","type":"uint256"}],"name":"getClaimableNFTs","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"address[]","name":"auctionNFTAddress","type":"address[]"},{"internalType":"uint256[]","name":"auctionIds","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFeeRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNFTList","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lastNumber","type":"uint256"}],"name":"getUserAuctions","outputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"address[]","name":"auctionNFTAddress","type":"address[]"},{"internalType":"uint256[]","name":"auctionIds","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nftContract","type":"address"}],"name":"getUserTokenIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"isClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"nftContractAuctions","outputs":[{"internalType":"address","name":"creator","type":"address"},{"internalType":"uint256","name":"startPrice","type":"uint256"},{"internalType":"uint256","name":"maxBid","type":"uint256"},{"internalType":"address","name":"maxBidder","type":"address"},{"internalType":"uint256","name":"directBuyPrice","type":"uint256"},{"internalType":"uint256","name":"minIncrement","type":"uint256"},{"internalType":"bool","name":"isDirectBuy","type":"bool"},{"internalType":"bool","name":"isCancelled","type":"bool"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"address","name":"nftAddress","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"feeRatio","type":"uint256"},{"internalType":"uint256","name":"auctionId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nftContracts","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"nftContractsList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_nftContract","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_bidValue","type":"uint256"}],"name":"placeBid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFeeRatio","type":"uint256"}],"name":"setFeeRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b50604051620047a0380380620047a08339810160408190526200003491620000b9565b6200003f3362000069565b600880546001600160a01b0319166001600160a01b039390931692909217909155600955620000f3565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60008060408385031215620000cc578182fd5b82516001600160a01b0381168114620000e3578283fd5b6020939093015192949293505050565b61469d80620001036000396000f3fe608060405234801561001057600080fd5b50600436106101735760003560e01c8063859b97fe116100de5780639e34070f11610097578063ba771ad411610071578063ba771ad4146104e5578063d5cafaf3146104f8578063f2fde38b1461050b578063fc3fc4ed1461051e57600080fd5b80639e34070f1461048e578063ada0f98f146104b1578063b954a6e3146104d457600080fd5b8063859b97fe146104085780638da5cb5b1461041b57806390a351061461044057806390b958f31461045357806392ddf23c1461045b5780639a7fda661461047b57600080fd5b80632fb5eac2116101305780632fb5eac214610310578063445a211214610331578063571a26a01461034657806357f5a95e146103cb57806359362b88146103ee578063715018a61461040057600080fd5b8063041fa0b81461017857806304717aca1461028357806309881007146102a6578063118a2b4d146102c657806319f4ff2f146102e857806328012606146102fd575b600080fd5b61020561018636600461413e565b6006602081815260009384526040808520909152918352912080546001820154600283015460038401546004850154600586015496860154600787015460088801546009890154600a8a0154600b909a01546001600160a01b03998a169b989a9799968716989597959660ff808716976101009097041695931692908d565b604080516001600160a01b039e8f168152602081019d909d528c019a909a52978b1660608b015260808a019690965260a089019490945291151560c0880152151560e08701526101008601529094166101208401526101408301939093526101608201929092526101808101919091526101a0015b60405180910390f35b610296610291366004614169565b610547565b604051901515815260200161027a565b6102b96102b43660046141bd565b611009565b60405161027a91906144b2565b6102d96102d43660046141bd565b611102565b60405161027a93929190614347565b6102fb6102f63660046141bd565b61154a565b005b61029661030b3660046141ed565b611579565b61032361031e3660046141bd565b611ac4565b60405161027a929190614306565b610339611d19565b60405161027a91906142f3565b6102056103543660046141bd565b600260208190526000918252604090912080546001820154928201546003830154600484015460058501546006860154600787015460088801546009890154600a8a0154600b909a01546001600160a01b03998a169b9a9899978816989697959660ff80871697610100909704169590931692908d565b6103de6103d93660046141bd565b611d7b565b60405161027a9493929190614465565b6009545b60405190815260200161027a565b6102fb612232565b61029661041636600461413e565b612268565b6000546001600160a01b03165b6040516001600160a01b03909116815260200161027a565b6102d961044e3660046141bd565b612836565b6001546103f2565b61046e610469366004614106565b612bbc565b60405161027a9190614334565b6102fb610489366004614106565b612d7d565b61029661049c3660046141bd565b60036020526000908152604090205460ff1681565b6102966104bf366004614106565b60046020526000908152604090205460ff1681565b6008546001600160a01b0316610428565b6102966104f336600461413e565b612e0d565b6104286105063660046141bd565b613581565b6102fb610519366004614106565b6135ab565b61053161052c3660046141bd565b613646565b60405161027a9a9998979695949392919061438a565b6001600160a01b03831660009081526004602052604081205460ff166105885760405162461bcd60e51b815260040161057f9061450d565b60405180910390fd5b6001600160a01b038481166000908152600660209081526040808320878452909152902080549091163314156106265760405162461bcd60e51b815260206004820152603860248201527f596f752063616e6e6f7420626964206f6e20796f7572206f776e20617563746960448201527f6f6e2e20436f6e73696465722063616e63656c6c696e672e0000000000000000606482015260840161057f565b600061063582600b0154611009565b600381111561065457634e487b7160e01b600052602160045260246000fd5b146106965760405162461bcd60e51b815260206004820152601260248201527120bab1ba34b7b71034b99031b637b9b2b21760711b604482015260640161057f565b80600101548310156107015760405162461bcd60e51b815260206004820152602e60248201527f54686520626964206d75737420626520686967686572207468616e207468652060448201526d7374617274696e6720707269636560901b606482015260840161057f565b806005015481600201546107159190614587565b831015806107265750806004015483145b6107ab5760405162461bcd60e51b815260206004820152604a60248201527f54686520626964206d75737420626520686967686572206f7220657175616c2060448201527f746f207468652063757272656e7420626964202b20746865206d696e696d756d606482015269081a5b98dc995b595b9d60b21b608482015260a40161057f565b8060040154831180156107c2575060008160040154115b156107cf57806004015492505b6008546107e7906001600160a01b0316333086613dd0565b336000908152600b60205260408120805460019290610807908490614587565b9250508190555060008160030160009054906101000a90046001600160a01b03169050600082600201549050848360020181905550338360030160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508260066000896001600160a01b03166001600160a01b0316815260200190815260200160002060008881526020019081526020016000206000820160009054906101000a90046001600160a01b03168160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060018201548160010155600282015481600201556003820160009054906101000a90046001600160a01b03168160030160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060048201548160040155600582015481600501556006820160009054906101000a900460ff168160060160006101000a81548160ff0219169083151502179055506006820160019054906101000a900460ff168160060160016101000a81548160ff021916908315150217905550600782015481600701556008820160009054906101000a90046001600160a01b03168160080160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060098201548160090155600a82015481600a0155600b82015481600b0155905050826002600085600b015481526020019081526020016000206000820160009054906101000a90046001600160a01b03168160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060018201548160010155600282015481600201556003820160009054906101000a90046001600160a01b03168160030160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060048201548160040155600582015481600501556006820160009054906101000a900460ff168160060160006101000a81548160ff0219169083151502179055506006820160019054906101000a900460ff168160060160016101000a81548160ff021916908315150217905550600782015481600701556008820160009054906101000a90046001600160a01b03168160080160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060098201548160090155600a82015481600a0155600b82015481600b015590505082600401548510158015610ba6575060008360040154115b15610efd5760018360060160006101000a81548160ff0219169083151502179055508260066000896001600160a01b03166001600160a01b0316815260200190815260200160002060008881526020019081526020016000206000820160009054906101000a90046001600160a01b03168160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060018201548160010155600282015481600201556003820160009054906101000a90046001600160a01b03168160030160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060048201548160040155600582015481600501556006820160009054906101000a900460ff168160060160006101000a81548160ff0219169083151502179055506006820160019054906101000a900460ff168160060160016101000a81548160ff021916908315150217905550600782015481600701556008820160009054906101000a90046001600160a01b03168160080160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060098201548160090155600a82015481600a0155600b82015481600b0155905050826002600085600b015481526020019081526020016000206000820160009054906101000a90046001600160a01b03168160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060018201548160010155600282015481600201556003820160009054906101000a90046001600160a01b03168160030160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060048201548160040155600582015481600501556006820160009054906101000a900460ff168160060160006101000a81548160ff0219169083151502179055506006820160019054906101000a900460ff168160060160016101000a81548160ff021916908315150217905550600782015481600701556008820160009054906101000a90046001600160a01b03168160080160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060098201548160090155600a82015481600a0155600b82015481600b0155905050610efb8787612e0d565b505b600b83015460009081526007602090815260408083208151808301909252338252818301898152815460018082018455928652939094209151600290930290910180546001600160a01b0319166001600160a01b0390931692909217825591519101558015610f7d57600854610f7d906001600160a01b03168383613e2e565b6001600160a01b0382166000908152600b60205260408120805460019290610fa69084906145de565b909155505060408051338152602081018790526001600160a01b038916818301526060810188905290517f0e1f7a6c628fd95c9633b2732b8035b7e8d0df8120df2274beadefa5296d5e949181900360800190a1600193505050505b9392505050565b600081815260026020818152604080842081516101a08101835281546001600160a01b039081168252600183015494820194909452938101549184019190915260038101548216606084015260048101546080840152600581015460a0840152600681015460ff808216151560c0860152610100918290041615801560e086015260078301549185019190915260088201549092166101208401526009810154610140840152600a810154610160840152600b01546101808301526110d15750600192915050565b8060c00151156110e45750600392915050565b80610100015142106110f95750600292915050565b50600092915050565b60608060606001548411156111175760015493505b336000908152600b602052604081205481908190819081906001600160401b0381111561115457634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561117d578160200160208202803683370190505b50336000908152600b60205260409020549098506001600160401b038111156111b657634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156111df578160200160208202803683370190505b50336000908152600b60205260409020549097506001600160401b0381111561121857634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611241578160200160208202803683370190505b50955060005b8981101561153d576112876002600060018460015461126691906145de565b61127091906145de565b8152602001908152602001600020600b0154611009565b60038111156112a657634e487b7160e01b600052602160045260246000fd5b945084600214806112b75750846003145b1561152b57600260006001836001546112d091906145de565b6112da91906145de565b81526020810191909152604001600090812054600180546001600160a01b0390921698506002929161130d9085906145de565b61131791906145de565b815260200190815260200160002060030160009054906101000a90046001600160a01b031693506002600060018360015461135291906145de565b61135c91906145de565b8152602001908152602001600020600201549250836001600160a01b0316336001600160a01b03161480156113de575060036000600260006001856001546113a491906145de565b6113ae91906145de565b8152602001908152602001600020600b0154815260200190815260200160002060009054906101000a900460ff16155b1561152b57600260006001836001546113f791906145de565b61140191906145de565b81526020019081526020016000206009015489838151811061143357634e487b7160e01b600052603260045260246000fd5b6020026020010181815250506002600060018360015461145391906145de565b61145d91906145de565b815260200190815260200160002060080160009054906101000a90046001600160a01b03168883815181106114a257634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b031681525050600260006001836001546114d691906145de565b6114e091906145de565b8152602001908152602001600020600b015487838151811061151257634e487b7160e01b600052603260045260246000fd5b60209081029190910101528161152781614621565b9250505b8061153581614621565b915050611247565b5050505050509193909250565b6000546001600160a01b031633146115745760405162461bcd60e51b815260040161057f90614552565b600955565b600084156115e6578484106115e65760405162461bcd60e51b815260206004820152602d60248201527f537461727420707269636520697320736d616c6c6572207468616e206469726560448201526c6374206275792070726963652160981b606482015260840161057f565b662386f26fc100008610156116595760405162461bcd60e51b815260206004820152603360248201527f4d696e696d756d20696e6372656d656e74206d7573742062652067726561746560448201527272206f7220657175616c20746f20302e30312160681b606482015260840161057f565b603c87116116ba5760405162461bcd60e51b815260206004820152602860248201527f456e642074696d65206d7573742062652067726561746572207468616e2031206044820152676d696e757465732160c01b606482015260840161057f565b6001600160a01b03831660009081526004602052604090205460ff166116f25760405162461bcd60e51b815260040161057f9061450d565b60018054908190600061170483614621565b9091555050604080516101a0810182523380825260208201889052600092820183905260608201526080810188905260a0810189905260c0810182905260e0810182905261010081016117578b42614587565b81526001600160a01b0387166020820181905260408083018890526009546060840152608090920185905290516323b872dd60e01b815291925086916323b872dd906117ab90339030908a906004016142cf565b600060405180830381600087803b1580156117c557600080fd5b505af11580156117d9573d6000803e3d6000fd5b5050336000908152600a602052604081208054600194509092506117fe908490614587565b9091555050336000908152600b60205260408120805460019290611823908490614587565b92505081905550816002600085815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550602082015181600101556040820151816002015560608201518160030160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506080820151816004015560a0820151816005015560c08201518160060160006101000a81548160ff02191690831515021790555060e08201518160060160016101000a81548160ff02191690831515021790555061010082015181600701556101208201518160080160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610140820151816009015561016082015181600a015561018082015181600b01559050508160066000886001600160a01b03166001600160a01b03168152602001908152602001600020600087815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550602082015181600101556040820151816002015560608201518160030160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506080820151816004015560a0820151816005015560c08201518160060160006101000a81548160ff02191690831515021790555060e08201518160060160016101000a81548160ff02191690831515021790555061010082015181600701556101208201518160080160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610140820151816009015561016082015181600a015561018082015181600b0155905050600193505050509695505050505050565b600081815260076020908152604080832080548251818502810185019093528083526060948594600a949193919290849084015b82821015611b40576000848152602090819020604080518082019091526002850290910180546001600160a01b03168252600190810154828401529083529092019101611af8565b5050505090508181511015611b5457805191505b6000826001600160401b03811115611b7c57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611ba5578160200160208202803683370190505b5090506000836001600160401b03811115611bd057634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611bf9578160200160208202803683370190505b50905060005b84811015611d0c57838160018651611c1791906145de565b611c2191906145de565b81518110611c3f57634e487b7160e01b600052603260045260246000fd5b602002602001015160000151838281518110611c6b57634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b031681525050838160018651611c9b91906145de565b611ca591906145de565b81518110611cc357634e487b7160e01b600052603260045260246000fd5b602002602001015160200151828281518110611cef57634e487b7160e01b600052603260045260246000fd5b602090810291909101015280611d0481614621565b915050611bff565b5090969095509350505050565b60606005805480602002602001604051908101604052809291908181526020018280548015611d7157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611d53575b5050505050905090565b606080606080600154851115611d915760015494505b336000908152600a602052604081205481908190819081906001600160401b03811115611dce57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611df7578160200160208202803683370190505b50336000908152600a60205260409020549099506001600160401b03811115611e3057634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611e59578160200160208202803683370190505b50336000908152600a60205260409020549098506001600160401b03811115611e9257634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611ebb578160200160208202803683370190505b50336000908152600a60205260409020549097506001600160401b03811115611ef457634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611f1d578160200160208202803683370190505b50955060005b8a81101561222557611f426002600060018460015461126691906145de565b6003811115611f6157634e487b7160e01b600052602160045260246000fd5b94508460021480611f725750846003145b156122135760026000600183600154611f8b91906145de565b611f9591906145de565b81526020810191909152604001600090812054600180546001600160a01b03909216985060029291611fc89085906145de565b611fd291906145de565b815260200190815260200160002060030160009054906101000a90046001600160a01b031693506002600060018360015461200d91906145de565b61201791906145de565b8152602001908152602001600020600201549250856001600160a01b0316336001600160a01b03161480156120995750600360006002600060018560015461205f91906145de565b61206991906145de565b8152602001908152602001600020600b0154815260200190815260200160002060009054906101000a900460ff16155b1561221357828a83815181106120bf57634e487b7160e01b600052603260045260246000fd5b602002602001018181525050600260006001836001546120df91906145de565b6120e991906145de565b81526020019081526020016000206009015489838151811061211b57634e487b7160e01b600052603260045260246000fd5b6020026020010181815250506002600060018360015461213b91906145de565b61214591906145de565b815260200190815260200160002060080160009054906101000a90046001600160a01b031688838151811061218a57634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b031681525050600260006001836001546121be91906145de565b6121c891906145de565b8152602001908152602001600020600b01548783815181106121fa57634e487b7160e01b600052603260045260246000fd5b60209081029190910101528161220f81614621565b9250505b8061221d81614621565b915050611f23565b5050505050509193509193565b6000546001600160a01b0316331461225c5760405162461bcd60e51b815260040161057f90614552565b6122666000613e63565b565b6001600160a01b03821660009081526004602052604081205460ff166122a05760405162461bcd60e51b815260040161057f9061450d565b6001600160a01b03808416600090815260066020818152604080842087855282529283902083516101a0810185528154861680825260018301549382019390935260028201549481019490945260038101548516606085015260048101546080850152600581015460a08501529182015460ff808216151560c08601526101009182900416151560e085015260078301549084015260088201549093166101208301526009810154610140830152600a810154610160830152600b015461018082015290849033146123cc5760405162461bcd60e51b815260206004820152602f60248201527f596f75206d75737420626520746865206f776e6572206f66207468652061756360448201526e3a34b7b7103a379031b0b731b2b61760891b606482015260840161057f565b60006123dc836101800151611009565b60038111156123fb57634e487b7160e01b600052602160045260246000fd5b146124485760405162461bcd60e51b815260206004820152601a60248201527f41756374696f6e20697320616c726561647920636c6f7365642e000000000000604482015260640161057f565b6040820151156124b15760405162461bcd60e51b815260206004820152602e60248201527f546865726520697320616c72656164792061206269642c2063616e6e6f74206360448201526d30b731b2b61030bab1ba34b7b71760911b606482015260840161057f565b600160e083015281516101408301516040516323b872dd60e01b81526001600160a01b038416926323b872dd926124ee92309291906004016142cf565b600060405180830381600087803b15801561250857600080fd5b505af115801561251c573d6000803e3d6000fd5b505050508160066000876001600160a01b03166001600160a01b03168152602001908152602001600020600086815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550602082015181600101556040820151816002015560608201518160030160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506080820151816004015560a0820151816005015560c08201518160060160006101000a81548160ff02191690831515021790555060e08201518160060160016101000a81548160ff02191690831515021790555061010082015181600701556101208201518160080160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610140820151816009015561016082015181600a015561018082015181600b01559050508160026000846101800151815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550602082015181600101556040820151816002015560608201518160030160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506080820151816004015560a0820151816005015560c08201518160060160006101000a81548160ff02191690831515021790555060e08201518160060160016101000a81548160ff02191690831515021790555061010082015181600701556101208201518160080160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610140820151816009015561016082015181600a015561018082015181600b01559050506001600a6000336001600160a01b03166001600160a01b0316815260200190815260200160002060008282546127e491906145de565b9091555050604080516001600160a01b0387168152602081018690527f39e6c898ce035bbacd9ba4f9753534f8c9f976e0ff70be83cfe887f235afa1d3910160405180910390a1506001949350505050565b606080606060015484111561284b5760015493505b336000908152600a6020526040812054819081906001600160401b0381111561288457634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156128ad578160200160208202803683370190505b50336000908152600a60205260409020549096506001600160401b038111156128e657634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561290f578160200160208202803683370190505b50336000908152600a60205260409020549095506001600160401b0381111561294857634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612971578160200160208202803683370190505b50935060005b87811015612bb1576129966002600060018460015461126691906145de565b60038111156129b557634e487b7160e01b600052602160045260246000fd5b925082612b9f57600260006001836001546129d091906145de565b6129da91906145de565b81526020810191909152604001600020546001600160a01b031693503384148015612a5257506003600060026000600185600154612a1891906145de565b612a2291906145de565b8152602001908152602001600020600b0154815260200190815260200160002060009054906101000a900460ff16155b15612b9f5760026000600183600154612a6b91906145de565b612a7591906145de565b815260200190815260200160002060090154878381518110612aa757634e487b7160e01b600052603260045260246000fd5b60200260200101818152505060026000600183600154612ac791906145de565b612ad191906145de565b815260200190815260200160002060080160009054906101000a90046001600160a01b0316868381518110612b1657634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b03168152505060026000600183600154612b4a91906145de565b612b5491906145de565b8152602001908152602001600020600b0154858381518110612b8657634e487b7160e01b600052603260045260246000fd5b602090810291909101015281612b9b81614621565b9250505b80612ba981614621565b915050612977565b505050509193909250565b6040516370a0823160e01b815233600482015260609082906000906001600160a01b038316906370a082319060240160206040518083038186803b158015612c0357600080fd5b505afa158015612c17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c3b91906141d5565b90506000816001600160401b03811115612c6557634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612c8e578160200160208202803683370190505b5090506000805b83821015612d72576040516331a9108f60e11b81526004810182905233906001600160a01b03871690636352211e9060240160206040518083038186803b158015612cdf57600080fd5b505afa158015612cf3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d179190614122565b6001600160a01b03161415612d605780838381518110612d4757634e487b7160e01b600052603260045260246000fd5b602090810291909101015281612d5c81614621565b9250505b80612d6a81614621565b915050612c95565b509095945050505050565b6000546001600160a01b03163314612da75760405162461bcd60e51b815260040161057f90614552565b6001600160a01b03166000818152600460205260408120805460ff191660019081179091556005805491820181559091527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00180546001600160a01b0319169091179055565b6001600160a01b03821660009081526004602052604081205460ff16612e455760405162461bcd60e51b815260040161057f9061450d565b6001600160a01b03808416600090815260066020818152604080842087855282529283902083516101a0810185528154861681526001820154928101929092526002808201549483019490945260038101548516606083015260048101546080830152600581015460a08301529182015460ff808216151560c08401526101009182900416151560e083015260078301549082015260088201549093166101208401526009810154610140840152600a810154610160840152600b01546101808301528490612f18836101800151611009565b6003811115612f3757634e487b7160e01b600052602160045260246000fd5b1480612f6f57506003612f4e836101800151611009565b6003811115612f6d57634e487b7160e01b600052602160045260246000fd5b145b612fe15760405162461bcd60e51b815260206004820152603b60248201527f5468652061756374696f6e206d75737420626520656e6465642062792065697460448201527f68657220612064697265637420627579206f722074696d656f75740000000000606482015260840161057f565b81516001600160a01b031633148061300e575081606001516001600160a01b0316336001600160a01b0316145b6130705760405162461bcd60e51b815260206004820152602d60248201527f596f7520646f206e6f7420686176652074686520726967687420746f20636c6160448201526c34b6903a343290333ab732399760991b606482015260840161057f565b61018082015160009081526003602052604090205460ff16156130d55760405162461bcd60e51b815260206004820152601860248201527f5265776172647320616c726561647920636c61696d65642e0000000000000000604482015260640161057f565b60608201516040516323b872dd60e01b81526001600160a01b038316916323b872dd9161310891309189906004016142cf565b600060405180830381600087803b15801561312257600080fd5b505af1158015613136573d6000803e3d6000fd5b505050507f037238854fe57fbf51f09946f854fc3916fe83938d6521f09bd05463839f130482606001518686604051613171939291906142cf565b60405180910390a160006064836101600151846040015161319291906145bf565b61319c919061459f565b90506131c66131b36000546001600160a01b031690565b6008546001600160a01b03169083613e2e565b6131f183600001518285604001516131de91906145de565b6008546001600160a01b03169190613e2e565b604083810151815133815260208101919091526001600160a01b038816818301526060810187905290517f62aa87e2fb76c553f1e5c0c7d479446974609c79292b00f40eb58d2031a8f9f39181900360800190a1600160036000856101800151815260200190815260200160002060006101000a81548160ff0219169083151502179055508260026000856101800151815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550602082015181600101556040820151816002015560608201518160030160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506080820151816004015560a0820151816005015560c08201518160060160006101000a81548160ff02191690831515021790555060e08201518160060160016101000a81548160ff02191690831515021790555061010082015181600701556101208201518160080160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610140820151816009015561016082015181600a015561018082015181600b01559050508260066000886001600160a01b03166001600160a01b03168152602001908152602001600020600087815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550602082015181600101556040820151816002015560608201518160030160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506080820151816004015560a0820151816005015560c08201518160060160006101000a81548160ff02191690831515021790555060e08201518160060160016101000a81548160ff02191690831515021790555061010082015181600701556101208201518160080160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550610140820151816009015561016082015181600a015561018082015181600b01559050506001600a600085600001516001600160a01b03166001600160a01b03168152602001908152602001600020600082825461353e91906145de565b909155505060608301516001600160a01b03166000908152600b602052604081208054600192906135709084906145de565b909155506001979650505050505050565b6005818154811061359157600080fd5b6000918252602090912001546001600160a01b0316905081565b6000546001600160a01b031633146135d55760405162461bcd60e51b815260040161057f90614552565b6001600160a01b03811661363a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161057f565b61364381613e63565b50565b6060806060806060806060806060806001548b1115613665576001549a505b8a6001600160401b0381111561368b57634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156136b4578160200160208202803683370190505b5099508a6001600160401b038111156136dd57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015613706578160200160208202803683370190505b5098508a6001600160401b0381111561372f57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015613758578160200160208202803683370190505b5097508a6001600160401b0381111561378157634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156137aa578160200160208202803683370190505b5096508a6001600160401b038111156137d357634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156137fc578160200160208202803683370190505b5095508a6001600160401b0381111561382557634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561384e578160200160208202803683370190505b5094508a6001600160401b0381111561387757634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156138a0578160200160208202803683370190505b5093508a6001600160401b038111156138c957634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156138f2578160200160208202803683370190505b5092508a6001600160401b0381111561391b57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015613944578160200160208202803683370190505b5091508a6001600160401b0381111561396d57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015613996578160200160208202803683370190505b50905060005b8b811015613dc257600260006001836001546139b891906145de565b6139c291906145de565b8152602001908152602001600020600401548b82815181106139f457634e487b7160e01b600052603260045260246000fd5b60200260200101818152505060026000600183600154613a1491906145de565b613a1e91906145de565b81526020810191909152604001600020548a516001600160a01b03909116908b9083908110613a5d57634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b03168152505060026000600183600154613a9191906145de565b613a9b91906145de565b815260200190815260200160002060020154898281518110613acd57634e487b7160e01b600052603260045260246000fd5b60200260200101818152505060026000600183600154613aed91906145de565b613af791906145de565b815260200190815260200160002060030160009054906101000a90046001600160a01b0316888281518110613b3c57634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b03168152505060026000600183600154613b7091906145de565b613b7a91906145de565b815260200190815260200160002060090154878281518110613bac57634e487b7160e01b600052603260045260246000fd5b60200260200101818152505060026000600183600154613bcc91906145de565b613bd691906145de565b815260200190815260200160002060070154868281518110613c0857634e487b7160e01b600052603260045260246000fd5b60200260200101818152505060026000600183600154613c2891906145de565b613c3291906145de565b815260200190815260200160002060010154858281518110613c6457634e487b7160e01b600052603260045260246000fd5b602002602001018181525050613c876002600060018460015461126691906145de565b6003811115613ca657634e487b7160e01b600052602160045260246000fd5b848281518110613cc657634e487b7160e01b600052603260045260246000fd5b60200260200101818152505060026000600183600154613ce691906145de565b613cf091906145de565b815260200190815260200160002060080160009054906101000a90046001600160a01b0316838281518110613d3557634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b03168152505060026000600183600154613d6991906145de565b613d7391906145de565b8152602001908152602001600020600b0154828281518110613da557634e487b7160e01b600052603260045260246000fd5b602090810291909101015280613dba81614621565b91505061399c565b509193959799509193959799565b613e28846323b872dd60e01b858585604051602401613df1939291906142cf565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613eb3565b50505050565b6040516001600160a01b038316602482015260448101829052613e5e90849063a9059cbb60e01b90606401613df1565b505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000613f08826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613f859092919063ffffffff16565b805190915015613e5e5780806020019051810190613f26919061419d565b613e5e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161057f565b6060613f948484600085613f9c565b949350505050565b606082471015613ffd5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161057f565b6001600160a01b0385163b6140545760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161057f565b600080866001600160a01b0316858760405161407091906142b3565b60006040518083038185875af1925050503d80600081146140ad576040519150601f19603f3d011682016040523d82523d6000602084013e6140b2565b606091505b50915091506140c28282866140cd565b979650505050505050565b606083156140dc575081611002565b8251156140ec5782518084602001fd5b8160405162461bcd60e51b815260040161057f91906144da565b600060208284031215614117578081fd5b813561100281614652565b600060208284031215614133578081fd5b815161100281614652565b60008060408385031215614150578081fd5b823561415b81614652565b946020939093013593505050565b60008060006060848603121561417d578081fd5b833561418881614652565b95602085013595506040909401359392505050565b6000602082840312156141ae578081fd5b81518015158114611002578182fd5b6000602082840312156141ce578081fd5b5035919050565b6000602082840312156141e6578081fd5b5051919050565b60008060008060008060c08789031215614205578182fd5b86359550602087013594506040870135935060608701359250608087013561422c81614652565b8092505060a087013590509295509295509295565b6000815180845260208085019450808401835b838110156142795781516001600160a01b031687529582019590820190600101614254565b509495945050505050565b6000815180845260208085019450808401835b8381101561427957815187529582019590820190600101614297565b600082516142c58184602087016145f5565b9190910192915050565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6020815260006110026020830184614241565b6040815260006143196040830185614241565b828103602084015261432b8185614284565b95945050505050565b6020815260006110026020830184614284565b60608152600061435a6060830186614284565b828103602084015261436c8186614241565b905082810360408401526143808185614284565b9695505050505050565b600061014080835261439e8184018e614284565b905082810360208401526143b2818d614241565b905082810360408401526143c6818c614284565b905082810360608401526143da818b614241565b905082810360808401526143ee818a614284565b905082810360a08401526144028189614284565b905082810360c08401526144168188614284565b905082810360e084015261442a8187614284565b905082810361010084015261443f8186614241565b90508281036101208401526144548185614284565b9d9c50505050505050505050505050565b6080815260006144786080830187614284565b828103602084015261448a8187614284565b9050828103604084015261449e8186614241565b905082810360608401526140c28185614284565b60208101600483106144d457634e487b7160e01b600052602160045260246000fd5b91905290565b60208152600082518060208401526144f98160408501602087016145f5565b601f01601f19169190910160400192915050565b60208082526025908201527f4e4654206973206e6f7420612070617274206f662048654320436f6c6c65637460408201526434b7b7399760d91b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6000821982111561459a5761459a61463c565b500190565b6000826145ba57634e487b7160e01b81526012600452602481fd5b500490565b60008160001904831182151516156145d9576145d961463c565b500290565b6000828210156145f0576145f061463c565b500390565b60005b838110156146105781810151838201526020016145f8565b83811115613e285750506000910152565b60006000198214156146355761463561463c565b5060010190565b634e487b7160e01b600052601160045260246000fd5b6001600160a01b038116811461364357600080fdfea2646970667358221220eaecd4edb68728fac854779033fbee895b50a21a8975f2c5ce1d6f458f2901f364736f6c63430008040033000000000000000000000000c7f4debc8072e23fe9259a5c0398326d8efb7f5c0000000000000000000000000000000000000000000000000000000000000000

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

000000000000000000000000c7f4debc8072e23fe9259a5c0398326d8efb7f5c0000000000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _bidToken (address): 0xc7f4debc8072e23fe9259a5c0398326d8efb7f5c
Arg [1] : _feeRatio (uint256): 0

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000c7f4debc8072e23fe9259a5c0398326d8efb7f5c
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000000


Deployed ByteCode Sourcemap

30420:21695:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31901:74;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;31901:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;5680:32:1;;;5662:51;;5744:2;5729:18;;5722:34;;;;5772:18;;5765:34;;;;5835:32;;;5830:2;5815:18;;5808:60;5899:3;5884:19;;5877:35;;;;5700:3;5928:19;;5921:35;;;;6000:14;;5993:22;5987:3;5972:19;;5965:51;6060:14;6053:22;6047:3;6032:19;;6025:51;6107:3;6092:19;;6085:35;2637:31;;;6171:3;6156:19;;2625:44;6207:3;6192:19;;6185:36;;;;6252:3;6237:19;;6230:36;;;;6297:3;6282:19;;6275:36;;;;5649:3;5634:19;31901:74:0;;;;;;;;45045:2841;;;;;;:::i;:::-;;:::i;:::-;;;11173:14:1;;11166:22;11148:41;;11136:2;11121:18;45045:2841:0;11103:92:1;51003:635:0;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;40802:1846::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;32710:100::-;;;;;;:::i;:::-;;:::i;:::-;;33574:2316;;;;;;:::i;:::-;;:::i;44316:684::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;32912:104::-;;;:::i;:::-;;;;;;;:::i;31656:40::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;31656:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38704:2035;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;32818:86::-;32888:8;;32818:86;;;19728:25:1;;;19716:2;19701:18;32818:86:0;19683:76:1;10733:103:0;;;:::i;49610:1354::-;;;;;;:::i;:::-;;:::i;10082:87::-;10128:7;10155:6;-1:-1:-1;;;;;10155:6:0;10082:87;;;-1:-1:-1;;;;;4033:32:1;;;4015:51;;4003:2;3988:18;10082:87:0;3970:102:1;42656:1603:0;;;;;;:::i;:::-;;:::i;35898:97::-;35970:17;;35898:97;;33024:512;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;32533:169::-;;;;;;:::i;:::-;;:::i;31715:38::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;31760:44;;;;;;:::i;:::-;;;;;;;;;;;;;;;;32430:95;32508:8;;-1:-1:-1;;;;;32508:8:0;32430:95;;47894:1708;;;;;;:::i;:::-;;:::i;31836:33::-;;;;;;:::i;:::-;;:::i;10991:201::-;;;;;;:::i;:::-;;:::i;36058:2638::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;;;:::i;45045:2841::-;-1:-1:-1;;;;;45164:26:0;;45139:4;45164:26;;;:12;:26;;;;;;;;45156:76;;;;-1:-1:-1;;;45156:76:0;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;45327:33:0;;;45300:24;45327:33;;;:19;:33;;;;;;;;:43;;;;;;;;45426:16;;45327:43;;45426:16;45412:10;:30;;45404:99;;;;-1:-1:-1;;;45404:99:0;;12961:2:1;45404:99:0;;;12943:21:1;13000:2;12980:18;;;12973:30;13039:34;13019:18;;;13012:62;13110:26;13090:18;;;13083:54;13154:19;;45404:99:0;12933:246:1;45404:99:0;45604:17;45565:35;45581:8;:18;;;45565:15;:35::i;:::-;:56;;;;;;-1:-1:-1;;;45565:56:0;;;;;;;;;;45557:87;;;;-1:-1:-1;;;45557:87:0;;13739:2:1;45557:87:0;;;13721:21:1;13778:2;13758:18;;;13751:30;-1:-1:-1;;;13797:18:1;;;13790:48;13855:18;;45557:87:0;13711:168:1;45557:87:0;45704:8;:19;;;45691:9;:32;;45683:91;;;;-1:-1:-1;;;45683:91:0;;17776:2:1;45683:91:0;;;17758:21:1;17815:2;17795:18;;;17788:30;17854:34;17834:18;;;17827:62;-1:-1:-1;;;17905:18:1;;;17898:44;17959:19;;45683:91:0;17748:236:1;45683:91:0;45874:8;:21;;;45856:8;:15;;;:39;;;;:::i;:::-;45843:9;:52;;:92;;;;45912:8;:23;;;45899:9;:36;45843:92;45835:179;;;;-1:-1:-1;;;45835:179:0;;16445:2:1;45835:179:0;;;16427:21:1;16484:2;16464:18;;;16457:30;16523:34;16503:18;;;16496:62;16594:34;16574:18;;;16567:62;-1:-1:-1;;;16645:19:1;;;16638:41;16696:19;;45835:179:0;16417:304:1;45835:179:0;46121:8;:23;;;46109:9;:35;:66;;;;;46174:1;46148:8;:23;;;:27;46109:66;46106:183;;;46254:8;:23;;;46242:35;;46106:183;46299:8;;:63;;-1:-1:-1;;;;;46299:8:0;46325:10;46345:4;46352:9;46299:25;:63::i;:::-;46391:10;46373:29;;;;:17;:29;;;;;:34;;46406:1;;46373:29;:34;;46406:1;;46373:34;:::i;:::-;;;;;;;;46420;46465:8;:18;;;;;;;;;;-1:-1:-1;;;;;46465:18:0;46420:64;;46537:22;46562:8;:15;;;46537:40;;46630:9;46612:8;:15;;:27;;;;46702:10;46673:8;:18;;;:40;;;;;-1:-1:-1;;;;;46673:40:0;;;;;-1:-1:-1;;;;;46673:40:0;;;;;;46813:8;46767:19;:33;46787:12;-1:-1:-1;;;;;46767:33:0;-1:-1:-1;;;;;46767:33:0;;;;;;;;;;;;:43;46801:8;46767:43;;;;;;;;;;;:54;;;;;;;;;;;-1:-1:-1;;;;;46767:54:0;;;;;;;;;;-1:-1:-1;;;;;46767:54:0;;;;;-1:-1:-1;;;;;46767:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;46767:54:0;;;;;;;;;;-1:-1:-1;;;;;46767:54:0;;;;;-1:-1:-1;;;;;46767:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;46767:54:0;;;;;;;;;;-1:-1:-1;;;;;46767:54:0;;;;;-1:-1:-1;;;;;46767:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46885:8;46854;:28;46863:8;:18;;;46854:28;;;;;;;;;;;:39;;;;;;;;;;;-1:-1:-1;;;;;46854:39:0;;;;;;;;;;-1:-1:-1;;;;;46854:39:0;;;;;-1:-1:-1;;;;;46854:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;46854:39:0;;;;;;;;;;-1:-1:-1;;;;;46854:39:0;;;;;-1:-1:-1;;;;;46854:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;46854:39:0;;;;;;;;;;-1:-1:-1;;;;;46854:39:0;;;;;-1:-1:-1;;;;;46854:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46922:8;:23;;;46909:9;:36;;:67;;;;;46975:1;46949:8;:23;;;:27;46909:67;46906:421;;;47066:4;47043:8;:20;;;:27;;;;;;;;;;;;;;;;;;47156:8;47110:19;:33;47130:12;-1:-1:-1;;;;;47110:33:0;-1:-1:-1;;;;;47110:33:0;;;;;;;;;;;;:43;47144:8;47110:43;;;;;;;;;;;:54;;;;;;;;;;;-1:-1:-1;;;;;47110:54:0;;;;;;;;;;-1:-1:-1;;;;;47110:54:0;;;;;-1:-1:-1;;;;;47110:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;47110:54:0;;;;;;;;;;-1:-1:-1;;;;;47110:54:0;;;;;-1:-1:-1;;;;;47110:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;47110:54:0;;;;;;;;;;-1:-1:-1;;;;;47110:54:0;;;;;-1:-1:-1;;;;;47110:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47232:8;47201;:28;47210:8;:18;;;47201:28;;;;;;;;;;;:39;;;;;;;;;;;-1:-1:-1;;;;;47201:39:0;;;;;;;;;;-1:-1:-1;;;;;47201:39:0;;;;;-1:-1:-1;;;;;47201:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;47201:39:0;;;;;;;;;;-1:-1:-1;;;;;47201:39:0;;;;;-1:-1:-1;;;;;47201:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;47201:39:0;;;;;;;;;;-1:-1:-1;;;;;47201:39:0;;;;;-1:-1:-1;;;;;47201:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47255:38;47270:12;47284:8;47255:14;:38::i;:::-;;46906:421;47342:18;;;;47337:24;;;;:4;:24;;;;;;;;47367:26;;;;;;;;47371:10;47367:26;;;;;;;;47337:57;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;47337:57:0;-1:-1:-1;;;;;47337:57:0;;;;;;;;;;;;;;47449:19;;47446:186;;47505:8;;:57;;-1:-1:-1;;;;;47505:8:0;47527:18;47547:14;47505:21;:57::i;:::-;-1:-1:-1;;;;;47642:37:0;;;;;;:17;:37;;;;;:42;;47683:1;;47642:37;:42;;47683:1;;47642:42;:::i;:::-;;;;-1:-1:-1;;47744:53:0;;;47751:10;5005:34:1;;5070:2;5055:18;;5048:34;;;-1:-1:-1;;;;;5118:15:1;;5098:18;;;5091:43;5165:2;5150:18;;5143:34;;;47744:53:0;;;;;;;4954:3:1;47744:53:0;;;47839:4;47832:11;;;;;45045:2841;;;;;;:::o;51003:635::-;51068:12;51119:20;;;:8;:20;;;;;;;;51093:46;;;;;;;;;-1:-1:-1;;;;;51093:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51171:54;;-1:-1:-1;51203:22:0;;51003:635;-1:-1:-1;;51003:635:0:o;51171:54::-;51287:8;:20;;;51284:55;;;-1:-1:-1;51316:23:0;;51003:635;-1:-1:-1;;51003:635:0:o;51284:55::-;51433:8;:16;;;51414:15;:35;51411:65;;-1:-1:-1;51458:18:0;;51003:635;-1:-1:-1;;51003:635:0:o;51411:65::-;-1:-1:-1;51588:17:0;;51003:635;-1:-1:-1;;51003:635:0:o;40802:1846::-;40913:25;40953:34;41002:27;41074:17;;41060:11;:31;41057:94;;;41122:17;;41108:31;;41057:94;41362:10;41161:21;41344:29;;;:17;:29;;;;;;41161:21;;;;;;;;-1:-1:-1;;;;;41330:44:0;;;;;-1:-1:-1;;;41330:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41330:44:0;-1:-1:-1;41437:10:0;41419:29;;;;:17;:29;;;;;;41319:55;;-1:-1:-1;;;;;;41405:44:0;;;;;-1:-1:-1;;;41405:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41405:44:0;-1:-1:-1;41505:10:0;41487:29;;;;:17;:29;;;;;;41385:64;;-1:-1:-1;;;;;;41473:44:0;;;;;-1:-1:-1;;;41473:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41473:44:0;;41460:57;;41535:9;41530:971;41554:11;41550:1;:15;41530:971;;;41631:62;41647:8;:35;41680:1;41676;41656:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;41647:35;;;;;;;;;;;:45;;;41631:15;:62::i;:::-;41623:71;;;;;;-1:-1:-1;;;41623:71:0;;;;;;;;;41607:87;;41712:13;41729:1;41712:18;:40;;;;41734:13;41751:1;41734:18;41712:40;41709:781;;;41789:8;:35;41822:1;41818;41798:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;41789:35;;;;;;;;;;;-1:-1:-1;41789:35:0;;;:43;;41909:17;;-1:-1:-1;;;;;41789:43:0;;;;-1:-1:-1;41900:8:0;;-1:-1:-1;41909:21:0;;41929:1;;41909:21;:::i;:::-;:25;;;;:::i;:::-;41900:35;;;;;;;;;;;:45;;;;;;;;;;-1:-1:-1;;;;;41900:45:0;41883:62;;41978:8;:35;42011:1;42007;41987:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;41978:35;;;;;;;;;;;:42;;;41964:56;;42056:14;-1:-1:-1;;;;;42042:28:0;:10;-1:-1:-1;;;;;42042:28:0;;:89;;;;;42075:9;:56;42085:8;:35;42118:1;42114;42094:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;42085:35;;;;;;;;;;;:45;;;42075:56;;;;;;;;;;;;;;;;;;;;;42074:57;42042:89;42039:436;;;42175:8;:35;42208:1;42204;42184:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;42175:35;;;;;;;;;;;:43;;;42156:8;42165:6;42156:16;;;;;;-1:-1:-1;;;42156:16:0;;;;;;;;;;;;;;:62;;;;;42289:8;:35;42322:1;42318;42298:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;42289:35;;;;;;;;;;;:46;;;;;;;;;;-1:-1:-1;;;;;42289:46:0;42261:17;42279:6;42261:25;;;;;;-1:-1:-1;;;42261:25:0;;;;;;;;;;;;;;:74;-1:-1:-1;;;;;42261:74:0;;;-1:-1:-1;;;;;42261:74:0;;;;;42379:8;:35;42412:1;42408;42388:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;42379:35;;;;;;;;;;;:45;;;42358:10;42369:6;42358:18;;;;;;-1:-1:-1;;;42358:18:0;;;;;;;;;;;;;;;;;;:66;42447:8;;;;:::i;:::-;;;;42039:436;41567:3;;;;:::i;:::-;;;;41530:971;;;;42521:119;;;;;40802:1846;;;;;:::o;32710:100::-;10128:7;10155:6;-1:-1:-1;;;;;10155:6:0;9029:10;10302:23;10294:68;;;;-1:-1:-1;;;10294:68:0;;;;;;;:::i;:::-;32780:8:::1;:22:::0;32710:100::o;33574:2316::-;33723:4;33871:19;;33868:185;;33929:15;33915:11;:29;33907:86;;;;-1:-1:-1;;;33907:86:0;;12140:2:1;33907:86:0;;;12122:21:1;12179:2;12159:18;;;12152:30;12218:34;12198:18;;;12191:62;-1:-1:-1;;;12269:18:1;;;12262:43;12322:19;;33907:86:0;12112:235:1;33907:86:0;34088:8;34071:13;:25;;34063:89;;;;-1:-1:-1;;;34063:89:0;;16928:2:1;34063:89:0;;;16910:21:1;16967:2;16947:18;;;16940:30;17006:34;16986:18;;;16979:62;-1:-1:-1;;;17057:18:1;;;17050:49;17116:19;;34063:89:0;16900:241:1;34063:89:0;34226:9;34215:8;:20;34207:73;;;;-1:-1:-1;;;34207:73:0;;19375:2:1;34207:73:0;;;19357:21:1;19414:2;19394:18;;;19387:30;19453:34;19433:18;;;19426:62;-1:-1:-1;;;19504:18:1;;;19497:38;19552:19;;34207:73:0;19347:230:1;34207:73:0;-1:-1:-1;;;;;34432:25:0;;;;;;:12;:25;;;;;;;;34424:75;;;;-1:-1:-1;;;34424:75:0;;;;;;;:::i;:::-;34586:17;;;;;;34569:14;34654:19;34586:17;34654:19;:::i;:::-;;;;-1:-1:-1;;34939:356:0;;;;;;;;34961:10;34939:356;;;;;;;;;34913:23;34939:356;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35168:27;35187:8;35168:15;:27;:::i;:::-;34939:356;;-1:-1:-1;;;;;34939:356:0;;;;;;;;;;;;;;;35262:8;;34939:356;;;;;;;;;;;35410:59;;-1:-1:-1;;;35410:59:0;;34913:382;;-1:-1:-1;35211:11:0;;35410:22;;:59;;35433:10;;35453:4;;35238:8;;35410:59;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;35535:10:0;35517:29;;;;:17;:29;;;;;:34;;35550:1;;-1:-1:-1;35517:29:0;;-1:-1:-1;35517:34:0;;35550:1;;35517:34;:::i;:::-;;;;-1:-1:-1;;35625:10:0;35607:29;;;;:17;:29;;;;;:34;;35640:1;;35607:29;:34;;35640:1;;35607:34;:::i;:::-;;;;;;;;35707:8;35685;:19;35694:9;35685:19;;;;;;;;;;;:30;;;;;;;;;;;;;-1:-1:-1;;;;;35685:30:0;;;;;-1:-1:-1;;;;;35685:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;35685:30:0;;;;;-1:-1:-1;;;;;35685:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;35685:30:0;;;;;-1:-1:-1;;;;;35685:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35801:8;35756:19;:32;35776:11;-1:-1:-1;;;;;35756:32:0;-1:-1:-1;;;;;35756:32:0;;;;;;;;;;;;:42;35789:8;35756:42;;;;;;;;;;;:53;;;;;;;;;;;;;-1:-1:-1;;;;;35756:53:0;;;;;-1:-1:-1;;;;;35756:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;35756:53:0;;;;;-1:-1:-1;;;;;35756:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;35756:53:0;;;;;-1:-1:-1;;;;;35756:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35878:4;35871:11;;;;;33574:2316;;;;;;;;:::o;44316:684::-;44455:18;44510:16;;;:4;:16;;;;;;;;44489:37;;;;;;;;;;;;;;;;;44403:16;;;;44476:2;;44455:18;;44489:37;;;44455:18;;44489:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;44489:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44586:10;44571:5;:12;:25;44568:82;;;44626:5;:12;44613:25;;44568:82;44660:22;44699:10;-1:-1:-1;;;;;44685:25:0;;;;;-1:-1:-1;;;44685:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44685:25:0;;44660:50;;44721:25;44763:10;-1:-1:-1;;;;;44749:25:0;;;;;-1:-1:-1;;;44749:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44749:25:0;;44721:53;;44790:9;44785:173;44809:10;44805:1;:14;44785:173;;;44852:5;44877:1;44873;44858:5;:12;:16;;;;:::i;:::-;:20;;;;:::i;:::-;44852:27;;;;;;-1:-1:-1;;;44852:27:0;;;;;;;;;;;;;;;:34;;;44841:5;44847:1;44841:8;;;;;;-1:-1:-1;;;44841:8:0;;;;;;;;;;;;;;:45;-1:-1:-1;;;;;44841:45:0;;;-1:-1:-1;;;;;44841:45:0;;;;;44915:5;44940:1;44936;44921:5;:12;:16;;;;:::i;:::-;:20;;;;:::i;:::-;44915:27;;;;;;-1:-1:-1;;;44915:27:0;;;;;;;;;;;;;;;:31;;;44901:8;44910:1;44901:11;;;;;;-1:-1:-1;;;44901:11:0;;;;;;;;;;;;;;;;;;:45;44821:3;;;;:::i;:::-;;;;44785:173;;;-1:-1:-1;44976:5:0;;44983:8;;-1:-1:-1;44316:684:0;-1:-1:-1;;;;44316:684:0:o;32912:104::-;32956:16;32992;32985:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;32985:23:0;;;;;;;;;;;;;;;;;;;;;;;32912:104;:::o;38704:2035::-;38815:27;38857:25;38897:34;38946:27;39018:17;;39004:11;:31;39001:94;;;39066:17;;39052:31;;39001:94;39308:10;39105:21;39290:29;;;:17;:29;;;;;;39105:21;;;;;;;;-1:-1:-1;;;;;39276:44:0;;;;;-1:-1:-1;;;39276:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;39276:44:0;-1:-1:-1;39374:10:0;39356:29;;;;:17;:29;;;;;;39263:57;;-1:-1:-1;;;;;;39342:44:0;;;;;-1:-1:-1;;;39342:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;39342:44:0;-1:-1:-1;39449:10:0;39431:29;;;;:17;:29;;;;;;39331:55;;-1:-1:-1;;;;;;39417:44:0;;;;;-1:-1:-1;;;39417:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;39417:44:0;-1:-1:-1;39517:10:0;39499:29;;;;:17;:29;;;;;;39397:64;;-1:-1:-1;;;;;;39485:44:0;;;;;-1:-1:-1;;;39485:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;39485:44:0;;39472:57;;39547:9;39542:1025;39566:11;39562:1;:15;39542:1025;;;39643:62;39659:8;:35;39692:1;39688;39668:17;;:21;;;;:::i;39643:62::-;39635:71;;;;;;-1:-1:-1;;;39635:71:0;;;;;;;;;39619:87;;39724:13;39741:1;39724:18;:40;;;;39746:13;39763:1;39746:18;39724:40;39721:835;;;39801:8;:35;39834:1;39830;39810:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;39801:35;;;;;;;;;;;-1:-1:-1;39801:35:0;;;:43;;39921:17;;-1:-1:-1;;;;;39801:43:0;;;;-1:-1:-1;39912:8:0;;-1:-1:-1;39921:21:0;;39941:1;;39921:21;:::i;:::-;:25;;;;:::i;:::-;39912:35;;;;;;;;;;;:45;;;;;;;;;;-1:-1:-1;;;;;39912:45:0;39895:62;;39990:8;:35;40023:1;40019;39999:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;39990:35;;;;;;;;;;;:42;;;39976:56;;40068:13;-1:-1:-1;;;;;40054:27:0;:10;-1:-1:-1;;;;;40054:27:0;;:88;;;;;40086:9;:56;40096:8;:35;40129:1;40125;40105:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;40096:35;;;;;;;;;;;:45;;;40086:56;;;;;;;;;;;;;;;;;;;;;40085:57;40054:88;40051:490;;;40188:11;40167:10;40178:6;40167:18;;;;;;-1:-1:-1;;;40167:18:0;;;;;;;;;;;;;;:32;;;;;40241:8;:35;40274:1;40270;40250:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;40241:35;;;;;;;;;;;:43;;;40222:8;40231:6;40222:16;;;;;;-1:-1:-1;;;40222:16:0;;;;;;;;;;;;;;:62;;;;;40355:8;:35;40388:1;40384;40364:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;40355:35;;;;;;;;;;;:46;;;;;;;;;;-1:-1:-1;;;;;40355:46:0;40327:17;40345:6;40327:25;;;;;;-1:-1:-1;;;40327:25:0;;;;;;;;;;;;;;:74;-1:-1:-1;;;;;40327:74:0;;;-1:-1:-1;;;;;40327:74:0;;;;;40445:8;:35;40478:1;40474;40454:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;40445:35;;;;;;;;;;;:45;;;40424:10;40435:6;40424:18;;;;;;-1:-1:-1;;;40424:18:0;;;;;;;;;;;;;;;;;;:66;40513:8;;;;:::i;:::-;;;;40051:490;39579:3;;;;:::i;:::-;;;;39542:1025;;;;40587:144;;;;;38704:2035;;;;;:::o;10733:103::-;10128:7;10155:6;-1:-1:-1;;;;;10155:6:0;9029:10;10302:23;10294:68;;;;-1:-1:-1;;;10294:68:0;;;;;;;:::i;:::-;10798:30:::1;10825:1;10798:18;:30::i;:::-;10733:103::o:0;49610:1354::-;-1:-1:-1;;;;;49736:26:0;;49690:4;49736:26;;;:12;:26;;;;;;;;49728:76;;;;-1:-1:-1;;;49728:76:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;49898:33:0;;;49872:23;49898:33;;;:19;:33;;;;;;;;:43;;;;;;;;;49872:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49918:12;;50052:10;:30;50044:90;;;;-1:-1:-1;;;50044:90:0;;15313:2:1;50044:90:0;;;15295:21:1;15352:2;15332:18;;;15325:30;15391:34;15371:18;;;15364:62;-1:-1:-1;;;15442:18:1;;;15435:45;15497:19;;50044:90:0;15285:237:1;50044:90:0;50243:17;50204:35;50220:8;:18;;;50204:15;:35::i;:::-;:56;;;;;;-1:-1:-1;;;50204:56:0;;;;;;;;;;50196:95;;;;-1:-1:-1;;;50196:95:0;;16090:2:1;50196:95:0;;;16072:21:1;16129:2;16109:18;;;16102:30;16168:28;16148:18;;;16141:56;16214:18;;50196:95:0;16062:176:1;50196:95:0;50338:15;;;;:20;50330:79;;;;-1:-1:-1;;;50330:79:0;;18960:2:1;50330:79:0;;;18942:21:1;18999:2;18979:18;;;18972:30;19038:34;19018:18;;;19011:62;-1:-1:-1;;;19089:18:1;;;19082:44;19143:19;;50330:79:0;18932:236:1;50330:79:0;50498:4;50475:20;;;:27;50580:16;;50598;;;;50547:68;;-1:-1:-1;;;50547:68:0;;-1:-1:-1;;;;;50547:17:0;;;;;:68;;50573:4;;50580:16;50598;50547:68;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50723:8;50677:19;:33;50697:12;-1:-1:-1;;;;;50677:33:0;-1:-1:-1;;;;;50677:33:0;;;;;;;;;;;;:43;50711:8;50677:43;;;;;;;;;;;:54;;;;;;;;;;;;;-1:-1:-1;;;;;50677:54:0;;;;;-1:-1:-1;;;;;50677:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;50677:54:0;;;;;-1:-1:-1;;;;;50677:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;50677:54:0;;;;;-1:-1:-1;;;;;50677:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50795:8;50764;:28;50773:8;:18;;;50764:28;;;;;;;;;;;:39;;;;;;;;;;;;;-1:-1:-1;;;;;50764:39:0;;;;;-1:-1:-1;;;;;50764:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;50764:39:0;;;;;-1:-1:-1;;;;;50764:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;50764:39:0;;;;;-1:-1:-1;;;;;50764:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50847:1;50814:17;:29;50832:10;-1:-1:-1;;;;;50814:29:0;-1:-1:-1;;;;;50814:29:0;;;;;;;;;;;;;:34;;;;;;;:::i;:::-;;;;-1:-1:-1;;50864:39:0;;;-1:-1:-1;;;;;4649:32:1;;4631:51;;4713:2;4698:18;;4691:34;;;50864:39:0;;4604:18:1;50864:39:0;;;;;;;-1:-1:-1;50952:4:0;;49610:1354;-1:-1:-1;;;;49610:1354:0:o;42656:1603::-;42766:25;42806:34;42855:27;42927:17;;42913:11;:31;42910:94;;;42975:17;;42961:31;;42910:94;43152:10;43014:21;43134:29;;;:17;:29;;;;;;43014:21;;;;-1:-1:-1;;;;;43120:44:0;;;;;-1:-1:-1;;;43120:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43120:44:0;-1:-1:-1;43227:10:0;43209:29;;;;:17;:29;;;;;;43109:55;;-1:-1:-1;;;;;;43195:44:0;;;;;-1:-1:-1;;;43195:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43195:44:0;-1:-1:-1;43295:10:0;43277:29;;;;:17;:29;;;;;;43175:64;;-1:-1:-1;;;;;;43263:44:0;;;;;-1:-1:-1;;;43263:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43263:44:0;;43250:57;;43325:9;43320:792;43344:11;43340:1;:15;43320:792;;;43421:62;43437:8;:35;43470:1;43466;43446:17;;:21;;;;:::i;43421:62::-;43413:71;;;;;;-1:-1:-1;;;43413:71:0;;;;;;;;;43397:87;-1:-1:-1;43502:18:0;43499:602;;43557:8;:35;43590:1;43586;43566:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;43557:35;;;;;;;;;;;-1:-1:-1;43557:35:0;:43;-1:-1:-1;;;;;43557:43:0;;-1:-1:-1;43654:10:0;:27;;:88;;;;;43686:9;:56;43696:8;:35;43729:1;43725;43705:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;43696:35;;;;;;;;;;;:45;;;43686:56;;;;;;;;;;;;;;;;;;;;;43685:57;43654:88;43651:435;;;43786:8;:35;43819:1;43815;43795:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;43786:35;;;;;;;;;;;:43;;;43767:8;43776:6;43767:16;;;;;;-1:-1:-1;;;43767:16:0;;;;;;;;;;;;;;:62;;;;;43900:8;:35;43933:1;43929;43909:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;43900:35;;;;;;;;;;;:46;;;;;;;;;;-1:-1:-1;;;;;43900:46:0;43872:17;43890:6;43872:25;;;;;;-1:-1:-1;;;43872:25:0;;;;;;;;;;;;;;:74;-1:-1:-1;;;;;43872:74:0;;;-1:-1:-1;;;;;43872:74:0;;;;;43990:8;:35;44023:1;44019;43999:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;43990:35;;;;;;;;;;;:45;;;43969:10;43980:6;43969:18;;;;;;-1:-1:-1;;;43969:18:0;;;;;;;;;;;;;;;;;;:66;44058:8;;;;:::i;:::-;;;;43651:435;43357:3;;;;:::i;:::-;;;;43320:792;;;;44132:119;;;42656:1603;;;;;:::o;33024:512::-;33188:26;;-1:-1:-1;;;33188:26:0;;33203:10;33188:26;;;4015:51:1;33093:16:0;;33145:12;;33122;;-1:-1:-1;;;;;33188:14:0;;;;;3988:18:1;;33188:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;33169:45;;33225:26;33268:8;-1:-1:-1;;;;;33254:23:0;;;;;-1:-1:-1;;;33254:23:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;33254:23:0;;33225:52;;33288:14;33323:6;33319:183;33344:8;33335:6;:17;33319:183;;;33377:15;;-1:-1:-1;;;33377:15:0;;;;;19728:25:1;;;33396:10:0;;-1:-1:-1;;;;;33377:12:0;;;;;19701:18:1;;33377:15:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;33377:29:0;;33374:117;;;33447:1;33427:9;33437:6;33427:17;;;;;;-1:-1:-1;;;33427:17:0;;;;;;;;;;;;;;;;;;:21;33467:8;;;;:::i;:::-;;;;33374:117;33354:3;;;;:::i;:::-;;;;33319:183;;;-1:-1:-1;33519:9:0;;33024:512;-1:-1:-1;;;;;33024:512:0:o;32533:169::-;10128:7;10155:6;-1:-1:-1;;;;;10155:6:0;9029:10;10302:23;10294:68;;;;-1:-1:-1;;;10294:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;32611:28:0::1;;::::0;;;:12:::1;:28;::::0;;;;:35;;-1:-1:-1;;32611:35:0::1;32642:4;32611:35:::0;;::::1;::::0;;;32657:16:::1;:37:::0;;;;::::1;::::0;;;;;;::::1;::::0;;-1:-1:-1;;;;;;32657:37:0::1;::::0;;::::1;::::0;;32533:169::o;47894:1708::-;-1:-1:-1;;;;;47998:26:0;;47973:4;47998:26;;;:12;:26;;;;;;;;47990:76;;;;-1:-1:-1;;;47990:76:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;48160:33:0;;;48134:23;48160:33;;;:19;:33;;;;;;;;:43;;;;;;;;;48134:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48180:12;;48314:35;48330:8;:18;;;48314:15;:35::i;:::-;:57;;;;;;-1:-1:-1;;;48314:57:0;;;;;;;;;;:123;;;-1:-1:-1;48414:23:0;48375:35;48391:8;:18;;;48375:15;:35::i;:::-;:62;;;;;;-1:-1:-1;;;48375:62:0;;;;;;;;;;48314:123;48306:195;;;;-1:-1:-1;;;48306:195:0;;17348:2:1;48306:195:0;;;17330:21:1;17387:2;17367:18;;;17360:30;17426:34;17406:18;;;17399:62;17497:29;17477:18;;;17470:57;17544:19;;48306:195:0;17320:249:1;48306:195:0;48534:16;;-1:-1:-1;;;;;48520:30:0;:10;:30;;:66;;;48568:8;:18;;;-1:-1:-1;;;;;48554:32:0;:10;-1:-1:-1;;;;;48554:32:0;;48520:66;48512:124;;;;-1:-1:-1;;;48512:124:0;;14899:2:1;48512:124:0;;;14881:21:1;14938:2;14918:18;;;14911:30;14977:34;14957:18;;;14950:62;-1:-1:-1;;;15028:18:1;;;15021:43;15081:19;;48512:124:0;14871:235:1;48512:124:0;48666:18;;;;48656:29;;;;:9;:29;;;;;;;;48655:30;48647:67;;;;-1:-1:-1;;;48647:67:0;;13386:2:1;48647:67:0;;;13368:21:1;13425:2;13405:18;;;13398:30;13464:26;13444:18;;;13437:54;13508:18;;48647:67:0;13358:174:1;48647:67:0;48760:18;;;;48727:62;;-1:-1:-1;;;48727:62:0;;-1:-1:-1;;;;;48727:17:0;;;;;:62;;48753:4;;48780:8;;48727:62;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48849:57;48863:8;:18;;;48883:12;48897:8;48849:57;;;;;;;;:::i;:::-;;;;;;;;48950:11;49004:3;48983:8;:17;;;48965:8;:15;;;:35;;;;:::i;:::-;48964:43;;;;:::i;:::-;48950:57;;49018:35;49040:7;10128;10155:6;-1:-1:-1;;;;;10155:6:0;;10082:87;49040:7;49018:8;;-1:-1:-1;;;;;49018:8:0;;49049:3;49018:21;:35::i;:::-;49093:62;49115:8;:16;;;49151:3;49133:8;:15;;;:21;;;;:::i;:::-;49093:8;;-1:-1:-1;;;;;49093:8:0;;:62;:21;:62::i;:::-;49231:15;;;;;49205:66;;49219:10;5005:34:1;;5070:2;5055:18;;5048:34;;;;-1:-1:-1;;;;;5118:15:1;;5098:18;;;5091:43;5165:2;5150:18;;5143:34;;;49205:66:0;;;;;;;4954:3:1;49205:66:0;;;49347:4;49315:9;:29;49325:8;:18;;;49315:29;;;;;;;;;;;;:36;;;;;;;;;;;;;;;;;;49393:8;49362;:28;49371:8;:18;;;49362:28;;;;;;;;;;;:39;;;;;;;;;;;;;-1:-1:-1;;;;;49362:39:0;;;;;-1:-1:-1;;;;;49362:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;49362:39:0;;;;;-1:-1:-1;;;;;49362:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;49362:39:0;;;;;-1:-1:-1;;;;;49362:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49458:8;49412:19;:33;49432:12;-1:-1:-1;;;;;49412:33:0;-1:-1:-1;;;;;49412:33:0;;;;;;;;;;;;:43;49446:8;49412:43;;;;;;;;;;;:54;;;;;;;;;;;;;-1:-1:-1;;;;;49412:54:0;;;;;-1:-1:-1;;;;;49412:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;49412:54:0;;;;;-1:-1:-1;;;;;49412:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;49412:54:0;;;;;-1:-1:-1;;;;;49412:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49518:1;49479:17;:35;49497:8;:16;;;-1:-1:-1;;;;;49479:35:0;-1:-1:-1;;;;;49479:35:0;;;;;;;;;;;;;:40;;;;;;;:::i;:::-;;;;-1:-1:-1;;49548:18:0;;;;-1:-1:-1;;;;;49530:37:0;;;;;:17;:37;;;;;:42;;49571:1;;49530:37;:42;;49571:1;;49530:42;:::i;:::-;;;;-1:-1:-1;49590:4:0;;47894:1708;-1:-1:-1;;;;;;;47894:1708:0:o;31836:33::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;31836:33:0;;-1:-1:-1;31836:33:0;:::o;10991:201::-;10128:7;10155:6;-1:-1:-1;;;;;10155:6:0;9029:10;10302:23;10294:68;;;;-1:-1:-1;;;10294:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;11080:22:0;::::1;11072:73;;;::::0;-1:-1:-1;;;11072:73:0;;12554:2:1;11072:73:0::1;::::0;::::1;12536:21:1::0;12593:2;12573:18;;;12566:30;12632:34;12612:18;;;12605:62;-1:-1:-1;;;12683:18:1;;;12676:36;12729:19;;11072:73:0::1;12526:228:1::0;11072:73:0::1;11156:28;11175:8;11156:18;:28::i;:::-;10991:201:::0;:::o;36058:2638::-;36167:26;36208:22;36245:27;36287:30;36332:25;36372:24;36411:27;36453:30;36498:34;36547:27;36619:17;;36605:11;:31;36602:94;;;36667:17;;36653:31;;36602:94;36732:11;-1:-1:-1;;;;;36718:26:0;;;;;-1:-1:-1;;;36718:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36718:26:0;;36706:38;;36844:11;-1:-1:-1;;;;;36830:26:0;;;;;-1:-1:-1;;;36830:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36830:26:0;;36822:34;;36961:11;-1:-1:-1;;;;;36947:26:0;;;;;-1:-1:-1;;;36947:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36947:26:0;;36934:39;;37014:11;-1:-1:-1;;;;;37000:26:0;;;;;-1:-1:-1;;;37000:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37000:26:0;;36984:42;;37062:11;-1:-1:-1;;;;;37048:26:0;;;;;-1:-1:-1;;;37048:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37048:26:0;;37037:37;;37109:11;-1:-1:-1;;;;;37095:26:0;;;;;-1:-1:-1;;;37095:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37095:26:0;;37085:36;;37159:11;-1:-1:-1;;;;;37145:26:0;;;;;-1:-1:-1;;;37145:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37145:26:0;;37132:39;;37212:11;-1:-1:-1;;;;;37198:26:0;;;;;-1:-1:-1;;;37198:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37198:26:0;;37182:42;;37269:11;-1:-1:-1;;;;;37255:26:0;;;;;-1:-1:-1;;;37255:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37255:26:0;;37235:46;;37319:11;-1:-1:-1;;;;;37305:26:0;;;;;-1:-1:-1;;;37305:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37305:26:0;;37292:39;;37351:9;37346:1031;37370:11;37366:1;:15;37346:1031;;;37438:8;:35;37471:1;37467;37447:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;37438:35;;;;;;;;;;;:50;;;37423:9;37433:1;37423:12;;;;;;-1:-1:-1;;;37423:12:0;;;;;;;;;;;;;;:65;;;;;37542:8;:35;37575:1;37571;37551:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;37542:35;;;;;;;;;;;-1:-1:-1;37542:35:0;:43;37531:8;;-1:-1:-1;;;;;37542:43:0;;;;37531:5;;37537:1;;37531:8;;;;-1:-1:-1;;;37531:8:0;;;;;;;;;;;;;;:54;-1:-1:-1;;;;;37531:54:0;;;-1:-1:-1;;;;;37531:54:0;;;;;37648:8;:35;37681:1;37677;37657:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;37648:35;;;;;;;;;;;:42;;;37632:10;37643:1;37632:13;;;;;;-1:-1:-1;;;37632:13:0;;;;;;;;;;;;;;:58;;;;;37747:8;:35;37780:1;37776;37756:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;37747:35;;;;;;;;;;;:45;;;;;;;;;;-1:-1:-1;;;;;37747:45:0;37728:13;37742:1;37728:16;;;;;;-1:-1:-1;;;37728:16:0;;;;;;;;;;;;;;:64;-1:-1:-1;;;;;37728:64:0;;;-1:-1:-1;;;;;37728:64:0;;;;;37821:8;:35;37854:1;37850;37830:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;37821:35;;;;;;;;;;;:43;;;37807:8;37816:1;37807:11;;;;;;-1:-1:-1;;;37807:11:0;;;;;;;;;;;;;;:57;;;;;37912:8;:35;37945:1;37941;37921:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;37912:35;;;;;;;;;;;:43;;;37899:7;37907:1;37899:10;;;;;;-1:-1:-1;;;37899:10:0;;;;;;;;;;;;;;:56;;;;;38006:8;:35;38039:1;38035;38015:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;38006:35;;;;;;;;;;;:46;;;37990:10;38001:1;37990:13;;;;;;-1:-1:-1;;;37990:13:0;;;;;;;;;;;;;;:62;;;;;38117;38133:8;:35;38166:1;38162;38142:17;;:21;;;;:::i;38117:62::-;38109:71;;;;;;-1:-1:-1;;;38109:71:0;;;;;;;;;38090:13;38104:1;38090:16;;;;;;-1:-1:-1;;;38090:16:0;;;;;;;;;;;;;;:90;;;;;38243:8;:35;38276:1;38272;38252:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;38243:35;;;;;;;;;;;:46;;;;;;;;;;-1:-1:-1;;;;;38243:46:0;38220:17;38238:1;38220:20;;;;;;-1:-1:-1;;;38220:20:0;;;;;;;;;;;;;;:69;-1:-1:-1;;;;;38220:69:0;;;-1:-1:-1;;;;;38220:69:0;;;;;38320:8;:35;38353:1;38349;38329:17;;:21;;;;:::i;:::-;:25;;;;:::i;:::-;38320:35;;;;;;;;;;;:45;;;38304:10;38315:1;38304:13;;;;;;-1:-1:-1;;;38304:13:0;;;;;;;;;;;;;;;;;;:61;37383:3;;;;:::i;:::-;;;;37346:1031;;;;36058:2638;;;;;;;;;;;:::o;15010:248::-;15154:96;15174:5;15204:27;;;15233:4;15239:2;15243:5;15181:68;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;15181:68:0;;;;;;;;;;;;;;-1:-1:-1;;;;;15181:68:0;-1:-1:-1;;;;;;15181:68:0;;;;;;;;;;15154:19;:96::i;:::-;15010:248;;;;:::o;14791:211::-;14935:58;;-1:-1:-1;;;;;4649:32:1;;14935:58:0;;;4631:51:1;4698:18;;;4691:34;;;14908:86:0;;14928:5;;-1:-1:-1;;;14958:23:0;4604:18:1;;14935:58:0;4586:145:1;14908:86:0;14791:211;;;:::o;11352:191::-;11426:16;11445:6;;-1:-1:-1;;;;;11462:17:0;;;-1:-1:-1;;;;;;11462:17:0;;;;;;11495:40;;11445:6;;;;;;;11495:40;;11426:16;11495:40;11352:191;;:::o;17364:716::-;17788:23;17814:69;17842:4;17814:69;;;;;;;;;;;;;;;;;17822:5;-1:-1:-1;;;;;17814:27:0;;;:69;;;;;:::i;:::-;17898:17;;17788:95;;-1:-1:-1;17898:21:0;17894:179;;17995:10;17984:30;;;;;;;;;;;;:::i;:::-;17976:85;;;;-1:-1:-1;;;17976:85:0;;18549:2:1;17976:85:0;;;18531:21:1;18588:2;18568:18;;;18561:30;18627:34;18607:18;;;18600:62;-1:-1:-1;;;18678:18:1;;;18671:40;18728:19;;17976:85:0;18521:232:1;3884:229:0;4021:12;4053:52;4075:6;4083:4;4089:1;4092:12;4053:21;:52::i;:::-;4046:59;3884:229;-1:-1:-1;;;;3884:229:0:o;5004:510::-;5174:12;5232:5;5207:21;:30;;5199:81;;;;-1:-1:-1;;;5199:81:0;;14086:2:1;5199:81:0;;;14068:21:1;14125:2;14105:18;;;14098:30;14164:34;14144:18;;;14137:62;-1:-1:-1;;;14215:18:1;;;14208:36;14261:19;;5199:81:0;14058:228:1;5199:81:0;-1:-1:-1;;;;;1434:19:0;;;5291:60;;;;-1:-1:-1;;;5291:60:0;;18191:2:1;5291:60:0;;;18173:21:1;18230:2;18210:18;;;18203:30;18269:31;18249:18;;;18242:59;18318:18;;5291:60:0;18163:179:1;5291:60:0;5365:12;5379:23;5406:6;-1:-1:-1;;;;;5406:11:0;5425:5;5432:4;5406:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5364:73;;;;5455:51;5472:7;5481:10;5493:12;5455:16;:51::i;:::-;5448:58;5004:510;-1:-1:-1;;;;;;;5004:510:0:o;7690:712::-;7840:12;7869:7;7865:530;;;-1:-1:-1;7900:10:0;7893:17;;7865:530;8014:17;;:21;8010:374;;8212:10;8206:17;8273:15;8260:10;8256:2;8252:19;8245:44;8160:148;8355:12;8348:20;;-1:-1:-1;;;8348:20:0;;;;;;;;:::i;14:257:1:-;73:6;126:2;114:9;105:7;101:23;97:32;94:2;;;147:6;139;132:22;94:2;191:9;178:23;210:31;235:5;210:31;:::i;276:261::-;346:6;399:2;387:9;378:7;374:23;370:32;367:2;;;420:6;412;405:22;367:2;457:9;451:16;476:31;501:5;476:31;:::i;542:325::-;610:6;618;671:2;659:9;650:7;646:23;642:32;639:2;;;692:6;684;677:22;639:2;736:9;723:23;755:31;780:5;755:31;:::i;:::-;805:5;857:2;842:18;;;;829:32;;-1:-1:-1;;;629:238:1:o;872:393::-;949:6;957;965;1018:2;1006:9;997:7;993:23;989:32;986:2;;;1039:6;1031;1024:22;986:2;1083:9;1070:23;1102:31;1127:5;1102:31;:::i;:::-;1152:5;1204:2;1189:18;;1176:32;;-1:-1:-1;1255:2:1;1240:18;;;1227:32;;976:289;-1:-1:-1;;;976:289:1:o;1270:297::-;1337:6;1390:2;1378:9;1369:7;1365:23;1361:32;1358:2;;;1411:6;1403;1396:22;1358:2;1448:9;1442:16;1501:5;1494:13;1487:21;1480:5;1477:32;1467:2;;1528:6;1520;1513:22;1572:190;1631:6;1684:2;1672:9;1663:7;1659:23;1655:32;1652:2;;;1705:6;1697;1690:22;1652:2;-1:-1:-1;1733:23:1;;1642:120;-1:-1:-1;1642:120:1:o;1767:194::-;1837:6;1890:2;1878:9;1869:7;1865:23;1861:32;1858:2;;;1911:6;1903;1896:22;1858:2;-1:-1:-1;1939:16:1;;1848:113;-1:-1:-1;1848:113:1:o;1966:600::-;2070:6;2078;2086;2094;2102;2110;2163:3;2151:9;2142:7;2138:23;2134:33;2131:2;;;2185:6;2177;2170:22;2131:2;2226:9;2213:23;2203:33;;2283:2;2272:9;2268:18;2255:32;2245:42;;2334:2;2323:9;2319:18;2306:32;2296:42;;2385:2;2374:9;2370:18;2357:32;2347:42;;2439:3;2428:9;2424:19;2411:33;2453:31;2478:5;2453:31;:::i;:::-;2503:5;2493:15;;;2555:3;2544:9;2540:19;2527:33;2517:43;;2121:445;;;;;;;;:::o;2680:463::-;2733:3;2771:5;2765:12;2798:6;2793:3;2786:19;2824:4;2853:2;2848:3;2844:12;2837:19;;2890:2;2883:5;2879:14;2911:3;2923:195;2937:6;2934:1;2931:13;2923:195;;;3002:13;;-1:-1:-1;;;;;2998:39:1;2986:52;;3058:12;;;;3093:15;;;;3034:1;2952:9;2923:195;;;-1:-1:-1;3134:3:1;;2741:402;-1:-1:-1;;;;;2741:402:1:o;3148:437::-;3201:3;3239:5;3233:12;3266:6;3261:3;3254:19;3292:4;3321:2;3316:3;3312:12;3305:19;;3358:2;3351:5;3347:14;3379:3;3391:169;3405:6;3402:1;3399:13;3391:169;;;3466:13;;3454:26;;3500:12;;;;3535:15;;;;3427:1;3420:9;3391:169;;3590:274;3719:3;3757:6;3751:13;3773:53;3819:6;3814:3;3807:4;3799:6;3795:17;3773:53;:::i;:::-;3842:16;;;;;3727:137;-1:-1:-1;;3727:137:1:o;4077:375::-;-1:-1:-1;;;;;4335:15:1;;;4317:34;;4387:15;;;;4382:2;4367:18;;4360:43;4434:2;4419:18;;4412:34;;;;4267:2;4252:18;;4234:218::o;6322:261::-;6501:2;6490:9;6483:21;6464:4;6521:56;6573:2;6562:9;6558:18;6550:6;6521:56;:::i;6588:465::-;6845:2;6834:9;6827:21;6808:4;6871:56;6923:2;6912:9;6908:18;6900:6;6871:56;:::i;:::-;6975:9;6967:6;6963:22;6958:2;6947:9;6943:18;6936:50;7003:44;7040:6;7032;7003:44;:::i;:::-;6995:52;6817:236;-1:-1:-1;;;;;6817:236:1:o;7058:261::-;7237:2;7226:9;7219:21;7200:4;7257:56;7309:2;7298:9;7294:18;7286:6;7257:56;:::i;7324:669::-;7659:2;7648:9;7641:21;7622:4;7685:56;7737:2;7726:9;7722:18;7714:6;7685:56;:::i;:::-;7789:9;7781:6;7777:22;7772:2;7761:9;7757:18;7750:50;7823:44;7860:6;7852;7823:44;:::i;:::-;7809:58;;7915:9;7907:6;7903:22;7898:2;7887:9;7883:18;7876:50;7943:44;7980:6;7972;7943:44;:::i;:::-;7935:52;7631:362;-1:-1:-1;;;;;;7631:362:1:o;7998:2125::-;8842:4;8871:3;8901:2;8890:9;8883:21;8927:56;8979:2;8968:9;8964:18;8956:6;8927:56;:::i;:::-;8913:70;;9031:9;9023:6;9019:22;9014:2;9003:9;8999:18;8992:50;9065:44;9102:6;9094;9065:44;:::i;:::-;9051:58;;9157:9;9149:6;9145:22;9140:2;9129:9;9125:18;9118:50;9191:44;9228:6;9220;9191:44;:::i;:::-;9177:58;;9283:9;9275:6;9271:22;9266:2;9255:9;9251:18;9244:50;9317:44;9354:6;9346;9317:44;:::i;:::-;9303:58;;9410:9;9402:6;9398:22;9392:3;9381:9;9377:19;9370:51;9444:44;9481:6;9473;9444:44;:::i;:::-;9430:58;;9537:9;9529:6;9525:22;9519:3;9508:9;9504:19;9497:51;9571:44;9608:6;9600;9571:44;:::i;:::-;9557:58;;9664:9;9656:6;9652:22;9646:3;9635:9;9631:19;9624:51;9698:44;9735:6;9727;9698:44;:::i;:::-;9684:58;;9791:9;9783:6;9779:22;9773:3;9762:9;9758:19;9751:51;9825:44;9862:6;9854;9825:44;:::i;:::-;9811:58;;9918:9;9910:6;9906:22;9900:3;9889:9;9885:19;9878:51;9952:44;9989:6;9981;9952:44;:::i;:::-;9938:58;;10045:9;10037:6;10033:22;10027:3;10016:9;10012:19;10005:51;10073:44;10110:6;10102;10073:44;:::i;:::-;10065:52;8851:1272;-1:-1:-1;;;;;;;;;;;;;8851:1272:1:o;10128:875::-;10541:3;10530:9;10523:22;10504:4;10568:57;10620:3;10609:9;10605:19;10597:6;10568:57;:::i;:::-;10673:9;10665:6;10661:22;10656:2;10645:9;10641:18;10634:50;10707:44;10744:6;10736;10707:44;:::i;:::-;10693:58;;10799:9;10791:6;10787:22;10782:2;10771:9;10767:18;10760:50;10833:44;10870:6;10862;10833:44;:::i;:::-;10819:58;;10925:9;10917:6;10913:22;10908:2;10897:9;10893:18;10886:50;10953:44;10990:6;10982;10953:44;:::i;11200:345::-;11349:2;11334:18;;11382:1;11371:13;;11361:2;;11427:10;11422:3;11418:20;11415:1;11408:31;11462:4;11459:1;11452:15;11490:4;11487:1;11480:15;11361:2;11514:25;;;11316:229;:::o;11550:383::-;11699:2;11688:9;11681:21;11662:4;11731:6;11725:13;11774:6;11769:2;11758:9;11754:18;11747:34;11790:66;11849:6;11844:2;11833:9;11829:18;11824:2;11816:6;11812:15;11790:66;:::i;:::-;11917:2;11896:15;-1:-1:-1;;11892:29:1;11877:45;;;;11924:2;11873:54;;11671:262;-1:-1:-1;;11671:262:1:o;14291:401::-;14493:2;14475:21;;;14532:2;14512:18;;;14505:30;14571:34;14566:2;14551:18;;14544:62;-1:-1:-1;;;14637:2:1;14622:18;;14615:35;14682:3;14667:19;;14465:227::o;15527:356::-;15729:2;15711:21;;;15748:18;;;15741:30;15807:34;15802:2;15787:18;;15780:62;15874:2;15859:18;;15701:182::o;19764:128::-;19804:3;19835:1;19831:6;19828:1;19825:13;19822:2;;;19841:18;;:::i;:::-;-1:-1:-1;19877:9:1;;19812:80::o;19897:217::-;19937:1;19963;19953:2;;-1:-1:-1;;;19988:31:1;;20042:4;20039:1;20032:15;20070:4;19995:1;20060:15;19953:2;-1:-1:-1;20099:9:1;;19943:171::o;20119:168::-;20159:7;20225:1;20221;20217:6;20213:14;20210:1;20207:21;20202:1;20195:9;20188:17;20184:45;20181:2;;;20232:18;;:::i;:::-;-1:-1:-1;20272:9:1;;20171:116::o;20292:125::-;20332:4;20360:1;20357;20354:8;20351:2;;;20365:18;;:::i;:::-;-1:-1:-1;20402:9:1;;20341:76::o;20422:258::-;20494:1;20504:113;20518:6;20515:1;20512:13;20504:113;;;20594:11;;;20588:18;20575:11;;;20568:39;20540:2;20533:10;20504:113;;;20635:6;20632:1;20629:13;20626:2;;;-1:-1:-1;;20670:1:1;20652:16;;20645:27;20475:205::o;20685:135::-;20724:3;-1:-1:-1;;20745:17:1;;20742:2;;;20765:18;;:::i;:::-;-1:-1:-1;20812:1:1;20801:13;;20732:88::o;20825:127::-;20886:10;20881:3;20877:20;20874:1;20867:31;20917:4;20914:1;20907:15;20941:4;20938:1;20931:15;20957:131;-1:-1:-1;;;;;21032:31:1;;21022:42;;21012:2;;21078:1;21075;21068:12

Swarm Source

ipfs://eaecd4edb68728fac854779033fbee895b50a21a8975f2c5ce1d6f458f2901f3
Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.