ETH Price: $3,337.59 (-1.18%)

Token

 

Overview

Max Total Supply

0

Holders

247

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
Coinbase: Fees
0x382fFCe2287252F930E1C8DC9328dac5BF282bA1
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
arteQTokens

Compiler Version
v0.8.0+commit.c7dfd78e

Optimization Enabled:
Yes with 2000 runs

Other Settings:
default evmVersion
File 1 of 14 : arteQTokens.sol
/*
 * This file is part of the contracts written for artèQ Investment Fund (https://github.com/billionbuild/arteq-contracts).
 * Copyright (c) 2021 BillionBuild (2B) Team.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
// SPDX-License-Identifier: GNU General Public License v3.0

pragma solidity 0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "./ERC1155Supply.sol";
import "./IarteQTokens.sol";
import "./IarteQTaskFinalizer.sol";

/// @author Kam Amini <[email protected]> <[email protected]> <[email protected]> <[email protected]>
///
/// Reviewed and revised by: Masoud Khosravi <masoud_at_2b.team> <mkh_at_arteq.io>
///                          Ali Jafari <ali_at_2b.team> <aj_at_arteq.io>
///
/// @title This contract keeps track of the tokens used in artèQ Investment
/// Fund ecosystem. It also contains the logic used for profit distribution.
///
/// @notice Use at your own risk
contract arteQTokens is ERC1155Supply, IarteQTokens {

    /// The main artèQ token
    uint256 public constant ARTEQ = 1;

    /// The governance token of artèQ Investment Fund
    uint256 public constant gARTEQ = 2;

    // The mapping from token IDs to their respective Metadata URIs
    mapping (uint256 => string) private _tokenMetadataURIs;

    // The admin smart contract
    address private _adminContract;

    // Treasury account responsible for asset-token ratio appreciation.
    address private _treasuryAccount;

    // This can be a Uniswap V1/V2 exchange (pool) account created for ARTEQ token,
    // or any other exchange account. Treasury contract uses these pools to buy
    // back or sell tokens. In case of buy backs, the tokens must be delivered to
    // treasury account from these contracts. Otherwise, the profit distribution
    // logic doesn't get triggered.
    address private _exchange1Account;
    address private _exchange2Account;
    address private _exchange3Account;
    address private _exchange4Account;
    address private _exchange5Account;

    // All the profits accumulated since the deployment of the contract. This is
    // used as a marker to facilitate the caluclation of every eligible account's
    // share from the profits in a given time range.
    uint256 private _allTimeProfit;

    // The actual number of profit tokens transferred to accounts
    uint256 private _profitTokensTransferredToAccounts;

    // The percentage of the bought back tokens which is considered as profit for gARTEQ owners
    // Default value is 20% and only admin contract can change that.
    uint private _profitPercentage;

    // In order to caluclate the share of each elgiible account from the profits,
    // and more importantly, in order to do this efficiently (less gas usage),
    // we need this mapping to remember the "all time profit" when an account
    // is modified (receives tokens or sends tokens).
    mapping (address => uint256) private _profitMarkers;

    // A timestamp indicating when the ramp-up phase gets expired.
    uint256 private _rampUpPhaseExpireTimestamp;

    // Indicates until when the address cannot send any tokens
    mapping (address => uint256) private _lockedUntilTimestamps;

    /// Emitted when the admin contract is changed.
    event AdminContractChanged(address newContract);

    /// Emitted when the treasury account is changed.
    event TreasuryAccountChanged(address newAccount);

    /// Emitted when the exchange account is changed.
    event Exchange1AccountChanged(address newAccount);
    event Exchange2AccountChanged(address newAccount);
    event Exchange3AccountChanged(address newAccount);
    event Exchange4AccountChanged(address newAccount);
    event Exchange5AccountChanged(address newAccount);

    /// Emitted when the profit percentage is changed.
    event ProfitPercentageChanged(uint newPercentage);

    /// Emitted when a token distribution occurs during the ramp-up phase
    event RampUpPhaseTokensDistributed(address to, uint256 amount, uint256 lockedUntilTimestamp);

    /// Emitted when some buy back tokens are received by the treasury account.
    event ProfitTokensCollected(uint256 amount);

    /// Emitted when a share holder receives its tokens from the buy back profits.
    event ProfitTokensDistributed(address to, uint256 amount);

    // Emitted when profits are caluclated because of a manual buy back event
    event ManualBuyBackWithdrawalFromTreasury(uint256 amount);

    modifier adminApprovalRequired(uint256 adminTaskId) {
        _;
        // This must succeed otherwise the tx gets reverted
        IarteQTaskFinalizer(_adminContract).finalizeTask(msg.sender, adminTaskId);
    }

    modifier validToken(uint256 tokenId) {
        require(tokenId == ARTEQ || tokenId == gARTEQ, "arteQTokens: non-existing token");
        _;
    }

    modifier onlyRampUpPhase() {
        require(block.timestamp < _rampUpPhaseExpireTimestamp, "arteQTokens: ramp up phase is finished");
        _;
    }

    constructor(address adminContract) {
        _adminContract = adminContract;

        /// Must be set later
        _treasuryAccount = address(0);

        /// Must be set later
        _exchange1Account = address(0);
        _exchange2Account = address(0);
        _exchange3Account = address(0);
        _exchange4Account = address(0);
        _exchange5Account = address(0);

        string memory arteQURI = "ipfs://QmfBtH8BSztaYn3QFnz2qvu2ehZgy8AZsNMJDkgr3pdqT8";
        string memory gArteQURI = "ipfs://QmRAXmU9AymDgtphh37hqx5R2QXSS2ngchQRDFtg6XSD7w";
        _tokenMetadataURIs[ARTEQ] = arteQURI;
        emit URI(arteQURI, ARTEQ);
        _tokenMetadataURIs[gARTEQ] = gArteQURI;
        emit URI(gArteQURI, gARTEQ);

        /// 10 billion
        _initialMint(_adminContract, ARTEQ, 10 ** 10, "");
        /// 1 million
        _initialMint(_adminContract, gARTEQ, 10 ** 6, "");

        /// Obviously, no profit at the time of deployment
        _allTimeProfit = 0;

        _profitPercentage = 20;

        /// Tuesday, February 1, 2022 12:00:00 AM
        _rampUpPhaseExpireTimestamp = 1643673600;
    }

    /// See {ERC1155-uri}
    function uri(uint256 tokenId) external view virtual override validToken(tokenId) returns (string memory) {
        return _tokenMetadataURIs[tokenId];
    }

    function setURI(
        uint256 adminTaskId,
        uint256 tokenId,
        string memory newUri
    ) external adminApprovalRequired(adminTaskId) validToken(tokenId) {
        _tokenMetadataURIs[tokenId] = newUri;
        emit URI(newUri, tokenId);
    }

    /// Returns the set treasury account
    /// @return The set treasury account
    function getTreasuryAccount() external view returns (address) {
        return _treasuryAccount;
    }

    /// Sets a new treasury account. Just after deployment, treasury account is set to zero address but once
    /// set to a non-zero address, it cannot be changed back to zero address again.
    ///
    /// @param adminTaskId the task which must have been approved by multiple admins
    /// @param newAccount new treasury address
    function setTreasuryAccount(uint256 adminTaskId, address newAccount) external adminApprovalRequired(adminTaskId) {
        require(newAccount != address(0), "arteQTokens: zero address for treasury account");
        _treasuryAccount = newAccount;
        emit TreasuryAccountChanged(newAccount);
    }

    /// Returns the 1st exchange account
    /// @return The 1st exchnage account
    function getExchange1Account() external view returns (address) {
        return _exchange1Account;
    }

    /// Returns the 2nd exchange account
    /// @return The 2nd exchnage account
    function getExchange2Account() external view returns (address) {
        return _exchange2Account;
    }

    /// Returns the 3rd exchange account
    /// @return The 3rd exchnage account
    function getExchange3Account() external view returns (address) {
        return _exchange3Account;
    }

    /// Returns the 4th exchange account
    /// @return The 4th exchnage account
    function getExchange4Account() external view returns (address) {
        return _exchange4Account;
    }

    /// Returns the 5th exchange account
    /// @return The 5th exchnage account
    function getExchange5Account() external view returns (address) {
        return _exchange5Account;
    }

    /// Sets a new exchange account. Just after deployment, exchange account is set to zero address but once
    /// set to a non-zero address, it cannot be changed back to zero address again.
    ///
    /// @param adminTaskId the task which must have been approved by multiple admins
    /// @param newAccount new exchange address
    function setExchange1Account(uint256 adminTaskId, address newAccount) external adminApprovalRequired(adminTaskId) {
        require(newAccount != address(0), "arteQTokens: zero address for exchange account");
        _exchange1Account = newAccount;
        emit Exchange1AccountChanged(newAccount);
    }

    /// Sets a new exchange account. Just after deployment, exchange account is set to zero address but once
    /// set to a non-zero address, it cannot be changed back to zero address again.
    ///
    /// @param adminTaskId the task which must have been approved by multiple admins
    /// @param newAccount new exchange address
    function setExchange2Account(uint256 adminTaskId, address newAccount) external adminApprovalRequired(adminTaskId) {
        require(newAccount != address(0), "arteQTokens: zero address for exchange account");
        _exchange2Account = newAccount;
        emit Exchange2AccountChanged(newAccount);
    }

    /// Sets a new exchange account. Just after deployment, exchange account is set to zero address but once
    /// set to a non-zero address, it cannot be changed back to zero address again.
    ///
    /// @param adminTaskId the task which must have been approved by multiple admins
    /// @param newAccount new exchange address
    function setExchange3Account(uint256 adminTaskId, address newAccount) external adminApprovalRequired(adminTaskId) {
        require(newAccount != address(0), "arteQTokens: zero address for exchange account");
        _exchange3Account = newAccount;
        emit Exchange3AccountChanged(newAccount);
    }

    /// Sets a new exchange account. Just after deployment, exchange account is set to zero address but once
    /// set to a non-zero address, it cannot be changed back to zero address again.
    ///
    /// @param adminTaskId the task which must have been approved by multiple admins
    /// @param newAccount new exchange address
    function setExchange4Account(uint256 adminTaskId, address newAccount) external adminApprovalRequired(adminTaskId) {
        require(newAccount != address(0), "arteQTokens: zero address for exchange account");
        _exchange4Account = newAccount;
        emit Exchange4AccountChanged(newAccount);
    }

    /// Sets a new exchange account. Just after deployment, exchange account is set to zero address but once
    /// set to a non-zero address, it cannot be changed back to zero address again.
    ///
    /// @param adminTaskId the task which must have been approved by multiple admins
    /// @param newAccount new exchange address
    function setExchange5Account(uint256 adminTaskId, address newAccount) external adminApprovalRequired(adminTaskId) {
        require(newAccount != address(0), "arteQTokens: zero address for exchange account");
        _exchange5Account = newAccount;
        emit Exchange5AccountChanged(newAccount);
    }

    /// Returns the profit percentage
    /// @return The set treasury account
    function getProfitPercentage() external view returns (uint) {
        return _profitPercentage;
    }

    /// Sets a new profit percentage. This is the percentage of bought-back tokens which is considered
    /// as profit for gARTEQ owners. The value can be between 10% and 50%.
    ///
    /// @param adminTaskId the task which must have been approved by multiple admins
    /// @param newPercentage new exchange address
    function setProfitPercentage(uint256 adminTaskId, uint newPercentage) external adminApprovalRequired(adminTaskId) {
        require(newPercentage >= 10 && newPercentage <= 50, "arteQTokens: invalid value for profit percentage");
        _profitPercentage = newPercentage;
        emit ProfitPercentageChanged(newPercentage);
    }

    /// Transfer from admin contract
    function transferFromAdminContract(
        uint256 adminTaskId,
        address to,
        uint256 id,
        uint256 amount
    ) external adminApprovalRequired(adminTaskId) {
        _safeTransferFrom(_msgSender(), _adminContract, to, id, amount, "");
    }

    /// A token distribution mechanism, only valid in ramp-up phase, valid till the end of Jan 2022.
    function rampUpPhaseDistributeToken(
        uint256 adminTaskId,
        address[] memory tos,
        uint256[] memory amounts,
        uint256[] memory lockedUntilTimestamps
    ) external adminApprovalRequired(adminTaskId) onlyRampUpPhase {
        require(tos.length == amounts.length, "arteQTokens: inputs have incorrect lengths");
        for (uint256 i = 0; i < tos.length; i++) {
            require(tos[i] != _treasuryAccount, "arteQTokens: cannot transfer to treasury account");
            require(tos[i] != _adminContract, "arteQTokens: cannot transfer to admin contract");
            _safeTransferFrom(_msgSender(), _adminContract, tos[i], ARTEQ, amounts[i], "");
            if (lockedUntilTimestamps[i] > 0) {
                _lockedUntilTimestamps[tos[i]] = lockedUntilTimestamps[i];
            }
            emit RampUpPhaseTokensDistributed(tos[i], amounts[i], lockedUntilTimestamps[i]);
        }
    }

    function balanceOf(address account, uint256 tokenId) public view virtual override validToken(tokenId) returns (uint256) {
        if (tokenId == gARTEQ) {
            return super.balanceOf(account, tokenId);
        }
        return super.balanceOf(account, tokenId) + _calcUnrealizedProfitTokens(account);
    }

    function allTimeProfit() external view returns (uint256) {
        return _allTimeProfit;
    }

    function totalCirculatingGovernanceTokens() external view returns (uint256) {
        return totalSupply(gARTEQ) - balanceOf(_adminContract, gARTEQ);
    }

    function profitTokensTransferredToAccounts() external view returns (uint256) {
        return _profitTokensTransferredToAccounts;
    }

    function compatBalanceOf(address /* origin */, address account, uint256 tokenId) external view virtual override returns (uint256) {
        return balanceOf(account, tokenId);
    }

    function compatTotalSupply(address /* origin */, uint256 tokenId) external view virtual override returns (uint256) {
        return totalSupply(tokenId);
    }

    function compatTransfer(address origin, address to, uint256 tokenId, uint256 amount) external virtual override {
        address from = origin;
        _safeTransferFrom(origin, from, to, tokenId, amount, "");
    }

    function compatTransferFrom(address origin, address from, address to, uint256 tokenId, uint256 amount) external virtual override {
        require(
            from == origin || isApprovedForAll(from, origin),
            "arteQTokens: caller is not owner nor approved "
        );
        _safeTransferFrom(origin, from, to, tokenId, amount, "");
    }

    function compatAllowance(address /* origin */, address account, address operator) external view virtual override returns (uint256) {
        if (isApprovedForAll(account, operator)) {
            return 2 ** 256 - 1;
        }
        return 0;
    }

    function compatApprove(address origin, address operator, uint256 amount) external virtual override {
        _setApprovalForAll(origin, operator, amount > 0);
    }

    // If this contract gets a balance in some ERC20 contract after it's finished, then we can rescue it.
    function rescueTokens(uint256 adminTaskId, IERC20 foreignToken, address to) external adminApprovalRequired(adminTaskId) {
        foreignToken.transfer(to, foreignToken.balanceOf(address(this)));
    }

    // If this contract gets a balance in some ERC721 contract after it's finished, then we can rescue it.
    function approveNFTRescue(uint256 adminTaskId, IERC721 foreignNFT, address to) external adminApprovalRequired(adminTaskId) {
        foreignNFT.setApprovalForAll(to, true);
    }

    // In case of any manual buy back event which is not processed through DEX contracts, this function
    // helps admins distribute the profits. This function must be called only when the bought back tokens
    // have been successfully transferred to treasury account.
    function processManualBuyBackEvent(uint256 adminTaskId, uint256 boughtBackTokensAmount) external adminApprovalRequired(adminTaskId) {
        uint256 profit = (boughtBackTokensAmount * _profitPercentage) / 100;
        if (profit > 0) {
            _balances[ARTEQ][_treasuryAccount] -= profit;
            emit ManualBuyBackWithdrawalFromTreasury(profit);
            _allTimeProfit += profit;
            emit ProfitTokensCollected(profit);
        }
    }

    function _beforeTokenTransfer(
        address operator,
        address from,
        address to,
        uint256 id,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual override {
        // We have to call the super function in order to have the total supply correct.
        // It is actually needed by the first two _initialMint calls only. After that, it is
        // a no-op function.
        super._beforeTokenTransfer(operator, from, to, id, amounts, data);

        // this is one of the two first _initialMint calls
        if (from == address(0)) {
            return;
        }

        // This is a buy-back callback from exchange account
        if ((
                from == _exchange1Account ||
                from == _exchange2Account ||
                from == _exchange3Account ||
                from == _exchange4Account ||
                from == _exchange5Account
        ) && to == _treasuryAccount) {
            require(amounts.length == 2 && id == ARTEQ, "arteQTokens: invalid transfer from exchange");
            uint256 profit = (amounts[0] * _profitPercentage) / 100;
            amounts[1] = amounts[0] - profit;
            if (profit > 0) {
                _allTimeProfit += profit;
                emit ProfitTokensCollected(profit);
            }
            return;
        }

        // Ensures that the locked accounts cannot send their ARTEQ tokens
        if (id == ARTEQ) {
            require(_lockedUntilTimestamps[from] == 0 || block.timestamp > _lockedUntilTimestamps[from], "arteQTokens: account cannot send tokens");
        }

        // Realize/Transfer the accumulated profit of 'from' account and make it spendable
        if (from != _adminContract &&
            from != _treasuryAccount &&
            from != _exchange1Account &&
            from != _exchange2Account &&
            from != _exchange3Account &&
            from != _exchange4Account &&
            from != _exchange5Account) {
            _realizeAccountProfitTokens(from);
        }

        // Realize/Transfer the accumulated profit of 'to' account and make it spendable
        if (to != _adminContract &&
            to != _treasuryAccount &&
            to != _exchange1Account &&
            to != _exchange2Account &&
            to != _exchange3Account &&
            to != _exchange4Account &&
            to != _exchange5Account) {
            _realizeAccountProfitTokens(to);
        }
    }

    function _calcUnrealizedProfitTokens(address account) internal view returns (uint256) {
        if (account == _adminContract ||
            account == _treasuryAccount ||
            account == _exchange1Account ||
            account == _exchange2Account ||
            account == _exchange3Account ||
            account == _exchange4Account ||
            account == _exchange5Account) {
            return 0;
        }
        uint256 profitDifference = _allTimeProfit - _profitMarkers[account];
        uint256 totalGovTokens = totalSupply(gARTEQ) - balanceOf(_adminContract, gARTEQ);
        if (totalGovTokens == 0) {
            return 0;
        }
        uint256 tokensToTransfer = (profitDifference * balanceOf(account, gARTEQ)) / totalGovTokens;
        return tokensToTransfer;
    }

    // This function actually transfers the unrealized accumulated profit tokens of an account
    // and make them spendable by that account. The balance should not differ after the
    // trasnfer as the balance already includes the unrealized tokens.
    function _realizeAccountProfitTokens(address account) internal {
        bool updateProfitMarker = true;
        // If 'account' has some governance tokens then calculate the accumulated profit since the last distribution
        if (balanceOf(account, gARTEQ) > 0) {
            uint256 tokensToTransfer = _calcUnrealizedProfitTokens(account);
            // If the profit is too small and no token can be transferred, then don't update the profit marker and
            // let the account wait for the next round of profit distribution
            if (tokensToTransfer == 0) {
                updateProfitMarker = false;
            } else {
                _balances[ARTEQ][account] += tokensToTransfer;
                _profitTokensTransferredToAccounts += tokensToTransfer;
                emit ProfitTokensDistributed(account, tokensToTransfer);
            }
        }
        if (updateProfitMarker) {
            _profitMarkers[account] = _allTimeProfit;
        }
    }

    receive() external payable {
        revert("arteQTokens: cannot accept ether");
    }

    fallback() external payable {
        revert("arteQTokens: cannot accept ether");
    }
}

