ETH Price: $2,614.73 (-3.02%)

Token

Redeemable Keep3r (rKP3R)
 

Overview

Max Total Supply

21,830.863621431100886554 rKP3R

Holders

596

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Filtered by Token Holder
chingtseng.eth
Balance
0.256279352720818485 rKP3R

Value
$0.00
0xC5883A16258Af48d77EF432472538F593842fCCb
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:
RedeemableKeep3r

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU LGPLv3 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-09-12
*/

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;

interface IERC165 {
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}


interface IERC721 is IERC165 {
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
    function balanceOf(address owner) external view returns (uint256 balance);
    function ownerOf(uint256 tokenId) external view returns (address owner);
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;
    function approve(address to, uint256 tokenId) external;
    function getApproved(uint256 tokenId) external view returns (address operator);
    function setApprovalForAll(address operator, bool _approved) external;
    function isApprovedForAll(address owner, address operator) external view returns (bool);
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;
}

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

interface IERC721Receiver {
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

abstract contract ERC165 is IERC165 {
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

interface IERC721Metadata is IERC721 {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

contract ERC721 is ERC165, IERC721 {
    using Strings for uint256;

    mapping(uint256 => address) private _owners;
    mapping(address => uint256) private _balances;
    mapping(uint256 => address) private _tokenApprovals;
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _balances[owner];
    }

    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            msg.sender == owner || isApprovedForAll(owner, msg.sender),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != msg.sender, "ERC721: approve to caller");

        _operatorApprovals[msg.sender][operator] = approved;
        emit ApprovalForAll(msg.sender, operator, approved);
    }

    function _isContract(address account) internal view returns (bool) {
        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }

    /**
     * @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.
     *
     * `_data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory _data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits a {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        if (_isContract(to)) {
            try IERC721Receiver(to).onERC721Received(msg.sender, from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver(to).onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}







/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}


/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _allTokens.length;
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, tokenId);

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}

library FullMath {
    function mulDiv(
        uint256 a,
        uint256 b,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        uint256 prod0; // Least significant 256 bits of the product
        uint256 prod1; // Most significant 256 bits of the product
        assembly {
            let mm := mulmod(a, b, not(0))
            prod0 := mul(a, b)
            prod1 := sub(sub(mm, prod0), lt(mm, prod0))
        }

        if (prod1 == 0) {
            require(denominator > 0);
            assembly {
                result := div(prod0, denominator)
            }
            return result;
        }

        require(denominator > prod1);

        uint256 remainder;
        assembly {
            remainder := mulmod(a, b, denominator)
        }
        assembly {
            prod1 := sub(prod1, gt(remainder, prod0))
            prod0 := sub(prod0, remainder)
        }
        int256 _denominator = int256(denominator);
        uint256 twos = uint256(-_denominator & _denominator);
        assembly {
            denominator := div(denominator, twos)
        }

        assembly {
            prod0 := div(prod0, twos)
        }

        assembly {
            twos := add(div(sub(0, twos), twos), 1)
        }
        prod0 |= prod1 * twos;

        uint256 inv = (3 * denominator) ^ 2;

        inv *= 2 - denominator * inv; // inverse mod 2**8
        inv *= 2 - denominator * inv; // inverse mod 2**16
        inv *= 2 - denominator * inv; // inverse mod 2**32
        inv *= 2 - denominator * inv; // inverse mod 2**64
        inv *= 2 - denominator * inv; // inverse mod 2**128
        inv *= 2 - denominator * inv; // inverse mod 2**256

        result = prod0 * inv;
        return result;
    }
}

library TickMath {
    int24 internal constant MIN_TICK = -887272;
    int24 internal constant MAX_TICK = -MIN_TICK;

    function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) {
        uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick));
        require(absTick <= uint256(int256(MAX_TICK)), 'T');

        uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000;
        if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;
        if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;
        if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;
        if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;
        if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;
        if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;
        if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;
        if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;
        if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;
        if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;
        if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;
        if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;
        if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;
        if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;
        if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;
        if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;
        if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;
        if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;
        if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;

        if (tick > 0) ratio = type(uint256).max / ratio;

        sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1));
    }
}

interface IUniswapV3Pool {
        function observe(uint32[] calldata secondsAgos)
        external
        view
        returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);
}

/// @title Oracle library
/// @notice Provides functions to integrate with V3 pool oracle
library OracleLibrary {
    /// @notice Fetches time-weighted average tick using Uniswap V3 oracle
    /// @param pool Address of Uniswap V3 pool that we want to observe
    /// @param period Number of seconds in the past to start calculating time-weighted average
    /// @return timeWeightedAverageTick The time-weighted average tick from (block.timestamp - period) to block.timestamp
    function consult(address pool, uint32 period) internal view returns (int24 timeWeightedAverageTick) {
        require(period != 0, 'BP');

        uint32[] memory secondAgos = new uint32[](2);
        secondAgos[0] = period;
        secondAgos[1] = 0;

        (int56[] memory tickCumulatives, ) = IUniswapV3Pool(pool).observe(secondAgos);
        int56 tickCumulativesDelta = tickCumulatives[1] - tickCumulatives[0];

        timeWeightedAverageTick = int24(tickCumulativesDelta / int(uint(period)));

        // Always round to negative infinity
        if (tickCumulativesDelta < 0 && (tickCumulativesDelta % int(uint(period)) != 0)) timeWeightedAverageTick--;
    }

    /// @notice Given a tick and a token amount, calculates the amount of token received in exchange
    /// @param tick Tick value used to calculate the quote
    /// @param baseAmount Amount of token to be converted
    /// @param baseToken Address of an ERC20 token contract used as the baseAmount denomination
    /// @param quoteToken Address of an ERC20 token contract used as the quoteAmount denomination
    /// @return quoteAmount Amount of quoteToken received for baseAmount of baseToken
    function getQuoteAtTick(
        int24 tick,
        uint128 baseAmount,
        address baseToken,
        address quoteToken
    ) internal pure returns (uint256 quoteAmount) {
        uint160 sqrtRatioX96 = TickMath.getSqrtRatioAtTick(tick);

        // Calculate quoteAmount with better precision if it doesn't overflow when multiplied by itself
        if (sqrtRatioX96 <= type(uint128).max) {
            uint256 ratioX192 = uint256(sqrtRatioX96) * sqrtRatioX96;
            quoteAmount = baseToken < quoteToken
                ? FullMath.mulDiv(ratioX192, baseAmount, 1 << 192)
                : FullMath.mulDiv(1 << 192, baseAmount, ratioX192);
        } else {
            uint256 ratioX128 = FullMath.mulDiv(sqrtRatioX96, sqrtRatioX96, 1 << 64);
            quoteAmount = baseToken < quoteToken
                ? FullMath.mulDiv(ratioX128, baseAmount, 1 << 128)
                : FullMath.mulDiv(1 << 128, baseAmount, ratioX128);
        }
    }
}

library PoolAddress {
    bytes32 internal constant POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;

    struct PoolKey {
        address token0;
        address token1;
        uint24 fee;
    }function getPoolKey(
        address tokenA,
        address tokenB,
        uint24 fee
    ) internal pure returns (PoolKey memory) {
        if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA);
        return PoolKey({token0: tokenA, token1: tokenB, fee: fee});
    }

    function computeAddress(address factory, PoolKey memory key) internal pure returns (address pool) {
        require(key.token0 < key.token1);
        pool = address(
            uint160(uint256(
                keccak256(
                    abi.encodePacked(
                        hex'ff',
                        factory,
                        keccak256(abi.encode(key.token0, key.token1, key.fee)),
                        POOL_INIT_CODE_HASH
                    )
                )
            )
        ));
    }
}

library SafeUint128 {
    function toUint128(uint256 y) internal pure returns (uint128 z) {
        require((z = uint128(y)) == y);
    }
}

interface erc20 {
    function transfer(address recipient, uint amount) external returns (bool);
    function balanceOf(address) external view returns (uint);
    function transferFrom(address sender, address recipient, uint amount) external returns (bool);
}

contract Keep3rOptions is ERC721Enumerable {
    string public constant name = "Keep3r Options";
    string public constant symbol = "oKP3R";
    address immutable rKP3R;

    constructor() {
        rKP3R = msg.sender;
    }

    function mint(address _user, uint _id) external returns (bool) {
        require(msg.sender == rKP3R);
        _safeMint(_user, _id);
        return true;
    }

    function burn(uint _id) external returns (bool) {
        require(msg.sender == rKP3R);
        _burn(_id);
        return true;
    }

    function isApprovedOrOwner(address _addr, uint _id) external view returns (bool) {
        return _isApprovedOrOwner(_addr, _id);
    }
}

contract RedeemableKeep3r {
    string public constant name = "Redeemable Keep3r";
    string public constant symbol = "rKP3R";
    uint8 public constant decimals = 18;

    address public gov;
    address public nextGov;
    uint public delayGov;

    uint public discount = 50;
    uint public nextDiscount;
    uint public delayDiscount;

    address public treasury;
    address public nextTreasury;
    uint public delayTreasury;

    struct option {
        uint amount;
        uint strike;
        uint expiry;
        bool exercised;
    }

    option[] public options;
    uint public nextIndex;

    address constant KP3R = address(0x1cEB5cB57C4D4E2b2433641b95Dd330A33185A44);
    address constant USDC = address(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48);
    address constant UNIv3 = 0x1F98431c8aD98523631AE4a59f267346ea31F984;
    address constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;

    uint32 constant TWAP_PERIOD = 86400;
    uint32 constant TWAP_NOW = 60;
    uint32 constant OPTION_EXPIRY = 1 days;
    uint32 constant DELAY = 1 days;
    uint32 constant BASE = 100;
    Keep3rOptions immutable public oKP3R;

    event Created(address indexed owner, uint amount, uint strike, uint expiry, uint id);
    event Redeem(address indexed from, address indexed owner, uint amount, uint strike, uint id);
    event Refund(address indexed from, address indexed owner, uint amount, uint strike, uint id);

    constructor(address _treasury) {
        gov = msg.sender;
        treasury = _treasury;
        oKP3R = new Keep3rOptions();
    }

    modifier g() {
        require(msg.sender == gov);
        _;
    }

    function setGov(address _gov) external g {
        nextGov = _gov;
        delayGov = block.timestamp + DELAY;
    }

    function acceptGov() external {
        require(msg.sender == nextGov && delayGov < block.timestamp);
        gov = nextGov;
    }

    function setDiscount(uint _discount) external g {
        nextDiscount = _discount;
        delayDiscount = block.timestamp + DELAY;
    }

    function commitDiscount() external g {
        require(delayDiscount < block.timestamp);
        discount = nextDiscount;
    }

    function setTreasury(address _treasury) external g {
        nextTreasury = _treasury;
        delayTreasury = block.timestamp + DELAY;
    }

    function commitTreasury() external g {
        require(delayTreasury < block.timestamp);
        treasury = nextTreasury;
    }

    /// @notice Total number of tokens in circulation
    uint public totalSupply = 0;

    mapping(address => mapping (address => uint)) public allowance;
    mapping(address => uint) public balanceOf;

    event Transfer(address indexed from, address indexed to, uint amount);
    event Approval(address indexed owner, address indexed spender, uint amount);

    function refund(uint[] memory _ids) external {
        for (uint i = 0; i < _ids.length; i++) {
            option storage _opt = options[_ids[i]];
            if (_opt.expiry < block.timestamp && !_opt.exercised) {
                _opt.exercised = true;
                _safeTransfer(KP3R, treasury, _opt.amount);
                address _owner = oKP3R.ownerOf(_ids[i]);
                oKP3R.burn(_ids[i]);
                emit Refund(msg.sender, _owner, _opt.amount, _opt.strike, _ids[i]);
            }
        }
    }

    function _fetchTwap(
        address _tokenIn,
        address _tokenOut,
        uint24 _poolFee,
        uint32 _twapPeriod,
        uint _amountIn
    ) internal view returns (uint256 amountOut) {
        address pool =
            PoolAddress.computeAddress(UNIv3, PoolAddress.getPoolKey(_tokenIn, _tokenOut, _poolFee));
        // Leave twapTick as a int256 to avoid solidity casting
        int256 twapTick = OracleLibrary.consult(pool, _twapPeriod);
        return
            OracleLibrary.getQuoteAtTick(
                int24(twapTick), // can assume safe being result from consult()
                SafeUint128.toUint128(_amountIn),
                _tokenIn,
                _tokenOut
            );
    }

    function assetToAsset(
        address _tokenIn,
        uint _amountIn,
        address _tokenOut,
        uint32 _twapPeriod
    ) public view returns (uint ethAmountOut) {
        uint256 ethAmount = assetToEth(_tokenIn, _amountIn, _twapPeriod);
        return ethToAsset(ethAmount, _tokenOut, _twapPeriod);
    }

    function assetToEth(
        address _tokenIn,
        uint _amountIn,
        uint32 _twapPeriod
    ) public view returns (uint ethAmountOut) {
        return _fetchTwap(_tokenIn, WETH, 10000, _twapPeriod, _amountIn);
    }

    function ethToAsset(
        uint _ethAmountIn,
        address _tokenOut,
        uint32 _twapPeriod
    ) public view returns (uint256 amountOut) {
        return _fetchTwap(WETH, _tokenOut, 3000, _twapPeriod, _ethAmountIn);
    }

    function price() external view returns (uint) {
        return assetToAsset(KP3R, 1e18, USDC, TWAP_PERIOD);
    }

    function twap() external view returns (uint) {
        return assetToAsset(KP3R, 1e18, USDC, TWAP_NOW);
    }

    function calc(uint amount) public view returns (uint) {
        uint _strike = assetToAsset(KP3R, amount, USDC, TWAP_PERIOD);
        uint _price = assetToAsset(KP3R, amount, USDC, TWAP_NOW);
        _strike = _strike * discount / BASE;
        _price = _price * discount / BASE;
        return _strike > _price ? _strike : _price;
    }

    function deposit(uint _amount) external returns (bool) {
        _safeTransferFrom(KP3R, msg.sender, address(this), _amount);
        _mint(msg.sender, _amount);
        return true;
    }

    function claim() external returns (uint) {
        uint _amount = balanceOf[msg.sender];
        _burn(msg.sender, _amount);
        return _claim(_amount);
    }

    function claim(uint amount) external returns (uint) {
        _burn(msg.sender, amount);
        return _claim(amount);
    }

    function _claim(uint amount) internal returns (uint) {
        uint _strike = calc(amount);
        uint _expiry = block.timestamp + OPTION_EXPIRY;
        options.push(option(amount, _strike, _expiry, false));
        oKP3R.mint(msg.sender, nextIndex);
        emit Created(msg.sender, amount, _strike, _expiry, nextIndex);
        return nextIndex++;
    }

    function redeem(uint id) external {
        require(oKP3R.isApprovedOrOwner(msg.sender, id));
        option storage _opt = options[id];
        require(_opt.expiry >= block.timestamp && !_opt.exercised);
        _opt.exercised = true;
        _safeTransferFrom(USDC, msg.sender, treasury, _opt.strike);
        _safeTransfer(KP3R, msg.sender, _opt.amount);
        oKP3R.burn(id);
        emit Redeem(msg.sender, msg.sender, _opt.amount, _opt.strike, id);
    }

    function _mint(address to, uint amount) internal {
        // mint the amount
        totalSupply += amount;
        // transfer the amount to the recipient
        balanceOf[to] += amount;
        emit Transfer(address(0), to, amount);
    }

    function _burn(address from, uint amount) internal {
        // burn the amount
        totalSupply -= amount;
        // transfer the amount from the recipient
        balanceOf[from] -= amount;
        emit Transfer(from, address(0), amount);
    }

    function approve(address spender, uint amount) external returns (bool) {
        allowance[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);
        return true;
    }

    function transfer(address dst, uint amount) external returns (bool) {
        _transferTokens(msg.sender, dst, amount);
        return true;
    }

    function transferFrom(address src, address dst, uint amount) external returns (bool) {
        address spender = msg.sender;
        uint spenderAllowance = allowance[src][spender];

        if (spender != src && spenderAllowance != type(uint).max) {
            uint newAllowance = spenderAllowance - amount;
            allowance[src][spender] = newAllowance;

            emit Approval(src, spender, newAllowance);
        }

        _transferTokens(src, dst, amount);
        return true;
    }

    function _transferTokens(address src, address dst, uint amount) internal {
        balanceOf[src] -= amount;
        balanceOf[dst] += amount;

        emit Transfer(src, dst, amount);
    }

    function _safeTransfer(address token, address to, uint256 value) internal {
        (bool success, bytes memory data) =
            token.call(abi.encodeWithSelector(erc20.transfer.selector, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))));
    }

    function _safeTransferFrom(address token, address from, address to, uint256 value) internal {
        (bool success, bytes memory data) =
            token.call(abi.encodeWithSelector(erc20.transferFrom.selector, from, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))));
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_treasury","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"strike","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"expiry","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Created","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"strike","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Redeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"strike","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Refund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"acceptGov","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenIn","type":"address"},{"internalType":"uint256","name":"_amountIn","type":"uint256"},{"internalType":"address","name":"_tokenOut","type":"address"},{"internalType":"uint32","name":"_twapPeriod","type":"uint32"}],"name":"assetToAsset","outputs":[{"internalType":"uint256","name":"ethAmountOut","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenIn","type":"address"},{"internalType":"uint256","name":"_amountIn","type":"uint256"},{"internalType":"uint32","name":"_twapPeriod","type":"uint32"}],"name":"assetToEth","outputs":[{"internalType":"uint256","name":"ethAmountOut","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"calc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"claim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"commitDiscount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"commitTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"delayDiscount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"delayGov","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"delayTreasury","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"discount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_ethAmountIn","type":"uint256"},{"internalType":"address","name":"_tokenOut","type":"address"},{"internalType":"uint32","name":"_twapPeriod","type":"uint32"}],"name":"ethToAsset","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gov","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextDiscount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextGov","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextTreasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oKP3R","outputs":[{"internalType":"contract Keep3rOptions","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"options","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"strike","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"bool","name":"exercised","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"}],"name":"refund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_discount","type":"uint256"}],"name":"setDiscount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gov","type":"address"}],"name":"setGov","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"src","type":"address"},{"internalType":"address","name":"dst","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"twap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

60a060405260326003556000600b553480156200001b57600080fd5b5060405162003df638038062003df68339810160408190526200003e91620000b8565b60008054336001600160a01b031991821617909155600680549091166001600160a01b0383161790556040516200007590620000aa565b604051809103906000f08015801562000092573d6000803e3d6000fd5b5060601b6001600160601b03191660805250620000ea565b611663806200279383390190565b600060208284031215620000cb57600080fd5b81516001600160a01b0381168114620000e357600080fd5b9392505050565b60805160601c6126676200012c6000396000818161032601528181610a2a01528181610ae301528181610d1e01528181610e6d01526111d801526126676000f3fe608060405234801561001057600080fd5b50600436106102325760003560e01c80636953bd8011610130578063b4bdf8b0116100b8578063dd62ed3e1161007c578063dd62ed3e146104fc578063e8594b3114610527578063ed7b686e1461053a578063f0f4426014610543578063fc7e9c6f1461055657600080fd5b8063b4bdf8b01461049d578063b6b55f25146104b0578063cfad57a2146104c3578063dabd2719146104d6578063db006a75146104e957600080fd5b80637f5bdf6a116100ff5780637f5bdf6a1461044257806395d89b411461044b578063a035b1fe1461046f578063a9059cbb14610477578063aa613df51461048a57600080fd5b80636953bd80146104085780636b6f4a9d1461041157806370a082311461041a5780637bc6729b1461043a57600080fd5b8063377f3300116101be5780634e71d92d116101825780634e71d92d146103be578063553999d9146103c657806358fac003146103cf5780635b36add4146103e257806361d027b3146103f557600080fd5b8063377f330014610348578063379607f51461035b57806338c9027a1461036e578063409e22051461038157806341d86d00146103b657600080fd5b806318160ddd1161020557806318160ddd146102e15780632114d61f146102ea57806323b872dd146102f4578063313ce56714610307578063350d19ad1461032157600080fd5b806306fdde0314610237578063095ea7b31461027d5780631208aa18146102a057806312d43a51146102b6575b600080fd5b610267604051806040016040528060118152602001702932b232b2b6b0b136329025b2b2b819b960791b81525081565b6040516102749190612382565b60405180910390f35b61029061028b366004612087565b61055f565b6040519015158152602001610274565b6102a86105cb565b604051908152602001610274565b6000546102c9906001600160a01b031681565b6040516001600160a01b039091168152602001610274565b6102a8600b5481565b6102f261060f565b005b610290610302366004612046565b61063c565b61030f601281565b60405160ff9091168152602001610274565b6102c97f000000000000000000000000000000000000000000000000000000000000000081565b6007546102c9906001600160a01b031681565b6102a86103693660046122ce565b610705565b6102a861037c3660046122ce565b610720565b61039461038f3660046122ce565b6107e6565b6040805194855260208501939093529183015215156060820152608001610274565b6102f2610823565b6102a861086c565b6102a860025481565b6102a86103dd3660046120b3565b610897565b6102a86103f0366004612104565b6108bc565b6006546102c9906001600160a01b031681565b6102a860045481565b6102a860035481565b6102a8610428366004611fd3565b600d6020526000908152604090205481565b6102f26108e1565b6102a860055481565b610267604051806040016040528060058152602001643925a819a960d91b81525081565b6102a8610929565b610290610485366004612087565b61096a565b6102f2610498366004612214565b610980565b6102a86104ab3660046122e7565b610c35565b6102906104be3660046122ce565b610c5a565b6102f26104d1366004611fd3565b610c8e565b6102f26104e43660046122ce565b610cd3565b6102f26104f73660046122ce565b610d02565b6102a861050a36600461200d565b600c60209081526000928352604080842090915290825290205481565b6001546102c9906001600160a01b031681565b6102a860085481565b6102f2610551366004611fd3565b610f43565b6102a8600a5481565b336000818152600c602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906105ba9086815260200190565b60405180910390a350600192915050565b600061060a731ceb5cb57c4d4e2b2433641b95dd330a33185a44670de0b6b3a764000073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48603c610897565b905090565b6000546001600160a01b0316331461062657600080fd5b426005541061063457600080fd5b600454600355565b6001600160a01b0383166000818152600c602090815260408083203380855292528220549192909190821480159061067657506000198114155b156106ec57600061068785836124d3565b6001600160a01b038881166000818152600c60209081526040808320948916808452948252918290208590559051848152939450919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505b6106f7868686610f88565b6001925050505b9392505050565b60006107113383611036565b61071a826110b8565b92915050565b60008061075a731ceb5cb57c4d4e2b2433641b95dd330a33185a448473a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4862015180610897565b90506000610793731ceb5cb57c4d4e2b2433641b95dd330a33185a448573a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48603c610897565b6003549091506064906107a69084612464565b6107b09190612450565b6003549092506064906107c39083612464565b6107cd9190612450565b90508082116107dc57806107de565b815b949350505050565b600981815481106107f657600080fd5b60009182526020909120600490910201805460018201546002830154600390930154919350919060ff1684565b6000546001600160a01b0316331461083a57600080fd5b426008541061084857600080fd5b600754600680546001600160a01b0319166001600160a01b03909216919091179055565b336000818152600d602052604081205490916108889082611036565b610891816110b8565b91505090565b6000806108a58686856108bc565b90506108b2818585610c35565b9695505050505050565b60006107de8473c02aaa39b223fe8d0a0e5c4f27ead9083c756cc261271085876112c7565b6001546001600160a01b0316331480156108fc575042600254105b61090557600080fd5b600154600080546001600160a01b0319166001600160a01b03909216919091179055565b600061060a731ceb5cb57c4d4e2b2433641b95dd330a33185a44670de0b6b3a764000073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4862015180610897565b6000610977338484610f88565b50600192915050565b60005b8151811015610c3157600060098383815181106109a2576109a26125ed565b6020026020010151815481106109ba576109ba6125ed565b906000526020600020906004020190504281600201541080156109e25750600381015460ff16155b15610c1e5760038101805460ff191660011790556006548154610a2691731ceb5cb57c4d4e2b2433641b95dd330a33185a44916001600160a01b0390911690611325565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636352211e858581518110610a6957610a696125ed565b60200260200101516040518263ffffffff1660e01b8152600401610a8f91815260200190565b60206040518083038186803b158015610aa757600080fd5b505afa158015610abb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610adf9190611ff0565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166342966c68858581518110610b2257610b226125ed565b60200260200101516040518263ffffffff1660e01b8152600401610b4891815260200190565b602060405180830381600087803b158015610b6257600080fd5b505af1158015610b76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9a91906122ac565b50806001600160a01b0316336001600160a01b03167f6fdfde810bf61273d8d40dc751d460edf1c920afc676b7f3276fae588ffe56d084600001548560010154888881518110610bec57610bec6125ed565b6020026020010151604051610c14939291909283526020830191909152604082015260600190565b60405180910390a3505b5080610c298161253e565b915050610983565b5050565b60006107de73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc284610bb885886112c7565b6000610c7c731ceb5cb57c4d4e2b2433641b95dd330a33185a443330856113fd565b610c8633836114de565b506001919050565b6000546001600160a01b03163314610ca557600080fd5b600180546001600160a01b0319166001600160a01b038316179055610ccd620151804261240a565b60025550565b6000546001600160a01b03163314610cea57600080fd5b6004819055610cfc620151804261240a565b60055550565b60405163430c208160e01b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063430c20819060440160206040518083038186803b158015610d6857600080fd5b505afa158015610d7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da091906122ac565b610da957600080fd5b600060098281548110610dbe57610dbe6125ed565b9060005260206000209060040201905042816002015410158015610de75750600381015460ff16155b610df057600080fd5b60038101805460ff1916600190811790915560065490820154610e349173a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489133916001600160a01b0316906113fd565b610e57731ceb5cb57c4d4e2b2433641b95dd330a33185a44338360000154611325565b604051630852cd8d60e31b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906342966c6890602401602060405180830381600087803b158015610eb957600080fd5b505af1158015610ecd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef191906122ac565b50805460018201546040805192835260208301919091528101839052339081907f215abfcd108b85fbee47f26fda2de66f90f14fa5fcaf0201698ad8ac9323545f906060015b60405180910390a35050565b6000546001600160a01b03163314610f5a57600080fd5b600780546001600160a01b0319166001600160a01b038316179055610f82620151804261240a565b60085550565b6001600160a01b0383166000908152600d602052604081208054839290610fb09084906124d3565b90915550506001600160a01b0382166000908152600d602052604081208054839290610fdd90849061240a565b92505081905550816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161102991815260200190565b60405180910390a3505050565b80600b600082825461104891906124d3565b90915550506001600160a01b0382166000908152600d6020526040812080548392906110759084906124d3565b90915550506040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610f37565b6000806110c483610720565b905060006110d5620151804261240a565b604080516080810182528681526020810185815281830184815260006060840181815260098054600181018255925293517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af60049283029081019190915592517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b084015590517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b183015591517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b2909101805460ff1916911515919091179055600a5491516340c10f1960e01b8152339181019190915260248101919091529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906340c10f1990604401602060405180830381600087803b15801561122457600080fd5b505af1158015611238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125c91906122ac565b50600a546040805186815260208101859052908101839052606081019190915233907f7191c0804172ee8ac080b63e93fd6c2f26bbea256aed023d843c2a9f3dee0d3b9060800160405180910390a2600a80549060006112bb8361253e565b90915550949350505050565b6000806112f2731f98431c8ad98523631ae4a59f267346ea31f9846112ed898989611560565b6115cb565b9050600061130082866116b4565b60020b9050611319816113128661188d565b8a8a6118a8565b98975050505050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691611381919061231c565b6000604051808303816000865af19150503d80600081146113be576040519150601f19603f3d011682016040523d82523d6000602084013e6113c3565b606091505b50915091508180156113ed5750805115806113ed5750808060200190518101906113ed91906122ac565b6113f657600080fd5b5050505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691611461919061231c565b6000604051808303816000865af19150503d806000811461149e576040519150601f19603f3d011682016040523d82523d6000602084013e6114a3565b606091505b50915091508180156114cd5750805115806114cd5750808060200190518101906114cd91906122ac565b6114d657600080fd5b505050505050565b80600b60008282546114f0919061240a565b90915550506001600160a01b0382166000908152600d60205260408120805483929061151d90849061240a565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610f37565b6040805160608101825260008082526020820181905291810191909152826001600160a01b0316846001600160a01b0316111561159b579192915b50604080516060810182526001600160a01b03948516815292909316602083015262ffffff169181019190915290565b600081602001516001600160a01b031682600001516001600160a01b0316106115f357600080fd5b815160208084015160408086015181516001600160a01b0395861681860152949092168482015262ffffff90911660608085019190915281518085038201815260808501909252815191909201206001600160f81b031960a08401529085901b6bffffffffffffffffffffffff191660a183015260b58201527fe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b5460d582015260f50160408051601f1981840301815291905280516020909101209392505050565b600063ffffffff82166116f35760405162461bcd60e51b8152602060048201526002602482015261042560f41b60448201526064015b60405180910390fd5b6040805160028082526060820183526000926020830190803683370190505090508281600081518110611728576117286125ed565b602002602001019063ffffffff16908163ffffffff1681525050600081600181518110611757576117576125ed565b63ffffffff9092166020928302919091019091015260405163883bdbfd60e01b81526000906001600160a01b0386169063883bdbfd9061179b908590600401612338565b60006040518083038186803b1580156117b357600080fd5b505afa1580156117c7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526117ef9190810190612142565b509050600081600081518110611807576118076125ed565b602002602001015182600181518110611822576118226125ed565b60200260200101516118349190612483565b905061184a63ffffffff8616600683900b612422565b935060008160060b128015611871575061186e63ffffffff8616600683900b612559565b15155b1561188457836118808161251a565b9450505b50505092915050565b806001600160801b03811681146118a357600080fd5b919050565b6000806118b4866119b6565b90506001600160801b036001600160a01b0382161161193a5760006118e26001600160a01b03831680612464565b9050836001600160a01b0316856001600160a01b03161061191a57611915600160c01b876001600160801b031683611dcb565b611932565b61193281876001600160801b0316600160c01b611dcb565b9250506119ad565b60006119596001600160a01b0383168068010000000000000000611dcb565b9050836001600160a01b0316856001600160a01b0316106119915761198c600160801b876001600160801b031683611dcb565b6119a9565b6119a981876001600160801b0316600160801b611dcb565b9250505b50949350505050565b60008060008360020b126119cd578260020b6119da565b8260020b6119da906125a4565b90506119e9620d89e719612581565b60020b811115611a1f5760405162461bcd60e51b81526020600482015260016024820152601560fa1b60448201526064016116ea565b600060018216611a3357600160801b611a45565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff1690506002821615611a84576080611a7f826ffff97272373d413259a46990580e213a612464565b901c90505b6004821615611aae576080611aa9826ffff2e50f5f656932ef12357cf3c7fdcc612464565b901c90505b6008821615611ad8576080611ad3826fffe5caca7e10e4e61c3624eaa0941cd0612464565b901c90505b6010821615611b02576080611afd826fffcb9843d60f6159c9db58835c926644612464565b901c90505b6020821615611b2c576080611b27826fff973b41fa98c081472e6896dfb254c0612464565b901c90505b6040821615611b56576080611b51826fff2ea16466c96a3843ec78b326b52861612464565b901c90505b6080821615611b80576080611b7b826ffe5dee046a99a2a811c461f1969c3053612464565b901c90505b610100821615611bab576080611ba6826ffcbe86c7900a88aedcffc83b479aa3a4612464565b901c90505b610200821615611bd6576080611bd1826ff987a7253ac413176f2b074cf7815e54612464565b901c90505b610400821615611c01576080611bfc826ff3392b0822b70005940c7a398e4b70f3612464565b901c90505b610800821615611c2c576080611c27826fe7159475a2c29b7443b29c7fa6e889d9612464565b901c90505b611000821615611c57576080611c52826fd097f3bdfd2022b8845ad8f792aa5825612464565b901c90505b612000821615611c82576080611c7d826fa9f746462d870fdf8a65dc1f90e061e5612464565b901c90505b614000821615611cad576080611ca8826f70d869a156d2a1b890bb3df62baf32f7612464565b901c90505b618000821615611cd8576080611cd3826f31be135f97d08fd981231505542fcfa6612464565b901c90505b62010000821615611d04576080611cff826f09aa508b5b7a84e1c677de54f3e99bc9612464565b901c90505b62020000821615611d2f576080611d2a826e5d6af8dedb81196699c329225ee604612464565b901c90505b62040000821615611d59576080611d54826d2216e584f5fa1ea926041bedfe98612464565b901c90505b62080000821615611d81576080611d7c826b048a170391f7dc42444e8fa2612464565b901c90505b60008460020b1315611d9c57611d9981600019612450565b90505b611dab6401000000008261256d565b15611db7576001611dba565b60005b6107de9060ff16602083901c61240a565b600080806000198587098587029250828110838203039150508060001415611e055760008411611dfa57600080fd5b5082900490506106fe565b808411611e1157600080fd5b60008486880980840393811190920391905084600081611e30816125a4565b16968790049694859004946000819003046001019050611e508185612464565b909417936000611e61886003612464565b6002189050611e708189612464565b611e7b9060026124d3565b611e859082612464565b9050611e918189612464565b611e9c9060026124d3565b611ea69082612464565b9050611eb28189612464565b611ebd9060026124d3565b611ec79082612464565b9050611ed38189612464565b611ede9060026124d3565b611ee89082612464565b9050611ef48189612464565b611eff9060026124d3565b611f099082612464565b9050611f158189612464565b611f209060026124d3565b611f2a9082612464565b9050611f368187612464565b9a9950505050505050505050565b600082601f830112611f5557600080fd5b81516020611f6a611f65836123e6565b6123b5565b80838252828201915082860187848660051b8901011115611f8a57600080fd5b60005b85811015611fb2578151611fa081612619565b84529284019290840190600101611f8d565b5090979650505050505050565b803563ffffffff811681146118a357600080fd5b600060208284031215611fe557600080fd5b81356106fe81612619565b60006020828403121561200257600080fd5b81516106fe81612619565b6000806040838503121561202057600080fd5b823561202b81612619565b9150602083013561203b81612619565b809150509250929050565b60008060006060848603121561205b57600080fd5b833561206681612619565b9250602084013561207681612619565b929592945050506040919091013590565b6000806040838503121561209a57600080fd5b82356120a581612619565b946020939093013593505050565b600080600080608085870312156120c957600080fd5b84356120d481612619565b93506020850135925060408501356120eb81612619565b91506120f960608601611fbf565b905092959194509250565b60008060006060848603121561211957600080fd5b833561212481612619565b92506020840135915061213960408501611fbf565b90509250925092565b6000806040838503121561215557600080fd5b825167ffffffffffffffff8082111561216d57600080fd5b818501915085601f83011261218157600080fd5b81516020612191611f65836123e6565b8083825282820191508286018a848660051b89010111156121b157600080fd5b600096505b848710156121e35780518060060b81146121cf57600080fd5b8352600196909601959183019183016121b6565b50918801519196509093505050808211156121fd57600080fd5b5061220a85828601611f44565b9150509250929050565b6000602080838503121561222757600080fd5b823567ffffffffffffffff81111561223e57600080fd5b8301601f8101851361224f57600080fd5b803561225d611f65826123e6565b80828252848201915084840188868560051b870101111561227d57600080fd5b600094505b838510156122a0578035835260019490940193918501918501612282565b50979650505050505050565b6000602082840312156122be57600080fd5b815180151581146106fe57600080fd5b6000602082840312156122e057600080fd5b5035919050565b6000806000606084860312156122fc57600080fd5b83359250602084013561230e81612619565b915061213960408501611fbf565b6000825161232e8184602087016124ea565b9190910192915050565b6020808252825182820181905260009190848201906040850190845b8181101561237657835163ffffffff1683529284019291840191600101612354565b50909695505050505050565b60208152600082518060208401526123a18160408501602087016124ea565b601f01601f19169190910160400192915050565b604051601f8201601f1916810167ffffffffffffffff811182821017156123de576123de612603565b604052919050565b600067ffffffffffffffff82111561240057612400612603565b5060051b60200190565b6000821982111561241d5761241d6125c1565b500190565b600082612431576124316125d7565b600160ff1b82146000198414161561244b5761244b6125c1565b500590565b60008261245f5761245f6125d7565b500490565b600081600019048311821515161561247e5761247e6125c1565b500290565b60008160060b8360060b6000811281667fffffffffffff19018312811516156124ae576124ae6125c1565b81667fffffffffffff0183138116156124c9576124c96125c1565b5090039392505050565b6000828210156124e5576124e56125c1565b500390565b60005b838110156125055781810151838201526020016124ed565b83811115612514576000848401525b50505050565b60008160020b627fffff19811415612534576125346125c1565b6000190192915050565b6000600019821415612552576125526125c1565b5060010190565b600082612568576125686125d7565b500790565b60008261257c5761257c6125d7565b500690565b60008160020b627fffff1981141561259b5761259b6125c1565b60000392915050565b6000600160ff1b8214156125ba576125ba6125c1565b5060000390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461262e57600080fd5b5056fea264697066735822122054ac2368e7277c98486dcda107f39705169fda9d9f41fca5fbfbc19b1e1cb15964736f6c6343000807003360a060405234801561001057600080fd5b5033606081901b60805261162a610039600039600081816105ad0152610612015261162a6000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c806342966c68116100a257806370a082311161007157806370a082311461026757806395d89b411461027a578063a22cb4651461029e578063b88d4fde146102b1578063e985e9c5146102c457600080fd5b806342966c681461021b578063430c20811461022e5780634f6ccce7146102415780636352211e1461025457600080fd5b806318160ddd116100e957806318160ddd146101bd57806323b872dd146101cf5780632f745c59146101e257806340c10f19146101f557806342842e0e1461020857600080fd5b806301ffc9a71461011b57806306fdde0314610143578063081812fc1461017d578063095ea7b3146101a8575b600080fd5b61012e6101293660046113c1565b6102d7565b60405190151581526020015b60405180910390f35b6101706040518060400160405280600e81526020016d4b6565703372204f7074696f6e7360901b81525081565b60405161013a919061149e565b61019061018b3660046113fb565b610329565b6040516001600160a01b03909116815260200161013a565b6101bb6101b6366004611397565b6103c3565b005b6006545b60405190815260200161013a565b6101bb6101dd366004611243565b6104d9565b6101c16101f0366004611397565b61050a565b61012e610203366004611397565b6105a0565b6101bb610216366004611243565b6105ea565b61012e6102293660046113fb565b610605565b61012e61023c366004611397565b61064d565b6101c161024f3660046113fb565b610660565b6101906102623660046113fb565b6106f3565b6101c16102753660046111f5565b61076a565b6101706040518060400160405280600581526020016437a5a819a960d91b81525081565b6101bb6102ac36600461135b565b6107f1565b6101bb6102bf36600461127f565b6108b6565b61012e6102d2366004611210565b6108ee565b60006001600160e01b031982166380ac58cd60e01b148061030857506001600160e01b03198216635b5e139f60e01b145b8061032357506301ffc9a760e01b6001600160e01b03198316145b92915050565b6000818152602081905260408120546001600160a01b03166103a75760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600260205260409020546001600160a01b031690565b60006103ce826106f3565b9050806001600160a01b0316836001600160a01b0316141561043c5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b606482015260840161039e565b336001600160a01b0382161480610458575061045881336108ee565b6104ca5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606482015260840161039e565b6104d4838361091c565b505050565b6104e3338261098a565b6104ff5760405162461bcd60e51b815260040161039e90611503565b6104d4838383610a61565b60006105158361076a565b82106105775760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b606482015260840161039e565b506001600160a01b03919091166000908152600460209081526040808320938352929052205490565b6000336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105d757600080fd5b6105e18383610c10565b50600192915050565b6104d4838383604051806020016040528060008152506108b6565b6000336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461063c57600080fd5b61064582610c2e565b506001919050565b6000610659838361098a565b9392505050565b600061066b60065490565b82106106ce5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b606482015260840161039e565b600682815481106106e1576106e16115af565b90600052602060002001549050919050565b6000818152602081905260408120546001600160a01b0316806103235760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b606482015260840161039e565b60006001600160a01b0382166107d55760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b606482015260840161039e565b506001600160a01b031660009081526001602052604090205490565b6001600160a01b03821633141561084a5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015260640161039e565b3360008181526003602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6108c0338361098a565b6108dc5760405162461bcd60e51b815260040161039e90611503565b6108e884848484610cd7565b50505050565b6001600160a01b03918216600090815260036020908152604080832093909416825291909152205460ff1690565b600081815260026020526040902080546001600160a01b0319166001600160a01b0384169081179091558190610951826106f3565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152602081905260408120546001600160a01b0316610a035760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b606482015260840161039e565b6000610a0e836106f3565b9050806001600160a01b0316846001600160a01b03161480610a495750836001600160a01b0316610a3e84610329565b6001600160a01b0316145b80610a595750610a5981856108ee565b949350505050565b826001600160a01b0316610a74826106f3565b6001600160a01b031614610adc5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b606482015260840161039e565b6001600160a01b038216610b3e5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b606482015260840161039e565b610b49838383610d0a565b610b5460008261091c565b6001600160a01b03831660009081526001602081905260408220805491929091610b7f90849061156c565b90915550506001600160a01b03821660009081526001602081905260408220805491929091610baf908490611554565b909155505060008181526020819052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b610c2a828260405180602001604052806000815250610dc2565b5050565b6000610c39826106f3565b9050610c4781600084610d0a565b610c5260008361091c565b6001600160a01b03811660009081526001602081905260408220805491929091610c7d90849061156c565b909155505060008281526020819052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b610ce2848484610a61565b610cee84848484610df5565b6108e85760405162461bcd60e51b815260040161039e906114b1565b6001600160a01b038316610d6557610d6081600680546000838152600760205260408120829055600182018355919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0155565b610d88565b816001600160a01b0316836001600160a01b031614610d8857610d888382610ef9565b6001600160a01b038216610d9f576104d481610f96565b826001600160a01b0316826001600160a01b0316146104d4576104d48282611045565b610dcc8383611089565b610dd96000848484610df5565b6104d45760405162461bcd60e51b815260040161039e906114b1565b6000833b15610eee57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290610e30903390899088908890600401611461565b602060405180830381600087803b158015610e4a57600080fd5b505af1925050508015610e7a575060408051601f3d908101601f19168201909252610e77918101906113de565b60015b610ed4573d808015610ea8576040519150601f19603f3d011682016040523d82523d6000602084013e610ead565b606091505b508051610ecc5760405162461bcd60e51b815260040161039e906114b1565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050610a59565b506001949350505050565b60006001610f068461076a565b610f10919061156c565b600083815260056020526040902054909150808214610f63576001600160a01b03841660009081526004602090815260408083208584528252808320548484528184208190558352600590915290208190555b5060009182526005602090815260408084208490556001600160a01b039094168352600481528383209183525290812055565b600654600090610fa89060019061156c565b60008381526007602052604081205460068054939450909284908110610fd057610fd06115af565b906000526020600020015490508060068381548110610ff157610ff16115af565b600091825260208083209091019290925582815260079091526040808220849055858252812055600680548061102957611029611599565b6001900381819060005260206000200160009055905550505050565b60006110508361076a565b6001600160a01b039093166000908152600460209081526040808320868452825280832085905593825260059052919091209190915550565b6001600160a01b0382166110df5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015260640161039e565b6000818152602081905260409020546001600160a01b0316156111445760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015260640161039e565b61115060008383610d0a565b6001600160a01b0382166000908152600160208190526040822080549192909161117b908490611554565b909155505060008181526020819052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b80356001600160a01b03811681146111f057600080fd5b919050565b60006020828403121561120757600080fd5b610659826111d9565b6000806040838503121561122357600080fd5b61122c836111d9565b915061123a602084016111d9565b90509250929050565b60008060006060848603121561125857600080fd5b611261846111d9565b925061126f602085016111d9565b9150604084013590509250925092565b6000806000806080858703121561129557600080fd5b61129e856111d9565b93506112ac602086016111d9565b925060408501359150606085013567ffffffffffffffff808211156112d057600080fd5b818701915087601f8301126112e457600080fd5b8135818111156112f6576112f66115c5565b604051601f8201601f19908116603f0116810190838211818310171561131e5761131e6115c5565b816040528281528a602084870101111561133757600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561136e57600080fd5b611377836111d9565b91506020830135801515811461138c57600080fd5b809150509250929050565b600080604083850312156113aa57600080fd5b6113b3836111d9565b946020939093013593505050565b6000602082840312156113d357600080fd5b8135610659816115db565b6000602082840312156113f057600080fd5b8151610659816115db565b60006020828403121561140d57600080fd5b5035919050565b6000815180845260005b8181101561143a5760208185018101518683018201520161141e565b8181111561144c576000602083870101525b50601f01601f19169290920160200192915050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061149490830184611414565b9695505050505050565b6020815260006106596020830184611414565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6000821982111561156757611567611583565b500190565b60008282101561157e5761157e611583565b500390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b0319811681146115f157600080fd5b5056fea2646970667358221220377eb001f223e1fcaa8a9f3f493f41c06118872dfc6c2f891c73471e4b2c7fac64736f6c634300080700330000000000000000000000000dba6457ea72ecf784a55abd738b1f9b6c45fd02

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102325760003560e01c80636953bd8011610130578063b4bdf8b0116100b8578063dd62ed3e1161007c578063dd62ed3e146104fc578063e8594b3114610527578063ed7b686e1461053a578063f0f4426014610543578063fc7e9c6f1461055657600080fd5b8063b4bdf8b01461049d578063b6b55f25146104b0578063cfad57a2146104c3578063dabd2719146104d6578063db006a75146104e957600080fd5b80637f5bdf6a116100ff5780637f5bdf6a1461044257806395d89b411461044b578063a035b1fe1461046f578063a9059cbb14610477578063aa613df51461048a57600080fd5b80636953bd80146104085780636b6f4a9d1461041157806370a082311461041a5780637bc6729b1461043a57600080fd5b8063377f3300116101be5780634e71d92d116101825780634e71d92d146103be578063553999d9146103c657806358fac003146103cf5780635b36add4146103e257806361d027b3146103f557600080fd5b8063377f330014610348578063379607f51461035b57806338c9027a1461036e578063409e22051461038157806341d86d00146103b657600080fd5b806318160ddd1161020557806318160ddd146102e15780632114d61f146102ea57806323b872dd146102f4578063313ce56714610307578063350d19ad1461032157600080fd5b806306fdde0314610237578063095ea7b31461027d5780631208aa18146102a057806312d43a51146102b6575b600080fd5b610267604051806040016040528060118152602001702932b232b2b6b0b136329025b2b2b819b960791b81525081565b6040516102749190612382565b60405180910390f35b61029061028b366004612087565b61055f565b6040519015158152602001610274565b6102a86105cb565b604051908152602001610274565b6000546102c9906001600160a01b031681565b6040516001600160a01b039091168152602001610274565b6102a8600b5481565b6102f261060f565b005b610290610302366004612046565b61063c565b61030f601281565b60405160ff9091168152602001610274565b6102c97f000000000000000000000000ba15ab4c5b27917e19f772c9718095e248feff3581565b6007546102c9906001600160a01b031681565b6102a86103693660046122ce565b610705565b6102a861037c3660046122ce565b610720565b61039461038f3660046122ce565b6107e6565b6040805194855260208501939093529183015215156060820152608001610274565b6102f2610823565b6102a861086c565b6102a860025481565b6102a86103dd3660046120b3565b610897565b6102a86103f0366004612104565b6108bc565b6006546102c9906001600160a01b031681565b6102a860045481565b6102a860035481565b6102a8610428366004611fd3565b600d6020526000908152604090205481565b6102f26108e1565b6102a860055481565b610267604051806040016040528060058152602001643925a819a960d91b81525081565b6102a8610929565b610290610485366004612087565b61096a565b6102f2610498366004612214565b610980565b6102a86104ab3660046122e7565b610c35565b6102906104be3660046122ce565b610c5a565b6102f26104d1366004611fd3565b610c8e565b6102f26104e43660046122ce565b610cd3565b6102f26104f73660046122ce565b610d02565b6102a861050a36600461200d565b600c60209081526000928352604080842090915290825290205481565b6001546102c9906001600160a01b031681565b6102a860085481565b6102f2610551366004611fd3565b610f43565b6102a8600a5481565b336000818152600c602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906105ba9086815260200190565b60405180910390a350600192915050565b600061060a731ceb5cb57c4d4e2b2433641b95dd330a33185a44670de0b6b3a764000073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48603c610897565b905090565b6000546001600160a01b0316331461062657600080fd5b426005541061063457600080fd5b600454600355565b6001600160a01b0383166000818152600c602090815260408083203380855292528220549192909190821480159061067657506000198114155b156106ec57600061068785836124d3565b6001600160a01b038881166000818152600c60209081526040808320948916808452948252918290208590559051848152939450919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505b6106f7868686610f88565b6001925050505b9392505050565b60006107113383611036565b61071a826110b8565b92915050565b60008061075a731ceb5cb57c4d4e2b2433641b95dd330a33185a448473a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4862015180610897565b90506000610793731ceb5cb57c4d4e2b2433641b95dd330a33185a448573a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48603c610897565b6003549091506064906107a69084612464565b6107b09190612450565b6003549092506064906107c39083612464565b6107cd9190612450565b90508082116107dc57806107de565b815b949350505050565b600981815481106107f657600080fd5b60009182526020909120600490910201805460018201546002830154600390930154919350919060ff1684565b6000546001600160a01b0316331461083a57600080fd5b426008541061084857600080fd5b600754600680546001600160a01b0319166001600160a01b03909216919091179055565b336000818152600d602052604081205490916108889082611036565b610891816110b8565b91505090565b6000806108a58686856108bc565b90506108b2818585610c35565b9695505050505050565b60006107de8473c02aaa39b223fe8d0a0e5c4f27ead9083c756cc261271085876112c7565b6001546001600160a01b0316331480156108fc575042600254105b61090557600080fd5b600154600080546001600160a01b0319166001600160a01b03909216919091179055565b600061060a731ceb5cb57c4d4e2b2433641b95dd330a33185a44670de0b6b3a764000073a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4862015180610897565b6000610977338484610f88565b50600192915050565b60005b8151811015610c3157600060098383815181106109a2576109a26125ed565b6020026020010151815481106109ba576109ba6125ed565b906000526020600020906004020190504281600201541080156109e25750600381015460ff16155b15610c1e5760038101805460ff191660011790556006548154610a2691731ceb5cb57c4d4e2b2433641b95dd330a33185a44916001600160a01b0390911690611325565b60007f000000000000000000000000ba15ab4c5b27917e19f772c9718095e248feff356001600160a01b0316636352211e858581518110610a6957610a696125ed565b60200260200101516040518263ffffffff1660e01b8152600401610a8f91815260200190565b60206040518083038186803b158015610aa757600080fd5b505afa158015610abb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610adf9190611ff0565b90507f000000000000000000000000ba15ab4c5b27917e19f772c9718095e248feff356001600160a01b03166342966c68858581518110610b2257610b226125ed565b60200260200101516040518263ffffffff1660e01b8152600401610b4891815260200190565b602060405180830381600087803b158015610b6257600080fd5b505af1158015610b76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9a91906122ac565b50806001600160a01b0316336001600160a01b03167f6fdfde810bf61273d8d40dc751d460edf1c920afc676b7f3276fae588ffe56d084600001548560010154888881518110610bec57610bec6125ed565b6020026020010151604051610c14939291909283526020830191909152604082015260600190565b60405180910390a3505b5080610c298161253e565b915050610983565b5050565b60006107de73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc284610bb885886112c7565b6000610c7c731ceb5cb57c4d4e2b2433641b95dd330a33185a443330856113fd565b610c8633836114de565b506001919050565b6000546001600160a01b03163314610ca557600080fd5b600180546001600160a01b0319166001600160a01b038316179055610ccd620151804261240a565b60025550565b6000546001600160a01b03163314610cea57600080fd5b6004819055610cfc620151804261240a565b60055550565b60405163430c208160e01b8152336004820152602481018290527f000000000000000000000000ba15ab4c5b27917e19f772c9718095e248feff356001600160a01b03169063430c20819060440160206040518083038186803b158015610d6857600080fd5b505afa158015610d7c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da091906122ac565b610da957600080fd5b600060098281548110610dbe57610dbe6125ed565b9060005260206000209060040201905042816002015410158015610de75750600381015460ff16155b610df057600080fd5b60038101805460ff1916600190811790915560065490820154610e349173a0b86991c6218b36c1d19d4a2e9eb0ce3606eb489133916001600160a01b0316906113fd565b610e57731ceb5cb57c4d4e2b2433641b95dd330a33185a44338360000154611325565b604051630852cd8d60e31b8152600481018390527f000000000000000000000000ba15ab4c5b27917e19f772c9718095e248feff356001600160a01b0316906342966c6890602401602060405180830381600087803b158015610eb957600080fd5b505af1158015610ecd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef191906122ac565b50805460018201546040805192835260208301919091528101839052339081907f215abfcd108b85fbee47f26fda2de66f90f14fa5fcaf0201698ad8ac9323545f906060015b60405180910390a35050565b6000546001600160a01b03163314610f5a57600080fd5b600780546001600160a01b0319166001600160a01b038316179055610f82620151804261240a565b60085550565b6001600160a01b0383166000908152600d602052604081208054839290610fb09084906124d3565b90915550506001600160a01b0382166000908152600d602052604081208054839290610fdd90849061240a565b92505081905550816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161102991815260200190565b60405180910390a3505050565b80600b600082825461104891906124d3565b90915550506001600160a01b0382166000908152600d6020526040812080548392906110759084906124d3565b90915550506040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610f37565b6000806110c483610720565b905060006110d5620151804261240a565b604080516080810182528681526020810185815281830184815260006060840181815260098054600181018255925293517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af60049283029081019190915592517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b084015590517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b183015591517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b2909101805460ff1916911515919091179055600a5491516340c10f1960e01b8152339181019190915260248101919091529091507f000000000000000000000000ba15ab4c5b27917e19f772c9718095e248feff356001600160a01b0316906340c10f1990604401602060405180830381600087803b15801561122457600080fd5b505af1158015611238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125c91906122ac565b50600a546040805186815260208101859052908101839052606081019190915233907f7191c0804172ee8ac080b63e93fd6c2f26bbea256aed023d843c2a9f3dee0d3b9060800160405180910390a2600a80549060006112bb8361253e565b90915550949350505050565b6000806112f2731f98431c8ad98523631ae4a59f267346ea31f9846112ed898989611560565b6115cb565b9050600061130082866116b4565b60020b9050611319816113128661188d565b8a8a6118a8565b98975050505050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691611381919061231c565b6000604051808303816000865af19150503d80600081146113be576040519150601f19603f3d011682016040523d82523d6000602084013e6113c3565b606091505b50915091508180156113ed5750805115806113ed5750808060200190518101906113ed91906122ac565b6113f657600080fd5b5050505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691611461919061231c565b6000604051808303816000865af19150503d806000811461149e576040519150601f19603f3d011682016040523d82523d6000602084013e6114a3565b606091505b50915091508180156114cd5750805115806114cd5750808060200190518101906114cd91906122ac565b6114d657600080fd5b505050505050565b80600b60008282546114f0919061240a565b90915550506001600160a01b0382166000908152600d60205260408120805483929061151d90849061240a565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610f37565b6040805160608101825260008082526020820181905291810191909152826001600160a01b0316846001600160a01b0316111561159b579192915b50604080516060810182526001600160a01b03948516815292909316602083015262ffffff169181019190915290565b600081602001516001600160a01b031682600001516001600160a01b0316106115f357600080fd5b815160208084015160408086015181516001600160a01b0395861681860152949092168482015262ffffff90911660608085019190915281518085038201815260808501909252815191909201206001600160f81b031960a08401529085901b6bffffffffffffffffffffffff191660a183015260b58201527fe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b5460d582015260f50160408051601f1981840301815291905280516020909101209392505050565b600063ffffffff82166116f35760405162461bcd60e51b8152602060048201526002602482015261042560f41b60448201526064015b60405180910390fd5b6040805160028082526060820183526000926020830190803683370190505090508281600081518110611728576117286125ed565b602002602001019063ffffffff16908163ffffffff1681525050600081600181518110611757576117576125ed565b63ffffffff9092166020928302919091019091015260405163883bdbfd60e01b81526000906001600160a01b0386169063883bdbfd9061179b908590600401612338565b60006040518083038186803b1580156117b357600080fd5b505afa1580156117c7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526117ef9190810190612142565b509050600081600081518110611807576118076125ed565b602002602001015182600181518110611822576118226125ed565b60200260200101516118349190612483565b905061184a63ffffffff8616600683900b612422565b935060008160060b128015611871575061186e63ffffffff8616600683900b612559565b15155b1561188457836118808161251a565b9450505b50505092915050565b806001600160801b03811681146118a357600080fd5b919050565b6000806118b4866119b6565b90506001600160801b036001600160a01b0382161161193a5760006118e26001600160a01b03831680612464565b9050836001600160a01b0316856001600160a01b03161061191a57611915600160c01b876001600160801b031683611dcb565b611932565b61193281876001600160801b0316600160c01b611dcb565b9250506119ad565b60006119596001600160a01b0383168068010000000000000000611dcb565b9050836001600160a01b0316856001600160a01b0316106119915761198c600160801b876001600160801b031683611dcb565b6119a9565b6119a981876001600160801b0316600160801b611dcb565b9250505b50949350505050565b60008060008360020b126119cd578260020b6119da565b8260020b6119da906125a4565b90506119e9620d89e719612581565b60020b811115611a1f5760405162461bcd60e51b81526020600482015260016024820152601560fa1b60448201526064016116ea565b600060018216611a3357600160801b611a45565b6ffffcb933bd6fad37aa2d162d1a5940015b70ffffffffffffffffffffffffffffffffff1690506002821615611a84576080611a7f826ffff97272373d413259a46990580e213a612464565b901c90505b6004821615611aae576080611aa9826ffff2e50f5f656932ef12357cf3c7fdcc612464565b901c90505b6008821615611ad8576080611ad3826fffe5caca7e10e4e61c3624eaa0941cd0612464565b901c90505b6010821615611b02576080611afd826fffcb9843d60f6159c9db58835c926644612464565b901c90505b6020821615611b2c576080611b27826fff973b41fa98c081472e6896dfb254c0612464565b901c90505b6040821615611b56576080611b51826fff2ea16466c96a3843ec78b326b52861612464565b901c90505b6080821615611b80576080611b7b826ffe5dee046a99a2a811c461f1969c3053612464565b901c90505b610100821615611bab576080611ba6826ffcbe86c7900a88aedcffc83b479aa3a4612464565b901c90505b610200821615611bd6576080611bd1826ff987a7253ac413176f2b074cf7815e54612464565b901c90505b610400821615611c01576080611bfc826ff3392b0822b70005940c7a398e4b70f3612464565b901c90505b610800821615611c2c576080611c27826fe7159475a2c29b7443b29c7fa6e889d9612464565b901c90505b611000821615611c57576080611c52826fd097f3bdfd2022b8845ad8f792aa5825612464565b901c90505b612000821615611c82576080611c7d826fa9f746462d870fdf8a65dc1f90e061e5612464565b901c90505b614000821615611cad576080611ca8826f70d869a156d2a1b890bb3df62baf32f7612464565b901c90505b618000821615611cd8576080611cd3826f31be135f97d08fd981231505542fcfa6612464565b901c90505b62010000821615611d04576080611cff826f09aa508b5b7a84e1c677de54f3e99bc9612464565b901c90505b62020000821615611d2f576080611d2a826e5d6af8dedb81196699c329225ee604612464565b901c90505b62040000821615611d59576080611d54826d2216e584f5fa1ea926041bedfe98612464565b901c90505b62080000821615611d81576080611d7c826b048a170391f7dc42444e8fa2612464565b901c90505b60008460020b1315611d9c57611d9981600019612450565b90505b611dab6401000000008261256d565b15611db7576001611dba565b60005b6107de9060ff16602083901c61240a565b600080806000198587098587029250828110838203039150508060001415611e055760008411611dfa57600080fd5b5082900490506106fe565b808411611e1157600080fd5b60008486880980840393811190920391905084600081611e30816125a4565b16968790049694859004946000819003046001019050611e508185612464565b909417936000611e61886003612464565b6002189050611e708189612464565b611e7b9060026124d3565b611e859082612464565b9050611e918189612464565b611e9c9060026124d3565b611ea69082612464565b9050611eb28189612464565b611ebd9060026124d3565b611ec79082612464565b9050611ed38189612464565b611ede9060026124d3565b611ee89082612464565b9050611ef48189612464565b611eff9060026124d3565b611f099082612464565b9050611f158189612464565b611f209060026124d3565b611f2a9082612464565b9050611f368187612464565b9a9950505050505050505050565b600082601f830112611f5557600080fd5b81516020611f6a611f65836123e6565b6123b5565b80838252828201915082860187848660051b8901011115611f8a57600080fd5b60005b85811015611fb2578151611fa081612619565b84529284019290840190600101611f8d565b5090979650505050505050565b803563ffffffff811681146118a357600080fd5b600060208284031215611fe557600080fd5b81356106fe81612619565b60006020828403121561200257600080fd5b81516106fe81612619565b6000806040838503121561202057600080fd5b823561202b81612619565b9150602083013561203b81612619565b809150509250929050565b60008060006060848603121561205b57600080fd5b833561206681612619565b9250602084013561207681612619565b929592945050506040919091013590565b6000806040838503121561209a57600080fd5b82356120a581612619565b946020939093013593505050565b600080600080608085870312156120c957600080fd5b84356120d481612619565b93506020850135925060408501356120eb81612619565b91506120f960608601611fbf565b905092959194509250565b60008060006060848603121561211957600080fd5b833561212481612619565b92506020840135915061213960408501611fbf565b90509250925092565b6000806040838503121561215557600080fd5b825167ffffffffffffffff8082111561216d57600080fd5b818501915085601f83011261218157600080fd5b81516020612191611f65836123e6565b8083825282820191508286018a848660051b89010111156121b157600080fd5b600096505b848710156121e35780518060060b81146121cf57600080fd5b8352600196909601959183019183016121b6565b50918801519196509093505050808211156121fd57600080fd5b5061220a85828601611f44565b9150509250929050565b6000602080838503121561222757600080fd5b823567ffffffffffffffff81111561223e57600080fd5b8301601f8101851361224f57600080fd5b803561225d611f65826123e6565b80828252848201915084840188868560051b870101111561227d57600080fd5b600094505b838510156122a0578035835260019490940193918501918501612282565b50979650505050505050565b6000602082840312156122be57600080fd5b815180151581146106fe57600080fd5b6000602082840312156122e057600080fd5b5035919050565b6000806000606084860312156122fc57600080fd5b83359250602084013561230e81612619565b915061213960408501611fbf565b6000825161232e8184602087016124ea565b9190910192915050565b6020808252825182820181905260009190848201906040850190845b8181101561237657835163ffffffff1683529284019291840191600101612354565b50909695505050505050565b60208152600082518060208401526123a18160408501602087016124ea565b601f01601f19169190910160400192915050565b604051601f8201601f1916810167ffffffffffffffff811182821017156123de576123de612603565b604052919050565b600067ffffffffffffffff82111561240057612400612603565b5060051b60200190565b6000821982111561241d5761241d6125c1565b500190565b600082612431576124316125d7565b600160ff1b82146000198414161561244b5761244b6125c1565b500590565b60008261245f5761245f6125d7565b500490565b600081600019048311821515161561247e5761247e6125c1565b500290565b60008160060b8360060b6000811281667fffffffffffff19018312811516156124ae576124ae6125c1565b81667fffffffffffff0183138116156124c9576124c96125c1565b5090039392505050565b6000828210156124e5576124e56125c1565b500390565b60005b838110156125055781810151838201526020016124ed565b83811115612514576000848401525b50505050565b60008160020b627fffff19811415612534576125346125c1565b6000190192915050565b6000600019821415612552576125526125c1565b5060010190565b600082612568576125686125d7565b500790565b60008261257c5761257c6125d7565b500690565b60008160020b627fffff1981141561259b5761259b6125c1565b60000392915050565b6000600160ff1b8214156125ba576125ba6125c1565b5060000390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461262e57600080fd5b5056fea264697066735822122054ac2368e7277c98486dcda107f39705169fda9d9f41fca5fbfbc19b1e1cb15964736f6c63430008070033

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

0000000000000000000000000dba6457ea72ecf784a55abd738b1f9b6c45fd02

-----Decoded View---------------
Arg [0] : _treasury (address): 0x0DBA6457EA72ecf784a55AbD738b1f9b6c45FD02

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000000dba6457ea72ecf784a55abd738b1f9b6c45fd02


Deployed Bytecode Sourcemap

30627:9201:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30660:49;;;;;;;;;;;;;;;-1:-1:-1;;;30660:49:0;;;;;;;;;;;;:::i;:::-;;;;;;;;38118:206;;;;;;:::i;:::-;;:::i;:::-;;;9415:14:1;;9408:22;9390:41;;9378:2;9363:18;38118:206:0;9250:187:1;35766:111:0;;;:::i;:::-;;;10865:25:1;;;10853:2;10838:18;35766:111:0;10719:177:1;30806:18:0;;;;;-1:-1:-1;;;;;30806:18:0;;;;;;-1:-1:-1;;;;;7502:32:1;;;7484:51;;7472:2;7457:18;30806::0;7338:203:1;33228:27:0;;;;;;32745:130;;;:::i;:::-;;38489:511;;;;;;:::i;:::-;;:::i;30762:35::-;;30795:2;30762:35;;;;;12199:4:1;12187:17;;;12169:36;;12157:2;12142:18;30762:35:0;12027:184:1;31771:36:0;;;;;31016:27;;;;;-1:-1:-1;;;;;31016:27:0;;;36610:128;;;;;;:::i;:::-;;:::i;35885:343::-;;;;;;:::i;:::-;;:::i;31205:23::-;;;;;;:::i;:::-;;:::i;:::-;;;;11450:25:1;;;11506:2;11491:18;;11484:34;;;;11534:18;;;11527:34;11604:14;11597:22;11592:2;11577:18;;11570:50;11437:3;11422:19;31205:23:0;11225:401:1;33035:130:0;;;:::i;36436:166::-;;;:::i;30860:20::-;;;;;;34826:324;;;;;;:::i;:::-;;:::i;35158:231::-;;;;;;:::i;:::-;;:::i;30986:23::-;;;;;-1:-1:-1;;;;;30986:23:0;;;30921:24;;;;;;30889:25;;;;;;33333:41;;;;;;:::i;:::-;;;;;;;;;;;;;;32455:133;;;:::i;30952:25::-;;;;;;30716:39;;;;;;;;;;;;;;;-1:-1:-1;;;30716:39:0;;;;;35643:115;;;:::i;38332:149::-;;;;;;:::i;:::-;;:::i;33543:533::-;;;;;;:::i;:::-;;:::i;35397:238::-;;;;;;:::i;:::-;;:::i;36236:192::-;;;;;;:::i;:::-;;:::i;32328:119::-;;;;;;:::i;:::-;;:::i;32596:141::-;;;;;;:::i;:::-;;:::i;37119:471::-;;;;;;:::i;:::-;;:::i;33264:62::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;30831:22;;;;;-1:-1:-1;;;;;30831:22:0;;;31050:25;;;;;;32883:144;;;;;;:::i;:::-;;:::i;31235:21::-;;;;;;38118:206;38210:10;38183:4;38200:21;;;:9;:21;;;;;;;;-1:-1:-1;;;;;38200:30:0;;;;;;;;;;:39;;;38257:37;38183:4;;38200:30;;38257:37;;;;38233:6;10865:25:1;;10853:2;10838:18;;10719:177;38257:37:0;;;;;;;;-1:-1:-1;38312:4:0;38118:206;;;;:::o;35766:111::-;35805:4;35829:40;31297:42;35848:4;31379:42;31647:2;35829:12;:40::i;:::-;35822:47;;35766:111;:::o;32745:130::-;32296:3;;-1:-1:-1;;;;;32296:3:0;32282:10;:17;32274:26;;;;;;32817:15:::1;32801:13;;:31;32793:40;;;::::0;::::1;;32855:12;::::0;32844:8:::1;:23:::0;32745:130::o;38489:511::-;-1:-1:-1;;;;;38648:14:0;;38568:4;38648:14;;;:9;:14;;;;;;;;38603:10;38648:23;;;;;;;;38568:4;;38603:10;;38648:23;38688:14;;;;;:52;;;-1:-1:-1;;38706:16:0;:34;;38688:52;38684:241;;;38757:17;38777:25;38796:6;38777:16;:25;:::i;:::-;-1:-1:-1;;;;;38817:14:0;;;;;;;:9;:14;;;;;;;;:23;;;;;;;;;;;;;:38;;;38877:36;;10865:25:1;;;38817:38:0;;-1:-1:-1;38817:23:0;;:14;;38877:36;;10838:18:1;38877:36:0;;;;;;;38742:183;38684:241;38937:33;38953:3;38958;38963:6;38937:15;:33::i;:::-;38988:4;38981:11;;;;38489:511;;;;;;:::o;36610:128::-;36656:4;36673:25;36679:10;36691:6;36673:5;:25::i;:::-;36716:14;36723:6;36716;:14::i;:::-;36709:21;36610:128;-1:-1:-1;;36610:128:0:o;35885:343::-;35933:4;35950:12;35965:45;31297:42;35984:6;31379:42;31608:5;35965:12;:45::i;:::-;35950:60;;36021:11;36035:42;31297;36054:6;31379:42;31647:2;36035:12;:42::i;:::-;36108:8;;36021:56;;-1:-1:-1;31761:3:0;;36098:18;;:7;:18;:::i;:::-;:25;;;;:::i;:::-;36152:8;;36088:35;;-1:-1:-1;31761:3:0;;36143:17;;:6;:17;:::i;:::-;:24;;;;:::i;:::-;36134:33;;36195:6;36185:7;:16;:35;;36214:6;36185:35;;;36204:7;36185:35;36178:42;35885:343;-1:-1:-1;;;;35885:343:0:o;31205:23::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31205:23:0;;;;;:::o;33035:130::-;32296:3;;-1:-1:-1;;;;;32296:3:0;32282:10;:17;32274:26;;;;;;33107:15:::1;33091:13;;:31;33083:40;;;::::0;::::1;;33145:12;::::0;33134:8:::1;:23:::0;;-1:-1:-1;;;;;;33134:23:0::1;-1:-1:-1::0;;;;;33145:12:0;;::::1;33134:23:::0;;;::::1;::::0;;33035:130::o;36436:166::-;36513:10;36471:4;36503:21;;;:9;:21;;;;;;36471:4;;36535:26;;36503:21;36535:5;:26::i;:::-;36579:15;36586:7;36579:6;:15::i;:::-;36572:22;;;36436:166;:::o;34826:324::-;34985:17;35015;35035:44;35046:8;35056:9;35067:11;35035:10;:44::i;:::-;35015:64;;35097:45;35108:9;35119;35130:11;35097:10;:45::i;:::-;35090:52;34826:324;-1:-1:-1;;;;;;34826:324:0:o;35158:231::-;35287:17;35324:57;35335:8;31527:42;35351:5;35358:11;35371:9;35324:10;:57::i;32455:133::-;32518:7;;-1:-1:-1;;;;;32518:7:0;32504:10;:21;:51;;;;;32540:15;32529:8;;:26;32504:51;32496:60;;;;;;32573:7;;;32567:13;;-1:-1:-1;;;;;;32567:13:0;-1:-1:-1;;;;;32573:7:0;;;32567:13;;;;;;32455:133::o;35643:115::-;35683:4;35707:43;31297:42;35726:4;31379:42;31608:5;35707:12;:43::i;38332:149::-;38394:4;38411:40;38427:10;38439:3;38444:6;38411:15;:40::i;:::-;-1:-1:-1;38469:4:0;38332:149;;;;:::o;33543:533::-;33604:6;33599:470;33620:4;:11;33616:1;:15;33599:470;;;33653:19;33675:7;33683:4;33688:1;33683:7;;;;;;;;:::i;:::-;;;;;;;33675:16;;;;;;;;:::i;:::-;;;;;;;;;;;33653:38;;33724:15;33710:4;:11;;;:29;:48;;;;-1:-1:-1;33744:14:0;;;;;;33743:15;33710:48;33706:352;;;33779:14;;;:21;;-1:-1:-1;;33779:21:0;33796:4;33779:21;;;33839:8;;33849:11;;33819:42;;31297;;-1:-1:-1;;;;;33839:8:0;;;;33819:13;:42::i;:::-;33880:14;33897:5;-1:-1:-1;;;;;33897:13:0;;33911:4;33916:1;33911:7;;;;;;;;:::i;:::-;;;;;;;33897:22;;;;;;;;;;;;;10865:25:1;;10853:2;10838:18;;10719:177;33897:22:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;33880:39;;33938:5;-1:-1:-1;;;;;33938:10:0;;33949:4;33954:1;33949:7;;;;;;;;:::i;:::-;;;;;;;33938:19;;;;;;;;;;;;;10865:25:1;;10853:2;10838:18;;10719:177;33938:19:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;34000:6;-1:-1:-1;;;;;33981:61:0;33988:10;-1:-1:-1;;;;;33981:61:0;;34008:4;:11;;;34021:4;:11;;;34034:4;34039:1;34034:7;;;;;;;;:::i;:::-;;;;;;;33981:61;;;;;;;11103:25:1;;;11159:2;11144:18;;11137:34;;;;11202:2;11187:18;;11180:34;11091:2;11076:18;;10901:319;33981:61:0;;;;;;;;33760:298;33706:352;-1:-1:-1;33633:3:0;;;;:::i;:::-;;;;33599:470;;;;33543:533;:::o;35397:238::-;35530:17;35567:60;31527:42;35584:9;35595:4;35601:11;35614:12;35567:10;:60::i;36236:192::-;36285:4;36302:59;31297:42;36326:10;36346:4;36353:7;36302:17;:59::i;:::-;36372:26;36378:10;36390:7;36372:5;:26::i;:::-;-1:-1:-1;36416:4:0;;36236:192;-1:-1:-1;36236:192:0:o;32328:119::-;32296:3;;-1:-1:-1;;;;;32296:3:0;32282:10;:17;32274:26;;;;;;32380:7:::1;:14:::0;;-1:-1:-1;;;;;;32380:14:0::1;-1:-1:-1::0;;;;;32380:14:0;::::1;;::::0;;32416:23:::1;31725:6;32416:15;:23;:::i;:::-;32405:8;:34:::0;-1:-1:-1;32328:119:0:o;32596:141::-;32296:3;;-1:-1:-1;;;;;32296:3:0;32282:10;:17;32274:26;;;;;;32655:12:::1;:24:::0;;;32706:23:::1;31725:6;32706:15;:23;:::i;:::-;32690:13;:39:::0;-1:-1:-1;32596:141:0:o;37119:471::-;37172:39;;-1:-1:-1;;;37172:39:0;;37196:10;37172:39;;;8493:51:1;8560:18;;;8553:34;;;37172:5:0;-1:-1:-1;;;;;37172:23:0;;;;8466:18:1;;37172:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;37164:48;;;;;;37223:19;37245:7;37253:2;37245:11;;;;;;;;:::i;:::-;;;;;;;;;;;37223:33;;37290:15;37275:4;:11;;;:30;;:49;;;;-1:-1:-1;37310:14:0;;;;;;37309:15;37275:49;37267:58;;;;;;37336:14;;;:21;;-1:-1:-1;;37336:21:0;37353:4;37336:21;;;;;;37404:8;;37414:11;;;;37368:58;;31379:42;;37392:10;;-1:-1:-1;;;;;37404:8:0;;37368:17;:58::i;:::-;37437:44;31297:42;37457:10;37469:4;:11;;;37437:13;:44::i;:::-;37492:14;;-1:-1:-1;;;37492:14:0;;;;;10865:25:1;;;37492:5:0;-1:-1:-1;;;;;37492:10:0;;;;10838:18:1;;37492:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;37553:11:0;;37566;;;;37522:60;;;11103:25:1;;;11159:2;11144:18;;11137:34;;;;11187:18;;11180:34;;;37541:10:0;;;;37522:60;;11091:2:1;11076:18;37522:60:0;;;;;;;;37153:437;37119:471;:::o;32883:144::-;32296:3;;-1:-1:-1;;;;;32296:3:0;32282:10;:17;32274:26;;;;;;32945:12:::1;:24:::0;;-1:-1:-1;;;;;;32945:24:0::1;-1:-1:-1::0;;;;;32945:24:0;::::1;;::::0;;32996:23:::1;31725:6;32996:15;:23;:::i;:::-;32980:13;:39:::0;-1:-1:-1;32883:144:0:o;39008:195::-;-1:-1:-1;;;;;39092:14:0;;;;;;:9;:14;;;;;:24;;39110:6;;39092:14;:24;;39110:6;;39092:24;:::i;:::-;;;;-1:-1:-1;;;;;;;39127:14:0;;;;;;:9;:14;;;;;:24;;39145:6;;39127:14;:24;;39145:6;;39127:24;:::i;:::-;;;;;;;;39183:3;-1:-1:-1;;;;;39169:26:0;39178:3;-1:-1:-1;;;;;39169:26:0;;39188:6;39169:26;;;;10865:25:1;;10853:2;10838:18;;10719:177;39169:26:0;;;;;;;;39008:195;;;:::o;37854:256::-;37959:6;37944:11;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;38027:15:0;;;;;;:9;:15;;;;;:25;;38046:6;;38027:15;:25;;38046:6;;38027:25;:::i;:::-;;;;-1:-1:-1;;38068:34:0;;10865:25:1;;;38091:1:0;;-1:-1:-1;;;;;38068:34:0;;;;;10853:2:1;10838:18;38068:34:0;10719:177:1;36746:365:0;36793:4;36810:12;36825;36830:6;36825:4;:12::i;:::-;36810:27;-1:-1:-1;36848:12:0;36863:31;31688:6;36863:15;:31;:::i;:::-;36918:39;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36918:39:0;;;;;;36905:7;:53;;36918:39;36905:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;36905:53:0;;;;;;;;;;36992:9;;36969:33;;-1:-1:-1;;;36969:33:0;;36980:10;36969:33;;;8493:51:1;;;;8560:18;;;8553:34;;;;36918:39:0;;-1:-1:-1;36969:5:0;-1:-1:-1;;;;;36969:10:0;;;;8466:18:1;;36969:33:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;37064:9:0;;37018:56;;;11862:25:1;;;11918:2;11903:18;;11896:34;;;11946:18;;;11939:34;;;12004:2;11989:18;;11982:34;;;;37026:10:0;;37018:56;;11849:3:1;11834:19;37018:56:0;;;;;;;37092:9;:11;;;:9;:11;;;:::i;:::-;;;;-1:-1:-1;37085:18:0;36746:365;-1:-1:-1;;;;36746:365:0:o;34084:734::-;34269:17;34299:12;34327:88;31454:42;34361:53;34384:8;34394:9;34405:8;34361:22;:53::i;:::-;34327:26;:88::i;:::-;34299:116;;34491:15;34509:40;34531:4;34537:11;34509:21;:40::i;:::-;34491:58;;;;34580:230;34633:8;34708:32;34730:9;34708:21;:32::i;:::-;34759:8;34786:9;34580:28;:230::i;:::-;34560:250;34084:734;-1:-1:-1;;;;;;;;34084:734:0:o;39211:289::-;39356:58;;;-1:-1:-1;;;;;8511:32:1;;;39356:58:0;;;8493:51:1;8560:18;;;;8553:34;;;39356:58:0;;;;;;;;;;8466:18:1;;;;39356:58:0;;;;;;;-1:-1:-1;;;;;39356:58:0;-1:-1:-1;;;39356:58:0;;;39345:70;;-1:-1:-1;;;;39345:10:0;;;;:70;;39356:58;39345:70;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39296:119;;;;39434:7;:57;;;;-1:-1:-1;39446:11:0;;:16;;:44;;;39477:4;39466:24;;;;;;;;;;;;:::i;:::-;39426:66;;;;;;39285:215;;39211:289;;;:::o;39508:317::-;39671:68;;;-1:-1:-1;;;;;8197:15:1;;;39671:68:0;;;8179:34:1;8249:15;;;8229:18;;;8222:43;8281:18;;;;8274:34;;;39671:68:0;;;;;;;;;;8114:18:1;;;;39671:68:0;;;;;;;-1:-1:-1;;;;;39671:68:0;-1:-1:-1;;;39671:68:0;;;39660:80;;-1:-1:-1;;;;39660:10:0;;;;:80;;39671:68;39660:80;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39611:129;;;;39759:7;:57;;;;-1:-1:-1;39771:11:0;;:16;;:44;;;39802:4;39791:24;;;;;;;;;;;;:::i;:::-;39751:66;;;;;;39600:225;;39508:317;;;;:::o;37598:248::-;37701:6;37686:11;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;37767:13:0;;;;;;:9;:13;;;;;:23;;37784:6;;37767:13;:23;;37784:6;;37767:23;:::i;:::-;;;;-1:-1:-1;;37806:32:0;;10865:25:1;;;-1:-1:-1;;;;;37806:32:0;;;37823:1;;37806:32;;10853:2:1;10838:18;37806:32:0;10719:177:1;28680:281:0;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;28841:6:0;-1:-1:-1;;;;;28832:15:0;:6;-1:-1:-1;;;;;28832:15:0;;28828:56;;;28869:6;;28877;28828:56;-1:-1:-1;28902:51:0;;;;;;;;-1:-1:-1;;;;;28902:51:0;;;;;;;;;;;;;;;;;;;;;;;28680:281::o;28969:535::-;29053:12;29099:3;:10;;;-1:-1:-1;;;;;29086:23:0;:3;:10;;;-1:-1:-1;;;;;29086:23:0;;29078:32;;;;;;29348:10;;29360;;;;;29372:7;;;;;29337:43;;-1:-1:-1;;;;;7802:15:1;;;29337:43:0;;;7784:34:1;7854:15;;;;7834:18;;;7827:43;7918:8;7906:21;;;7886:18;;;;7879:49;;;;29337:43:0;;;;;;;;;7719:18:1;;;29337:43:0;;;29327:54;;;;;;;-1:-1:-1;;;;;;29216:234:0;;;7116:26:1;7175:15;;;;-1:-1:-1;;7171:53:1;7158:11;;;7151:74;7241:12;;;7234:28;28511:66:0;7278:12:1;;;7271:28;7315:12;;29216:234:0;;;-1:-1:-1;;29216:234:0;;;;;;;;;29184:285;;29216:234;29184:285;;;;;28969:535;-1:-1:-1;;;28969:535:0:o;26259:683::-;26328:29;26378:11;;;26370:26;;;;-1:-1:-1;;;26370:26:0;;10262:2:1;26370:26:0;;;10244:21:1;10301:1;10281:18;;;10274:29;-1:-1:-1;;;10319:18:1;;;10312:32;10361:18;;26370:26:0;;;;;;;;;26438:15;;;26451:1;26438:15;;;;;;;;26409:26;;26438:15;;;;;;;;;;-1:-1:-1;26438:15:0;26409:44;;26480:6;26464:10;26475:1;26464:13;;;;;;;;:::i;:::-;;;;;;:22;;;;;;;;;;;26513:1;26497:10;26508:1;26497:13;;;;;;;;:::i;:::-;:17;;;;:13;;;;;;;;;;;:17;26564:40;;-1:-1:-1;;;26564:40:0;;26528:30;;-1:-1:-1;;;;;26564:28:0;;;;;:40;;26593:10;;26564:40;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;26564:40:0;;;;;;;;;;;;:::i;:::-;26527:77;;;26615:26;26665:15;26681:1;26665:18;;;;;;;;:::i;:::-;;;;;;;26644:15;26660:1;26644:18;;;;;;;;:::i;:::-;;;;;;;:39;;;;:::i;:::-;26615:68;-1:-1:-1;26728:40:0;26755:12;;;26728:40;;;;;:::i;:::-;26696:73;;26855:1;26832:20;:24;;;:75;;;;-1:-1:-1;26861:40:0;26888:12;;;26861:40;;;;;:::i;:::-;:45;;26832:75;26828:106;;;26909:25;;;;:::i;:::-;;;;26828:106;26359:583;;;26259:683;;;;:::o;29538:113::-;29641:1;-1:-1:-1;;;;;29621:21:0;;;;29613:30;;;;;;29538:113;;;:::o;27454:975::-;27615:19;27647:20;27670:33;27698:4;27670:27;:33::i;:::-;27647:56;-1:-1:-1;;;;;;;;;;;27825:33:0;;;27821:601;;27875:17;27895:36;-1:-1:-1;;;;;27895:36:0;;;;:::i;:::-;27875:56;;27972:10;-1:-1:-1;;;;;27960:22:0;:9;-1:-1:-1;;;;;27960:22:0;;:158;;28070:48;-1:-1:-1;;;28096:10:0;-1:-1:-1;;;;;28070:48:0;28108:9;28070:15;:48::i;:::-;27960:158;;;28002:48;28018:9;28029:10;-1:-1:-1;;;;;28002:48:0;-1:-1:-1;;;28002:15:0;:48::i;:::-;27946:172;;27860:270;27821:601;;;28151:17;28171:52;-1:-1:-1;;;;;28171:52:0;;;28215:7;28171:15;:52::i;:::-;28151:72;;28264:10;-1:-1:-1;;;;;28252:22:0;:9;-1:-1:-1;;;;;28252:22:0;;:158;;28362:48;-1:-1:-1;;;28388:10:0;-1:-1:-1;;;;;28362:48:0;28400:9;28362:15;:48::i;:::-;28252:158;;;28294:48;28310:9;28321:10;-1:-1:-1;;;;;28294:48:0;-1:-1:-1;;;28294:15:0;:48::i;:::-;28238:172;;28136:286;27821:601;27636:793;27454:975;;;;;;:::o;23221:2317::-;23284:20;23317:15;23342:1;23335:4;:8;;;:57;;23386:4;23379:12;;23335:57;;;23362:4;23355:12;;23354:13;;;:::i;:::-;23317:75;-1:-1:-1;23203:9:0;-1:-1:-1;;23203:9:0;:::i;:::-;23430:16;;23411:7;:36;;23403:50;;;;-1:-1:-1;;;23403:50:0;;10592:2:1;23403:50:0;;;10574:21:1;10631:1;10611:18;;;10604:29;-1:-1:-1;;;10649:18:1;;;10642:31;10690:18;;23403:50:0;10390:324:1;23403:50:0;23466:13;23492:3;23482:13;;:93;;-1:-1:-1;;;23482:93:0;;;23503:34;23482:93;23466:109;;;-1:-1:-1;23600:3:0;23590:13;;:18;23586:83;;23666:3;23619:42;:5;23627:34;23619:42;:::i;:::-;23618:51;;23610:59;;23586:83;23694:3;23684:13;;:18;23680:83;;23760:3;23713:42;:5;23721:34;23713:42;:::i;:::-;23712:51;;23704:59;;23680:83;23788:3;23778:13;;:18;23774:83;;23854:3;23807:42;:5;23815:34;23807:42;:::i;:::-;23806:51;;23798:59;;23774:83;23882:4;23872:14;;:19;23868:84;;23949:3;23902:42;:5;23910:34;23902:42;:::i;:::-;23901:51;;23893:59;;23868:84;23977:4;23967:14;;:19;23963:84;;24044:3;23997:42;:5;24005:34;23997:42;:::i;:::-;23996:51;;23988:59;;23963:84;24072:4;24062:14;;:19;24058:84;;24139:3;24092:42;:5;24100:34;24092:42;:::i;:::-;24091:51;;24083:59;;24058:84;24167:4;24157:14;;:19;24153:84;;24234:3;24187:42;:5;24195:34;24187:42;:::i;:::-;24186:51;;24178:59;;24153:84;24262:5;24252:15;;:20;24248:85;;24330:3;24283:42;:5;24291:34;24283:42;:::i;:::-;24282:51;;24274:59;;24248:85;24358:5;24348:15;;:20;24344:85;;24426:3;24379:42;:5;24387:34;24379:42;:::i;:::-;24378:51;;24370:59;;24344:85;24454:5;24444:15;;:20;24440:85;;24522:3;24475:42;:5;24483:34;24475:42;:::i;:::-;24474:51;;24466:59;;24440:85;24550:5;24540:15;;:20;24536:85;;24618:3;24571:42;:5;24579:34;24571:42;:::i;:::-;24570:51;;24562:59;;24536:85;24646:6;24636:16;;:21;24632:86;;24715:3;24668:42;:5;24676:34;24668:42;:::i;:::-;24667:51;;24659:59;;24632:86;24743:6;24733:16;;:21;24729:86;;24812:3;24765:42;:5;24773:34;24765:42;:::i;:::-;24764:51;;24756:59;;24729:86;24840:6;24830:16;;:21;24826:86;;24909:3;24862:42;:5;24870:34;24862:42;:::i;:::-;24861:51;;24853:59;;24826:86;24937:6;24927:16;;:21;24923:86;;25006:3;24959:42;:5;24967:34;24959:42;:::i;:::-;24958:51;;24950:59;;24923:86;25034:7;25024:17;;:22;25020:86;;25103:3;25057:41;:5;25065:33;25057:41;:::i;:::-;25056:50;;25048:58;;25020:86;25131:7;25121:17;;:22;25117:85;;25199:3;25154:40;:5;25162:32;25154:40;:::i;:::-;25153:49;;25145:57;;25117:85;25227:7;25217:17;;:22;25213:83;;25293:3;25250:38;:5;25258:30;25250:38;:::i;:::-;25249:47;;25241:55;;25213:83;25321:7;25311:17;;:22;25307:78;;25382:3;25344:33;:5;25352:25;25344:33;:::i;:::-;25343:42;;25335:50;;25307:78;25409:1;25402:4;:8;;;25398:47;;;25420:25;25440:5;-1:-1:-1;;25420:25:0;:::i;:::-;25412:33;;25398:47;25498:17;25507:7;25498:5;:17;:::i;:::-;:22;:30;;25527:1;25498:30;;;25523:1;25498:30;25481:48;;;;25491:2;25482:11;;;25481:48;:::i;21311:1777::-;21427:14;;;-1:-1:-1;;21635:1:0;21632;21625:20;21675:1;21672;21668:9;21659:18;;21727:5;21723:2;21720:13;21712:5;21708:2;21704:14;21700:34;21691:43;;;21761:5;21770:1;21761:10;21757:185;;;21810:1;21796:11;:15;21788:24;;;;;;-1:-1:-1;21865:23:0;;;;-1:-1:-1;21917:13:0;;21757:185;21976:5;21962:11;:19;21954:28;;;;;;21995:17;22073:11;22070:1;22067;22060:25;22194:21;;;;22150:20;;22139:32;;;;22047:38;-1:-1:-1;22265:11:0;22236:19;22265:11;22311:13;22265:11;22311:13;:::i;:::-;:28;22390:22;;;;;22468:16;;;;;22551:1;22547:12;;;22543:23;22568:1;22539:31;;-1:-1:-1;22600:12:0;22539:31;22600:5;:12;:::i;:::-;22591:21;;;;22625:11;22640:15;22644:11;22640:1;:15;:::i;:::-;22659:1;22639:21;;-1:-1:-1;22684:17:0;22639:21;22684:11;:17;:::i;:::-;22680:21;;:1;:21;:::i;:::-;22673:28;;;;:::i;:::-;;-1:-1:-1;22743:17:0;22673:28;22743:11;:17;:::i;:::-;22739:21;;:1;:21;:::i;:::-;22732:28;;;;:::i;:::-;;-1:-1:-1;22803:17:0;22732:28;22803:11;:17;:::i;:::-;22799:21;;:1;:21;:::i;:::-;22792:28;;;;:::i;:::-;;-1:-1:-1;22863:17:0;22792:28;22863:11;:17;:::i;:::-;22859:21;;:1;:21;:::i;:::-;22852:28;;;;:::i;:::-;;-1:-1:-1;22923:17:0;22852:28;22923:11;:17;:::i;:::-;22919:21;;:1;:21;:::i;:::-;22912:28;;;;:::i;:::-;;-1:-1:-1;22984:17:0;22912:28;22984:11;:17;:::i;:::-;22980:21;;:1;:21;:::i;:::-;22973:28;;;;:::i;:::-;;-1:-1:-1;23045:11:0;22973:28;23045:5;:11;:::i;:::-;23036:20;21311:1777;-1:-1:-1;;;;;;;;;;21311:1777:0:o;14:743:1:-;79:5;132:3;125:4;117:6;113:17;109:27;99:55;;150:1;147;140:12;99:55;179:6;173:13;205:4;229:58;245:41;283:2;245:41;:::i;:::-;229:58;:::i;:::-;309:3;333:2;328:3;321:15;361:2;356:3;352:12;345:19;;396:2;388:6;384:15;448:3;443:2;437;434:1;430:10;422:6;418:23;414:32;411:41;408:61;;;465:1;462;455:12;408:61;487:1;497:231;511:2;508:1;505:9;497:231;;;575:3;569:10;592:31;617:5;592:31;:::i;:::-;636:18;;674:12;;;;706;;;;529:1;522:9;497:231;;;-1:-1:-1;746:5:1;;14:743;-1:-1:-1;;;;;;;14:743:1:o;762:163::-;829:20;;889:10;878:22;;868:33;;858:61;;915:1;912;905:12;930:247;989:6;1042:2;1030:9;1021:7;1017:23;1013:32;1010:52;;;1058:1;1055;1048:12;1010:52;1097:9;1084:23;1116:31;1141:5;1116:31;:::i;1182:251::-;1252:6;1305:2;1293:9;1284:7;1280:23;1276:32;1273:52;;;1321:1;1318;1311:12;1273:52;1353:9;1347:16;1372:31;1397:5;1372:31;:::i;1438:388::-;1506:6;1514;1567:2;1555:9;1546:7;1542:23;1538:32;1535:52;;;1583:1;1580;1573:12;1535:52;1622:9;1609:23;1641:31;1666:5;1641:31;:::i;:::-;1691:5;-1:-1:-1;1748:2:1;1733:18;;1720:32;1761:33;1720:32;1761:33;:::i;:::-;1813:7;1803:17;;;1438:388;;;;;:::o;1831:456::-;1908:6;1916;1924;1977:2;1965:9;1956:7;1952:23;1948:32;1945:52;;;1993:1;1990;1983:12;1945:52;2032:9;2019:23;2051:31;2076:5;2051:31;:::i;:::-;2101:5;-1:-1:-1;2158:2:1;2143:18;;2130:32;2171:33;2130:32;2171:33;:::i;:::-;1831:456;;2223:7;;-1:-1:-1;;;2277:2:1;2262:18;;;;2249:32;;1831:456::o;2292:315::-;2360:6;2368;2421:2;2409:9;2400:7;2396:23;2392:32;2389:52;;;2437:1;2434;2427:12;2389:52;2476:9;2463:23;2495:31;2520:5;2495:31;:::i;:::-;2545:5;2597:2;2582:18;;;;2569:32;;-1:-1:-1;;;2292:315:1:o;2612:529::-;2697:6;2705;2713;2721;2774:3;2762:9;2753:7;2749:23;2745:33;2742:53;;;2791:1;2788;2781:12;2742:53;2830:9;2817:23;2849:31;2874:5;2849:31;:::i;:::-;2899:5;-1:-1:-1;2951:2:1;2936:18;;2923:32;;-1:-1:-1;3007:2:1;2992:18;;2979:32;3020:33;2979:32;3020:33;:::i;:::-;3072:7;-1:-1:-1;3098:37:1;3131:2;3116:18;;3098:37;:::i;:::-;3088:47;;2612:529;;;;;;;:::o;3146:387::-;3222:6;3230;3238;3291:2;3279:9;3270:7;3266:23;3262:32;3259:52;;;3307:1;3304;3297:12;3259:52;3346:9;3333:23;3365:31;3390:5;3365:31;:::i;:::-;3415:5;-1:-1:-1;3467:2:1;3452:18;;3439:32;;-1:-1:-1;3490:37:1;3523:2;3508:18;;3490:37;:::i;:::-;3480:47;;3146:387;;;;;:::o;3538:1244::-;3665:6;3673;3726:2;3714:9;3705:7;3701:23;3697:32;3694:52;;;3742:1;3739;3732:12;3694:52;3775:9;3769:16;3804:18;3845:2;3837:6;3834:14;3831:34;;;3861:1;3858;3851:12;3831:34;3899:6;3888:9;3884:22;3874:32;;3944:7;3937:4;3933:2;3929:13;3925:27;3915:55;;3966:1;3963;3956:12;3915:55;3995:2;3989:9;4017:4;4041:58;4057:41;4095:2;4057:41;:::i;4041:58::-;4121:3;4145:2;4140:3;4133:15;4173:2;4168:3;4164:12;4157:19;;4204:2;4200;4196:11;4252:7;4247:2;4241;4238:1;4234:10;4230:2;4226:19;4222:28;4219:41;4216:61;;;4273:1;4270;4263:12;4216:61;4295:1;4286:10;;4305:259;4319:2;4316:1;4313:9;4305:259;;;4383:3;4377:10;4434:5;4431:1;4420:20;4413:5;4410:31;4400:59;;4455:1;4452;4445:12;4400:59;4472:18;;4337:1;4330:9;;;;;4510:12;;;;4542;;4305:259;;;-1:-1:-1;4619:18:1;;;4613:25;4583:5;;-1:-1:-1;4613:25:1;;-1:-1:-1;;;4650:16:1;;;4647:36;;;4679:1;4676;4669:12;4647:36;;4702:74;4768:7;4757:8;4746:9;4742:24;4702:74;:::i;:::-;4692:84;;;3538:1244;;;;;:::o;4787:900::-;4871:6;4902:2;4945;4933:9;4924:7;4920:23;4916:32;4913:52;;;4961:1;4958;4951:12;4913:52;5001:9;4988:23;5034:18;5026:6;5023:30;5020:50;;;5066:1;5063;5056:12;5020:50;5089:22;;5142:4;5134:13;;5130:27;-1:-1:-1;5120:55:1;;5171:1;5168;5161:12;5120:55;5207:2;5194:16;5230:58;5246:41;5284:2;5246:41;:::i;5230:58::-;5310:3;5334:2;5329:3;5322:15;5362:2;5357:3;5353:12;5346:19;;5393:2;5389;5385:11;5441:7;5436:2;5430;5427:1;5423:10;5419:2;5415:19;5411:28;5408:41;5405:61;;;5462:1;5459;5452:12;5405:61;5484:1;5475:10;;5494:163;5508:2;5505:1;5502:9;5494:163;;;5565:17;;5553:30;;5526:1;5519:9;;;;;5603:12;;;;5635;;5494:163;;;-1:-1:-1;5676:5:1;4787:900;-1:-1:-1;;;;;;;4787:900:1:o;5692:277::-;5759:6;5812:2;5800:9;5791:7;5787:23;5783:32;5780:52;;;5828:1;5825;5818:12;5780:52;5860:9;5854:16;5913:5;5906:13;5899:21;5892:5;5889:32;5879:60;;5935:1;5932;5925:12;5974:180;6033:6;6086:2;6074:9;6065:7;6061:23;6057:32;6054:52;;;6102:1;6099;6092:12;6054:52;-1:-1:-1;6125:23:1;;5974:180;-1:-1:-1;5974:180:1:o;6159:387::-;6235:6;6243;6251;6304:2;6292:9;6283:7;6279:23;6275:32;6272:52;;;6320:1;6317;6310:12;6272:52;6356:9;6343:23;6333:33;;6416:2;6405:9;6401:18;6388:32;6429:31;6454:5;6429:31;:::i;:::-;6479:5;-1:-1:-1;6503:37:1;6536:2;6521:18;;6503:37;:::i;6551:274::-;6680:3;6718:6;6712:13;6734:53;6780:6;6775:3;6768:4;6760:6;6756:17;6734:53;:::i;:::-;6803:16;;;;;6551:274;-1:-1:-1;;6551:274:1:o;8598:647::-;8767:2;8819:21;;;8889:13;;8792:18;;;8911:22;;;8738:4;;8767:2;8990:15;;;;8964:2;8949:18;;;8738:4;9033:186;9047:6;9044:1;9041:13;9033:186;;;9112:13;;9127:10;9108:30;9096:43;;9194:15;;;;9159:12;;;;9069:1;9062:9;9033:186;;;-1:-1:-1;9236:3:1;;8598:647;-1:-1:-1;;;;;;8598:647:1:o;9672:383::-;9821:2;9810:9;9803:21;9784:4;9853:6;9847:13;9896:6;9891:2;9880:9;9876:18;9869:34;9912:66;9971:6;9966:2;9955:9;9951:18;9946:2;9938:6;9934:15;9912:66;:::i;:::-;10039:2;10018:15;-1:-1:-1;;10014:29:1;9999:45;;;;10046:2;9995:54;;9672:383;-1:-1:-1;;9672:383:1:o;12216:275::-;12287:2;12281:9;12352:2;12333:13;;-1:-1:-1;;12329:27:1;12317:40;;12387:18;12372:34;;12408:22;;;12369:62;12366:88;;;12434:18;;:::i;:::-;12470:2;12463:22;12216:275;;-1:-1:-1;12216:275:1:o;12496:181::-;12554:4;12587:18;12579:6;12576:30;12573:56;;;12609:18;;:::i;:::-;-1:-1:-1;12654:1:1;12650:14;12666:4;12646:25;;12496:181::o;12682:128::-;12722:3;12753:1;12749:6;12746:1;12743:13;12740:39;;;12759:18;;:::i;:::-;-1:-1:-1;12795:9:1;;12682:128::o;12815:193::-;12854:1;12880;12870:35;;12885:18;;:::i;:::-;-1:-1:-1;;;12921:18:1;;-1:-1:-1;;12941:13:1;;12917:38;12914:64;;;12958:18;;:::i;:::-;-1:-1:-1;12992:10:1;;12815:193::o;13013:120::-;13053:1;13079;13069:35;;13084:18;;:::i;:::-;-1:-1:-1;13118:9:1;;13013:120::o;13138:168::-;13178:7;13244:1;13240;13236:6;13232:14;13229:1;13226:21;13221:1;13214:9;13207:17;13203:45;13200:71;;;13251:18;;:::i;:::-;-1:-1:-1;13291:9:1;;13138:168::o;13311:359::-;13349:4;13393:1;13390;13379:16;13429:1;13426;13415:16;13459:1;13454:3;13450:11;13525:3;13506:16;13502:21;13498:31;13493:3;13489:41;13484:2;13477:10;13473:58;13470:84;;;13534:18;;:::i;:::-;13605:3;13587:16;13583:26;13578:3;13574:36;13570:2;13566:45;13563:71;;;13614:18;;:::i;:::-;-1:-1:-1;13651:13:1;;;13311:359;-1:-1:-1;;;13311:359:1:o;13675:125::-;13715:4;13743:1;13740;13737:8;13734:34;;;13748:18;;:::i;:::-;-1:-1:-1;13785:9:1;;13675:125::o;13805:258::-;13877:1;13887:113;13901:6;13898:1;13895:13;13887:113;;;13977:11;;;13971:18;13958:11;;;13951:39;13923:2;13916:10;13887:113;;;14018:6;14015:1;14012:13;14009:48;;;14053:1;14044:6;14039:3;14035:16;14028:27;14009:48;;13805:258;;;:::o;14068:192::-;14105:3;14152:5;14149:1;14138:20;14186:7;14182:12;14173:7;14170:25;14167:51;;;14198:18;;:::i;:::-;-1:-1:-1;;14234:20:1;;14068:192;-1:-1:-1;;14068:192:1:o;14265:135::-;14304:3;-1:-1:-1;;14325:17:1;;14322:43;;;14345:18;;:::i;:::-;-1:-1:-1;14392:1:1;14381:13;;14265:135::o;14405:112::-;14436:1;14462;14452:35;;14467:18;;:::i;:::-;-1:-1:-1;14501:10:1;;14405:112::o;14522:::-;14554:1;14580;14570:35;;14585:18;;:::i;:::-;-1:-1:-1;14619:9:1;;14522:112::o;14639:184::-;14673:3;14720:5;14717:1;14706:20;14754:7;14750:12;14741:7;14738:25;14735:51;;;14766:18;;:::i;:::-;14806:1;14802:15;;14639:184;-1:-1:-1;;14639:184:1:o;14828:136::-;14863:3;-1:-1:-1;;;14884:22:1;;14881:48;;;14909:18;;:::i;:::-;-1:-1:-1;14949:1:1;14945:13;;14828:136::o;14969:127::-;15030:10;15025:3;15021:20;15018:1;15011:31;15061:4;15058:1;15051:15;15085:4;15082:1;15075:15;15101:127;15162:10;15157:3;15153:20;15150:1;15143:31;15193:4;15190:1;15183:15;15217:4;15214:1;15207:15;15233:127;15294:10;15289:3;15285:20;15282:1;15275:31;15325:4;15322:1;15315:15;15349:4;15346:1;15339:15;15365:127;15426:10;15421:3;15417:20;15414:1;15407:31;15457:4;15454:1;15447:15;15481:4;15478:1;15471:15;15497:131;-1:-1:-1;;;;;15572:31:1;;15562:42;;15552:70;;15618:1;15615;15608:12;15552:70;15497:131;:::o

Swarm Source

ipfs://377eb001f223e1fcaa8a9f3f493f41c06118872dfc6c2f891c73471e4b2c7fac
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.