File 2 of 14 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @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 `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, 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 `sender` to `recipient` 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 sender,
        address recipient,
        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);
}

File 3 of 14 : IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

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

File 4 of 14 : ERC1155Supply.sol
/*
 * This file is part of the contracts written for artèQ Investment Fund (https://github.com/billionbuild/arteq-contracts).
 * Copyright (c) 2021 BillionBuild (2B) Team.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
// SPDX-License-Identifier: GNU General Public License v3.0
// Based on OpenZeppelin Contracts v4.3.2 (token/ERC1155/extensions/ERC1155Supply.sol)

pragma solidity 0.8.0;

import "./ERC1155.sol";

/**
 * @author Modified by Kam Amini <[email protected]> <[email protected]> <[email protected]>
 *
 * @notice Use at your own risk
 *
 * @dev Extension of ERC1155 that adds tracking of total supply per id.
 *
 * Useful for scenarios where Fungible and Non-fungible tokens have to be
 * clearly identified. Note: While a totalSupply of 1 might mean the
 * corresponding is an NFT, there is no guarantees that no other token with the
 * same id are not going to be minted.
 *
 * Note: 2B has modified the original code to cover its needs as
 * part of artèQ Investment Fund ecosystem
 */
abstract contract ERC1155Supply is ERC1155 {
    mapping(uint256 => uint256) private _totalSupply;

    /**
     * @dev Total amount of tokens in with a given id.
     */
    function totalSupply(uint256 id) public view virtual returns (uint256) {
        return _totalSupply[id];
    }

    /**
     * @dev Indicates whether any token exist with a given id, or not.
     */
    function exists(uint256 id) public view virtual returns (bool) {
        return ERC1155Supply.totalSupply(id) > 0;
    }

    /**
     * @dev See {ERC1155-_beforeTokenTransfer}.
     */
    function _beforeTokenTransfer(
        address operator,
        address from,
        address to,
        uint256 id,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual override {
        super._beforeTokenTransfer(operator, from, to, id, amounts, data);

        if (from == address(0)) {
            _totalSupply[id] += amounts[0];
        }

        if (to == address(0)) {
            _totalSupply[id] -= amounts[0];
        }
    }
}

File 5 of 14 : IarteQTokens.sol
/*
 * This file is part of the contracts written for artèQ Investment Fund (https://github.com/billionbuild/arteq-contracts).
 * Copyright (c) 2021 BillionBuild (2B) Team.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
// SPDX-License-Identifier: GNU General Public License v3.0

pragma solidity 0.8.0;

/// @author Kam Amini <[email protected]> <[email protected]> <[email protected]>
///
/// @title An interface which allows ERC-20 tokens to interact with the
/// main ERC-1155 contract
///
/// @notice Use at your own risk
interface IarteQTokens {
    function compatBalanceOf(address origin, address account, uint256 tokenId) external view returns (uint256);
    function compatTotalSupply(address origin, uint256 tokenId) external view returns (uint256);
    function compatTransfer(address origin, address to, uint256 tokenId, uint256 amount) external;
    function compatTransferFrom(address origin, address from, address to, uint256 tokenId, uint256 amount) external;
    function compatAllowance(address origin, address account, address operator) external view returns (uint256);
    function compatApprove(address origin, address operator, uint256 amount) external;
}

File 6 of 14 : IarteQTaskFinalizer.sol
/*
 * This file is part of the contracts written for artèQ Investment Fund (https://github.com/billionbuild/arteq-contracts).
 * Copyright (c) 2021 BillionBuild (2B) Team.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
// SPDX-License-Identifier: GNU General Public License v3.0

pragma solidity 0.8.0;

/// @author Kam Amini <[email protected]> <[email protected]> <[email protected]>
/// @title The interface for finalizing tasks. Mainly used by artèQ contracts to
/// perform administrative tasks in conjuction with admin contract.
interface IarteQTaskFinalizer {

    event TaskFinalized(address finalizer, address origin, uint256 taskId);

    function finalizeTask(address origin, uint256 taskId) external;
}

File 7 of 14 : IERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

File 8 of 14 : ERC1155.sol
/*
 * This file is part of the contracts written for artèQ Investment Fund (https://github.com/billionbuild/arteq-contracts).
 * Copyright (c) 2021 BillionBuild (2B) Team.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
// SPDX-License-Identifier: GNU General Public License v3.0
// Based on OpenZeppelin Contracts v4.3.2 (token/ERC1155/ERC1155.sol)

pragma solidity 0.8.0;

import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
import "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/utils/introspection/ERC165.sol";

 /**
  * @author Modified by Kam Amini <[email protected]> <[email protected]> <[email protected]>
  *
  * @notice Use at your own risk
  *
  * Note: 2B has modified the original code to cover its needs as
  * part of artèQ Investment Fund ecosystem
  */
abstract contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
    using Address for address;

    // Mapping from token ID to account balances
    // arteQ: we made this field public in order to distribute profits in the token contract
    mapping(uint256 => mapping(address => uint256)) public _balances;

    // Mapping from account to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    /**
     * @dev See {_setURI}.
     */
    constructor() {
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC1155).interfaceId ||
            interfaceId == type(IERC1155MetadataURI).interfaceId ||
            super.supportsInterface(interfaceId);
    }


    /**
     * @dev See {IERC1155-balanceOf}.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
        require(account != address(0), "ERC1155: balance query for the zero address");
        return _balances[id][account];
    }

    /**
     * @dev See {IERC1155-balanceOfBatch}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
        public
        view
        virtual
        override
        returns (uint256[] memory)
    {
        require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");

        uint256[] memory batchBalances = new uint256[](accounts.length);

        for (uint256 i = 0; i < accounts.length; ++i) {
            batchBalances[i] = balanceOf(accounts[i], ids[i]);
        }

        return batchBalances;
    }

    /**
     * @dev See {IERC1155-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC1155-isApprovedForAll}.
     */
    function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[account][operator];
    }

    /**
     * @dev See {IERC1155-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) public virtual override {
        require(
            from == _msgSender() || isApprovedForAll(from, _msgSender()),
            "ERC1155: caller is not owner nor approved "
        );
        _safeTransferFrom(_msgSender(), from, to, id, amount, data);
    }

    /**
     * @dev See {IERC1155-safeBatchTransferFrom}.
     */
    function safeBatchTransferFrom(
        address /* from */,
        address /* to */,
        uint256[] memory /* ids */,
        uint256[] memory /* amounts */,
        bytes memory /* data */
    ) public virtual override {
        revert("ERC1155: not implemented");
    }

    function _safeTransferFrom(
        address operator,
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: transfer to the zero address");

        // arteQ: we have to read the returned amount again as it can change in the function
        uint256[] memory amounts = _asArray(amount, 2);
        _beforeTokenTransfer(operator, from, to, id, amounts, data);
        uint256 fromAmount = amounts[0];
        uint256 toAmount = amounts[1];

        uint256 fromBalance = _balances[id][from];
        require(fromBalance >= fromAmount, "ERC1155: insufficient balance for transfer");
        unchecked {
            _balances[id][from] = fromBalance - fromAmount;
        }
        _balances[id][to] += toAmount;

        emit TransferSingle(operator, from, to, id, amount);
    }

    function _initialMint(
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: mint to the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, address(0), to, id, _asArray(amount, 2), data);

        _balances[id][to] += amount;
        emit TransferSingle(operator, address(0), to, id, amount);
    }

    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC1155: setting approval status for self");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    function _beforeTokenTransfer(
        address /* operator */,
        address /* from */,
        address /* to */,
        uint256 /* id */,
        uint256[] memory /* amounts */,
        bytes memory /* data */
    ) internal virtual {}

    function _asArray(uint256 element, uint len) private pure returns (uint256[] memory) {
        if (len == 1) {
            uint256[] memory array = new uint256[](1);
            array[0] = element;
            return array;
        } else if (len == 2) {
            uint256[] memory array = new uint256[](2);
            array[0] = element;
            array[1] = element;
            return array;
        }
        revert("ERC1155: length must be 1 or 2");
    }
}

File 9 of 14 : IERC1155.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
        external
        view
        returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}

File 10 of 14 : IERC1155Receiver.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev _Available since v3.1._
 */
interface IERC1155Receiver is IERC165 {
    /**
        @dev Handles the receipt of a single ERC1155 token type. This function is
        called at the end of a `safeTransferFrom` after the balance has been updated.
        To accept the transfer, this must return
        `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
        (i.e. 0xf23a6e61, or its own function selector).
        @param operator The address which initiated the transfer (i.e. msg.sender)
        @param from The address which previously owned the token
        @param id The ID of the token being transferred
        @param value The amount of tokens being transferred
        @param data Additional data with no specified format
        @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
    */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    /**
        @dev Handles the receipt of a multiple ERC1155 token types. This function
        is called at the end of a `safeBatchTransferFrom` after the balances have
        been updated. To accept the transfer(s), this must return
        `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
        (i.e. 0xbc197c81, or its own function selector).
        @param operator The address which initiated the batch transfer (i.e. msg.sender)
        @param from The address which previously owned the token
        @param ids An array containing ids of each token being transferred (order and length must match values array)
        @param values An array containing amounts of each token being transferred (order and length must match ids array)
        @param data Additional data with no specified format
        @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
    */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}

File 11 of 14 : IERC1155MetadataURI.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../IERC1155.sol";

/**
 * @dev Interface of the optional ERC1155MetadataExtension interface, as defined
 * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155MetadataURI is IERC1155 {
    /**
     * @dev Returns the URI for token type `id`.
     *
     * If the `\{id\}` substring is present in the URI, it must be replaced by
     * clients with the actual token type ID.
     */
    function uri(uint256 id) external view returns (string memory);
}

File 12 of 14 : Address.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @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
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 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);
            }
        }
    }
}

File 13 of 14 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

File 14 of 14 : ERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 2000,
    "details": {
      "yul": true,
      "yulDetails": {
        "stackAllocation": true,
        "optimizerSteps": "dhfoDgvulfnTUtnIf"
      }
    }
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"adminContract","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newContract","type":"address"}],"name":"AdminContractChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAccount","type":"address"}],"name":"Exchange1AccountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAccount","type":"address"}],"name":"Exchange2AccountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAccount","type":"address"}],"name":"Exchange3AccountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAccount","type":"address"}],"name":"Exchange4AccountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAccount","type":"address"}],"name":"Exchange5AccountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ManualBuyBackWithdrawalFromTreasury","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newPercentage","type":"uint256"}],"name":"ProfitPercentageChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ProfitTokensCollected","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ProfitTokensDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lockedUntilTimestamp","type":"uint256"}],"name":"RampUpPhaseTokensDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAccount","type":"address"}],"name":"TreasuryAccountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"ARTEQ","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"_balances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allTimeProfit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"adminTaskId","type":"uint256"},{"internalType":"contract IERC721","name":"foreignNFT","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"approveNFTRescue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"compatAllowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"origin","type":"address"},{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"compatApprove","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"compatBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"compatTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"origin","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"compatTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"origin","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"compatTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gARTEQ","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExchange1Account","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExchange2Account","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExchange3Account","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExchange4Account","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExchange5Account","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProfitPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTreasuryAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"adminTaskId","type":"uint256"},{"internalType":"uint256","name":"boughtBackTokensAmount","type":"uint256"}],"name":"processManualBuyBackEvent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"profitTokensTransferredToAccounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"adminTaskId","type":"uint256"},{"internalType":"address[]","name":"tos","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"lockedUntilTimestamps","type":"uint256[]"}],"name":"rampUpPhaseDistributeToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"adminTaskId","type":"uint256"},{"internalType":"contract IERC20","name":"foreignToken","type":"address"},{"internalType":"address","name":"to","type":"address"}],"name":"rescueTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"adminTaskId","type":"uint256"},{"internalType":"address","name":"newAccount","type":"address"}],"name":"setExchange1Account","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"adminTaskId","type":"uint256"},{"internalType":"address","name":"newAccount","type":"address"}],"name":"setExchange2Account","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"adminTaskId","type":"uint256"},{"internalType":"address","name":"newAccount","type":"address"}],"name":"setExchange3Account","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"adminTaskId","type":"uint256"},{"internalType":"address","name":"newAccount","type":"address"}],"name":"setExchange4Account","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"adminTaskId","type":"uint256"},{"internalType":"address","name":"newAccount","type":"address"}],"name":"setExchange5Account","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"adminTaskId","type":"uint256"},{"internalType":"uint256","name":"newPercentage","type":"uint256"}],"name":"setProfitPercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"adminTaskId","type":"uint256"},{"internalType":"address","name":"newAccount","type":"address"}],"name":"setTreasuryAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"adminTaskId","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"newUri","type":"string"}],"name":"setURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalCirculatingGovernanceTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"adminTaskId","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFromAdminContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

60806040523480156200001157600080fd5b5060405162004a8638038062004a86833981016040819052620000349162000d01565b600480546001600160a01b0383166001600160a01b03199182161790915560058054821690556006805482169055600780548216905560088054821690556009805482169055600a805490911690556040805160608101909152603580825260009190620049fc60208301399050600060405180606001604052806035815260200162004a31603591396001600052600360209081528351919250620000ff917fa15bc60c955c405d20d9149c709e2460f1c2d9a497496a7f46004d1772c3054c9185019062000c4e565b50600160008051602062004a668339815191528360405162000122919062000f5f565b60405180910390a2600260005260036020908152815162000169917fc3a24b0501bd2c13a7e57f2db4369ec4c223447539fc0724a9d55ac4a06ebd4d919084019062000c4e565b50600260008051602062004a66833981519152826040516200018c919062000f5f565b60405180910390a2600454604080516020810190915260008152620001c5916001600160a01b0316906001906402540be400906200020f565b600454604080516020810190915260008152620001f4916001600160a01b031690600290620f4240906200020f565b50506000600b55506014600d556361f87800600f55620011c0565b6001600160a01b038416620002415760405162461bcd60e51b8152600401620002389062000fcc565b60405180910390fd5b60006200024d62000306565b90506200026c8160008787620002658860026200030a565b876200040b565b6000848152602081815260408083206001600160a01b0389168452909152812080548592906200029e9084906200100b565b92505081905550846001600160a01b031660006001600160a01b0316826001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628787604051620002f792919062000fee565b60405180910390a45050505050565b3390565b606081600114156200036e576040805160018082528183019092526000916020808301908036833701905050905083816000815181106200035b57634e487b7160e01b600052603260045260246000fd5b6020908102919091010152905062000405565b8160021415620003eb576040805160028082526060820183526000926020830190803683370190505090508381600081518110620003bc57634e487b7160e01b600052603260045260246000fd5b60200260200101818152505083816001815181106200035b57634e487b7160e01b600052603260045260246000fd5b60405162461bcd60e51b8152600401620002389062000fa8565b92915050565b620004268686868686866200080a60201b620019381760201c565b6001600160a01b0385166200043b5762000802565b6006546001600160a01b03868116911614806200046557506007546001600160a01b038681169116145b806200047e57506008546001600160a01b038681169116145b806200049757506009546001600160a01b038681169116145b80620004b05750600a546001600160a01b038681169116145b8015620004ca57506005546001600160a01b038581169116145b15620006125781516002148015620004e25750600183145b620005015760405162461bcd60e51b8152600401620002389062000f72565b60006064600d54846000815181106200052a57634e487b7160e01b600052603260045260246000fd5b60200260200101516200053e919062001071565b6200054a919062001040565b905080836000815181106200056f57634e487b7160e01b600052603260045260246000fd5b6020026020010151620005839190620010ad565b83600181518110620005a557634e487b7160e01b600052603260045260246000fd5b602090810291909101015280156200060b5780600b6000828254620005cb91906200100b565b90915550506040517f9321fdff5089c7f90f702ac90c35fbd2b03c0aca094d4efc4b1f2bf557ba2b93906200060290839062000fde565b60405180910390a15b5062000802565b600183141562000678576001600160a01b03851660009081526010602052604090205415806200065957506001600160a01b03851660009081526010602052604090205442115b620006785760405162461bcd60e51b8152600401620002389062000fba565b6004546001600160a01b03868116911614801590620006a557506005546001600160a01b03868116911614155b8015620006c057506006546001600160a01b03868116911614155b8015620006db57506007546001600160a01b03868116911614155b8015620006f657506008546001600160a01b03868116911614155b80156200071157506009546001600160a01b03868116911614155b80156200072c5750600a546001600160a01b03868116911614155b156200073d576200073d85620008f2565b6004546001600160a01b038581169116148015906200076a57506005546001600160a01b03858116911614155b80156200078557506006546001600160a01b03858116911614155b8015620007a057506007546001600160a01b03858116911614155b8015620007bb57506008546001600160a01b03858116911614155b8015620007d657506009546001600160a01b03858116911614155b8015620007f15750600a546001600160a01b03858116911614155b1562000802576200080284620008f2565b505050505050565b620008258686868686866200080260201b62001a041760201c565b6001600160a01b0385166200088857816000815181106200085657634e487b7160e01b600052603260045260246000fd5b60200260200101516002600085815260200190815260200160002060008282546200088291906200100b565b90915550505b6001600160a01b038416620008025781600081518110620008b957634e487b7160e01b600052603260045260246000fd5b6020026020010151600260008581526020019081526020016000206000828254620008e59190620010ad565b9091555050505050505050565b6001600062000903836002620009f9565b1115620009d1576000620009178362000a8c565b905080620009295760009150620009cf565b6001600160a01b03831660009081527fada5013122d395ba3c54772283fb069b10426056ef8ca54750cb9bb552a59e7d602052604081208054839290620009729084906200100b565b9250508190555080600c60008282546200098d91906200100b565b90915550506040517f1e502a6fb88dedf91c528965a2660d813c5e51072cf0bf34d1dd0e8497ce6d6090620009c6908590849062000f40565b60405180910390a15b505b8015620009f557600b546001600160a01b0383166000908152600e60205260409020555b5050565b600081600181148062000a0c5750600281145b62000a2b5760405162461bcd60e51b8152600401620002389062000f96565b600283141562000a545762000a4c848462000beb60201b62001a0c1760201c565b915062000a85565b62000a5f8462000a8c565b62000a76858562000beb60201b62001a0c1760201c565b62000a8291906200100b565b91505b5092915050565b6004546000906001600160a01b038381169116148062000ab957506005546001600160a01b038381169116145b8062000ad257506006546001600160a01b038381169116145b8062000aeb57506007546001600160a01b038381169116145b8062000b0457506008546001600160a01b038381169116145b8062000b1d57506009546001600160a01b038381169116145b8062000b365750600a546001600160a01b038381169116145b1562000b455750600062000be6565b6001600160a01b0382166000908152600e6020526040812054600b5462000b6d9190620010ad565b60045490915060009062000b8c906001600160a01b03166002620009f9565b62000b98600262000c3c565b62000ba49190620010ad565b90508062000bb85760009250505062000be6565b60008162000bc8866002620009f9565b62000bd4908562001071565b62000be0919062001040565b93505050505b919050565b60006001600160a01b03831662000c165760405162461bcd60e51b8152600401620002389062000f84565b506000908152602081815260408083206001600160a01b03949094168352929052205490565b60009081526002602052604090205490565b82805462000c5c9062001129565b90600052602060002090601f01602090048101928262000c80576000855562000ccb565b82601f1062000c9b57805160ff191683800117855562000ccb565b8280016001018555821562000ccb579182015b8281111562000ccb57825182559160200191906001019062000cae565b5062000cd992915062000cdd565b5090565b5b8082111562000cd9576000815560010162000cde565b80516200040581620011a6565b60006020828403121562000d13578081fd5b62000d218382840162000cf4565b9392505050565b62000d3381620010e1565b82525050565b600062000d468262000ffe565b62000d52818562001002565b935062000d64818560208601620010f6565b62000d6f816200119c565b9093019392505050565b600062000d88602b8362001002565b7f6172746551546f6b656e733a20696e76616c6964207472616e73666572206672918101919091526a6f6d2065786368616e676560a81b6020820152604001919050565b600062000ddb602b8362001002565b7f455243313135353a2062616c616e636520717565727920666f7220746865207a918101919091526a65726f206164647265737360a81b6020820152604001919050565b600062000e2e601f8362001002565b7f6172746551546f6b656e733a206e6f6e2d6578697374696e6720746f6b656e0091810191909152602001919050565b600062000e6d601e8362001002565b7f455243313135353a206c656e677468206d7573742062652031206f722032000091810191909152602001919050565b600062000eac60278362001002565b7f6172746551546f6b656e733a206163636f756e742063616e6e6f742073656e64918101919091526620746f6b656e7360c81b6020820152604001919050565b600062000efb60218362001002565b7f455243313135353a206d696e7420746f20746865207a65726f2061646472657391810191909152607360f81b6020820152604001919050565b62000d3381620010f3565b6040810162000f50828562000d28565b62000d21602083018462000f35565b6020808252810162000d21818462000d39565b60208082528101620004058162000d79565b60208082528101620004058162000dcc565b60208082528101620004058162000e1f565b60208082528101620004058162000e5e565b60208082528101620004058162000e9d565b60208082528101620004058162000eec565b6020810162000405828462000f35565b6040810162000f50828562000f35565b5190565b90815260200190565b60006200101882620010f3565b91506200102583620010f3565b925082198211156200103b576200103b6200115a565b500190565b60006200104d82620010f3565b91506200105a83620010f3565b9250826200106c576200106c62001170565b500490565b60006200107e82620010f3565b91506200108b83620010f3565b9250816000190483118215151615620010a857620010a86200115a565b500290565b6000620010ba82620010f3565b9150620010c783620010f3565b925082821015620010dc57620010dc6200115a565b500390565b60006001600160a01b03821662000405565b90565b60005b8381101562001113578181015183820152602001620010f9565b8381111562001123576000848401525b50505050565b6002810460018216806200113e57607f821691505b6020821081141562001154576200115462001186565b50919050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602260045260246000fd5b601f01601f191690565b620011b181620010e1565b8114620011bd57600080fd5b50565b61382c80620011d06000396000f3fe6080604052600436106102d45760003560e01c80638beb9ad611610179578063c80c3ae6116100d6578063d6a8e1461161008a578063f245feb711610064578063f245feb7146107c5578063f7866ee3146107e5578063fc25a4da146107fa576102fa565b8063d6a8e14614610765578063e985e9c514610785578063f242432a146107a5576102fa565b8063cecde709116100bb578063cecde70914610705578063d07d425d14610725578063d5306c2c14610745576102fa565b8063c80c3ae6146106c5578063c933ce57146106e5576102fa565b8063bbac03641161012d578063bd85b03911610112578063bd85b03914610670578063c14ce3ce14610690578063c7d0161a146106a5576102fa565b8063bbac03641461063b578063bc8e89ed1461065b576102fa565b8063a22cb4651161015e578063a22cb465146105e6578063b5ae043114610606578063b664ab251461061b576102fa565b80638beb9ad6146105b1578063953a586d146105d1576102fa565b80632eb2c2d6116102325780634f558e79116101e657806377a2c680116101c057806377a2c68014610567578063818679ae1461057c578063838d320a14610591576102fa565b80634f558e791461051257806358dba2e71461053257806376875dc614610552576102fa565b80633b186e5a116102175780633b186e5a146104b05780634e1273f4146104c55780634ec8d973146104f2576102fa565b80632eb2c2d61461046e5780633262ae971461048e576102fa565b80630dc7e8da116102895780630ea68d4e1161026e5780630ea68d4e1461040e5780631d1a2b641461042e5780632bbe579c1461044e576102fa565b80630dc7e8da146103c15780630e89341c146103e1576102fa565b80630820c3fd116102ba5780630820c3fd1461037557806309d44ccc146103975780630b61905f146103ac576102fa565b8062fdd58e1461031257806301ffc9a714610348576102fa565b366102fa5760405162461bcd60e51b81526004016102f19061345f565b60405180910390fd5b60405162461bcd60e51b81526004016102f19061345f565b34801561031e57600080fd5b5061033261032d3660046128d7565b61081a565b60405161033f919061351f565b60405180910390f35b34801561035457600080fd5b50610368610363366004612980565b610889565b60405161033f91906133c0565b34801561038157600080fd5b506103956103903660046129f5565b610933565b005b3480156103a357600080fd5b506103326109d2565b3480156103b857600080fd5b506103326109d7565b3480156103cd57600080fd5b506103326103dc3660046127b4565b6109dd565b3480156103ed57600080fd5b506104016103fc36600461299d565b6109f3565b60405161033f91906133ce565b34801561041a57600080fd5b506103956104293660046129d7565b610ac1565b34801561043a57600080fd5b50610395610449366004612696565b610bb0565b34801561045a57600080fd5b506103956104693660046129d7565b610c15565b34801561047a57600080fd5b50610395610489366004612709565b610c94565b34801561049a57600080fd5b506104a3610cac565b60405161033f919061333b565b3480156104bc57600080fd5b506104a3610cbb565b3480156104d157600080fd5b506104e56104e0366004612905565b610cca565b60405161033f91906133af565b3480156104fe57600080fd5b5061039561050d3660046127b4565b610dec565b34801561051e57600080fd5b5061036861052d36600461299d565b610dff565b34801561053e57600080fd5b5061039561054d3660046129d7565b610e12565b34801561055e57600080fd5b50610332610e91565b34801561057357600080fd5b50610332610e96565b34801561058857600080fd5b506104a3610e9c565b34801561059d57600080fd5b506103956105ac3660046129d7565b610eab565b3480156105bd57600080fd5b506103956105cc3660046129d7565b610f2a565b3480156105dd57600080fd5b506104a3610fa9565b3480156105f257600080fd5b506103956106013660046128a9565b610fb8565b34801561061257600080fd5b50610332610fce565b34801561062757600080fd5b5061033261063636600461264b565b610fd4565b34801561064757600080fd5b50610395610656366004612afc565b610ff8565b34801561066757600080fd5b506104a36110e7565b34801561067c57600080fd5b5061033261068b36600461299d565b6110f6565b34801561069c57600080fd5b50610332611108565b3480156106b157600080fd5b506103956106c03660046129d7565b61113b565b3480156106d157600080fd5b506103326106e03660046128d7565b6111ba565b3480156106f157600080fd5b50610395610700366004612aae565b6111c5565b34801561071157600080fd5b50610395610720366004612a16565b6112f3565b34801561073157600080fd5b506103956107403660046127f5565b611622565b34801561075157600080fd5b50610395610760366004612aae565b611644565b34801561077157600080fd5b50610395610780366004612ade565b6116f1565b34801561079157600080fd5b506103686107a0366004612613565b611755565b3480156107b157600080fd5b506103956107c0366004612854565b611783565b3480156107d157600080fd5b506103956107e0366004612ade565b6117e2565b3480156107f157600080fd5b506104a361190f565b34801561080657600080fd5b506103326108153660046129d7565b61191e565b600081600181148061082c5750600281145b6108485760405162461bcd60e51b81526004016102f1906134bf565b60028314156108625761085b8484611a0c565b9150610882565b61086b84611a5a565b6108758585611a0c565b61087f91906135c7565b91505b5092915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fd9b67a2600000000000000000000000000000000000000000000000000000000148061091c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e89341c00000000000000000000000000000000000000000000000000000000145b8061092b575061092b82611b9f565b90505b919050565b8361096861093f611be9565b6004546040805160208101909152600081526001600160a01b0390911690879087908790611bed565b6004805460405163241bffc960e11b81526001600160a01b0390911691634837ff9291610999913391869101613364565b600060405180830381600087803b1580156109b357600080fd5b505af11580156109c7573d6000803e3d6000fd5b505050505050505050565b600181565b600d5490565b60006109e9838361081a565b90505b9392505050565b6060816001811480610a055750600281145b610a215760405162461bcd60e51b81526004016102f1906134bf565b60008381526003602052604090208054610a3a9061370c565b80601f0160208091040260200160405190810160405280929190818152602001828054610a669061370c565b8015610ab35780601f10610a8857610100808354040283529160200191610ab3565b820191906000526020600020905b815481529060010190602001808311610a9657829003601f168201915b505050505091505b50919050565b816001600160a01b038216610ae85760405162461bcd60e51b81526004016102f19061349f565b6009805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384161790556040517fa93ac75a96171f52a7619531fcda8739cbee1a0c13d29d1f9da3102f1bbfcb9690610b4090849061333b565b60405180910390a16004805460405163241bffc960e11b81526001600160a01b0390911691634837ff9291610b79913391869101613364565b600060405180830381600087803b158015610b9357600080fd5b505af1158015610ba7573d6000803e3d6000fd5b50505050505050565b846001600160a01b0316846001600160a01b03161480610bd55750610bd58486611755565b610bf15760405162461bcd60e51b81526004016102f19061344f565b610c0e858585858560405180602001604052806000815250611bed565b5050505050565b816001600160a01b038216610c3c5760405162461bcd60e51b81526004016102f19061349f565b600a805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384161790556040517fb81ecfa0c1e6047897f246ac79544aa9972fad267a504f2352221d3d2c464c1b90610b4090849061333b565b60405162461bcd60e51b81526004016102f19061343f565b6008546001600160a01b031690565b600a546001600160a01b031690565b60608151835114610ced5760405162461bcd60e51b81526004016102f1906134ff565b6000835167ffffffffffffffff811115610d1757634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610d40578160200160208202803683370190505b50905060005b8451811015610de257610da7858281518110610d7257634e487b7160e01b600052603260045260246000fd5b6020026020010151858381518110610d9a57634e487b7160e01b600052603260045260246000fd5b602002602001015161081a565b828281518110610dc757634e487b7160e01b600052603260045260246000fd5b6020908102919091010152610ddb81613733565b9050610d46565b5090505b92915050565b610dfa838360008411611d77565b505050565b600080610e0b836110f6565b1192915050565b816001600160a01b038216610e395760405162461bcd60e51b81526004016102f19061349f565b6006805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384161790556040517f153eda18b041b4a03fe82bbe08eeb15a85d2dbccf428e4f230e83c899168eed390610b4090849061333b565b600281565b600b5490565b6007546001600160a01b031690565b816001600160a01b038216610ed25760405162461bcd60e51b81526004016102f19061349f565b6008805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384161790556040517f26aaf0e0cbcf298b549557a14be11462d4523e3f60c0d0713f3c46ab75adad9390610b4090849061333b565b816001600160a01b038216610f515760405162461bcd60e51b81526004016102f1906133ef565b6005805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384161790556040517f71a52d46d1a509e43eaa5846ebd6a9e21d589bf8b521eec9d922ae952134b8d590610b4090849061333b565b6006546001600160a01b031690565b610fca610fc3611be9565b8383611d77565b5050565b600c5490565b6000610fe08383611755565b15610fee57506000196109ec565b5060009392505050565b828260018114806110095750600281145b6110255760405162461bcd60e51b81526004016102f1906134bf565b60008481526003602090815260409091208451611044928601906123d7565b50837f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b8460405161107591906133ce565b60405180910390a2506004805460405163241bffc960e11b81526001600160a01b0390911691634837ff92916110af913391869101613364565b600060405180830381600087803b1580156110c957600080fd5b505af11580156110dd573d6000803e3d6000fd5b5050505050505050565b6009546001600160a01b031690565b60009081526002602052604090205490565b600454600090611122906001600160a01b0316600261081a565b61112c60026110f6565b6111369190613654565b905090565b816001600160a01b0382166111625760405162461bcd60e51b81526004016102f19061349f565b6007805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384161790556040517fc8f2ccc0dc16be390202f0cf8fc118882f61d6fa5ef964fb49776ff0ffd9505690610b4090849061333b565b60006109ec826110f6565b82826001600160a01b031663a9059cbb83856001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401611202919061333b565b60206040518083038186803b15801561121a57600080fd5b505afa15801561122e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125291906129ba565b6040518363ffffffff1660e01b815260040161126f929190613364565b602060405180830381600087803b15801561128957600080fd5b505af115801561129d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c19190612963565b506004805460405163241bffc960e11b81526001600160a01b0390911691634837ff92916110af913391869101613364565b83600f5442106113155760405162461bcd60e51b81526004016102f19061340f565b82518451146113365760405162461bcd60e51b81526004016102f1906134df565b60005b84518110156115f05760055485516001600160a01b039091169086908390811061137357634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b031614156113a25760405162461bcd60e51b81526004016102f19061347f565b60045485516001600160a01b03909116908690839081106113d357634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b031614156114025760405162461bcd60e51b81526004016102f19061348f565b61148561140d611be9565b60045487516001600160a01b039091169088908590811061143e57634e487b7160e01b600052603260045260246000fd5b6020026020010151600188868151811061146857634e487b7160e01b600052603260045260246000fd5b602002602001015160405180602001604052806000815250611bed565b60008382815181106114a757634e487b7160e01b600052603260045260246000fd5b6020026020010151111561152e578281815181106114d557634e487b7160e01b600052603260045260246000fd5b60200260200101516010600087848151811061150157634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055505b7f031f4332289fd9ed0642e73630b62171132cdbff2182dbd4bb5b87966e1f117185828151811061156f57634e487b7160e01b600052603260045260246000fd5b602002602001015185838151811061159757634e487b7160e01b600052603260045260246000fd5b60200260200101518584815181106115bf57634e487b7160e01b600052603260045260246000fd5b60200260200101516040516115d69392919061337f565b60405180910390a1806115e881613733565b915050611339565b506004805460405163241bffc960e11b81526001600160a01b0390911691634837ff9291610999913391869101613364565b6000849050610c0e858286868660405180602001604052806000815250611bed565b6040517fa22cb46500000000000000000000000000000000000000000000000000000000815283906001600160a01b0384169063a22cb4659061168e908590600190600401613349565b600060405180830381600087803b1580156116a857600080fd5b505af11580156116bc573d6000803e3d6000fd5b50506004805460405163241bffc960e11b81526001600160a01b039091169350634837ff9292506110af913391869101613364565b81600a8210158015611704575060328211155b6117205760405162461bcd60e51b81526004016102f19061341f565b600d8290556040517fb4a2fc7f11003412e991f39dbf793cae2786d3be5f271f93cafe882a1f0d3e2890610b4090849061351f565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205460ff1690565b61178b611be9565b6001600160a01b0316856001600160a01b031614806117b157506117b1856107a0611be9565b6117cd5760405162461bcd60e51b81526004016102f19061342f565b610c0e6117d8611be9565b8686868686611bed565b8160006064600d54846117f5919061361f565b6117ff91906135f5565b905080156118dd576005546001600160a01b031660009081527fada5013122d395ba3c54772283fb069b10426056ef8ca54750cb9bb552a59e7d602052604081208054839290611850908490613654565b90915550506040517fbd9779c6fb9b82c5347f169487e861f37edccf20d3c38dc1c5ac485e1ef181269061188590839061351f565b60405180910390a180600b600082825461189f91906135c7565b90915550506040517f9321fdff5089c7f90f702ac90c35fbd2b03c0aca094d4efc4b1f2bf557ba2b93906118d490839061351f565b60405180910390a15b506004805460405163241bffc960e11b81526001600160a01b0390911691634837ff9291610b79913391869101613364565b6005546001600160a01b031690565b600060208181529281526040808220909352908152205481565b611946868686868686611a04565b6001600160a01b0385166119a5578160008151811061197557634e487b7160e01b600052603260045260246000fd5b602002602001015160026000858152602001908152602001600020600082825461199f91906135c7565b90915550505b6001600160a01b038416611a0457816000815181106119d457634e487b7160e01b600052603260045260246000fd5b60200260200101516002600085815260200190815260200160002060008282546119fe9190613654565b90915550505b505050505050565b60006001600160a01b038316611a345760405162461bcd60e51b81526004016102f1906133ff565b506000908152602081815260408083206001600160a01b03949094168352929052205490565b6004546000906001600160a01b0383811691161480611a8657506005546001600160a01b038381169116145b80611a9e57506006546001600160a01b038381169116145b80611ab657506007546001600160a01b038381169116145b80611ace57506008546001600160a01b038381169116145b80611ae657506009546001600160a01b038381169116145b80611afe5750600a546001600160a01b038381169116145b15611b0b5750600061092e565b6001600160a01b0382166000908152600e6020526040812054600b54611b319190613654565b600454909150600090611b4e906001600160a01b0316600261081a565b611b5860026110f6565b611b629190613654565b905080611b745760009250505061092e565b600081611b8286600261081a565b611b8c908561361f565b611b9691906135f5565b95945050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f01ffc9a70000000000000000000000000000000000000000000000000000000014919050565b3390565b6001600160a01b038416611c135760405162461bcd60e51b81526004016102f19061346f565b6000611c20836002611e38565b9050611c30878787878587611f2b565b600081600081518110611c5357634e487b7160e01b600052603260045260246000fd5b60200260200101519050600082600181518110611c8057634e487b7160e01b600052603260045260246000fd5b602090810291909101810151600088815280835260408082206001600160a01b038d168352909352919091205490915082811015611cd05760405162461bcd60e51b81526004016102f1906134af565b6000878152602081815260408083206001600160a01b038d8116855292528083208685039055908a16825281208054849290611d0d9084906135c7565b92505081905550876001600160a01b0316896001600160a01b03168b6001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628a8a604051611d6392919061352d565b60405180910390a450505050505050505050565b816001600160a01b0316836001600160a01b03161415611da95760405162461bcd60e51b81526004016102f1906134ef565b6001600160a01b038381166000818152600160209081526040808320948716808452949091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016851515179055517f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3190611e2b9085906133c0565b60405180910390a3505050565b60608160011415611e9957604080516001808252818301909252600091602080830190803683370190505090508381600081518110611e8757634e487b7160e01b600052603260045260246000fd5b60209081029190910101529050610de6565b8160021415611f13576040805160028082526060820183526000926020830190803683370190505090508381600081518110611ee557634e487b7160e01b600052603260045260246000fd5b6020026020010181815250508381600181518110611e8757634e487b7160e01b600052603260045260246000fd5b60405162461bcd60e51b81526004016102f1906134cf565b611f39868686868686611938565b6001600160a01b038516611f4c57611a04565b6006546001600160a01b0386811691161480611f7557506007546001600160a01b038681169116145b80611f8d57506008546001600160a01b038681169116145b80611fa557506009546001600160a01b038681169116145b80611fbd5750600a546001600160a01b038681169116145b8015611fd657506005546001600160a01b038581169116145b1561210a5781516002148015611fec5750600183145b6120085760405162461bcd60e51b81526004016102f1906133df565b60006064600d548460008151811061203057634e487b7160e01b600052603260045260246000fd5b6020026020010151612042919061361f565b61204c91906135f5565b9050808360008151811061207057634e487b7160e01b600052603260045260246000fd5b60200260200101516120829190613654565b836001815181106120a357634e487b7160e01b600052603260045260246000fd5b602090810291909101015280156121045780600b60008282546120c691906135c7565b90915550506040517f9321fdff5089c7f90f702ac90c35fbd2b03c0aca094d4efc4b1f2bf557ba2b93906120fb90839061351f565b60405180910390a15b50611a04565b600183141561216b576001600160a01b038516600090815260106020526040902054158061214f57506001600160a01b03851660009081526010602052604090205442115b61216b5760405162461bcd60e51b81526004016102f19061350f565b6004546001600160a01b0386811691161480159061219757506005546001600160a01b03868116911614155b80156121b157506006546001600160a01b03868116911614155b80156121cb57506007546001600160a01b03868116911614155b80156121e557506008546001600160a01b03868116911614155b80156121ff57506009546001600160a01b03868116911614155b80156122195750600a546001600160a01b03868116911614155b1561222757612227856122df565b6004546001600160a01b0385811691161480159061225357506005546001600160a01b03858116911614155b801561226d57506006546001600160a01b03858116911614155b801561228757506007546001600160a01b03858116911614155b80156122a157506008546001600160a01b03858116911614155b80156122bb57506009546001600160a01b03858116911614155b80156122d55750600a546001600160a01b03858116911614155b15611a0457611a04845b600160006122ee83600261081a565b11156123b15760006122ff83611a5a565b90508061230f57600091506123af565b6001600160a01b03831660009081527fada5013122d395ba3c54772283fb069b10426056ef8ca54750cb9bb552a59e7d6020526040812080548392906123569084906135c7565b9250508190555080600c600082825461236f91906135c7565b90915550506040517f1e502a6fb88dedf91c528965a2660d813c5e51072cf0bf34d1dd0e8497ce6d60906123a69085908490613364565b60405180910390a15b505b8015610fca57600b546001600160a01b0383166000908152600e60205260409020555050565b8280546123e39061370c565b90600052602060002090601f016020900481019282612405576000855561244b565b82601f1061241e57805160ff191683800117855561244b565b8280016001018555821561244b579182015b8281111561244b578251825591602001919060010190612430565b5061245792915061245b565b5090565b5b80821115612457576000815560010161245c565b600061248361247e84613565565b61353b565b905080838252602082019050828560208602850111156124a257600080fd5b60005b858110156124cc576124b78783612566565b835260209283019291909101906001016124a5565b5050509392505050565b60006124e461247e84613565565b9050808382526020820190508285602086028501111561250357600080fd5b60005b858110156124cc5761251887836125fd565b83526020928301929190910190600101612506565b600061253b61247e84613589565b90508281526020810184848401111561255357600080fd5b61255e8482856136d0565b509392505050565b8035610de6816137bb565b600082601f830112612581578081fd5b813561087f848260208601612470565b600082601f8301126125a1578081fd5b813561087f8482602086016124d6565b8035610de6816137d2565b8051610de6816137d2565b8035610de6816137db565b600082601f8301126125e2578081fd5b813561087f84826020860161252d565b8035610de6816137e4565b8035610de6816137ed565b8051610de6816137ed565b60008060408385031215612625578182fd5b61263184838501612566565b9150602061264185828601612566565b9150509250929050565b60008060006060848603121561265f578081fd5b61266b85828601612566565b9250602061267b86828701612566565b925050604061268c86828701612566565b9150509250925092565b600080600080600060a086880312156126ad578081fd5b6126b987828801612566565b945060206126c988828901612566565b94505060406126da88828901612566565b93505060606126eb888289016125fd565b92505060806126fc888289016125fd565b9150509295509295909350565b600080600080600060a08688031215612720578081fd5b61272c87828801612566565b9450602061273c88828901612566565b945050604086013567ffffffffffffffff811115612758578182fd5b61276488828901612591565b935050606086013567ffffffffffffffff811115612780578182fd5b61278c88828901612591565b925050608086013567ffffffffffffffff8111156127a8578182fd5b6126fc888289016125d2565b6000806000606084860312156127c8578283fd5b6127d485848601612566565b925060206127e486828701612566565b925050604061268c868287016125fd565b6000806000806080858703121561280a578182fd5b61281686838701612566565b9350602061282687828801612566565b9350506040612837878288016125fd565b9250506060612848878288016125fd565b91505092959194509250565b600080600080600060a0868803121561286b578283fd5b61287787848801612566565b9450602061288788828901612566565b9450506040612898888289016125fd565b935050606061278c888289016125fd565b600080604083850312156128bb578182fd5b6128c784838501612566565b91506020612641858286016125b1565b600080604083850312156128e9578182fd5b6128f584838501612566565b91506020612641858286016125fd565b60008060408385031215612917578182fd5b8183013567ffffffffffffffff81111561292f578283fd5b61293b85828601612571565b925050602083013567ffffffffffffffff811115612957578182fd5b61264185828601612591565b600060208284031215612974578081fd5b6109ec838284016125bc565b600060208284031215612991578081fd5b6109ec838284016125c7565b6000602082840312156129ae578081fd5b6109ec838284016125fd565b6000602082840312156129cb578081fd5b6109ec83828401612608565b600080604083850312156129e9578182fd5b612631848385016125fd565b60008060008060808587031215612a0a578182fd5b612816868387016125fd565b60008060008060808587031215612a2b578182fd5b612a37868387016125fd565b9350602085013567ffffffffffffffff811115612a52578283fd5b612a5e87828801612571565b935050604085013567ffffffffffffffff811115612a7a578283fd5b612a8687828801612591565b925050606085013567ffffffffffffffff811115612aa2578182fd5b61284887828801612591565b600080600060608486031215612ac2578081fd5b612ace858286016125fd565b9250602061267b868287016125f2565b60008060408385031215612af0578182fd5b6128f5848385016125fd565b600080600060608486031215612b10578081fd5b612b1c858286016125fd565b92506020612b2c868287016125fd565b925050604084013567ffffffffffffffff811115612b48578182fd5b61268c868287016125d2565b6000612b608383613332565b505060200190565b612b7181613681565b82525050565b6000612b82826135ba565b612b8c81856135be565b9350612b97836135b4565b825b82811015612bc3578151612bad8782612b54565b965050612bb9826135b4565b9150600101612b99565b5093949350505050565b612b718161368c565b6000612be1826135ba565b612beb81856135be565b9350612bfb8185602086016136dc565b612c04816137b1565b9093019392505050565b6000612c1b602b836135be565b7f6172746551546f6b656e733a20696e76616c6964207472616e73666572206672918101919091527f6f6d2065786368616e67650000000000000000000000000000000000000000006020820152604001919050565b6000612c7e602e836135be565b7f6172746551546f6b656e733a207a65726f206164647265737320666f72207472918101919091527f656173757279206163636f756e740000000000000000000000000000000000006020820152604001919050565b6000612ce1602b836135be565b7f455243313135353a2062616c616e636520717565727920666f7220746865207a918101919091527f65726f20616464726573730000000000000000000000000000000000000000006020820152604001919050565b6000612d446026836135be565b7f6172746551546f6b656e733a2072616d70207570207068617365206973206669918101919091527f6e697368656400000000000000000000000000000000000000000000000000006020820152604001919050565b6000612da76030836135be565b7f6172746551546f6b656e733a20696e76616c69642076616c756520666f722070918101919091527f726f6669742070657263656e74616765000000000000000000000000000000006020820152604001919050565b6000612e0a602a836135be565b7f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f72918101919091527f20617070726f76656420000000000000000000000000000000000000000000006020820152604001919050565b6000612e6d6018836135be565b7f455243313135353a206e6f7420696d706c656d656e746564000000000000000091810191909152602001919050565b6000612eaa602e836135be565b7f6172746551546f6b656e733a2063616c6c6572206973206e6f74206f776e6572918101919091527f206e6f7220617070726f766564200000000000000000000000000000000000006020820152604001919050565b6000612f0d6020836135be565b7f6172746551546f6b656e733a2063616e6e6f742061636365707420657468657291810191909152602001919050565b6000612f4a6025836135be565b7f455243313135353a207472616e7366657220746f20746865207a65726f206164918101919091527f64726573730000000000000000000000000000000000000000000000000000006020820152604001919050565b6000612fad6030836135be565b7f6172746551546f6b656e733a2063616e6e6f74207472616e7366657220746f20918101919091527f7472656173757279206163636f756e74000000000000000000000000000000006020820152604001919050565b6000613010602e836135be565b7f6172746551546f6b656e733a2063616e6e6f74207472616e7366657220746f20918101919091527f61646d696e20636f6e74726163740000000000000000000000000000000000006020820152604001919050565b6000613073602e836135be565b7f6172746551546f6b656e733a207a65726f206164647265737320666f72206578918101919091527f6368616e6765206163636f756e740000000000000000000000000000000000006020820152604001919050565b60006130d6602a836135be565b7f455243313135353a20696e73756666696369656e742062616c616e636520666f918101919091527f72207472616e73666572000000000000000000000000000000000000000000006020820152604001919050565b6000613139601f836135be565b7f6172746551546f6b656e733a206e6f6e2d6578697374696e6720746f6b656e0091810191909152602001919050565b6000613176601e836135be565b7f455243313135353a206c656e677468206d7573742062652031206f722032000091810191909152602001919050565b60006131b3602a836135be565b7f6172746551546f6b656e733a20696e70757473206861766520696e636f727265918101919091527f6374206c656e67746873000000000000000000000000000000000000000000006020820152604001919050565b60006132166029836135be565b7f455243313135353a2073657474696e6720617070726f76616c20737461747573918101919091527f20666f722073656c6600000000000000000000000000000000000000000000006020820152604001919050565b60006132796029836135be565b7f455243313135353a206163636f756e747320616e6420696473206c656e677468918101919091527f206d69736d6174636800000000000000000000000000000000000000000000006020820152604001919050565b60006132dc6027836135be565b7f6172746551546f6b656e733a206163636f756e742063616e6e6f742073656e64918101919091527f20746f6b656e73000000000000000000000000000000000000000000000000006020820152604001919050565b612b71816136cd565b60208101610de68284612b68565b604081016133578285612b68565b6109ec6020830184612bcd565b604081016133728285612b68565b6109ec6020830184613332565b6060810161338d8286612b68565b61339a6020830185613332565b6133a76040830184613332565b949350505050565b602080825281016109ec8184612b77565b60208101610de68284612bcd565b602080825281016109ec8184612bd6565b6020808252810161092b81612c0e565b6020808252810161092b81612c71565b6020808252810161092b81612cd4565b6020808252810161092b81612d37565b6020808252810161092b81612d9a565b6020808252810161092b81612dfd565b6020808252810161092b81612e60565b6020808252810161092b81612e9d565b6020808252810161092b81612f00565b6020808252810161092b81612f3d565b6020808252810161092b81612fa0565b6020808252810161092b81613003565b6020808252810161092b81613066565b6020808252810161092b816130c9565b6020808252810161092b8161312c565b6020808252810161092b81613169565b6020808252810161092b816131a6565b6020808252810161092b81613209565b6020808252810161092b8161326c565b6020808252810161092b816132cf565b60208101610de68284613332565b604081016133728285613332565b60405181810167ffffffffffffffff8111828210171561355d5761355d61379b565b604052919050565b600067ffffffffffffffff82111561357f5761357f61379b565b5060209081020190565b600067ffffffffffffffff8211156135a3576135a361379b565b506020601f91909101601f19160190565b60200190565b5190565b90815260200190565b60006135d2826136cd565b91506135dd836136cd565b925082198211156135f0576135f0613759565b500190565b6000613600826136cd565b915061360b836136cd565b92508261361a5761361a61376f565b500490565b600061362a826136cd565b9150613635836136cd565b925081600019048311821515161561364f5761364f613759565b500290565b600061365f826136cd565b915061366a836136cd565b92508282101561367c5761367c613759565b500390565b600061092b826136c1565b151590565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b600061092b82613681565b6001600160a01b031690565b90565b82818337506000910152565b60005b838110156136f75781810151838201526020016136df565b83811115613706576000848401525b50505050565b60028104600182168061372057607f821691505b60208210811415610abb57610abb613785565b600061373e826136cd565b915060001982141561375257613752613759565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b601f01601f191690565b6137c481613681565b81146137cf57600080fd5b50565b6137c48161368c565b6137c481613691565b6137c4816136b6565b6137c4816136cd56fea2646970667358221220b636c5b9522786ec6a0cf12b179614001b4f6e3dcf8abb2e0d965945f011d34b64736f6c63430008000033697066733a2f2f516d664274483842537a7461596e3351466e7a327176753265685a677938415a734e4d4a446b6772337064715438697066733a2f2f516d5241586d553941796d446774706868333768717835523251585353326e6763685152444674673658534437776bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b000000000000000000000000554823b9ddb01304252b84dafedfb2214e7e5fd8

Deployed Bytecode

0x6080604052600436106102d45760003560e01c80638beb9ad611610179578063c80c3ae6116100d6578063d6a8e1461161008a578063f245feb711610064578063f245feb7146107c5578063f7866ee3146107e5578063fc25a4da146107fa576102fa565b8063d6a8e14614610765578063e985e9c514610785578063f242432a146107a5576102fa565b8063cecde709116100bb578063cecde70914610705578063d07d425d14610725578063d5306c2c14610745576102fa565b8063c80c3ae6146106c5578063c933ce57146106e5576102fa565b8063bbac03641161012d578063bd85b03911610112578063bd85b03914610670578063c14ce3ce14610690578063c7d0161a146106a5576102fa565b8063bbac03641461063b578063bc8e89ed1461065b576102fa565b8063a22cb4651161015e578063a22cb465146105e6578063b5ae043114610606578063b664ab251461061b576102fa565b80638beb9ad6146105b1578063953a586d146105d1576102fa565b80632eb2c2d6116102325780634f558e79116101e657806377a2c680116101c057806377a2c68014610567578063818679ae1461057c578063838d320a14610591576102fa565b80634f558e791461051257806358dba2e71461053257806376875dc614610552576102fa565b80633b186e5a116102175780633b186e5a146104b05780634e1273f4146104c55780634ec8d973146104f2576102fa565b80632eb2c2d61461046e5780633262ae971461048e576102fa565b80630dc7e8da116102895780630ea68d4e1161026e5780630ea68d4e1461040e5780631d1a2b641461042e5780632bbe579c1461044e576102fa565b80630dc7e8da146103c15780630e89341c146103e1576102fa565b80630820c3fd116102ba5780630820c3fd1461037557806309d44ccc146103975780630b61905f146103ac576102fa565b8062fdd58e1461031257806301ffc9a714610348576102fa565b366102fa5760405162461bcd60e51b81526004016102f19061345f565b60405180910390fd5b60405162461bcd60e51b81526004016102f19061345f565b34801561031e57600080fd5b5061033261032d3660046128d7565b61081a565b60405161033f919061351f565b60405180910390f35b34801561035457600080fd5b50610368610363366004612980565b610889565b60405161033f91906133c0565b34801561038157600080fd5b506103956103903660046129f5565b610933565b005b3480156103a357600080fd5b506103326109d2565b3480156103b857600080fd5b506103326109d7565b3480156103cd57600080fd5b506103326103dc3660046127b4565b6109dd565b3480156103ed57600080fd5b506104016103fc36600461299d565b6109f3565b60405161033f91906133ce565b34801561041a57600080fd5b506103956104293660046129d7565b610ac1565b34801561043a57600080fd5b50610395610449366004612696565b610bb0565b34801561045a57600080fd5b506103956104693660046129d7565b610c15565b34801561047a57600080fd5b50610395610489366004612709565b610c94565b34801561049a57600080fd5b506104a3610cac565b60405161033f919061333b565b3480156104bc57600080fd5b506104a3610cbb565b3480156104d157600080fd5b506104e56104e0366004612905565b610cca565b60405161033f91906133af565b3480156104fe57600080fd5b5061039561050d3660046127b4565b610dec565b34801561051e57600080fd5b5061036861052d36600461299d565b610dff565b34801561053e57600080fd5b5061039561054d3660046129d7565b610e12565b34801561055e57600080fd5b50610332610e91565b34801561057357600080fd5b50610332610e96565b34801561058857600080fd5b506104a3610e9c565b34801561059d57600080fd5b506103956105ac3660046129d7565b610eab565b3480156105bd57600080fd5b506103956105cc3660046129d7565b610f2a565b3480156105dd57600080fd5b506104a3610fa9565b3480156105f257600080fd5b506103956106013660046128a9565b610fb8565b34801561061257600080fd5b50610332610fce565b34801561062757600080fd5b5061033261063636600461264b565b610fd4565b34801561064757600080fd5b50610395610656366004612afc565b610ff8565b34801561066757600080fd5b506104a36110e7565b34801561067c57600080fd5b5061033261068b36600461299d565b6110f6565b34801561069c57600080fd5b50610332611108565b3480156106b157600080fd5b506103956106c03660046129d7565b61113b565b3480156106d157600080fd5b506103326106e03660046128d7565b6111ba565b3480156106f157600080fd5b50610395610700366004612aae565b6111c5565b34801561071157600080fd5b50610395610720366004612a16565b6112f3565b34801561073157600080fd5b506103956107403660046127f5565b611622565b34801561075157600080fd5b50610395610760366004612aae565b611644565b34801561077157600080fd5b50610395610780366004612ade565b6116f1565b34801561079157600080fd5b506103686107a0366004612613565b611755565b3480156107b157600080fd5b506103956107c0366004612854565b611783565b3480156107d157600080fd5b506103956107e0366004612ade565b6117e2565b3480156107f157600080fd5b506104a361190f565b34801561080657600080fd5b506103326108153660046129d7565b61191e565b600081600181148061082c5750600281145b6108485760405162461bcd60e51b81526004016102f1906134bf565b60028314156108625761085b8484611a0c565b9150610882565b61086b84611a5a565b6108758585611a0c565b61087f91906135c7565b91505b5092915050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fd9b67a2600000000000000000000000000000000000000000000000000000000148061091c57507fffffffff0000000000000000000000000000000000000000000000000000000082167f0e89341c00000000000000000000000000000000000000000000000000000000145b8061092b575061092b82611b9f565b90505b919050565b8361096861093f611be9565b6004546040805160208101909152600081526001600160a01b0390911690879087908790611bed565b6004805460405163241bffc960e11b81526001600160a01b0390911691634837ff9291610999913391869101613364565b600060405180830381600087803b1580156109b357600080fd5b505af11580156109c7573d6000803e3d6000fd5b505050505050505050565b600181565b600d5490565b60006109e9838361081a565b90505b9392505050565b6060816001811480610a055750600281145b610a215760405162461bcd60e51b81526004016102f1906134bf565b60008381526003602052604090208054610a3a9061370c565b80601f0160208091040260200160405190810160405280929190818152602001828054610a669061370c565b8015610ab35780601f10610a8857610100808354040283529160200191610ab3565b820191906000526020600020905b815481529060010190602001808311610a9657829003601f168201915b505050505091505b50919050565b816001600160a01b038216610ae85760405162461bcd60e51b81526004016102f19061349f565b6009805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384161790556040517fa93ac75a96171f52a7619531fcda8739cbee1a0c13d29d1f9da3102f1bbfcb9690610b4090849061333b565b60405180910390a16004805460405163241bffc960e11b81526001600160a01b0390911691634837ff9291610b79913391869101613364565b600060405180830381600087803b158015610b9357600080fd5b505af1158015610ba7573d6000803e3d6000fd5b50505050505050565b846001600160a01b0316846001600160a01b03161480610bd55750610bd58486611755565b610bf15760405162461bcd60e51b81526004016102f19061344f565b610c0e858585858560405180602001604052806000815250611bed565b5050505050565b816001600160a01b038216610c3c5760405162461bcd60e51b81526004016102f19061349f565b600a805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384161790556040517fb81ecfa0c1e6047897f246ac79544aa9972fad267a504f2352221d3d2c464c1b90610b4090849061333b565b60405162461bcd60e51b81526004016102f19061343f565b6008546001600160a01b031690565b600a546001600160a01b031690565b60608151835114610ced5760405162461bcd60e51b81526004016102f1906134ff565b6000835167ffffffffffffffff811115610d1757634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610d40578160200160208202803683370190505b50905060005b8451811015610de257610da7858281518110610d7257634e487b7160e01b600052603260045260246000fd5b6020026020010151858381518110610d9a57634e487b7160e01b600052603260045260246000fd5b602002602001015161081a565b828281518110610dc757634e487b7160e01b600052603260045260246000fd5b6020908102919091010152610ddb81613733565b9050610d46565b5090505b92915050565b610dfa838360008411611d77565b505050565b600080610e0b836110f6565b1192915050565b816001600160a01b038216610e395760405162461bcd60e51b81526004016102f19061349f565b6006805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384161790556040517f153eda18b041b4a03fe82bbe08eeb15a85d2dbccf428e4f230e83c899168eed390610b4090849061333b565b600281565b600b5490565b6007546001600160a01b031690565b816001600160a01b038216610ed25760405162461bcd60e51b81526004016102f19061349f565b6008805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384161790556040517f26aaf0e0cbcf298b549557a14be11462d4523e3f60c0d0713f3c46ab75adad9390610b4090849061333b565b816001600160a01b038216610f515760405162461bcd60e51b81526004016102f1906133ef565b6005805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384161790556040517f71a52d46d1a509e43eaa5846ebd6a9e21d589bf8b521eec9d922ae952134b8d590610b4090849061333b565b6006546001600160a01b031690565b610fca610fc3611be9565b8383611d77565b5050565b600c5490565b6000610fe08383611755565b15610fee57506000196109ec565b5060009392505050565b828260018114806110095750600281145b6110255760405162461bcd60e51b81526004016102f1906134bf565b60008481526003602090815260409091208451611044928601906123d7565b50837f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b8460405161107591906133ce565b60405180910390a2506004805460405163241bffc960e11b81526001600160a01b0390911691634837ff92916110af913391869101613364565b600060405180830381600087803b1580156110c957600080fd5b505af11580156110dd573d6000803e3d6000fd5b5050505050505050565b6009546001600160a01b031690565b60009081526002602052604090205490565b600454600090611122906001600160a01b0316600261081a565b61112c60026110f6565b6111369190613654565b905090565b816001600160a01b0382166111625760405162461bcd60e51b81526004016102f19061349f565b6007805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384161790556040517fc8f2ccc0dc16be390202f0cf8fc118882f61d6fa5ef964fb49776ff0ffd9505690610b4090849061333b565b60006109ec826110f6565b82826001600160a01b031663a9059cbb83856001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401611202919061333b565b60206040518083038186803b15801561121a57600080fd5b505afa15801561122e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125291906129ba565b6040518363ffffffff1660e01b815260040161126f929190613364565b602060405180830381600087803b15801561128957600080fd5b505af115801561129d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c19190612963565b506004805460405163241bffc960e11b81526001600160a01b0390911691634837ff92916110af913391869101613364565b83600f5442106113155760405162461bcd60e51b81526004016102f19061340f565b82518451146113365760405162461bcd60e51b81526004016102f1906134df565b60005b84518110156115f05760055485516001600160a01b039091169086908390811061137357634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b031614156113a25760405162461bcd60e51b81526004016102f19061347f565b60045485516001600160a01b03909116908690839081106113d357634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b031614156114025760405162461bcd60e51b81526004016102f19061348f565b61148561140d611be9565b60045487516001600160a01b039091169088908590811061143e57634e487b7160e01b600052603260045260246000fd5b6020026020010151600188868151811061146857634e487b7160e01b600052603260045260246000fd5b602002602001015160405180602001604052806000815250611bed565b60008382815181106114a757634e487b7160e01b600052603260045260246000fd5b6020026020010151111561152e578281815181106114d557634e487b7160e01b600052603260045260246000fd5b60200260200101516010600087848151811061150157634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055505b7f031f4332289fd9ed0642e73630b62171132cdbff2182dbd4bb5b87966e1f117185828151811061156f57634e487b7160e01b600052603260045260246000fd5b602002602001015185838151811061159757634e487b7160e01b600052603260045260246000fd5b60200260200101518584815181106115bf57634e487b7160e01b600052603260045260246000fd5b60200260200101516040516115d69392919061337f565b60405180910390a1806115e881613733565b915050611339565b506004805460405163241bffc960e11b81526001600160a01b0390911691634837ff9291610999913391869101613364565b6000849050610c0e858286868660405180602001604052806000815250611bed565b6040517fa22cb46500000000000000000000000000000000000000000000000000000000815283906001600160a01b0384169063a22cb4659061168e908590600190600401613349565b600060405180830381600087803b1580156116a857600080fd5b505af11580156116bc573d6000803e3d6000fd5b50506004805460405163241bffc960e11b81526001600160a01b039091169350634837ff9292506110af913391869101613364565b81600a8210158015611704575060328211155b6117205760405162461bcd60e51b81526004016102f19061341f565b600d8290556040517fb4a2fc7f11003412e991f39dbf793cae2786d3be5f271f93cafe882a1f0d3e2890610b4090849061351f565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205460ff1690565b61178b611be9565b6001600160a01b0316856001600160a01b031614806117b157506117b1856107a0611be9565b6117cd5760405162461bcd60e51b81526004016102f19061342f565b610c0e6117d8611be9565b8686868686611bed565b8160006064600d54846117f5919061361f565b6117ff91906135f5565b905080156118dd576005546001600160a01b031660009081527fada5013122d395ba3c54772283fb069b10426056ef8ca54750cb9bb552a59e7d602052604081208054839290611850908490613654565b90915550506040517fbd9779c6fb9b82c5347f169487e861f37edccf20d3c38dc1c5ac485e1ef181269061188590839061351f565b60405180910390a180600b600082825461189f91906135c7565b90915550506040517f9321fdff5089c7f90f702ac90c35fbd2b03c0aca094d4efc4b1f2bf557ba2b93906118d490839061351f565b60405180910390a15b506004805460405163241bffc960e11b81526001600160a01b0390911691634837ff9291610b79913391869101613364565b6005546001600160a01b031690565b600060208181529281526040808220909352908152205481565b611946868686868686611a04565b6001600160a01b0385166119a5578160008151811061197557634e487b7160e01b600052603260045260246000fd5b602002602001015160026000858152602001908152602001600020600082825461199f91906135c7565b90915550505b6001600160a01b038416611a0457816000815181106119d457634e487b7160e01b600052603260045260246000fd5b60200260200101516002600085815260200190815260200160002060008282546119fe9190613654565b90915550505b505050505050565b60006001600160a01b038316611a345760405162461bcd60e51b81526004016102f1906133ff565b506000908152602081815260408083206001600160a01b03949094168352929052205490565b6004546000906001600160a01b0383811691161480611a8657506005546001600160a01b038381169116145b80611a9e57506006546001600160a01b038381169116145b80611ab657506007546001600160a01b038381169116145b80611ace57506008546001600160a01b038381169116145b80611ae657506009546001600160a01b038381169116145b80611afe5750600a546001600160a01b038381169116145b15611b0b5750600061092e565b6001600160a01b0382166000908152600e6020526040812054600b54611b319190613654565b600454909150600090611b4e906001600160a01b0316600261081a565b611b5860026110f6565b611b629190613654565b905080611b745760009250505061092e565b600081611b8286600261081a565b611b8c908561361f565b611b9691906135f5565b95945050505050565b7fffffffff0000000000000000000000000000000000000000000000000000000081167f01ffc9a70000000000000000000000000000000000000000000000000000000014919050565b3390565b6001600160a01b038416611c135760405162461bcd60e51b81526004016102f19061346f565b6000611c20836002611e38565b9050611c30878787878587611f2b565b600081600081518110611c5357634e487b7160e01b600052603260045260246000fd5b60200260200101519050600082600181518110611c8057634e487b7160e01b600052603260045260246000fd5b602090810291909101810151600088815280835260408082206001600160a01b038d168352909352919091205490915082811015611cd05760405162461bcd60e51b81526004016102f1906134af565b6000878152602081815260408083206001600160a01b038d8116855292528083208685039055908a16825281208054849290611d0d9084906135c7565b92505081905550876001600160a01b0316896001600160a01b03168b6001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628a8a604051611d6392919061352d565b60405180910390a450505050505050505050565b816001600160a01b0316836001600160a01b03161415611da95760405162461bcd60e51b81526004016102f1906134ef565b6001600160a01b038381166000818152600160209081526040808320948716808452949091529081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016851515179055517f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3190611e2b9085906133c0565b60405180910390a3505050565b60608160011415611e9957604080516001808252818301909252600091602080830190803683370190505090508381600081518110611e8757634e487b7160e01b600052603260045260246000fd5b60209081029190910101529050610de6565b8160021415611f13576040805160028082526060820183526000926020830190803683370190505090508381600081518110611ee557634e487b7160e01b600052603260045260246000fd5b6020026020010181815250508381600181518110611e8757634e487b7160e01b600052603260045260246000fd5b60405162461bcd60e51b81526004016102f1906134cf565b611f39868686868686611938565b6001600160a01b038516611f4c57611a04565b6006546001600160a01b0386811691161480611f7557506007546001600160a01b038681169116145b80611f8d57506008546001600160a01b038681169116145b80611fa557506009546001600160a01b038681169116145b80611fbd5750600a546001600160a01b038681169116145b8015611fd657506005546001600160a01b038581169116145b1561210a5781516002148015611fec5750600183145b6120085760405162461bcd60e51b81526004016102f1906133df565b60006064600d548460008151811061203057634e487b7160e01b600052603260045260246000fd5b6020026020010151612042919061361f565b61204c91906135f5565b9050808360008151811061207057634e487b7160e01b600052603260045260246000fd5b60200260200101516120829190613654565b836001815181106120a357634e487b7160e01b600052603260045260246000fd5b602090810291909101015280156121045780600b60008282546120c691906135c7565b90915550506040517f9321fdff5089c7f90f702ac90c35fbd2b03c0aca094d4efc4b1f2bf557ba2b93906120fb90839061351f565b60405180910390a15b50611a04565b600183141561216b576001600160a01b038516600090815260106020526040902054158061214f57506001600160a01b03851660009081526010602052604090205442115b61216b5760405162461bcd60e51b81526004016102f19061350f565b6004546001600160a01b0386811691161480159061219757506005546001600160a01b03868116911614155b80156121b157506006546001600160a01b03868116911614155b80156121cb57506007546001600160a01b03868116911614155b80156121e557506008546001600160a01b03868116911614155b80156121ff57506009546001600160a01b03868116911614155b80156122195750600a546001600160a01b03868116911614155b1561222757612227856122df565b6004546001600160a01b0385811691161480159061225357506005546001600160a01b03858116911614155b801561226d57506006546001600160a01b03858116911614155b801561228757506007546001600160a01b03858116911614155b80156122a157506008546001600160a01b03858116911614155b80156122bb57506009546001600160a01b03858116911614155b80156122d55750600a546001600160a01b03858116911614155b15611a0457611a04845b600160006122ee83600261081a565b11156123b15760006122ff83611a5a565b90508061230f57600091506123af565b6001600160a01b03831660009081527fada5013122d395ba3c54772283fb069b10426056ef8ca54750cb9bb552a59e7d6020526040812080548392906123569084906135c7565b9250508190555080600c600082825461236f91906135c7565b90915550506040517f1e502a6fb88dedf91c528965a2660d813c5e51072cf0bf34d1dd0e8497ce6d60906123a69085908490613364565b60405180910390a15b505b8015610fca57600b546001600160a01b0383166000908152600e60205260409020555050565b8280546123e39061370c565b90600052602060002090601f016020900481019282612405576000855561244b565b82601f1061241e57805160ff191683800117855561244b565b8280016001018555821561244b579182015b8281111561244b578251825591602001919060010190612430565b5061245792915061245b565b5090565b5b80821115612457576000815560010161245c565b600061248361247e84613565565b61353b565b905080838252602082019050828560208602850111156124a257600080fd5b60005b858110156124cc576124b78783612566565b835260209283019291909101906001016124a5565b5050509392505050565b60006124e461247e84613565565b9050808382526020820190508285602086028501111561250357600080fd5b60005b858110156124cc5761251887836125fd565b83526020928301929190910190600101612506565b600061253b61247e84613589565b90508281526020810184848401111561255357600080fd5b61255e8482856136d0565b509392505050565b8035610de6816137bb565b600082601f830112612581578081fd5b813561087f848260208601612470565b600082601f8301126125a1578081fd5b813561087f8482602086016124d6565b8035610de6816137d2565b8051610de6816137d2565b8035610de6816137db565b600082601f8301126125e2578081fd5b813561087f84826020860161252d565b8035610de6816137e4565b8035610de6816137ed565b8051610de6816137ed565b60008060408385031215612625578182fd5b61263184838501612566565b9150602061264185828601612566565b9150509250929050565b60008060006060848603121561265f578081fd5b61266b85828601612566565b9250602061267b86828701612566565b925050604061268c86828701612566565b9150509250925092565b600080600080600060a086880312156126ad578081fd5b6126b987828801612566565b945060206126c988828901612566565b94505060406126da88828901612566565b93505060606126eb888289016125fd565b92505060806126fc888289016125fd565b9150509295509295909350565b600080600080600060a08688031215612720578081fd5b61272c87828801612566565b9450602061273c88828901612566565b945050604086013567ffffffffffffffff811115612758578182fd5b61276488828901612591565b935050606086013567ffffffffffffffff811115612780578182fd5b61278c88828901612591565b925050608086013567ffffffffffffffff8111156127a8578182fd5b6126fc888289016125d2565b6000806000606084860312156127c8578283fd5b6127d485848601612566565b925060206127e486828701612566565b925050604061268c868287016125fd565b6000806000806080858703121561280a578182fd5b61281686838701612566565b9350602061282687828801612566565b9350506040612837878288016125fd565b9250506060612848878288016125fd565b91505092959194509250565b600080600080600060a0868803121561286b578283fd5b61287787848801612566565b9450602061288788828901612566565b9450506040612898888289016125fd565b935050606061278c888289016125fd565b600080604083850312156128bb578182fd5b6128c784838501612566565b91506020612641858286016125b1565b600080604083850312156128e9578182fd5b6128f584838501612566565b91506020612641858286016125fd565b60008060408385031215612917578182fd5b8183013567ffffffffffffffff81111561292f578283fd5b61293b85828601612571565b925050602083013567ffffffffffffffff811115612957578182fd5b61264185828601612591565b600060208284031215612974578081fd5b6109ec838284016125bc565b600060208284031215612991578081fd5b6109ec838284016125c7565b6000602082840312156129ae578081fd5b6109ec838284016125fd565b6000602082840312156129cb578081fd5b6109ec83828401612608565b600080604083850312156129e9578182fd5b612631848385016125fd565b60008060008060808587031215612a0a578182fd5b612816868387016125fd565b60008060008060808587031215612a2b578182fd5b612a37868387016125fd565b9350602085013567ffffffffffffffff811115612a52578283fd5b612a5e87828801612571565b935050604085013567ffffffffffffffff811115612a7a578283fd5b612a8687828801612591565b925050606085013567ffffffffffffffff811115612aa2578182fd5b61284887828801612591565b600080600060608486031215612ac2578081fd5b612ace858286016125fd565b9250602061267b868287016125f2565b60008060408385031215612af0578182fd5b6128f5848385016125fd565b600080600060608486031215612b10578081fd5b612b1c858286016125fd565b92506020612b2c868287016125fd565b925050604084013567ffffffffffffffff811115612b48578182fd5b61268c868287016125d2565b6000612b608383613332565b505060200190565b612b7181613681565b82525050565b6000612b82826135ba565b612b8c81856135be565b9350612b97836135b4565b825b82811015612bc3578151612bad8782612b54565b965050612bb9826135b4565b9150600101612b99565b5093949350505050565b612b718161368c565b6000612be1826135ba565b612beb81856135be565b9350612bfb8185602086016136dc565b612c04816137b1565b9093019392505050565b6000612c1b602b836135be565b7f6172746551546f6b656e733a20696e76616c6964207472616e73666572206672918101919091527f6f6d2065786368616e67650000000000000000000000000000000000000000006020820152604001919050565b6000612c7e602e836135be565b7f6172746551546f6b656e733a207a65726f206164647265737320666f72207472918101919091527f656173757279206163636f756e740000000000000000000000000000000000006020820152604001919050565b6000612ce1602b836135be565b7f455243313135353a2062616c616e636520717565727920666f7220746865207a918101919091527f65726f20616464726573730000000000000000000000000000000000000000006020820152604001919050565b6000612d446026836135be565b7f6172746551546f6b656e733a2072616d70207570207068617365206973206669918101919091527f6e697368656400000000000000000000000000000000000000000000000000006020820152604001919050565b6000612da76030836135be565b7f6172746551546f6b656e733a20696e76616c69642076616c756520666f722070918101919091527f726f6669742070657263656e74616765000000000000000000000000000000006020820152604001919050565b6000612e0a602a836135be565b7f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f72918101919091527f20617070726f76656420000000000000000000000000000000000000000000006020820152604001919050565b6000612e6d6018836135be565b7f455243313135353a206e6f7420696d706c656d656e746564000000000000000091810191909152602001919050565b6000612eaa602e836135be565b7f6172746551546f6b656e733a2063616c6c6572206973206e6f74206f776e6572918101919091527f206e6f7220617070726f766564200000000000000000000000000000000000006020820152604001919050565b6000612f0d6020836135be565b7f6172746551546f6b656e733a2063616e6e6f742061636365707420657468657291810191909152602001919050565b6000612f4a6025836135be565b7f455243313135353a207472616e7366657220746f20746865207a65726f206164918101919091527f64726573730000000000000000000000000000000000000000000000000000006020820152604001919050565b6000612fad6030836135be565b7f6172746551546f6b656e733a2063616e6e6f74207472616e7366657220746f20918101919091527f7472656173757279206163636f756e74000000000000000000000000000000006020820152604001919050565b6000613010602e836135be565b7f6172746551546f6b656e733a2063616e6e6f74207472616e7366657220746f20918101919091527f61646d696e20636f6e74726163740000000000000000000000000000000000006020820152604001919050565b6000613073602e836135be565b7f6172746551546f6b656e733a207a65726f206164647265737320666f72206578918101919091527f6368616e6765206163636f756e740000000000000000000000000000000000006020820152604001919050565b60006130d6602a836135be565b7f455243313135353a20696e73756666696369656e742062616c616e636520666f918101919091527f72207472616e73666572000000000000000000000000000000000000000000006020820152604001919050565b6000613139601f836135be565b7f6172746551546f6b656e733a206e6f6e2d6578697374696e6720746f6b656e0091810191909152602001919050565b6000613176601e836135be565b7f455243313135353a206c656e677468206d7573742062652031206f722032000091810191909152602001919050565b60006131b3602a836135be565b7f6172746551546f6b656e733a20696e70757473206861766520696e636f727265918101919091527f6374206c656e67746873000000000000000000000000000000000000000000006020820152604001919050565b60006132166029836135be565b7f455243313135353a2073657474696e6720617070726f76616c20737461747573918101919091527f20666f722073656c6600000000000000000000000000000000000000000000006020820152604001919050565b60006132796029836135be565b7f455243313135353a206163636f756e747320616e6420696473206c656e677468918101919091527f206d69736d6174636800000000000000000000000000000000000000000000006020820152604001919050565b60006132dc6027836135be565b7f6172746551546f6b656e733a206163636f756e742063616e6e6f742073656e64918101919091527f20746f6b656e73000000000000000000000000000000000000000000000000006020820152604001919050565b612b71816136cd565b60208101610de68284612b68565b604081016133578285612b68565b6109ec6020830184612bcd565b604081016133728285612b68565b6109ec6020830184613332565b6060810161338d8286612b68565b61339a6020830185613332565b6133a76040830184613332565b949350505050565b602080825281016109ec8184612b77565b60208101610de68284612bcd565b602080825281016109ec8184612bd6565b6020808252810161092b81612c0e565b6020808252810161092b81612c71565b6020808252810161092b81612cd4565b6020808252810161092b81612d37565b6020808252810161092b81612d9a565b6020808252810161092b81612dfd565b6020808252810161092b81612e60565b6020808252810161092b81612e9d565b6020808252810161092b81612f00565b6020808252810161092b81612f3d565b6020808252810161092b81612fa0565b6020808252810161092b81613003565b6020808252810161092b81613066565b6020808252810161092b816130c9565b6020808252810161092b8161312c565b6020808252810161092b81613169565b6020808252810161092b816131a6565b6020808252810161092b81613209565b6020808252810161092b8161326c565b6020808252810161092b816132cf565b60208101610de68284613332565b604081016133728285613332565b60405181810167ffffffffffffffff8111828210171561355d5761355d61379b565b604052919050565b600067ffffffffffffffff82111561357f5761357f61379b565b5060209081020190565b600067ffffffffffffffff8211156135a3576135a361379b565b506020601f91909101601f19160190565b60200190565b5190565b90815260200190565b60006135d2826136cd565b91506135dd836136cd565b925082198211156135f0576135f0613759565b500190565b6000613600826136cd565b915061360b836136cd565b92508261361a5761361a61376f565b500490565b600061362a826136cd565b9150613635836136cd565b925081600019048311821515161561364f5761364f613759565b500290565b600061365f826136cd565b915061366a836136cd565b92508282101561367c5761367c613759565b500390565b600061092b826136c1565b151590565b7fffffffff000000000000000000000000000000000000000000000000000000001690565b600061092b82613681565b6001600160a01b031690565b90565b82818337506000910152565b60005b838110156136f75781810151838201526020016136df565b83811115613706576000848401525b50505050565b60028104600182168061372057607f821691505b60208210811415610abb57610abb613785565b600061373e826136cd565b915060001982141561375257613752613759565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b601f01601f191690565b6137c481613681565b81146137cf57600080fd5b50565b6137c48161368c565b6137c481613691565b6137c4816136b6565b6137c4816136cd56fea2646970667358221220b636c5b9522786ec6a0cf12b179614001b4f6e3dcf8abb2e0d965945f011d34b64736f6c63430008000033

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

000000000000000000000000554823b9ddb01304252b84dafedfb2214e7e5fd8

-----Decoded View---------------
Arg [0] : adminContract (address): 0x554823B9dDB01304252b84DAfedFB2214e7E5FD8

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000554823b9ddb01304252b84dafedfb2214e7e5fd8


Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.