ETH Price: $3,885.14 (+6.02%)

Token

FLUX (FLUX)
 

Overview

Max Total Supply

3,733,739.484716359072317565 FLUX

Holders

847 (0.00%)

Market

Price

$0.05 @ 0.000014 ETH (+2.42%)

Onchain Market Cap

$203,962.99

Circulating Supply Market Cap

$203,962.00

Other Info

Token Contract (WITH 18 Decimals)

Balance
0.000042319479901289 FLUX

Value
$0.00 ( ~0 Eth) [0.0000%]
0x9d16648c1f595006baf93c74584a92d8b32bbd43
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Datamine Network is a new non-custodial and decentralized open-source economic system that uses smart contracts to create Adaptive Money. Our deflationary DeFi protocol generates FLUX tokens every 15 seconds.

# Exchange Pair Price  24H Volume % Volume
1
Sushiswap (Arbitrum One)
0XF80D589B3DBE130C270A69F1A69D050F268786DF-0X82AF49447D8A07E3BD95BD0D56F35241523FBAB1$0.0553
0.0000142 Eth
$559.23
10,000.000 0XF80D589B3DBE130C270A69F1A69D050F268786DF
93.1917%
2
Uniswap V3 (Ethereum)
0X469EDA64AED3A3AD6F868C44564291AA415CB1D9-0XC02AAA39B223FE8D0A0E5C4F27EAD9083C756CC2$0.0565
0.0000146 Eth
$41.30
730.569 0X469EDA64AED3A3AD6F868C44564291AA415CB1D9
6.8083%

Contract Source Code Verified (Exact Match)

Contract Name:
FluxToken

Compiler Version
v0.6.9+commit.3e3065ac

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license, Audited

Contract Source Code (Solidity)Audit Report

/**
 *Submitted for verification at Etherscan.io on 2020-06-08
*/

// File: @openzeppelin/contracts/GSN/Context.sol

pragma solidity ^0.6.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
contract Context {
    // Empty internal constructor, to prevent people from mistakenly deploying
    // an instance of this contract, which should be used via inheritance.
    constructor () internal { }

    function _msgSender() internal view virtual returns (address payable) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

// File: @openzeppelin/contracts/token/ERC777/IERC777.sol

pragma solidity ^0.6.0;

/**
 * @dev Interface of the ERC777Token standard as defined in the EIP.
 *
 * This contract uses the
 * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let
 * token holders and recipients react to token movements by using setting implementers
 * for the associated interfaces in said registry. See {IERC1820Registry} and
 * {ERC1820Implementer}.
 */
interface IERC777 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the smallest part of the token that is not divisible. This
     * means all token operations (creation, movement and destruction) must have
     * amounts that are a multiple of this number.
     *
     * For most token contracts, this value will equal 1.
     */
    function granularity() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * If send or receive hooks are registered for the caller and `recipient`,
     * the corresponding functions will be called with `data` and empty
     * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.
     *
     * Emits a {Sent} event.
     *
     * Requirements
     *
     * - the caller must have at least `amount` tokens.
     * - `recipient` cannot be the zero address.
     * - if `recipient` is a contract, it must implement the {IERC777Recipient}
     * interface.
     */
    function send(address recipient, uint256 amount, bytes calldata data) external;

    /**
     * @dev Destroys `amount` tokens from the caller's account, reducing the
     * total supply.
     *
     * If a send hook is registered for the caller, the corresponding function
     * will be called with `data` and empty `operatorData`. See {IERC777Sender}.
     *
     * Emits a {Burned} event.
     *
     * Requirements
     *
     * - the caller must have at least `amount` tokens.
     */
    function burn(uint256 amount, bytes calldata data) external;

    /**
     * @dev Returns true if an account is an operator of `tokenHolder`.
     * Operators can send and burn tokens on behalf of their owners. All
     * accounts are their own operator.
     *
     * See {operatorSend} and {operatorBurn}.
     */
    function isOperatorFor(address operator, address tokenHolder) external view returns (bool);

    /**
     * @dev Make an account an operator of the caller.
     *
     * See {isOperatorFor}.
     *
     * Emits an {AuthorizedOperator} event.
     *
     * Requirements
     *
     * - `operator` cannot be calling address.
     */
    function authorizeOperator(address operator) external;

    /**
     * @dev Revoke an account's operator status for the caller.
     *
     * See {isOperatorFor} and {defaultOperators}.
     *
     * Emits a {RevokedOperator} event.
     *
     * Requirements
     *
     * - `operator` cannot be calling address.
     */
    function revokeOperator(address operator) external;

    /**
     * @dev Returns the list of default operators. These accounts are operators
     * for all token holders, even if {authorizeOperator} was never called on
     * them.
     *
     * This list is immutable, but individual holders may revoke these via
     * {revokeOperator}, in which case {isOperatorFor} will return false.
     */
    function defaultOperators() external view returns (address[] memory);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must
     * be an operator of `sender`.
     *
     * If send or receive hooks are registered for `sender` and `recipient`,
     * the corresponding functions will be called with `data` and
     * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.
     *
     * Emits a {Sent} event.
     *
     * Requirements
     *
     * - `sender` cannot be the zero address.
     * - `sender` must have at least `amount` tokens.
     * - the caller must be an operator for `sender`.
     * - `recipient` cannot be the zero address.
     * - if `recipient` is a contract, it must implement the {IERC777Recipient}
     * interface.
     */
    function operatorSend(
        address sender,
        address recipient,
        uint256 amount,
        bytes calldata data,
        bytes calldata operatorData
    ) external;

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the total supply.
     * The caller must be an operator of `account`.
     *
     * If a send hook is registered for `account`, the corresponding function
     * will be called with `data` and `operatorData`. See {IERC777Sender}.
     *
     * Emits a {Burned} event.
     *
     * Requirements
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     * - the caller must be an operator for `account`.
     */
    function operatorBurn(
        address account,
        uint256 amount,
        bytes calldata data,
        bytes calldata operatorData
    ) external;

    event Sent(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256 amount,
        bytes data,
        bytes operatorData
    );

    event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);

    event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);

    event AuthorizedOperator(address indexed operator, address indexed tokenHolder);

    event RevokedOperator(address indexed operator, address indexed tokenHolder);
}

// File: @openzeppelin/contracts/token/ERC777/IERC777Recipient.sol

pragma solidity ^0.6.0;

/**
 * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP.
 *
 * Accounts can be notified of {IERC777} tokens being sent to them by having a
 * contract implement this interface (contract holders can be their own
 * implementer) and registering it on the
 * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].
 *
 * See {IERC1820Registry} and {ERC1820Implementer}.
 */
interface IERC777Recipient {
    /**
     * @dev Called by an {IERC777} token contract whenever tokens are being
     * moved or created into a registered account (`to`). The type of operation
     * is conveyed by `from` being the zero address or not.
     *
     * This call occurs _after_ the token contract's state is updated, so
     * {IERC777-balanceOf}, etc., can be used to query the post-operation state.
     *
     * This function may revert to prevent the operation from being executed.
     */
    function tokensReceived(
        address operator,
        address from,
        address to,
        uint256 amount,
        bytes calldata userData,
        bytes calldata operatorData
    ) external;
}

// File: @openzeppelin/contracts/token/ERC777/IERC777Sender.sol

pragma solidity ^0.6.0;

/**
 * @dev Interface of the ERC777TokensSender standard as defined in the EIP.
 *
 * {IERC777} Token holders can be notified of operations performed on their
 * tokens by having a contract implement this interface (contract holders can be
 *  their own implementer) and registering it on the
 * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry].
 *
 * See {IERC1820Registry} and {ERC1820Implementer}.
 */
interface IERC777Sender {
    /**
     * @dev Called by an {IERC777} token contract whenever a registered holder's
     * (`from`) tokens are about to be moved or destroyed. The type of operation
     * is conveyed by `to` being the zero address or not.
     *
     * This call occurs _before_ the token contract's state is updated, so
     * {IERC777-balanceOf}, etc., can be used to query the pre-operation state.
     *
     * This function may revert to prevent the operation from being executed.
     */
    function tokensToSend(
        address operator,
        address from,
        address to,
        uint256 amount,
        bytes calldata userData,
        bytes calldata operatorData
    ) external;
}

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol

pragma solidity ^0.6.0;

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

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

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

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

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

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

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

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

// File: @openzeppelin/contracts/math/SafeMath.sol

pragma solidity ^0.6.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

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

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

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

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

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

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

// File: @openzeppelin/contracts/utils/Address.sol

pragma solidity ^0.6.2;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
        // for accounts without code, i.e. `keccak256('')`
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        // solhint-disable-next-line no-inline-assembly
        assembly { codehash := extcodehash(account) }
        return (codehash != accountHash && codehash != 0x0);
    }

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

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }
}

// File: @openzeppelin/contracts/introspection/IERC1820Registry.sol

pragma solidity ^0.6.0;

/**
 * @dev Interface of the global ERC1820 Registry, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register
 * implementers for interfaces in this registry, as well as query support.
 *
 * Implementers may be shared by multiple accounts, and can also implement more
 * than a single interface for each account. Contracts can implement interfaces
 * for themselves, but externally-owned accounts (EOA) must delegate this to a
 * contract.
 *
 * {IERC165} interfaces can also be queried via the registry.
 *
 * For an in-depth explanation and source code analysis, see the EIP text.
 */
interface IERC1820Registry {
    /**
     * @dev Sets `newManager` as the manager for `account`. A manager of an
     * account is able to set interface implementers for it.
     *
     * By default, each account is its own manager. Passing a value of `0x0` in
     * `newManager` will reset the manager to this initial state.
     *
     * Emits a {ManagerChanged} event.
     *
     * Requirements:
     *
     * - the caller must be the current manager for `account`.
     */
    function setManager(address account, address newManager) external;

    /**
     * @dev Returns the manager for `account`.
     *
     * See {setManager}.
     */
    function getManager(address account) external view returns (address);

    /**
     * @dev Sets the `implementer` contract as ``account``'s implementer for
     * `interfaceHash`.
     *
     * `account` being the zero address is an alias for the caller's address.
     * The zero address can also be used in `implementer` to remove an old one.
     *
     * See {interfaceHash} to learn how these are created.
     *
     * Emits an {InterfaceImplementerSet} event.
     *
     * Requirements:
     *
     * - the caller must be the current manager for `account`.
     * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not
     * end in 28 zeroes).
     * - `implementer` must implement {IERC1820Implementer} and return true when
     * queried for support, unless `implementer` is the caller. See
     * {IERC1820Implementer-canImplementInterfaceForAddress}.
     */
    function setInterfaceImplementer(address account, bytes32 interfaceHash, address implementer) external;

    /**
     * @dev Returns the implementer of `interfaceHash` for `account`. If no such
     * implementer is registered, returns the zero address.
     *
     * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28
     * zeroes), `account` will be queried for support of it.
     *
     * `account` being the zero address is an alias for the caller's address.
     */
    function getInterfaceImplementer(address account, bytes32 interfaceHash) external view returns (address);

    /**
     * @dev Returns the interface hash for an `interfaceName`, as defined in the
     * corresponding
     * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP].
     */
    function interfaceHash(string calldata interfaceName) external pure returns (bytes32);

    /**
     *  @notice Updates the cache with whether the contract implements an ERC165 interface or not.
     *  @param account Address of the contract for which to update the cache.
     *  @param interfaceId ERC165 interface for which to update the cache.
     */
    function updateERC165Cache(address account, bytes4 interfaceId) external;

    /**
     *  @notice Checks whether a contract implements an ERC165 interface or not.
     *  If the result is not cached a direct lookup on the contract address is performed.
     *  If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling
     *  {updateERC165Cache} with the contract address.
     *  @param account Address of the contract to check.
     *  @param interfaceId ERC165 interface to check.
     *  @return True if `account` implements `interfaceId`, false otherwise.
     */
    function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool);

    /**
     *  @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache.
     *  @param account Address of the contract to check.
     *  @param interfaceId ERC165 interface to check.
     *  @return True if `account` implements `interfaceId`, false otherwise.
     */
    function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool);

    event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer);

    event ManagerChanged(address indexed account, address indexed newManager);
}

// File: @openzeppelin/contracts/token/ERC777/ERC777.sol

pragma solidity ^0.6.0;









/**
 * @dev Implementation of the {IERC777} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 *
 * Support for ERC20 is included in this contract, as specified by the EIP: both
 * the ERC777 and ERC20 interfaces can be safely used when interacting with it.
 * Both {IERC777-Sent} and {IERC20-Transfer} events are emitted on token
 * movements.
 *
 * Additionally, the {IERC777-granularity} value is hard-coded to `1`, meaning that there
 * are no special restrictions in the amount of tokens that created, moved, or
 * destroyed. This makes integration with ERC20 applications seamless.
 */
contract ERC777 is Context, IERC777, IERC20 {
    using SafeMath for uint256;
    using Address for address;

    IERC1820Registry constant internal _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);

    mapping(address => uint256) private _balances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    // We inline the result of the following hashes because Solidity doesn't resolve them at compile time.
    // See https://github.com/ethereum/solidity/issues/4024.

    // keccak256("ERC777TokensSender")
    bytes32 constant private _TOKENS_SENDER_INTERFACE_HASH =
        0x29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe895;

    // keccak256("ERC777TokensRecipient")
    bytes32 constant private _TOKENS_RECIPIENT_INTERFACE_HASH =
        0xb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b;

    // This isn't ever read from - it's only used to respond to the defaultOperators query.
    address[] private _defaultOperatorsArray;

    // Immutable, but accounts may revoke them (tracked in __revokedDefaultOperators).
    mapping(address => bool) private _defaultOperators;

    // For each account, a mapping of its operators and revoked default operators.
    mapping(address => mapping(address => bool)) private _operators;
    mapping(address => mapping(address => bool)) private _revokedDefaultOperators;

    // ERC20-allowances
    mapping (address => mapping (address => uint256)) private _allowances;

    /**
     * @dev `defaultOperators` may be an empty array.
     */
    constructor(
        string memory name,
        string memory symbol,
        address[] memory defaultOperators
    ) public {
        _name = name;
        _symbol = symbol;

        _defaultOperatorsArray = defaultOperators;
        for (uint256 i = 0; i < _defaultOperatorsArray.length; i++) {
            _defaultOperators[_defaultOperatorsArray[i]] = true;
        }

        // register interfaces
        _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC777Token"), address(this));
        _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC20Token"), address(this));
    }

    /**
     * @dev See {IERC777-name}.
     */
    function name() public view override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC777-symbol}.
     */
    function symbol() public view override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {ERC20-decimals}.
     *
     * Always returns 18, as per the
     * [ERC777 EIP](https://eips.ethereum.org/EIPS/eip-777#backward-compatibility).
     */
    function decimals() public pure returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC777-granularity}.
     *
     * This implementation always returns `1`.
     */
    function granularity() public view override returns (uint256) {
        return 1;
    }

    /**
     * @dev See {IERC777-totalSupply}.
     */
    function totalSupply() public view override(IERC20, IERC777) returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev Returns the amount of tokens owned by an account (`tokenHolder`).
     */
    function balanceOf(address tokenHolder) public view override(IERC20, IERC777) returns (uint256) {
        return _balances[tokenHolder];
    }

    /**
     * @dev See {IERC777-send}.
     *
     * Also emits a {IERC20-Transfer} event for ERC20 compatibility.
     */
    function send(address recipient, uint256 amount, bytes memory data) public override  {
        _send(_msgSender(), recipient, amount, data, "", true);
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Unlike `send`, `recipient` is _not_ required to implement the {IERC777Recipient}
     * interface if it is a contract.
     *
     * Also emits a {Sent} event.
     */
    function transfer(address recipient, uint256 amount) public override returns (bool) {
        require(recipient != address(0), "ERC777: transfer to the zero address");

        address from = _msgSender();

        _callTokensToSend(from, from, recipient, amount, "", "");

        _move(from, from, recipient, amount, "", "");

        _callTokensReceived(from, from, recipient, amount, "", "", false);

        return true;
    }

    /**
     * @dev See {IERC777-burn}.
     *
     * Also emits a {IERC20-Transfer} event for ERC20 compatibility.
     */
    function burn(uint256 amount, bytes memory data) public override  {
        _burn(_msgSender(), amount, data, "");
    }

    /**
     * @dev See {IERC777-isOperatorFor}.
     */
    function isOperatorFor(
        address operator,
        address tokenHolder
    ) public view override returns (bool) {
        return operator == tokenHolder ||
            (_defaultOperators[operator] && !_revokedDefaultOperators[tokenHolder][operator]) ||
            _operators[tokenHolder][operator];
    }

    /**
     * @dev See {IERC777-authorizeOperator}.
     */
    function authorizeOperator(address operator) public override  {
        require(_msgSender() != operator, "ERC777: authorizing self as operator");

        if (_defaultOperators[operator]) {
            delete _revokedDefaultOperators[_msgSender()][operator];
        } else {
            _operators[_msgSender()][operator] = true;
        }

        emit AuthorizedOperator(operator, _msgSender());
    }

    /**
     * @dev See {IERC777-revokeOperator}.
     */
    function revokeOperator(address operator) public override  {
        require(operator != _msgSender(), "ERC777: revoking self as operator");

        if (_defaultOperators[operator]) {
            _revokedDefaultOperators[_msgSender()][operator] = true;
        } else {
            delete _operators[_msgSender()][operator];
        }

        emit RevokedOperator(operator, _msgSender());
    }

    /**
     * @dev See {IERC777-defaultOperators}.
     */
    function defaultOperators() public view override returns (address[] memory) {
        return _defaultOperatorsArray;
    }

    /**
     * @dev See {IERC777-operatorSend}.
     *
     * Emits {Sent} and {IERC20-Transfer} events.
     */
    function operatorSend(
        address sender,
        address recipient,
        uint256 amount,
        bytes memory data,
        bytes memory operatorData
    )
    public override
    {
        require(isOperatorFor(_msgSender(), sender), "ERC777: caller is not an operator for holder");
        _send(sender, recipient, amount, data, operatorData, true);
    }

    /**
     * @dev See {IERC777-operatorBurn}.
     *
     * Emits {Burned} and {IERC20-Transfer} events.
     */
    function operatorBurn(address account, uint256 amount, bytes memory data, bytes memory operatorData) public override {
        require(isOperatorFor(_msgSender(), account), "ERC777: caller is not an operator for holder");
        _burn(account, amount, data, operatorData);
    }

    /**
     * @dev See {IERC20-allowance}.
     *
     * Note that operator and allowance concepts are orthogonal: operators may
     * not have allowance, and accounts with allowance may not be operators
     * themselves.
     */
    function allowance(address holder, address spender) public view override returns (uint256) {
        return _allowances[holder][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Note that accounts cannot have allowance issued by their operators.
     */
    function approve(address spender, uint256 value) public override returns (bool) {
        address holder = _msgSender();
        _approve(holder, spender, value);
        return true;
    }

   /**
    * @dev See {IERC20-transferFrom}.
    *
    * Note that operator and allowance concepts are orthogonal: operators cannot
    * call `transferFrom` (unless they have allowance), and accounts with
    * allowance cannot call `operatorSend` (unless they are operators).
    *
    * Emits {Sent}, {IERC20-Transfer} and {IERC20-Approval} events.
    */
    function transferFrom(address holder, address recipient, uint256 amount) public override returns (bool) {
        require(recipient != address(0), "ERC777: transfer to the zero address");
        require(holder != address(0), "ERC777: transfer from the zero address");

        address spender = _msgSender();

        _callTokensToSend(spender, holder, recipient, amount, "", "");

        _move(spender, holder, recipient, amount, "", "");
        _approve(holder, spender, _allowances[holder][spender].sub(amount, "ERC777: transfer amount exceeds allowance"));

        _callTokensReceived(spender, holder, recipient, amount, "", "", false);

        return true;
    }

    /**
     * @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * If a send hook is registered for `account`, the corresponding function
     * will be called with `operator`, `data` and `operatorData`.
     *
     * See {IERC777Sender} and {IERC777Recipient}.
     *
     * Emits {Minted} and {IERC20-Transfer} events.
     *
     * Requirements
     *
     * - `account` cannot be the zero address.
     * - if `account` is a contract, it must implement the {IERC777Recipient}
     * interface.
     */
    function _mint(
        address account,
        uint256 amount,
        bytes memory userData,
        bytes memory operatorData
    )
    internal virtual
    {
        require(account != address(0), "ERC777: mint to the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, address(0), account, amount);

        // Update state variables
        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);

        _callTokensReceived(operator, address(0), account, amount, userData, operatorData, true);

        emit Minted(operator, account, amount, userData, operatorData);
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Send tokens
     * @param from address token holder address
     * @param to address recipient address
     * @param amount uint256 amount of tokens to transfer
     * @param userData bytes extra information provided by the token holder (if any)
     * @param operatorData bytes extra information provided by the operator (if any)
     * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient
     */
    function _send(
        address from,
        address to,
        uint256 amount,
        bytes memory userData,
        bytes memory operatorData,
        bool requireReceptionAck
    )
        internal
    {
        require(from != address(0), "ERC777: send from the zero address");
        require(to != address(0), "ERC777: send to the zero address");

        address operator = _msgSender();

        _callTokensToSend(operator, from, to, amount, userData, operatorData);

        _move(operator, from, to, amount, userData, operatorData);

        _callTokensReceived(operator, from, to, amount, userData, operatorData, requireReceptionAck);
    }

    /**
     * @dev Burn tokens
     * @param from address token holder address
     * @param amount uint256 amount of tokens to burn
     * @param data bytes extra information provided by the token holder
     * @param operatorData bytes extra information provided by the operator (if any)
     */
    function _burn(
        address from,
        uint256 amount,
        bytes memory data,
        bytes memory operatorData
    )
        internal virtual
    {
        require(from != address(0), "ERC777: burn from the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, address(0), amount);

        _callTokensToSend(operator, from, address(0), amount, data, operatorData);

        // Update state variables
        _balances[from] = _balances[from].sub(amount, "ERC777: burn amount exceeds balance");
        _totalSupply = _totalSupply.sub(amount);

        emit Burned(operator, from, amount, data, operatorData);
        emit Transfer(from, address(0), amount);
    }

    function _move(
        address operator,
        address from,
        address to,
        uint256 amount,
        bytes memory userData,
        bytes memory operatorData
    )
        private
    {
        _beforeTokenTransfer(operator, from, to, amount);

        _balances[from] = _balances[from].sub(amount, "ERC777: transfer amount exceeds balance");
        _balances[to] = _balances[to].add(amount);

        emit Sent(operator, from, to, amount, userData, operatorData);
        emit Transfer(from, to, amount);
    }

    /**
     * @dev See {ERC20-_approve}.
     *
     * Note that accounts cannot have allowance issued by their operators.
     */
    function _approve(address holder, address spender, uint256 value) internal {
        require(holder != address(0), "ERC777: approve from the zero address");
        require(spender != address(0), "ERC777: approve to the zero address");

        _allowances[holder][spender] = value;
        emit Approval(holder, spender, value);
    }

    /**
     * @dev Call from.tokensToSend() if the interface is registered
     * @param operator address operator requesting the transfer
     * @param from address token holder address
     * @param to address recipient address
     * @param amount uint256 amount of tokens to transfer
     * @param userData bytes extra information provided by the token holder (if any)
     * @param operatorData bytes extra information provided by the operator (if any)
     */
    function _callTokensToSend(
        address operator,
        address from,
        address to,
        uint256 amount,
        bytes memory userData,
        bytes memory operatorData
    )
        private
    {
        address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(from, _TOKENS_SENDER_INTERFACE_HASH);
        if (implementer != address(0)) {
            IERC777Sender(implementer).tokensToSend(operator, from, to, amount, userData, operatorData);
        }
    }

    /**
     * @dev Call to.tokensReceived() if the interface is registered. Reverts if the recipient is a contract but
     * tokensReceived() was not registered for the recipient
     * @param operator address operator requesting the transfer
     * @param from address token holder address
     * @param to address recipient address
     * @param amount uint256 amount of tokens to transfer
     * @param userData bytes extra information provided by the token holder (if any)
     * @param operatorData bytes extra information provided by the operator (if any)
     * @param requireReceptionAck if true, contract recipients are required to implement ERC777TokensRecipient
     */
    function _callTokensReceived(
        address operator,
        address from,
        address to,
        uint256 amount,
        bytes memory userData,
        bytes memory operatorData,
        bool requireReceptionAck
    )
        private
    {
        address implementer = _ERC1820_REGISTRY.getInterfaceImplementer(to, _TOKENS_RECIPIENT_INTERFACE_HASH);
        if (implementer != address(0)) {
            IERC777Recipient(implementer).tokensReceived(operator, from, to, amount, userData, operatorData);
        } else if (requireReceptionAck) {
            require(!to.isContract(), "ERC777: token recipient contract has no implementer for ERC777TokensRecipient");
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes
     * calls to {send}, {transfer}, {operatorSend}, 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 operator, address from, address to, uint256 tokenId) internal virtual { }
}

// File: @openzeppelin/contracts/math/Math.sol

pragma solidity ^0.6.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow, so we distribute
        return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
    }
}

// File: contracts/FluxToken.sol

pragma solidity 0.6.9;







/**
 * @dev Representation of each DAM Lock-in
 */
struct AddressLock {
    /**
     * @dev DAM locked-in amount
     */
    uint256 amount;

    /**
     * @dev How much FLUX was burned
     */
    uint256 burnedAmount;

    /**
     * @dev When did the lock-in start
     */
    uint256 blockNumber;

    /**
     * @dev When was the last time this address minted?
     */
    uint256 lastMintBlockNumber;

    /**
     * @dev Who is allowed to mint on behalf of this address
     */
    address minterAddress;
}

/**
 * @dev Datamine Crypto - FLUX Smart Contract
 */
contract FluxToken is ERC777, IERC777Recipient {
    /**
     * @dev Protect against overflows by using safe math operations (these are .add,.sub functions)
     */
    using SafeMath for uint256;

    /**
     * @dev for the re-entrancy attack protection
     */
    mapping(address => bool) private mutex;

    /**
     * @dev To avoid re-entrancy attacks
     */
    modifier preventRecursion() {
        if(mutex[_msgSender()] == false) {
            mutex[_msgSender()] = true;
            _; // Call the actual code
            mutex[_msgSender()] = false;
        }
        
        // Don't call the method if you are inside one already (_ above is what does the calling)
    }

    /**
     * @dev To limit one action per block per address 
     */
    modifier preventSameBlock(address targetAddress) {
        require(addressLocks[targetAddress].blockNumber != block.number && addressLocks[targetAddress].lastMintBlockNumber != block.number, "You can not lock/unlock/mint in the same block");
        
        _; // Call the actual code
    }

    /**
     * @dev DAM must be locked-in to execute this function
     */
    modifier requireLocked(address targetAddress, bool requiredState) {
        if (requiredState) {
            require(addressLocks[targetAddress].amount != 0, "You must have locked-in your DAM tokens");
        }else{
            require(addressLocks[targetAddress].amount == 0, "You must have unlocked your DAM tokens");
        }

        _; // Call the actual code
    }

    /**
     * @dev This will be DAM token smart contract address
     */
    IERC777 immutable private _token;

    IERC1820Registry private _erc1820 = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24);
    bytes32 constant private TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient");
	
    /**
     * @dev Decline some incoming transactions (Only allow FLUX smart contract to send/recieve DAM tokens)
     */
    function tokensReceived(
        address operator,
        address from,
        address to,
        uint256 amount,
        bytes calldata,
        bytes calldata
    ) external override {
        require(amount > 0, "You must receive a positive number of tokens");
        require(_msgSender() == address(_token), "You can only lock-in DAM tokens");

        // Ensure someone doesn't send in some DAM to this contract by mistake (Only the contract itself can send itself DAM)
        require(operator == address(this) , "Only FLUX contract can send itself DAM tokens");
        require(to == address(this), "Funds must be coming into FLUX token");
        require(from != to, "Why would FLUX contract send tokens to itself?");
    }

    /**
     * @dev Set to 5760 on mainnet (min 24 hours before time bonus starts)
     */
    uint256 immutable private _startTimeReward;

    /**
     * @dev Set to 161280 on mainnet (max 28 days before max 3x time reward bonus)
     */
    uint256 immutable private _maxTimeReward;

    /**
     * @dev How long until you can lock-in any DAM token amount
     */
    uint256 immutable private _failsafeTargetBlock;
	 
    constructor(address token, uint256 startTimeReward, uint256 maxTimeReward, uint256 failsafeBlockDuration) public ERC777("FLUX", "FLUX", new address[](0)) {
		require(maxTimeReward > 0, "maxTimeReward must be at least 1 block"); // to avoid division by 0

        _token = IERC777(token);
        _startTimeReward = startTimeReward;
        _maxTimeReward = maxTimeReward;
        _failsafeTargetBlock = block.number.add(failsafeBlockDuration);

        _erc1820.setInterfaceImplementer(address(this), TOKENS_RECIPIENT_INTERFACE_HASH, address(this));
    }

    /**
     * @dev How much max DAM can you lock-in during failsafe duration?
     */
     uint256 private constant _failsafeMaxAmount = 100 * (10 ** 18);

    /**
     * @dev 0.00000001 FLUX minted/block/1 DAM
     * @dev 10^18 / 10^8 = 10^10
     */
    uint256 private constant _mintPerBlockDivisor = 10 ** 8;

    /**
     * @dev To avoid small FLUX/DAM burn ratios we multiply the ratios by this number.
     */
    uint256 private constant _ratioMultiplier = 10 ** 10;

    /**
     * @dev To get 4 decimals on our multipliers we'll multiply all ratios & divide ratios by this number.
	 * @dev This is done because we're using integers without any decimals.
     */
    uint256 private constant _percentMultiplier = 10000;

    /**
     * @dev This is our max 10x FLUX burn multiplier. It's multiplicative with the time multiplier.
     */
    uint256 private constant _maxBurnMultiplier = 100000;

    /**
     * @dev This is our max 3x DAM lock-in time multiplier. It's multiplicative with the burn multiplier.
     */
	uint256 private constant _maxTimeMultiplier = 30000;

	/**
	 * @dev How does time reward bonus scales? This is the "2x" in the "1x base + (0x to 2x bonus) = max 3x"
	 */
	uint256 private constant  _targetBlockMultiplier = 20000;
    
    /**
     * @dev PUBLIC FACING: By making addressLocks public we can access elements through the contract view (vs having to create methods)
     */
    mapping (address => AddressLock) public addressLocks;
    
    /**
     * @dev PUBLIC FACING: Store how much locked in DAM there is globally
     */
    uint256 public globalLockedAmount;
    
    /**
     * @dev PUBLIC FACING: Store how much is burned globally (only from the locked-in DAM addresses)
     */
    uint256 public globalBurnedAmount;

    // Events
    event Locked(address sender, uint256 blockNumber, address minterAddress, uint256 amount, uint256 burnedAmountIncrease);
    event Unlocked(address sender, uint256 amount, uint256 burnedAmountDecrease);
    event BurnedToAddress(address sender, address targetAddress, uint256 amount);
    event Minted(address sender, uint256 blockNumber, address sourceAddress, address targetAddress, uint256 targetBlock, uint256 amount);
    
    //////////////////// END HEADER //////////////////////

	/**
	 * @dev PUBLIC FACING: Lock-in DAM tokens with the specified address as the minter.
	 */
    function lock(address minterAddress, uint256 amount) 
        preventRecursion 
        preventSameBlock(_msgSender())
        requireLocked(_msgSender(), false) // Ensure DAM is unlocked for sender
    public {
        require(amount > 0, "You must provide a positive amount to lock-in");

        // Ensure you can only lock up to 100 DAM during failsafe period
        if (block.number < _failsafeTargetBlock) {
            require(amount <= _failsafeMaxAmount, "You can only lock-in up to 100 DAM during failsafe.");
        }

        AddressLock storage senderAddressLock = addressLocks[_msgSender()]; // Shortcut accessor

        senderAddressLock.amount = amount;
        senderAddressLock.blockNumber = block.number;
        senderAddressLock.lastMintBlockNumber = block.number; // Reset the last mint height to new lock height
        senderAddressLock.minterAddress = minterAddress;
        
        globalLockedAmount = globalLockedAmount.add(amount);
        globalBurnedAmount = globalBurnedAmount.add(senderAddressLock.burnedAmount);

        emit Locked(_msgSender(), block.number, minterAddress, amount, senderAddressLock.burnedAmount);

        // Send [amount] of DAM token from the address that is calling this function to FLUX smart contract.
        IERC777(_token).operatorSend(_msgSender(), address(this), amount, "", ""); // [RE-ENTRANCY WARNING] external call, must be at the end
    }
    
	/**
	 * @dev PUBLIC FACING: Unlock any sender locked-in DAM tokens
	 */
    function unlock() 
        preventRecursion 
        preventSameBlock(_msgSender())
        requireLocked(_msgSender(), true)  // Ensure DAM is locked-in for sender
    public {
        AddressLock storage senderAddressLock = addressLocks[_msgSender()]; // Shortcut accessor

        uint256 amount = senderAddressLock.amount;
        senderAddressLock.amount = 0;

        globalLockedAmount = globalLockedAmount.sub(amount);
        globalBurnedAmount = globalBurnedAmount.sub(senderAddressLock.burnedAmount);

        emit Unlocked(_msgSender(), amount, senderAddressLock.burnedAmount);

        // Send back the locked-in DAM amount to person calling the method
        IERC777(_token).send(_msgSender(), amount, ""); // [RE-ENTRANCY WARNING] external call, must be at the end       
    }

	/**
	 * @dev PUBLIC FACING: Burn FLUX tokens to a specific address
	 */
    function burnToAddress(address targetAddress, uint256 amount) 
        preventRecursion 
        requireLocked(targetAddress, true) // Ensure the address you are burning to has DAM locked-in
    public {
        require(amount > 0, "You must burn > 0 FLUX");

        AddressLock storage targetAddressLock = addressLocks[targetAddress]; // Shortcut accessor, pay attention to targetAddress here
        
        targetAddressLock.burnedAmount = targetAddressLock.burnedAmount.add(amount);

        globalBurnedAmount = globalBurnedAmount.add(amount);
        
        emit BurnedToAddress(_msgSender(), targetAddress, amount);

        // Call the normal ERC-777 burn (this will destroy FLUX tokens). We don't check address balance for amount because the internal burn does this check for us.
        _burn(_msgSender(), amount, "", ""); // [RE-ENTRANCY WARNING] external call, must be at the end      
    }

	/**
	 * @dev PUBLIC FACING: Mint FLUX tokens from a specific address to a specified address UP TO the target block
	 */
    function mintToAddress(address sourceAddress, address targetAddress, uint256 targetBlock) 
        preventRecursion 
        preventSameBlock(sourceAddress)
        requireLocked(sourceAddress, true) // Ensure the adress that is being minted from has DAM locked-in
    public {
        require(targetBlock <= block.number, "You can only mint up to current block");
        
        AddressLock storage sourceAddressLock = addressLocks[sourceAddress]; // Shortcut accessor, pay attention to sourceAddress here
        
        require(sourceAddressLock.lastMintBlockNumber < targetBlock, "You can only mint ahead of last mint block");
        require(sourceAddressLock.minterAddress == _msgSender(), "You must be the delegated minter of the sourceAddress");

        uint256 mintAmount = getMintAmount(sourceAddress, targetBlock);
        require(mintAmount > 0, "You can not mint zero balance");
        
        sourceAddressLock.lastMintBlockNumber = targetBlock; // Reset the mint height

        emit Minted(_msgSender(), block.number, sourceAddress, targetAddress, targetBlock, mintAmount);

        // Call the normal ERC-777 mint (this will mint FLUX tokens to targetAddress)
        _mint(targetAddress, mintAmount, "", ""); // [RE-ENTRANCY WARNING] external call, must be at the end      
    }

    //////////////////// VIEW ONLY //////////////////////

	/**
	 * @dev PUBLIC FACING: Get mint amount of a specific amount up to a target block
	 */
    function getMintAmount(address targetAddress, uint256 targetBlock) public view returns(uint256) {
        AddressLock storage targetAddressLock = addressLocks[targetAddress]; // Shortcut accessor

        // Ensure this address has DAM locked-in
        if (targetAddressLock.amount == 0) {
            return 0;
        }

        require(targetBlock <= block.number, "You can only calculate up to current block");
        require(targetAddressLock.lastMintBlockNumber <= targetBlock, "You can only specify blocks at or ahead of last mint block");

        uint256 blocksMinted = targetBlock.sub(targetAddressLock.lastMintBlockNumber);

        uint256 amount = targetAddressLock.amount; // Total of locked-in DAM for this address
        uint256 blocksMintedByAmount = amount.mul(blocksMinted);

        // Adjust by multipliers
        uint256 burnMultiplier = getAddressBurnMultiplier(targetAddress);
        uint256 timeMultipler = getAddressTimeMultiplier(targetAddress);
        uint256 fluxAfterMultiplier = blocksMintedByAmount.mul(burnMultiplier).div(_percentMultiplier).mul(timeMultipler).div(_percentMultiplier);

        uint256 actualFluxMinted = fluxAfterMultiplier.div(_mintPerBlockDivisor);
        return actualFluxMinted;
    }
    
	/**
	 * @dev PUBLIC FACING: Find out the current address DAM lock-in time bonus (Using 1 block = 15 sec formula)
	 */
    function getAddressTimeMultiplier(address targetAddress) public view returns(uint256) {
        AddressLock storage targetAddressLock = addressLocks[targetAddress]; // Shortcut accessor

        // Ensure this address has DAM locked-in
        if (targetAddressLock.amount == 0) {
            return _percentMultiplier;
        }
        
        // You don't get any bonus until min blocks passed
        uint256 targetBlockNumber = targetAddressLock.blockNumber.add(_startTimeReward);
        if (block.number < targetBlockNumber) {
            return _percentMultiplier;
        }

        // 24 hours - min before starting to receive rewards
        // 28 days - max for waiting 28 days (The function returns PERCENT (10000x) the multiplier for 4 decimal accuracy
        uint256 blockDiff = block.number.sub(targetBlockNumber).mul(_targetBlockMultiplier).div(_maxTimeReward).add(_percentMultiplier); 

        uint256 timeMultiplier = Math.min(_maxTimeMultiplier, blockDiff); // Min 1x, Max 3x
        return timeMultiplier;
    }

    /**
     * @dev PUBLIC FACING: Get burn multipler for a specific address. This will be returned as PERCENT (10000x)
     */
    function getAddressBurnMultiplier(address targetAddress) public view returns(uint256) {
        uint256 myRatio = getAddressRatio(targetAddress);
        uint256 globalRatio = getGlobalRatio();
        
        // Avoid division by 0 & ensure 1x multiplier if nothing is locked
        if (globalRatio == 0 || myRatio == 0) {
            return _percentMultiplier;
        }

        // The final multiplier is return with 10000x multiplication and will need to be divided by 10000 for final number
        uint256 burnMultiplier = Math.min(_maxBurnMultiplier, myRatio.mul(_percentMultiplier).div(globalRatio).add(_percentMultiplier)); // Min 1x, Max 10x
        return burnMultiplier;
    }

    /**
     * @dev PUBLIC FACING: Get DAM/FLUX burn ratio for a specific address
     */
    function getAddressRatio(address targetAddress) public view returns(uint256) {
        AddressLock storage targetAddressLock = addressLocks[targetAddress]; // Shortcut accessor

        uint256 addressLockedAmount = targetAddressLock.amount;
        uint256 addressBurnedAmount = targetAddressLock.burnedAmount;

        // If you haven't minted or burned anything then you get the default 1x multiplier
        if (addressLockedAmount == 0) {
            return 0;
        }

        // Burn/Lock-in ratios for both address & network
        // Note that we multiply both ratios by the ratio multiplier before dividing. For tiny FLUX/DAM burn ratios.
        uint256 myRatio = addressBurnedAmount.mul(_ratioMultiplier).div(addressLockedAmount);
        return myRatio;
    }

    /**
     * @dev PUBLIC FACING: Get DAM/FLUX burn ratio for global (entire network)
     */
    function getGlobalRatio() public view returns(uint256) {
        // If you haven't minted or burned anything then you get the default 1x multiplier
        if (globalLockedAmount == 0) {
            return 0;
        }

        // Burn/Lock-in ratios for both address & network
        // Note that we multiply both ratios by the ratio multiplier before dividing. For tiny FLUX/DAM burn ratios.
        uint256 globalRatio = globalBurnedAmount.mul(_ratioMultiplier).div(globalLockedAmount);
        return globalRatio;
    }

    /**
     * @dev PUBLIC FACING: Grab a collection of data
     * @dev ABIEncoderV2 was still experimental at time of writing this. Better approach would be to return struct.
     */
    function getAddressDetails(address targetAddress) public view returns(uint256,uint256,uint256,uint256,uint256,uint256,uint256) {
        uint256 fluxBalance = balanceOf(targetAddress);
        uint256 mintAmount = getMintAmount(targetAddress, block.number);

        uint256 addressTimeMultiplier = getAddressTimeMultiplier(targetAddress);
        uint256 addressBurnMultiplier = getAddressBurnMultiplier(targetAddress);

        return (
            block.number, 
            fluxBalance, 
            mintAmount, 
            addressTimeMultiplier,
            addressBurnMultiplier,
            globalLockedAmount, 
            globalBurnedAmount);
    }
    
    /**
     * @dev PUBLIC FACING: Grab additional token details
     * @dev ABIEncoderV2 was still experimental at time of writing this. Better approach would be to return struct.
     */
    function getAddressTokenDetails(address targetAddress) public view returns(uint256,bool,uint256,uint256,uint256) {
        bool isFluxOperator = IERC777(_token).isOperatorFor(address(this), targetAddress);
        uint256 damBalance = IERC777(_token).balanceOf(targetAddress);

        uint256 myRatio = getAddressRatio(targetAddress);
        uint256 globalRatio = getGlobalRatio();

        return (
            block.number, 
            isFluxOperator, 
            damBalance,
            myRatio,
            globalRatio);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"startTimeReward","type":"uint256"},{"internalType":"uint256","name":"maxTimeReward","type":"uint256"},{"internalType":"uint256","name":"failsafeBlockDuration","type":"uint256"}],"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":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"tokenHolder","type":"address"}],"name":"AuthorizedOperator","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"operatorData","type":"bytes"}],"name":"Burned","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"targetAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BurnedToAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"},{"indexed":false,"internalType":"address","name":"minterAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"burnedAmountIncrease","type":"uint256"}],"name":"Locked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"blockNumber","type":"uint256"},{"indexed":false,"internalType":"address","name":"sourceAddress","type":"address"},{"indexed":false,"internalType":"address","name":"targetAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"targetBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"operatorData","type":"bytes"}],"name":"Minted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"tokenHolder","type":"address"}],"name":"RevokedOperator","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"operatorData","type":"bytes"}],"name":"Sent","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":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"burnedAmountDecrease","type":"uint256"}],"name":"Unlocked","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addressLocks","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"burnedAmount","type":"uint256"},{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"uint256","name":"lastMintBlockNumber","type":"uint256"},{"internalType":"address","name":"minterAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"authorizeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenHolder","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"targetAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnToAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"defaultOperators","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"targetAddress","type":"address"}],"name":"getAddressBurnMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"targetAddress","type":"address"}],"name":"getAddressDetails","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"targetAddress","type":"address"}],"name":"getAddressRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"targetAddress","type":"address"}],"name":"getAddressTimeMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"targetAddress","type":"address"}],"name":"getAddressTokenDetails","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGlobalRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"targetAddress","type":"address"},{"internalType":"uint256","name":"targetBlock","type":"uint256"}],"name":"getMintAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"globalBurnedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"globalLockedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"granularity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"tokenHolder","type":"address"}],"name":"isOperatorFor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"minterAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"lock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sourceAddress","type":"address"},{"internalType":"address","name":"targetAddress","type":"address"},{"internalType":"uint256","name":"targetBlock","type":"uint256"}],"name":"mintToAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"operatorData","type":"bytes"}],"name":"operatorBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bytes","name":"operatorData","type":"bytes"}],"name":"operatorSend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"revokeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"send","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"tokensReceived","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"holder","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unlock","outputs":[],"stateMutability":"nonpayable","type":"function"}]

610100604052600a80546001600160a01b031916731820a4b7618bde71dce8cdc73aab6c95905fad241790553480156200003857600080fd5b506040516200418838038062004188833981810160405260808110156200005e57600080fd5b5080516020808301516040808501516060909501518151808301835260048082526308c98aab60e31b8287018181528551808701875292835282880191909152845160008152968701909452815196979496949592949193909291620000c7916002916200040b565b508151620000dd9060039060208501906200040b565b508051620000f390600490602084019062000490565b5060005b6004548110156200015357600160056000600484815481106200011657fe5b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff1916911515919091179055600101620000f7565b50604080516a22a9219b9b9baa37b5b2b760a91b8152815190819003600b0181206329965a1d60e01b82523060048301819052602483019190915260448201529051731820a4b7618bde71dce8cdc73aab6c95905fad24916329965a1d91606480830192600092919082900301818387803b158015620001d257600080fd5b505af1158015620001e7573d6000803e3d6000fd5b5050604080516922a92199182a37b5b2b760b11b8152815190819003600a0181206329965a1d60e01b82523060048301819052602483019190915260448201529051731820a4b7618bde71dce8cdc73aab6c95905fad2493506329965a1d9250606480830192600092919082900301818387803b1580156200026857600080fd5b505af11580156200027d573d6000803e3d6000fd5b5050505050505060008211620002c55760405162461bcd60e51b8152600401808060200182810382526026815260200180620041626026913960400191505060405180910390fd5b606084901b6001600160601b03191660805260a083905260c0829052620002f94382620003a9602090811b6200273317901c565b60e052600a54604080517f455243373737546f6b656e73526563697069656e740000000000000000000000815281519081900360150181206329965a1d60e01b825230600483018190526024830191909152604482015290516001600160a01b03909216916329965a1d9160648082019260009290919082900301818387803b1580156200038657600080fd5b505af11580156200039b573d6000803e3d6000fd5b50505050505050506200053d565b60008282018381101562000404576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200044e57805160ff19168380011785556200047e565b828001600101855582156200047e579182015b828111156200047e57825182559160200191906001019062000461565b506200048c929150620004f6565b5090565b828054828255906000526020600020908101928215620004e8579160200282015b82811115620004e857825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620004b1565b506200048c92915062000516565b6200051391905b808211156200048c5760008155600101620004fd565b90565b6200051391905b808211156200048c5780546001600160a01b03191681556001016200051d565b60805160601c60a05160c05160e051613bd86200058a600039806112e052508061169952508061164c525080610bf552806114355280611deb528061231552806123f75250613bd86000f3fe608060405234801561001057600080fd5b50600436106101fa5760003560e01c806370a082311161011a578063a69df4b5116100ad578063d95b63711161007c578063d95b637114610949578063dd62ed3e14610977578063fad8b32a146109a5578063fc673c4f146109cb578063fe9d930314610b09576101fa565b8063a69df4b51461088e578063a9059cbb14610896578063aff510a7146108c2578063be6ca56d146108f8576101fa565b80638238ba80116100e95780638238ba801461074d578063959b8c3f146107a757806395d89b41146107cd5780639bd9bbc6146107d5576101fa565b806370a08231146106cd578063710b2d8c146106f35780637e3fa2b9146107195780637fd2ca1314610721576101fa565b80633133e3ab1161019257806338ee5fb11161016157806338ee5fb11461054e57806345958be414610556578063556f0dc71461057c57806362ad1b8314610584576101fa565b80633133e3ab146104a4578063313ce5671461050257806332b04a0114610520578063331d7cfa14610546576101fa565b806318160ddd116101ce57806318160ddd146103fc578063195d0e281461041657806323b872dd14610442578063282d3fdf14610478576101fa565b806223de29146101ff57806306e48538146102e757806306fdde031461033f578063095ea7b3146103bc575b600080fd5b6102e5600480360360c081101561021557600080fd5b6001600160a01b03823581169260208101358216926040820135909216916060820135919081019060a081016080820135600160201b81111561025757600080fd5b82018360208201111561026957600080fd5b803590602001918460018302840111600160201b8311171561028a57600080fd5b919390929091602081019035600160201b8111156102a757600080fd5b8201836020820111156102b957600080fd5b803590602001918460018302840111600160201b831117156102da57600080fd5b509092509050610bb4565b005b6102ef610d69565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561032b578181015183820152602001610313565b505050509050019250505060405180910390f35b610347610dcc565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610381578181015183820152602001610369565b50505050905090810190601f1680156103ae5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103e8600480360360408110156103d257600080fd5b506001600160a01b038135169060200135610e56565b604080519115158252519081900360200190f35b610404610e7a565b60408051918252519081900360200190f35b6104046004803603604081101561042c57600080fd5b506001600160a01b038135169060200135610e80565b6103e86004803603606081101561045857600080fd5b506001600160a01b03813581169160208101359091169060400135610fd3565b6102e56004803603604081101561048e57600080fd5b506001600160a01b038135169060200135611156565b6104ca600480360360208110156104ba57600080fd5b50356001600160a01b0316611532565b604080519788526020880196909652868601949094526060860192909252608085015260a084015260c0830152519081900360e00190f35b61050a61158f565b6040805160ff9092168252519081900360200190f35b6104046004803603602081101561053657600080fd5b50356001600160a01b0316611594565b610404611609565b61040461160f565b6104046004803603602081101561056c57600080fd5b50356001600160a01b0316611615565b6104046116e8565b6102e5600480360360a081101561059a57600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b8111156105d457600080fd5b8201836020820111156105e657600080fd5b803590602001918460018302840111600160201b8311171561060757600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561065957600080fd5b82018360208201111561066b57600080fd5b803590602001918460018302840111600160201b8311171561068c57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506116ed945050505050565b610404600480360360208110156106e357600080fd5b50356001600160a01b031661174f565b6104046004803603602081101561070957600080fd5b50356001600160a01b031661176a565b6104046117b5565b6102e56004803603604081101561073757600080fd5b506001600160a01b0381351690602001356117f2565b6107736004803603602081101561076357600080fd5b50356001600160a01b03166119d8565b6040805195865260208601949094528484019290925260608401526001600160a01b03166080830152519081900360a00190f35b6102e5600480360360208110156107bd57600080fd5b50356001600160a01b0316611a10565b610347611b5c565b6102e5600480360360608110156107eb57600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b81111561081a57600080fd5b82018360208201111561082c57600080fd5b803590602001918460018302840111600160201b8311171561084d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611bbd945050505050565b6102e5611be7565b6103e8600480360360408110156108ac57600080fd5b506001600160a01b038135169060200135611ecf565b6102e5600480360360608110156108d857600080fd5b506001600160a01b03813581169160208101359091169060400135611fa8565b61091e6004803603602081101561090e57600080fd5b50356001600160a01b031661230a565b6040805195865293151560208601528484019290925260608401526080830152519081900360a00190f35b6103e86004803603604081101561095f57600080fd5b506001600160a01b038135811691602001351661249a565b6104046004803603604081101561098d57600080fd5b506001600160a01b038135811691602001351661253c565b6102e5600480360360208110156109bb57600080fd5b50356001600160a01b0316612567565b6102e5600480360360808110156109e157600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b811115610a1057600080fd5b820183602082011115610a2257600080fd5b803590602001918460018302840111600160201b83111715610a4357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b811115610a9557600080fd5b820183602082011115610aa757600080fd5b803590602001918460018302840111600160201b83111715610ac857600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506126b3945050505050565b6102e560048036036040811015610b1f57600080fd5b81359190810190604081016020820135600160201b811115610b4057600080fd5b820183602082011115610b5257600080fd5b803590602001918460018302840111600160201b83111715610b7357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612711945050505050565b60008511610bf35760405162461bcd60e51b815260040180806020018281038252602c8152602001806139c9602c913960400191505060405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610c2561278d565b6001600160a01b031614610c80576040805162461bcd60e51b815260206004820152601f60248201527f596f752063616e206f6e6c79206c6f636b2d696e2044414d20746f6b656e7300604482015290519081900360640190fd5b6001600160a01b0388163014610cc75760405162461bcd60e51b815260040180806020018281038252602d815260200180613b29602d913960400191505060405180910390fd5b6001600160a01b0386163014610d0e5760405162461bcd60e51b81526004018080602001828103825260248152602001806139576024913960400191505060405180910390fd5b856001600160a01b0316876001600160a01b03161415610d5f5760405162461bcd60e51b815260040180806020018281038252602e8152602001806139f5602e913960400191505060405180910390fd5b5050505050505050565b60606004805480602002602001604051908101604052809291908181526020018280548015610dc157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610da3575b505050505090505b90565b60028054604080516020601f6000196101006001871615020190941685900493840181900481028201810190925282815260609390929091830182828015610dc15780601f10610e2a57610100808354040283529160200191610dc1565b820191906000526020600020905b815481529060010190602001808311610e3857509395945050505050565b600080610e6161278d565b9050610e6e818585612791565b60019150505b92915050565b60015490565b6001600160a01b0382166000908152600b602052604081208054610ea8576000915050610e74565b43831115610ee75760405162461bcd60e51b815260040180806020018281038252602a815260200180613b79602a913960400191505060405180910390fd5b8281600301541115610f2a5760405162461bcd60e51b815260040180806020018281038252603a815260200180613a23603a913960400191505060405180910390fd5b6000610f4382600301548561287d90919063ffffffff16565b82549091506000610f5a828463ffffffff6128bf16565b90506000610f6788611594565b90506000610f7489611615565b90506000610fac612710610f9484610fa083838a8a63ffffffff6128bf16565b9063ffffffff61291816565b9063ffffffff6128bf16565b90506000610fc4826305f5e10063ffffffff61291816565b9b9a5050505050505050505050565b60006001600160a01b03831661101a5760405162461bcd60e51b81526004018080602001828103825260248152602001806139a56024913960400191505060405180910390fd5b6001600160a01b03841661105f5760405162461bcd60e51b8152600401808060200182810382526026815260200180613ae06026913960400191505060405180910390fd5b600061106961278d565b905061109781868686604051806020016040528060008152506040518060200160405280600081525061295a565b6110c3818686866040518060200160405280600081525060405180602001604052806000815250612ba2565b61111d858261111886604051806060016040528060298152602001613ab7602991396001600160a01b03808c166000908152600860209081526040808320938b1683529290522054919063ffffffff612dc716565b612791565b61114b8186868660405180602001604052806000815250604051806020016040528060008152506000612e5e565b506001949350505050565b6009600061116261278d565b6001600160a01b0316815260208101919091526040016000205460ff1661152e5760016009600061119161278d565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790556111c161278d565b6001600160a01b0381166000908152600b6020526040902060020154431480159061120757506001600160a01b0381166000908152600b60205260409020600301544314155b6112425760405162461bcd60e51b815260040180806020018281038252602e815260200180613a5d602e913960400191505060405180910390fd5b61124a61278d565b6001600160a01b0381166000908152600b60205260408120541561129f5760405162461bcd60e51b81526004018080602001828103825260268152602001806138236026913960400191505060405180910390fd5b600084116112de5760405162461bcd60e51b815260040180806020018281038252602d81526020018061377b602d913960400191505060405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000043101561134e5768056bc75e2d6310000084111561134e5760405162461bcd60e51b815260040180806020018281038252603381526020018061388f6033913960400191505060405180910390fd5b6000600b600061135c61278d565b6001600160a01b0390811682526020820192909252604001600020868155436002820181905560038201556004810180546001600160a01b03191692891692909217909155600c549091506113b19086612733565b600c556001810154600d546113cb9163ffffffff61273316565b600d557f839301d49a1ea695b991657eb992fdd6280a423122f6d73152cd912b0fdb79706113f761278d565b6001830154604080516001600160a01b039384168152436020820152928a1683820152606083018990526080830191909152519081900360a00190a17f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166362ad1b8361146a61278d565b6040805160e084811b6001600160e01b03191682526001600160a01b03939093166004820152306024820152604481018a905260a06064820152600060a48201819052608482019390935260e481018390529051610124808301939282900301818387803b1580156114db57600080fd5b505af11580156114ef573d6000803e3d6000fd5b505050505050505060006009600061150561278d565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790555b5050565b6000806000806000806000806115478961174f565b905060006115558a43610e80565b905060006115628b611615565b9050600061156f8c611594565b600c54600d54439f969e50949c50929a5098509096509094509092505050565b601290565b6000806115a08361176a565b905060006115ac6117b5565b90508015806115b9575081155b156115ca5761271092505050611604565b60006115fe620186a06115f96127106115ed86610f94898463ffffffff6128bf16565b9063ffffffff61273316565b6130f4565b93505050505b919050565b600c5481565b600d5481565b6001600160a01b0381166000908152600b60205260408120805461163e57612710915050611604565b6002810154600090611676907f000000000000000000000000000000000000000000000000000000000000000063ffffffff61273316565b90508043101561168c5761271092505050611604565b60006116ce6127106115ed7f0000000000000000000000000000000000000000000000000000000000000000610f94614e20610fa0438963ffffffff61287d16565b905060006116de617530836130f4565b9695505050505050565b600190565b6116fe6116f861278d565b8661249a565b6117395760405162461bcd60e51b815260040180806020018281038252602c815260200180613a8b602c913960400191505060405180910390fd5b6117488585858585600161310a565b5050505050565b6001600160a01b031660009081526020819052604090205490565b6001600160a01b0381166000908152600b60205260408120805460018201548161179a5760009350505050611604565b60006116de83610f94846402540be40063ffffffff6128bf16565b6000600c54600014156117ca57506000610dc9565b60006117ec600c54610f946402540be400600d546128bf90919063ffffffff16565b91505090565b600960006117fe61278d565b6001600160a01b0316815260208101919091526040016000205460ff1661152e5760016009600061182d61278d565b6001600160a01b031681526020810191909152604001600020805491151560ff199092169190911790558160016001600160a01b0382166000908152600b60205260409020546118ae5760405162461bcd60e51b81526004018080602001828103825260278152602001806138c26027913960400191505060405180910390fd5b600083116118fc576040805162461bcd60e51b81526020600482015260166024820152750b2deea40daeae6e840c4eae4dc407c4060408c98aab60531b604482015290519081900360640190fd5b6001600160a01b0384166000908152600b602052604090206001810154611929908563ffffffff61273316565b6001820155600d54611941908563ffffffff61273316565b600d557f0988e44904d6f878152b5838c395fd103556e89960b84cca544f25bb8e14544d61196d61278d565b604080516001600160a01b0392831681529188166020830152818101879052519081900360600190a16119c76119a161278d565b8560405180602001604052806000815250604051806020016040528060008152506131e1565b50505060006009600061150561278d565b600b6020526000908152604090208054600182015460028301546003840154600490940154929391929091906001600160a01b031685565b806001600160a01b0316611a2261278d565b6001600160a01b03161415611a685760405162461bcd60e51b81526004018080602001828103825260248152602001806137ca6024913960400191505060405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff1615611acb5760076000611a9561278d565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff19169055611b12565b600160066000611ad961278d565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff19169115159190911790555b611b1a61278d565b6001600160a01b0316816001600160a01b03167ff4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f960405160405180910390a350565b60038054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610dc15780601f10610e2a57610100808354040283529160200191610dc1565b611be2611bc861278d565b84848460405180602001604052806000815250600161310a565b505050565b60096000611bf361278d565b6001600160a01b0316815260208101919091526040016000205460ff16611ecd57600160096000611c2261278d565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055611c5261278d565b6001600160a01b0381166000908152600b60205260409020600201544314801590611c9857506001600160a01b0381166000908152600b60205260409020600301544314155b611cd35760405162461bcd60e51b815260040180806020018281038252602e815260200180613a5d602e913960400191505060405180910390fd5b611cdb61278d565b60016001600160a01b0382166000908152600b6020526040902054611d315760405162461bcd60e51b81526004018080602001828103825260278152602001806138c26027913960400191505060405180910390fd5b6000600b6000611d3f61278d565b6001600160a01b03168152602081019190915260400160009081208054918155600c54909250611d75908263ffffffff61287d16565b600c556001820154600d54611d8f9163ffffffff61287d16565b600d557f3f2f29fa02cc34566ac167b446be0be9e0254cac18eda93b2dfe6a7a7c8affb9611dbb61278d565b6001840154604080516001600160a01b0390931683526020830185905282810191909152519081900360600190a17f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639bd9bbc6611e2061278d565b604080516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820185905260606044830152600060648301819052905160a48084019382900301818387803b158015611e7957600080fd5b505af1158015611e8d573d6000803e3d6000fd5b505050505050505050600060096000611ea461278d565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790555b565b60006001600160a01b038316611f165760405162461bcd60e51b81526004018080602001828103825260248152602001806139a56024913960400191505060405180910390fd5b6000611f2061278d565b9050611f4e81828686604051806020016040528060008152506040518060200160405280600081525061295a565b611f7a818286866040518060200160405280600081525060405180602001604052806000815250612ba2565b610e6e8182868660405180602001604052806000815250604051806020016040528060008152506000612e5e565b60096000611fb461278d565b6001600160a01b0316815260208101919091526040016000205460ff16611be257600160096000611fe361278d565b6001600160a01b03908116825260208083019390935260409182016000908120805460ff19169515159590951790945586168352600b9091529020600201548390431480159061204e57506001600160a01b0381166000908152600b60205260409020600301544314155b6120895760405162461bcd60e51b815260040180806020018281038252602e815260200180613a5d602e913960400191505060405180910390fd5b8360016001600160a01b0382166000908152600b60205260409020546120e05760405162461bcd60e51b81526004018080602001828103825260278152602001806138c26027913960400191505060405180910390fd5b4384111561211f5760405162461bcd60e51b815260040180806020018281038252602581526020018061386a6025913960400191505060405180910390fd5b6001600160a01b0386166000908152600b60205260409020600381015485116121795760405162461bcd60e51b815260040180806020018281038252602a81526020018061397b602a913960400191505060405180910390fd5b61218161278d565b60048201546001600160a01b039081169116146121cf5760405162461bcd60e51b81526004018080602001828103825260358152602001806137ee6035913960400191505060405180910390fd5b60006121db8887610e80565b905060008111612232576040805162461bcd60e51b815260206004820152601d60248201527f596f752063616e206e6f74206d696e74207a65726f2062616c616e6365000000604482015290519081900360640190fd5b600382018690557f362b95f53c81f53b3bf4a4ee37bdb0d75f2ecd94ae81b2a82579218fbedf99ed61226261278d565b604080516001600160a01b039283168152436020820152828c1681830152918a1660608301526080820189905260a08201849052519081900360c00190a16122ca87826040518060200160405280600081525060405180602001604052806000815250613427565b50505050506000600960006122dd61278d565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055505050565b6000806000806000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d95b637130896040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b031681526020019250505060206040518083038186803b1580156123a357600080fd5b505afa1580156123b7573d6000803e3d6000fd5b505050506040513d60208110156123cd57600080fd5b5051604080516370a0823160e01b81526001600160a01b038a8116600483015291519293506000927f0000000000000000000000000000000000000000000000000000000000000000909216916370a0823191602480820192602092909190829003018186803b15801561244057600080fd5b505afa158015612454573d6000803e3d6000fd5b505050506040513d602081101561246a57600080fd5b5051905060006124798961176a565b905060006124856117b5565b439b949a509298509096509094509092505050565b6000816001600160a01b0316836001600160a01b0316148061250557506001600160a01b03831660009081526005602052604090205460ff16801561250557506001600160a01b0380831660009081526007602090815260408083209387168352929052205460ff16155b8061253557506001600160a01b0380831660009081526006602090815260408083209387168352929052205460ff165b9392505050565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205490565b61256f61278d565b6001600160a01b0316816001600160a01b031614156125bf5760405162461bcd60e51b81526004018080602001828103825260218152602001806138496021913960400191505060405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff161561262b576001600760006125ee61278d565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff1916911515919091179055612669565b6006600061263761278d565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690555b61267161278d565b6001600160a01b0316816001600160a01b03167f50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa160405160405180910390a350565b6126c46126be61278d565b8561249a565b6126ff5760405162461bcd60e51b815260040180806020018281038252602c815260200180613a8b602c913960400191505060405180910390fd5b61270b848484846131e1565b50505050565b61152e61271c61278d565b8383604051806020016040528060008152506131e1565b600082820183811015612535576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b3390565b6001600160a01b0383166127d65760405162461bcd60e51b815260040180806020018281038252602581526020018061370d6025913960400191505060405180910390fd5b6001600160a01b03821661281b5760405162461bcd60e51b8152600401808060200182810382526023815260200180613b566023913960400191505060405180910390fd5b6001600160a01b03808416600081815260086020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b600061253583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612dc7565b6000826128ce57506000610e74565b828202828482816128db57fe5b04146125355760405162461bcd60e51b81526004018080602001828103825260218152602001806138e96021913960400191505060405180910390fd5b600061253583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061366b565b6040805163555ddc6560e11b81526001600160a01b03871660048201527f29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe89560248201529051600091731820a4b7618bde71dce8cdc73aab6c95905fad249163aabbb8ca91604480820192602092909190829003018186803b1580156129de57600080fd5b505afa1580156129f2573d6000803e3d6000fd5b505050506040513d6020811015612a0857600080fd5b505190506001600160a01b03811615612b9957806001600160a01b03166375ab97828888888888886040518763ffffffff1660e01b815260040180876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b031681526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015612ace578181015183820152602001612ab6565b50505050905090810190601f168015612afb5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015612b2e578181015183820152602001612b16565b50505050905090810190601f168015612b5b5780820380516001836020036101000a031916815260200191505b5098505050505050505050600060405180830381600087803b158015612b8057600080fd5b505af1158015612b94573d6000803e3d6000fd5b505050505b50505050505050565b612bae8686868661270b565b612bf183604051806060016040528060278152602001613754602791396001600160a01b038816600090815260208190526040902054919063ffffffff612dc716565b6001600160a01b038087166000908152602081905260408082209390935590861681522054612c26908463ffffffff61273316565b600080866001600160a01b03166001600160a01b0316815260200190815260200160002081905550836001600160a01b0316856001600160a01b0316876001600160a01b03167f06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987868686604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015612cd7578181015183820152602001612cbf565b50505050905090810190601f168015612d045780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015612d37578181015183820152602001612d1f565b50505050905090810190601f168015612d645780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a4836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3505050505050565b60008184841115612e565760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612e1b578181015183820152602001612e03565b50505050905090810190601f168015612e485780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6040805163555ddc6560e11b81526001600160a01b03871660048201527fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b60248201529051600091731820a4b7618bde71dce8cdc73aab6c95905fad249163aabbb8ca91604480820192602092909190829003018186803b158015612ee257600080fd5b505afa158015612ef6573d6000803e3d6000fd5b505050506040513d6020811015612f0c57600080fd5b505190506001600160a01b038116156130a057806001600160a01b03166223de298989898989896040518763ffffffff1660e01b815260040180876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b031681526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015612fd1578181015183820152602001612fb9565b50505050905090810190601f168015612ffe5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015613031578181015183820152602001613019565b50505050905090810190601f16801561305e5780820380516001836020036101000a031916815260200191505b5098505050505050505050600060405180830381600087803b15801561308357600080fd5b505af1158015613097573d6000803e3d6000fd5b50505050610d5f565b8115610d5f576130b8866001600160a01b03166136d0565b15610d5f5760405162461bcd60e51b815260040180806020018281038252604d81526020018061390a604d913960600191505060405180910390fd5b60008183106131035781612535565b5090919050565b6001600160a01b03861661314f5760405162461bcd60e51b81526004018080602001828103825260228152602001806137326022913960400191505060405180910390fd5b6001600160a01b0385166131aa576040805162461bcd60e51b815260206004820181905260248201527f4552433737373a2073656e6420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b60006131b461278d565b90506131c481888888888861295a565b6131d2818888888888612ba2565b612b9981888888888888612e5e565b6001600160a01b0384166132265760405162461bcd60e51b81526004018080602001828103825260228152602001806137a86022913960400191505060405180910390fd5b600061323061278d565b905061323f818660008761270b565b61324e8186600087878761295a565b61329184604051806060016040528060238152602001613b06602391396001600160a01b038816600090815260208190526040902054919063ffffffff612dc716565b6001600160a01b0386166000908152602081905260409020556001546132bd908563ffffffff61287d16565b600181905550846001600160a01b0316816001600160a01b03167fa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098868686604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561334257818101518382015260200161332a565b50505050905090810190601f16801561336f5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156133a257818101518382015260200161338a565b50505050905090810190601f1680156133cf5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a36040805185815290516000916001600160a01b038816917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050505050565b6001600160a01b038416613482576040805162461bcd60e51b815260206004820181905260248201527f4552433737373a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b600061348c61278d565b905061349b816000878761270b565b6001546134ae908563ffffffff61273316565b6001556001600160a01b0385166000908152602081905260409020546134da908563ffffffff61273316565b6001600160a01b038616600090815260208190526040812091909155613507908290878787876001612e5e565b846001600160a01b0316816001600160a01b03167f2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d868686604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561358657818101518382015260200161356e565b50505050905090810190601f1680156135b35780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156135e65781810151838201526020016135ce565b50505050905090810190601f1680156136135780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a36040805185815290516001600160a01b038716916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050505050565b600081836136ba5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612e1b578181015183820152602001612e03565b5060008385816136c657fe5b0495945050505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061370457508115155b94935050505056fe4552433737373a20617070726f76652066726f6d20746865207a65726f20616464726573734552433737373a2073656e642066726f6d20746865207a65726f20616464726573734552433737373a207472616e7366657220616d6f756e7420657863656564732062616c616e6365596f75206d7573742070726f76696465206120706f73697469766520616d6f756e7420746f206c6f636b2d696e4552433737373a206275726e2066726f6d20746865207a65726f20616464726573734552433737373a20617574686f72697a696e672073656c66206173206f70657261746f72596f75206d757374206265207468652064656c656761746564206d696e746572206f662074686520736f7572636541646472657373596f75206d757374206861766520756e6c6f636b656420796f75722044414d20746f6b656e734552433737373a207265766f6b696e672073656c66206173206f70657261746f72596f752063616e206f6e6c79206d696e7420757020746f2063757272656e7420626c6f636b596f752063616e206f6e6c79206c6f636b2d696e20757020746f203130302044414d20647572696e67206661696c736166652e596f75206d7573742068617665206c6f636b65642d696e20796f75722044414d20746f6b656e73536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774552433737373a20746f6b656e20726563697069656e7420636f6e747261637420686173206e6f20696d706c656d656e74657220666f7220455243373737546f6b656e73526563697069656e7446756e6473206d75737420626520636f6d696e6720696e746f20464c555820746f6b656e596f752063616e206f6e6c79206d696e74206168656164206f66206c617374206d696e7420626c6f636b4552433737373a207472616e7366657220746f20746865207a65726f2061646472657373596f75206d7573742072656365697665206120706f736974697665206e756d626572206f6620746f6b656e7357687920776f756c6420464c555820636f6e74726163742073656e6420746f6b656e7320746f20697473656c663f596f752063616e206f6e6c79207370656369667920626c6f636b73206174206f72206168656164206f66206c617374206d696e7420626c6f636b596f752063616e206e6f74206c6f636b2f756e6c6f636b2f6d696e7420696e207468652073616d6520626c6f636b4552433737373a2063616c6c6572206973206e6f7420616e206f70657261746f7220666f7220686f6c6465724552433737373a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654552433737373a207472616e736665722066726f6d20746865207a65726f20616464726573734552433737373a206275726e20616d6f756e7420657863656564732062616c616e63654f6e6c7920464c555820636f6e74726163742063616e2073656e6420697473656c662044414d20746f6b656e734552433737373a20617070726f766520746f20746865207a65726f2061646472657373596f752063616e206f6e6c792063616c63756c61746520757020746f2063757272656e7420626c6f636ba26469706673582212203fc6f0e643f8fd29e42709747a8844e0be38b1542153d3415e0f4e8ed57d9a6c64736f6c634300060900336d617854696d65526577617264206d757374206265206174206c65617374203120626c6f636b000000000000000000000000f80d589b3dbe130c270a69f1a69d050f268786df000000000000000000000000000000000000000000000000000000000000168000000000000000000000000000000000000000000000000000000000000276000000000000000000000000000000000000000000000000000000000000027600

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101fa5760003560e01c806370a082311161011a578063a69df4b5116100ad578063d95b63711161007c578063d95b637114610949578063dd62ed3e14610977578063fad8b32a146109a5578063fc673c4f146109cb578063fe9d930314610b09576101fa565b8063a69df4b51461088e578063a9059cbb14610896578063aff510a7146108c2578063be6ca56d146108f8576101fa565b80638238ba80116100e95780638238ba801461074d578063959b8c3f146107a757806395d89b41146107cd5780639bd9bbc6146107d5576101fa565b806370a08231146106cd578063710b2d8c146106f35780637e3fa2b9146107195780637fd2ca1314610721576101fa565b80633133e3ab1161019257806338ee5fb11161016157806338ee5fb11461054e57806345958be414610556578063556f0dc71461057c57806362ad1b8314610584576101fa565b80633133e3ab146104a4578063313ce5671461050257806332b04a0114610520578063331d7cfa14610546576101fa565b806318160ddd116101ce57806318160ddd146103fc578063195d0e281461041657806323b872dd14610442578063282d3fdf14610478576101fa565b806223de29146101ff57806306e48538146102e757806306fdde031461033f578063095ea7b3146103bc575b600080fd5b6102e5600480360360c081101561021557600080fd5b6001600160a01b03823581169260208101358216926040820135909216916060820135919081019060a081016080820135600160201b81111561025757600080fd5b82018360208201111561026957600080fd5b803590602001918460018302840111600160201b8311171561028a57600080fd5b919390929091602081019035600160201b8111156102a757600080fd5b8201836020820111156102b957600080fd5b803590602001918460018302840111600160201b831117156102da57600080fd5b509092509050610bb4565b005b6102ef610d69565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561032b578181015183820152602001610313565b505050509050019250505060405180910390f35b610347610dcc565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610381578181015183820152602001610369565b50505050905090810190601f1680156103ae5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103e8600480360360408110156103d257600080fd5b506001600160a01b038135169060200135610e56565b604080519115158252519081900360200190f35b610404610e7a565b60408051918252519081900360200190f35b6104046004803603604081101561042c57600080fd5b506001600160a01b038135169060200135610e80565b6103e86004803603606081101561045857600080fd5b506001600160a01b03813581169160208101359091169060400135610fd3565b6102e56004803603604081101561048e57600080fd5b506001600160a01b038135169060200135611156565b6104ca600480360360208110156104ba57600080fd5b50356001600160a01b0316611532565b604080519788526020880196909652868601949094526060860192909252608085015260a084015260c0830152519081900360e00190f35b61050a61158f565b6040805160ff9092168252519081900360200190f35b6104046004803603602081101561053657600080fd5b50356001600160a01b0316611594565b610404611609565b61040461160f565b6104046004803603602081101561056c57600080fd5b50356001600160a01b0316611615565b6104046116e8565b6102e5600480360360a081101561059a57600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135600160201b8111156105d457600080fd5b8201836020820111156105e657600080fd5b803590602001918460018302840111600160201b8311171561060757600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b81111561065957600080fd5b82018360208201111561066b57600080fd5b803590602001918460018302840111600160201b8311171561068c57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506116ed945050505050565b610404600480360360208110156106e357600080fd5b50356001600160a01b031661174f565b6104046004803603602081101561070957600080fd5b50356001600160a01b031661176a565b6104046117b5565b6102e56004803603604081101561073757600080fd5b506001600160a01b0381351690602001356117f2565b6107736004803603602081101561076357600080fd5b50356001600160a01b03166119d8565b6040805195865260208601949094528484019290925260608401526001600160a01b03166080830152519081900360a00190f35b6102e5600480360360208110156107bd57600080fd5b50356001600160a01b0316611a10565b610347611b5c565b6102e5600480360360608110156107eb57600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b81111561081a57600080fd5b82018360208201111561082c57600080fd5b803590602001918460018302840111600160201b8311171561084d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611bbd945050505050565b6102e5611be7565b6103e8600480360360408110156108ac57600080fd5b506001600160a01b038135169060200135611ecf565b6102e5600480360360608110156108d857600080fd5b506001600160a01b03813581169160208101359091169060400135611fa8565b61091e6004803603602081101561090e57600080fd5b50356001600160a01b031661230a565b6040805195865293151560208601528484019290925260608401526080830152519081900360a00190f35b6103e86004803603604081101561095f57600080fd5b506001600160a01b038135811691602001351661249a565b6104046004803603604081101561098d57600080fd5b506001600160a01b038135811691602001351661253c565b6102e5600480360360208110156109bb57600080fd5b50356001600160a01b0316612567565b6102e5600480360360808110156109e157600080fd5b6001600160a01b0382351691602081013591810190606081016040820135600160201b811115610a1057600080fd5b820183602082011115610a2257600080fd5b803590602001918460018302840111600160201b83111715610a4357600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b811115610a9557600080fd5b820183602082011115610aa757600080fd5b803590602001918460018302840111600160201b83111715610ac857600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506126b3945050505050565b6102e560048036036040811015610b1f57600080fd5b81359190810190604081016020820135600160201b811115610b4057600080fd5b820183602082011115610b5257600080fd5b803590602001918460018302840111600160201b83111715610b7357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612711945050505050565b60008511610bf35760405162461bcd60e51b815260040180806020018281038252602c8152602001806139c9602c913960400191505060405180910390fd5b7f000000000000000000000000f80d589b3dbe130c270a69f1a69d050f268786df6001600160a01b0316610c2561278d565b6001600160a01b031614610c80576040805162461bcd60e51b815260206004820152601f60248201527f596f752063616e206f6e6c79206c6f636b2d696e2044414d20746f6b656e7300604482015290519081900360640190fd5b6001600160a01b0388163014610cc75760405162461bcd60e51b815260040180806020018281038252602d815260200180613b29602d913960400191505060405180910390fd5b6001600160a01b0386163014610d0e5760405162461bcd60e51b81526004018080602001828103825260248152602001806139576024913960400191505060405180910390fd5b856001600160a01b0316876001600160a01b03161415610d5f5760405162461bcd60e51b815260040180806020018281038252602e8152602001806139f5602e913960400191505060405180910390fd5b5050505050505050565b60606004805480602002602001604051908101604052809291908181526020018280548015610dc157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610da3575b505050505090505b90565b60028054604080516020601f6000196101006001871615020190941685900493840181900481028201810190925282815260609390929091830182828015610dc15780601f10610e2a57610100808354040283529160200191610dc1565b820191906000526020600020905b815481529060010190602001808311610e3857509395945050505050565b600080610e6161278d565b9050610e6e818585612791565b60019150505b92915050565b60015490565b6001600160a01b0382166000908152600b602052604081208054610ea8576000915050610e74565b43831115610ee75760405162461bcd60e51b815260040180806020018281038252602a815260200180613b79602a913960400191505060405180910390fd5b8281600301541115610f2a5760405162461bcd60e51b815260040180806020018281038252603a815260200180613a23603a913960400191505060405180910390fd5b6000610f4382600301548561287d90919063ffffffff16565b82549091506000610f5a828463ffffffff6128bf16565b90506000610f6788611594565b90506000610f7489611615565b90506000610fac612710610f9484610fa083838a8a63ffffffff6128bf16565b9063ffffffff61291816565b9063ffffffff6128bf16565b90506000610fc4826305f5e10063ffffffff61291816565b9b9a5050505050505050505050565b60006001600160a01b03831661101a5760405162461bcd60e51b81526004018080602001828103825260248152602001806139a56024913960400191505060405180910390fd5b6001600160a01b03841661105f5760405162461bcd60e51b8152600401808060200182810382526026815260200180613ae06026913960400191505060405180910390fd5b600061106961278d565b905061109781868686604051806020016040528060008152506040518060200160405280600081525061295a565b6110c3818686866040518060200160405280600081525060405180602001604052806000815250612ba2565b61111d858261111886604051806060016040528060298152602001613ab7602991396001600160a01b03808c166000908152600860209081526040808320938b1683529290522054919063ffffffff612dc716565b612791565b61114b8186868660405180602001604052806000815250604051806020016040528060008152506000612e5e565b506001949350505050565b6009600061116261278d565b6001600160a01b0316815260208101919091526040016000205460ff1661152e5760016009600061119161278d565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790556111c161278d565b6001600160a01b0381166000908152600b6020526040902060020154431480159061120757506001600160a01b0381166000908152600b60205260409020600301544314155b6112425760405162461bcd60e51b815260040180806020018281038252602e815260200180613a5d602e913960400191505060405180910390fd5b61124a61278d565b6001600160a01b0381166000908152600b60205260408120541561129f5760405162461bcd60e51b81526004018080602001828103825260268152602001806138236026913960400191505060405180910390fd5b600084116112de5760405162461bcd60e51b815260040180806020018281038252602d81526020018061377b602d913960400191505060405180910390fd5b7f00000000000000000000000000000000000000000000000000000000009e79c243101561134e5768056bc75e2d6310000084111561134e5760405162461bcd60e51b815260040180806020018281038252603381526020018061388f6033913960400191505060405180910390fd5b6000600b600061135c61278d565b6001600160a01b0390811682526020820192909252604001600020868155436002820181905560038201556004810180546001600160a01b03191692891692909217909155600c549091506113b19086612733565b600c556001810154600d546113cb9163ffffffff61273316565b600d557f839301d49a1ea695b991657eb992fdd6280a423122f6d73152cd912b0fdb79706113f761278d565b6001830154604080516001600160a01b039384168152436020820152928a1683820152606083018990526080830191909152519081900360a00190a17f000000000000000000000000f80d589b3dbe130c270a69f1a69d050f268786df6001600160a01b03166362ad1b8361146a61278d565b6040805160e084811b6001600160e01b03191682526001600160a01b03939093166004820152306024820152604481018a905260a06064820152600060a48201819052608482019390935260e481018390529051610124808301939282900301818387803b1580156114db57600080fd5b505af11580156114ef573d6000803e3d6000fd5b505050505050505060006009600061150561278d565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790555b5050565b6000806000806000806000806115478961174f565b905060006115558a43610e80565b905060006115628b611615565b9050600061156f8c611594565b600c54600d54439f969e50949c50929a5098509096509094509092505050565b601290565b6000806115a08361176a565b905060006115ac6117b5565b90508015806115b9575081155b156115ca5761271092505050611604565b60006115fe620186a06115f96127106115ed86610f94898463ffffffff6128bf16565b9063ffffffff61273316565b6130f4565b93505050505b919050565b600c5481565b600d5481565b6001600160a01b0381166000908152600b60205260408120805461163e57612710915050611604565b6002810154600090611676907f000000000000000000000000000000000000000000000000000000000000168063ffffffff61273316565b90508043101561168c5761271092505050611604565b60006116ce6127106115ed7f0000000000000000000000000000000000000000000000000000000000027600610f94614e20610fa0438963ffffffff61287d16565b905060006116de617530836130f4565b9695505050505050565b600190565b6116fe6116f861278d565b8661249a565b6117395760405162461bcd60e51b815260040180806020018281038252602c815260200180613a8b602c913960400191505060405180910390fd5b6117488585858585600161310a565b5050505050565b6001600160a01b031660009081526020819052604090205490565b6001600160a01b0381166000908152600b60205260408120805460018201548161179a5760009350505050611604565b60006116de83610f94846402540be40063ffffffff6128bf16565b6000600c54600014156117ca57506000610dc9565b60006117ec600c54610f946402540be400600d546128bf90919063ffffffff16565b91505090565b600960006117fe61278d565b6001600160a01b0316815260208101919091526040016000205460ff1661152e5760016009600061182d61278d565b6001600160a01b031681526020810191909152604001600020805491151560ff199092169190911790558160016001600160a01b0382166000908152600b60205260409020546118ae5760405162461bcd60e51b81526004018080602001828103825260278152602001806138c26027913960400191505060405180910390fd5b600083116118fc576040805162461bcd60e51b81526020600482015260166024820152750b2deea40daeae6e840c4eae4dc407c4060408c98aab60531b604482015290519081900360640190fd5b6001600160a01b0384166000908152600b602052604090206001810154611929908563ffffffff61273316565b6001820155600d54611941908563ffffffff61273316565b600d557f0988e44904d6f878152b5838c395fd103556e89960b84cca544f25bb8e14544d61196d61278d565b604080516001600160a01b0392831681529188166020830152818101879052519081900360600190a16119c76119a161278d565b8560405180602001604052806000815250604051806020016040528060008152506131e1565b50505060006009600061150561278d565b600b6020526000908152604090208054600182015460028301546003840154600490940154929391929091906001600160a01b031685565b806001600160a01b0316611a2261278d565b6001600160a01b03161415611a685760405162461bcd60e51b81526004018080602001828103825260248152602001806137ca6024913960400191505060405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff1615611acb5760076000611a9561278d565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff19169055611b12565b600160066000611ad961278d565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff19169115159190911790555b611b1a61278d565b6001600160a01b0316816001600160a01b03167ff4caeb2d6ca8932a215a353d0703c326ec2d81fc68170f320eb2ab49e9df61f960405160405180910390a350565b60038054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610dc15780601f10610e2a57610100808354040283529160200191610dc1565b611be2611bc861278d565b84848460405180602001604052806000815250600161310a565b505050565b60096000611bf361278d565b6001600160a01b0316815260208101919091526040016000205460ff16611ecd57600160096000611c2261278d565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055611c5261278d565b6001600160a01b0381166000908152600b60205260409020600201544314801590611c9857506001600160a01b0381166000908152600b60205260409020600301544314155b611cd35760405162461bcd60e51b815260040180806020018281038252602e815260200180613a5d602e913960400191505060405180910390fd5b611cdb61278d565b60016001600160a01b0382166000908152600b6020526040902054611d315760405162461bcd60e51b81526004018080602001828103825260278152602001806138c26027913960400191505060405180910390fd5b6000600b6000611d3f61278d565b6001600160a01b03168152602081019190915260400160009081208054918155600c54909250611d75908263ffffffff61287d16565b600c556001820154600d54611d8f9163ffffffff61287d16565b600d557f3f2f29fa02cc34566ac167b446be0be9e0254cac18eda93b2dfe6a7a7c8affb9611dbb61278d565b6001840154604080516001600160a01b0390931683526020830185905282810191909152519081900360600190a17f000000000000000000000000f80d589b3dbe130c270a69f1a69d050f268786df6001600160a01b0316639bd9bbc6611e2061278d565b604080516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820185905260606044830152600060648301819052905160a48084019382900301818387803b158015611e7957600080fd5b505af1158015611e8d573d6000803e3d6000fd5b505050505050505050600060096000611ea461278d565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790555b565b60006001600160a01b038316611f165760405162461bcd60e51b81526004018080602001828103825260248152602001806139a56024913960400191505060405180910390fd5b6000611f2061278d565b9050611f4e81828686604051806020016040528060008152506040518060200160405280600081525061295a565b611f7a818286866040518060200160405280600081525060405180602001604052806000815250612ba2565b610e6e8182868660405180602001604052806000815250604051806020016040528060008152506000612e5e565b60096000611fb461278d565b6001600160a01b0316815260208101919091526040016000205460ff16611be257600160096000611fe361278d565b6001600160a01b03908116825260208083019390935260409182016000908120805460ff19169515159590951790945586168352600b9091529020600201548390431480159061204e57506001600160a01b0381166000908152600b60205260409020600301544314155b6120895760405162461bcd60e51b815260040180806020018281038252602e815260200180613a5d602e913960400191505060405180910390fd5b8360016001600160a01b0382166000908152600b60205260409020546120e05760405162461bcd60e51b81526004018080602001828103825260278152602001806138c26027913960400191505060405180910390fd5b4384111561211f5760405162461bcd60e51b815260040180806020018281038252602581526020018061386a6025913960400191505060405180910390fd5b6001600160a01b0386166000908152600b60205260409020600381015485116121795760405162461bcd60e51b815260040180806020018281038252602a81526020018061397b602a913960400191505060405180910390fd5b61218161278d565b60048201546001600160a01b039081169116146121cf5760405162461bcd60e51b81526004018080602001828103825260358152602001806137ee6035913960400191505060405180910390fd5b60006121db8887610e80565b905060008111612232576040805162461bcd60e51b815260206004820152601d60248201527f596f752063616e206e6f74206d696e74207a65726f2062616c616e6365000000604482015290519081900360640190fd5b600382018690557f362b95f53c81f53b3bf4a4ee37bdb0d75f2ecd94ae81b2a82579218fbedf99ed61226261278d565b604080516001600160a01b039283168152436020820152828c1681830152918a1660608301526080820189905260a08201849052519081900360c00190a16122ca87826040518060200160405280600081525060405180602001604052806000815250613427565b50505050506000600960006122dd61278d565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055505050565b6000806000806000807f000000000000000000000000f80d589b3dbe130c270a69f1a69d050f268786df6001600160a01b031663d95b637130896040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b031681526020019250505060206040518083038186803b1580156123a357600080fd5b505afa1580156123b7573d6000803e3d6000fd5b505050506040513d60208110156123cd57600080fd5b5051604080516370a0823160e01b81526001600160a01b038a8116600483015291519293506000927f000000000000000000000000f80d589b3dbe130c270a69f1a69d050f268786df909216916370a0823191602480820192602092909190829003018186803b15801561244057600080fd5b505afa158015612454573d6000803e3d6000fd5b505050506040513d602081101561246a57600080fd5b5051905060006124798961176a565b905060006124856117b5565b439b949a509298509096509094509092505050565b6000816001600160a01b0316836001600160a01b0316148061250557506001600160a01b03831660009081526005602052604090205460ff16801561250557506001600160a01b0380831660009081526007602090815260408083209387168352929052205460ff16155b8061253557506001600160a01b0380831660009081526006602090815260408083209387168352929052205460ff165b9392505050565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205490565b61256f61278d565b6001600160a01b0316816001600160a01b031614156125bf5760405162461bcd60e51b81526004018080602001828103825260218152602001806138496021913960400191505060405180910390fd5b6001600160a01b03811660009081526005602052604090205460ff161561262b576001600760006125ee61278d565b6001600160a01b03908116825260208083019390935260409182016000908120918616815292529020805460ff1916911515919091179055612669565b6006600061263761278d565b6001600160a01b03908116825260208083019390935260409182016000908120918516815292529020805460ff191690555b61267161278d565b6001600160a01b0316816001600160a01b03167f50546e66e5f44d728365dc3908c63bc5cfeeab470722c1677e3073a6ac294aa160405160405180910390a350565b6126c46126be61278d565b8561249a565b6126ff5760405162461bcd60e51b815260040180806020018281038252602c815260200180613a8b602c913960400191505060405180910390fd5b61270b848484846131e1565b50505050565b61152e61271c61278d565b8383604051806020016040528060008152506131e1565b600082820183811015612535576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b3390565b6001600160a01b0383166127d65760405162461bcd60e51b815260040180806020018281038252602581526020018061370d6025913960400191505060405180910390fd5b6001600160a01b03821661281b5760405162461bcd60e51b8152600401808060200182810382526023815260200180613b566023913960400191505060405180910390fd5b6001600160a01b03808416600081815260086020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b600061253583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612dc7565b6000826128ce57506000610e74565b828202828482816128db57fe5b04146125355760405162461bcd60e51b81526004018080602001828103825260218152602001806138e96021913960400191505060405180910390fd5b600061253583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061366b565b6040805163555ddc6560e11b81526001600160a01b03871660048201527f29ddb589b1fb5fc7cf394961c1adf5f8c6454761adf795e67fe149f658abe89560248201529051600091731820a4b7618bde71dce8cdc73aab6c95905fad249163aabbb8ca91604480820192602092909190829003018186803b1580156129de57600080fd5b505afa1580156129f2573d6000803e3d6000fd5b505050506040513d6020811015612a0857600080fd5b505190506001600160a01b03811615612b9957806001600160a01b03166375ab97828888888888886040518763ffffffff1660e01b815260040180876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b031681526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015612ace578181015183820152602001612ab6565b50505050905090810190601f168015612afb5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015612b2e578181015183820152602001612b16565b50505050905090810190601f168015612b5b5780820380516001836020036101000a031916815260200191505b5098505050505050505050600060405180830381600087803b158015612b8057600080fd5b505af1158015612b94573d6000803e3d6000fd5b505050505b50505050505050565b612bae8686868661270b565b612bf183604051806060016040528060278152602001613754602791396001600160a01b038816600090815260208190526040902054919063ffffffff612dc716565b6001600160a01b038087166000908152602081905260408082209390935590861681522054612c26908463ffffffff61273316565b600080866001600160a01b03166001600160a01b0316815260200190815260200160002081905550836001600160a01b0316856001600160a01b0316876001600160a01b03167f06b541ddaa720db2b10a4d0cdac39b8d360425fc073085fac19bc82614677987868686604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015612cd7578181015183820152602001612cbf565b50505050905090810190601f168015612d045780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015612d37578181015183820152602001612d1f565b50505050905090810190601f168015612d645780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a4836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a3505050505050565b60008184841115612e565760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612e1b578181015183820152602001612e03565b50505050905090810190601f168015612e485780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6040805163555ddc6560e11b81526001600160a01b03871660048201527fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b60248201529051600091731820a4b7618bde71dce8cdc73aab6c95905fad249163aabbb8ca91604480820192602092909190829003018186803b158015612ee257600080fd5b505afa158015612ef6573d6000803e3d6000fd5b505050506040513d6020811015612f0c57600080fd5b505190506001600160a01b038116156130a057806001600160a01b03166223de298989898989896040518763ffffffff1660e01b815260040180876001600160a01b03166001600160a01b03168152602001866001600160a01b03166001600160a01b03168152602001856001600160a01b03166001600160a01b031681526020018481526020018060200180602001838103835285818151815260200191508051906020019080838360005b83811015612fd1578181015183820152602001612fb9565b50505050905090810190601f168015612ffe5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b83811015613031578181015183820152602001613019565b50505050905090810190601f16801561305e5780820380516001836020036101000a031916815260200191505b5098505050505050505050600060405180830381600087803b15801561308357600080fd5b505af1158015613097573d6000803e3d6000fd5b50505050610d5f565b8115610d5f576130b8866001600160a01b03166136d0565b15610d5f5760405162461bcd60e51b815260040180806020018281038252604d81526020018061390a604d913960600191505060405180910390fd5b60008183106131035781612535565b5090919050565b6001600160a01b03861661314f5760405162461bcd60e51b81526004018080602001828103825260228152602001806137326022913960400191505060405180910390fd5b6001600160a01b0385166131aa576040805162461bcd60e51b815260206004820181905260248201527f4552433737373a2073656e6420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b60006131b461278d565b90506131c481888888888861295a565b6131d2818888888888612ba2565b612b9981888888888888612e5e565b6001600160a01b0384166132265760405162461bcd60e51b81526004018080602001828103825260228152602001806137a86022913960400191505060405180910390fd5b600061323061278d565b905061323f818660008761270b565b61324e8186600087878761295a565b61329184604051806060016040528060238152602001613b06602391396001600160a01b038816600090815260208190526040902054919063ffffffff612dc716565b6001600160a01b0386166000908152602081905260409020556001546132bd908563ffffffff61287d16565b600181905550846001600160a01b0316816001600160a01b03167fa78a9be3a7b862d26933ad85fb11d80ef66b8f972d7cbba06621d583943a4098868686604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561334257818101518382015260200161332a565b50505050905090810190601f16801561336f5780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156133a257818101518382015260200161338a565b50505050905090810190601f1680156133cf5780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a36040805185815290516000916001600160a01b038816917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050505050565b6001600160a01b038416613482576040805162461bcd60e51b815260206004820181905260248201527f4552433737373a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b600061348c61278d565b905061349b816000878761270b565b6001546134ae908563ffffffff61273316565b6001556001600160a01b0385166000908152602081905260409020546134da908563ffffffff61273316565b6001600160a01b038616600090815260208190526040812091909155613507908290878787876001612e5e565b846001600160a01b0316816001600160a01b03167f2fe5be0146f74c5bce36c0b80911af6c7d86ff27e89d5cfa61fc681327954e5d868686604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b8381101561358657818101518382015260200161356e565b50505050905090810190601f1680156135b35780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b838110156135e65781810151838201526020016135ce565b50505050905090810190601f1680156136135780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a36040805185815290516001600160a01b038716916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050505050565b600081836136ba5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315612e1b578181015183820152602001612e03565b5060008385816136c657fe5b0495945050505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061370457508115155b94935050505056fe4552433737373a20617070726f76652066726f6d20746865207a65726f20616464726573734552433737373a2073656e642066726f6d20746865207a65726f20616464726573734552433737373a207472616e7366657220616d6f756e7420657863656564732062616c616e6365596f75206d7573742070726f76696465206120706f73697469766520616d6f756e7420746f206c6f636b2d696e4552433737373a206275726e2066726f6d20746865207a65726f20616464726573734552433737373a20617574686f72697a696e672073656c66206173206f70657261746f72596f75206d757374206265207468652064656c656761746564206d696e746572206f662074686520736f7572636541646472657373596f75206d757374206861766520756e6c6f636b656420796f75722044414d20746f6b656e734552433737373a207265766f6b696e672073656c66206173206f70657261746f72596f752063616e206f6e6c79206d696e7420757020746f2063757272656e7420626c6f636b596f752063616e206f6e6c79206c6f636b2d696e20757020746f203130302044414d20647572696e67206661696c736166652e596f75206d7573742068617665206c6f636b65642d696e20796f75722044414d20746f6b656e73536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774552433737373a20746f6b656e20726563697069656e7420636f6e747261637420686173206e6f20696d706c656d656e74657220666f7220455243373737546f6b656e73526563697069656e7446756e6473206d75737420626520636f6d696e6720696e746f20464c555820746f6b656e596f752063616e206f6e6c79206d696e74206168656164206f66206c617374206d696e7420626c6f636b4552433737373a207472616e7366657220746f20746865207a65726f2061646472657373596f75206d7573742072656365697665206120706f736974697665206e756d626572206f6620746f6b656e7357687920776f756c6420464c555820636f6e74726163742073656e6420746f6b656e7320746f20697473656c663f596f752063616e206f6e6c79207370656369667920626c6f636b73206174206f72206168656164206f66206c617374206d696e7420626c6f636b596f752063616e206e6f74206c6f636b2f756e6c6f636b2f6d696e7420696e207468652073616d6520626c6f636b4552433737373a2063616c6c6572206973206e6f7420616e206f70657261746f7220666f7220686f6c6465724552433737373a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654552433737373a207472616e736665722066726f6d20746865207a65726f20616464726573734552433737373a206275726e20616d6f756e7420657863656564732062616c616e63654f6e6c7920464c555820636f6e74726163742063616e2073656e6420697473656c662044414d20746f6b656e734552433737373a20617070726f766520746f20746865207a65726f2061646472657373596f752063616e206f6e6c792063616c63756c61746520757020746f2063757272656e7420626c6f636ba26469706673582212203fc6f0e643f8fd29e42709747a8844e0be38b1542153d3415e0f4e8ed57d9a6c64736f6c63430006090033

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

000000000000000000000000f80d589b3dbe130c270a69f1a69d050f268786df000000000000000000000000000000000000000000000000000000000000168000000000000000000000000000000000000000000000000000000000000276000000000000000000000000000000000000000000000000000000000000027600

-----Decoded View---------------
Arg [0] : token (address): 0xF80D589b3Dbe130c270a69F1a69D050f268786Df
Arg [1] : startTimeReward (uint256): 5760
Arg [2] : maxTimeReward (uint256): 161280
Arg [3] : failsafeBlockDuration (uint256): 161280

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000f80d589b3dbe130c270a69f1a69d050f268786df
Arg [1] : 0000000000000000000000000000000000000000000000000000000000001680
Arg [2] : 0000000000000000000000000000000000000000000000000000000000027600
Arg [3] : 0000000000000000000000000000000000000000000000000000000000027600


Deployed Bytecode Sourcemap

44867:17626:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46875:750;;;;;;;;;;;;;;;;-1:-1:-1;;;;;46875:750:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;46875:750:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;46875:750:0;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;46875:750:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;46875:750:0;;;;;;;;;;-1:-1:-1;46875:750:0;;-1:-1:-1;46875:750:0;-1:-1:-1;46875:750:0;:::i;:::-;;32790:124;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28971:92;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34365:193;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;34365:193:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;29765:117;;;:::i;:::-;;;;;;;;;;;;;;;;56037:1269;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;56037:1269:0;;;;;;;;:::i;34934:686::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;34934:686:0;;;;;;;;;;;;;;;;;:::i;51073:1438::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;51073:1438:0;;;;;;;;:::i;61065:673::-;;;;;;;;;;;;;;;;-1:-1:-1;61065:673:0;-1:-1:-1;;;;;61065:673:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29412:76;;;:::i;:::-;;;;;;;;;;;;;;;;;;;58634:703;;;;;;;;;;;;;;;;-1:-1:-1;58634:703:0;-1:-1:-1;;;;;58634:703:0;;:::i;50254:33::-;;;:::i;50420:::-;;;:::i;57440:1055::-;;;;;;;;;;;;;;;;-1:-1:-1;57440:1055:0;-1:-1:-1;;;;;57440:1055:0;;:::i;29610:89::-;;;:::i;33040:377::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;33040:377:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;33040:377:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;33040:377:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;33040:377:0;;;;;;;;-1:-1:-1;33040:377:0;;-1:-1:-1;;;;;33040:377:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;33040:377:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;33040:377:0;;-1:-1:-1;33040:377:0;;-1:-1:-1;;;;;33040:377:0:i;29987:144::-;;;;;;;;;;;;;;;;-1:-1:-1;29987:144:0;-1:-1:-1;;;;;29987:144:0;;:::i;59438:790::-;;;;;;;;;;;;;;;;-1:-1:-1;59438:790:0;-1:-1:-1;;;;;59438:790:0;;:::i;60334:534::-;;;:::i;53493:924::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;53493:924:0;;;;;;;;:::i;50096:52::-;;;;;;;;;;;;;;;;-1:-1:-1;50096:52:0;-1:-1:-1;;;;;50096:52:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;50096:52:0;;;;;;;;;;;;;;31829:415;;;;;;;;;;;;;;;;-1:-1:-1;31829:415:0;-1:-1:-1;;;;;31829:415:0;;:::i;29124:96::-;;;:::i;30268:158::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;30268:158:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;30268:158:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;30268:158:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;30268:158:0;;-1:-1:-1;30268:158:0;;-1:-1:-1;;;;;30268:158:0:i;52599:810::-;;;:::i;30667:443::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;30667:443:0;;;;;;;;:::i;54549:1324::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;54549:1324:0;;;;;;;;;;;;;;;;;:::i;61943:547::-;;;;;;;;;;;;;;;;-1:-1:-1;61943:547:0;-1:-1:-1;;;;;61943:547:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31437:320;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;31437:320:0;;;;;;;;;;:::i;34075:145::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;34075:145:0;;;;;;;;;;:::i;32313:406::-;;;;;;;;;;;;;;;;-1:-1:-1;32313:406:0;-1:-1:-1;;;;;32313:406:0;;:::i;33545:282::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;33545:282:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;33545:282:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;33545:282:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;33545:282:0;;;;;;;;-1:-1:-1;33545:282:0;;-1:-1:-1;;;;;33545:282:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;33545:282:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;33545:282:0;;-1:-1:-1;33545:282:0;;-1:-1:-1;;;;;33545:282:0:i;31247:122::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;31247:122:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;31247:122:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31247:122:0;;-1:-1:-1;31247:122:0;;-1:-1:-1;;;;;31247:122:0:i;46875:750::-;47098:1;47089:6;:10;47081:67;;;;-1:-1:-1;;;47081:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47191:6;-1:-1:-1;;;;;47167:31:0;:12;:10;:12::i;:::-;-1:-1:-1;;;;;47167:31:0;;47159:75;;;;;-1:-1:-1;;;47159:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;47382:25:0;;47402:4;47382:25;47374:84;;;;-1:-1:-1;;;47374:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;47477:19:0;;47491:4;47477:19;47469:68;;;;-1:-1:-1;;;47469:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47564:2;-1:-1:-1;;;;;47556:10:0;:4;-1:-1:-1;;;;;47556:10:0;;;47548:69;;;;-1:-1:-1;;;47548:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46875:750;;;;;;;;:::o;32790:124::-;32848:16;32884:22;32877:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;32877:29:0;;;;;;;;;;;;;;;;;;;;;;;32790:124;;:::o;28971:92::-;29050:5;29043:12;;;;;;;-1:-1:-1;;29043:12:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29017:13;;29043:12;;29050:5;;29043:12;;29050:5;29043:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;29043:12:0;;28971:92;-1:-1:-1;;;;;28971:92:0:o;34365:193::-;34439:4;34456:14;34473:12;:10;:12::i;:::-;34456:29;;34496:32;34505:6;34513:7;34522:5;34496:8;:32::i;:::-;34546:4;34539:11;;;34365:193;;;;;:::o;29765:117::-;29862:12;;29765:117;:::o;56037:1269::-;-1:-1:-1;;;;;56184:27:0;;56124:7;56184:27;;;:12;:27;;;;;56299:24;;56295:70;;56352:1;56345:8;;;;;56295:70;56400:12;56385:11;:27;;56377:82;;;;-1:-1:-1;;;56377:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56519:11;56478:17;:37;;;:52;;56470:123;;;;-1:-1:-1;;;56470:123:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56606:20;56629:54;56645:17;:37;;;56629:11;:15;;:54;;;;:::i;:::-;56713:24;;56606:77;;-1:-1:-1;56696:14:0;56822:24;56713;56606:77;56822:24;:10;:24;:::i;:::-;56791:55;;56893:22;56918:39;56943:13;56918:24;:39::i;:::-;56893:64;;56968:21;56992:39;57017:13;56992:24;:39::i;:::-;56968:63;-1:-1:-1;57042:27:0;57072:107;49380:5;57072:83;56968:63;57072:64;49380:5;57072:83;:20;57097:14;57072:40;:24;:40;:::i;:::-;:44;:64;:44;:64;:::i;:::-;:68;:83;:68;:83;:::i;:107::-;57042:137;-1:-1:-1;57192:24:0;57219:45;57042:137;48951:7;57219:45;:23;:45;:::i;:::-;57192:72;56037:1269;-1:-1:-1;;;;;;;;;;;56037:1269:0:o;34934:686::-;35032:4;-1:-1:-1;;;;;35057:23:0;;35049:72;;;;-1:-1:-1;;;35049:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;35140:20:0;;35132:71;;;;-1:-1:-1;;;35132:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35216:15;35234:12;:10;:12::i;:::-;35216:30;;35259:61;35277:7;35286:6;35294:9;35305:6;35259:61;;;;;;;;;;;;;;;;;;;;;;;;:17;:61::i;:::-;35333:49;35339:7;35348:6;35356:9;35367:6;35333:49;;;;;;;;;;;;;;;;;;;;;;;;:5;:49::i;:::-;35393:112;35402:6;35410:7;35419:85;35452:6;35419:85;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;35419:19:0;;;;;;;:11;:19;;;;;;;;:28;;;;;;;;;;;:85;;:32;:85;:::i;:::-;35393:8;:112::i;:::-;35518:70;35538:7;35547:6;35555:9;35566:6;35518:70;;;;;;;;;;;;;;;;;;;;;;;;35582:5;35518:19;:70::i;:::-;-1:-1:-1;35608:4:0;;34934:686;-1:-1:-1;;;;34934:686:0:o;51073:1438::-;45293:5;:19;45299:12;:10;:12::i;:::-;-1:-1:-1;;;;;45293:19:0;;;;;;;;;;;;-1:-1:-1;45293:19:0;;;;45290:168;;45360:4;45338:5;:19;45344:12;:10;:12::i;:::-;-1:-1:-1;;;;;45338:19:0;;;;;;;;;;;;-1:-1:-1;45338:19:0;:26;;-1:-1:-1;;45338:26:0;;;;;;;;;;51180:12:::1;:10;:12::i;:::-;-1:-1:-1::0;;;;;45724:27:0;::::1;;::::0;;;:12:::1;:27;::::0;;;;:39:::1;;::::0;45767:12:::1;45724:55;::::0;::::1;::::0;:122:::1;;-1:-1:-1::0;;;;;;45783:27:0;::::1;;::::0;;;:12:::1;:27;::::0;;;;:47:::1;;::::0;45834:12:::1;45783:63;;45724:122;45716:181;;;;-1:-1:-1::0;;;45716:181:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51217:12:::2;:10;:12::i;:::-;-1:-1:-1::0;;;;;46278:27:0;::::2;51231:5;46278:27:::0;;;:12:::2;:27;::::0;;;;:34;:39;46270:90:::2;;;;-1:-1:-1::0;;;46270:90:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51315:1:::3;51306:6;:10;51298:68;;;;-1:-1:-1::0;;;51298:68:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51472:20;51457:12;:35;51453:160;;;48778:16;51517:6;:28;;51509:92;;;;-1:-1:-1::0;;;51509:92:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51625:37;51665:12;:26;51678:12;:10;:12::i;:::-;-1:-1:-1::0;;;;;51665:26:0;;::::3;::::0;;::::3;::::0;::::3;::::0;;;;;;-1:-1:-1;51665:26:0;51725:33;;;51801:12:::3;51769:29;::::0;::::3;:44:::0;;;51824:37:::3;::::0;::::3;:52:::0;51936:31:::3;::::0;::::3;:47:::0;;-1:-1:-1;;;;;;51936:47:0::3;::::0;;::::3;::::0;;;::::3;::::0;;;52025:18:::3;::::0;51665:26;;-1:-1:-1;52025:30:0::3;::::0;51725:33;52025:22:::3;:30::i;:::-;52004:18;:51:::0;52110:30:::3;::::0;::::3;::::0;52087:18:::3;::::0;:54:::3;::::0;::::3;:22;:54;:::i;:::-;52066:18;:75:::0;52159:89:::3;52166:12;:10;:12::i;:::-;52217:30;::::0;::::3;::::0;52159:89:::3;::::0;;-1:-1:-1;;;;;52159:89:0;;::::3;::::0;;52180:12:::3;52159:89;::::0;::::3;::::0;;;::::3;::::0;;;;;;;;;;;;;;;;;;;;;;;;;::::3;52379:6;-1:-1:-1::0;;;;;52371:28:0::3;;52400:12;:10;:12::i;:::-;52371:73;::::0;;::::3;::::0;;;-1:-1:-1;;;;;;52371:73:0;;;-1:-1:-1;;;;;52371:73:0;;;::::3;;::::0;::::3;::::0;52422:4:::3;52371:73:::0;;;;;;;;;;;;;;;-1:-1:-1;52371:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;52371:73:0;;;;;-1:-1:-1;52371:73:0;;::::3;;::::0;::::3;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;46384:1;45918::::2;;45379::::1;45441:5:::0;45419;:19;45425:12;:10;:12::i;:::-;-1:-1:-1;;;;;45419:19:0;;;;;;;;;;;;-1:-1:-1;45419:19:0;:27;;-1:-1:-1;;45419:27:0;;;;;;;;;;45290:168;51073:1438;;:::o;61065:673::-;61135:7;61143;61151;61159;61167;61175;61183;61203:19;61225:24;61235:13;61225:9;:24::i;:::-;61203:46;;61260:18;61281:42;61295:13;61310:12;61281:13;:42::i;:::-;61260:63;;61336:29;61368:39;61393:13;61368:24;:39::i;:::-;61336:71;;61418:29;61450:39;61475:13;61450:24;:39::i;:::-;61677:18;;61711;;61524:12;;61552:11;;-1:-1:-1;61579:10:0;;-1:-1:-1;61605:21:0;;-1:-1:-1;61605:21:0;-1:-1:-1;61677:18:0;;-1:-1:-1;61711:18:0;;-1:-1:-1;61065:673:0;;-1:-1:-1;;;61065:673:0:o;29412:76::-;29478:2;29412:76;:::o;58634:703::-;58711:7;58731:15;58749:30;58765:13;58749:15;:30::i;:::-;58731:48;;58790:19;58812:16;:14;:16::i;:::-;58790:38;-1:-1:-1;58929:16:0;;;:32;;-1:-1:-1;58949:12:0;;58929:32;58925:90;;;49380:5;58978:25;;;;;;58925:90;59151:22;59176:102;49559:6;59205:72;49380:5;59205:48;59241:11;59205:31;:7;49380:5;59205:31;:11;:31;:::i;:48::-;:52;:72;:52;:72;:::i;:::-;59176:8;:102::i;:::-;59151:127;-1:-1:-1;;;;58634:703:0;;;;:::o;50254:33::-;;;;:::o;50420:::-;;;;:::o;57440:1055::-;-1:-1:-1;;;;;57577:27:0;;57517:7;57577:27;;;:12;:27;;;;;57692:24;;57688:87;;49380:5;57738:25;;;;;57688:87;57883:29;;;;57855:25;;57883:51;;57917:16;57883:51;:33;:51;:::i;:::-;57855:79;;57964:17;57949:12;:32;57945:90;;;49380:5;57998:25;;;;;;57945:90;58232:17;58252:107;49380:5;58252:83;58320:14;58252:63;49923:5;58252:35;:12;58269:17;58252:35;:16;:35;:::i;:107::-;58232:127;;58373:22;58398:39;49742:5;58427:9;58398:8;:39::i;:::-;58373:64;57440:1055;-1:-1:-1;;;;;;57440:1055:0:o;29610:89::-;29690:1;29610:89;:::o;33040:377::-;33256:35;33270:12;:10;:12::i;:::-;33284:6;33256:13;:35::i;:::-;33248:92;;;;-1:-1:-1;;;33248:92:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33351:58;33357:6;33365:9;33376:6;33384:4;33390:12;33404:4;33351:5;:58::i;:::-;33040:377;;;;;:::o;29987:144::-;-1:-1:-1;;;;;30101:22:0;30074:7;30101:22;;;;;;;;;;;;29987:144::o;59438:790::-;-1:-1:-1;;;;;59566:27:0;;59506:7;59566:27;;;:12;:27;;;;;59657:24;;59722:30;;;;59861:24;59857:65;;59909:1;59902:8;;;;;;;59857:65;60111:15;60129:66;60175:19;60129:41;:19;49117:8;60129:41;:23;:41;:::i;60334:534::-;60380:7;60496:18;;60518:1;60496:23;60492:64;;;-1:-1:-1;60543:1:0;60536:8;;60492:64;60745:19;60767:64;60812:18;;60767:40;49117:8;60767:18;;:22;;:40;;;;:::i;:64::-;60745:86;-1:-1:-1;;60334:534:0;:::o;53493:924::-;45293:5;:19;45299:12;:10;:12::i;:::-;-1:-1:-1;;;;;45293:19:0;;;;;;;;;;;;-1:-1:-1;45293:19:0;;;;45290:168;;45360:4;45338:5;:19;45344:12;:10;:12::i;:::-;-1:-1:-1;;;;;45338:19:0;;;;;;;;;;;;-1:-1:-1;45338:19:0;:26;;;;;-1:-1:-1;;45338:26:0;;;;;;;;;53606:13;45338:26;-1:-1:-1;;;;;46156:27:0;::::1;;::::0;;;:12:::1;:27;::::0;;;;:34;46148:91:::1;;;;-1:-1:-1::0;;;46148:91:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53726:1:::2;53717:6;:10;53709:45;;;::::0;;-1:-1:-1;;;53709:45:0;;::::2;;::::0;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;53709:45:0;;;;;;;;;;;;;::::2;;-1:-1:-1::0;;;;;53807:27:0;::::2;53767:37;53807:27:::0;;;:12:::2;:27;::::0;;;;53946:30:::2;::::0;::::2;::::0;:42:::2;::::0;53981:6;53946:42:::2;:34;:42;:::i;:::-;53913:30;::::0;::::2;:75:::0;54022:18:::2;::::0;:30:::2;::::0;54045:6;54022:30:::2;:22;:30;:::i;:::-;54001:18;:51:::0;54078:52:::2;54094:12;:10;:12::i;:::-;54078:52;::::0;;-1:-1:-1;;;;;54078:52:0;;::::2;::::0;;;;::::2;;::::0;::::2;::::0;;;;;;;;;;;;;;;::::2;54309:35;54315:12;:10;:12::i;:::-;54329:6;54309:35;;;;;;;;;;;::::0;::::2;;;;;;;;;;;::::0;:5:::2;:35::i;:::-;46384:1;45379::::1;;45441:5:::0;45419;:19;45425:12;:10;:12::i;50096:52::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;50096:52:0;;:::o;31829:415::-;31926:8;-1:-1:-1;;;;;31910:24:0;:12;:10;:12::i;:::-;-1:-1:-1;;;;;31910:24:0;;;31902:73;;;;-1:-1:-1;;;31902:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;31992:27:0;;;;;;:17;:27;;;;;;;;31988:189;;;32043:24;:38;32068:12;:10;:12::i;:::-;-1:-1:-1;;;;;32043:38:0;;;;;;;;;;;;;;;;;-1:-1:-1;32043:38:0;;;:48;;;;;;;;;32036:55;;-1:-1:-1;;32036:55:0;;;31988:189;;;32161:4;32124:10;:24;32135:12;:10;:12::i;:::-;-1:-1:-1;;;;;32124:24:0;;;;;;;;;;;;;;;;;-1:-1:-1;32124:24:0;;;:34;;;;;;;;;:41;;-1:-1:-1;;32124:41:0;;;;;;;;;;31988:189;32223:12;:10;:12::i;:::-;-1:-1:-1;;;;;32194:42:0;32213:8;-1:-1:-1;;;;;32194:42:0;;;;;;;;;;;31829:415;:::o;29124:96::-;29205:7;29198:14;;;;;;;;-1:-1:-1;;29198:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29172:13;;29198:14;;29205:7;;29198:14;;29205:7;29198:14;;;;;;;;;;;;;;;;;;;;;;;;30268:158;30364:54;30370:12;:10;:12::i;:::-;30384:9;30395:6;30403:4;30364:54;;;;;;;;;;;;30413:4;30364:5;:54::i;:::-;30268:158;;;:::o;52599:810::-;45293:5;:19;45299:12;:10;:12::i;:::-;-1:-1:-1;;;;;45293:19:0;;;;;;;;;;;;-1:-1:-1;45293:19:0;;;;45290:168;;45360:4;45338:5;:19;45344:12;:10;:12::i;:::-;-1:-1:-1;;;;;45338:19:0;;;;;;;;;;;;-1:-1:-1;45338:19:0;:26;;-1:-1:-1;;45338:26:0;;;;;;;;;;52671:12:::1;:10;:12::i;:::-;-1:-1:-1::0;;;;;45724:27:0;::::1;;::::0;;;:12:::1;:27;::::0;;;;:39:::1;;::::0;45767:12:::1;45724:55;::::0;::::1;::::0;:122:::1;;-1:-1:-1::0;;;;;;45783:27:0;::::1;;::::0;;;:12:::1;:27;::::0;;;;:47:::1;;::::0;45834:12:::1;45783:63;;45724:122;45716:181;;;;-1:-1:-1::0;;;45716:181:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52708:12:::2;:10;:12::i;:::-;52722:4;-1:-1:-1::0;;;;;46156:27:0;::::2;;::::0;;;:12:::2;:27;::::0;;;;:34;46148:91:::2;;;;-1:-1:-1::0;;;46148:91:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52790:37:::3;52830:12;:26;52843:12;:10;:12::i;:::-;-1:-1:-1::0;;;;;52830:26:0::3;::::0;;::::3;::::0;::::3;::::0;;;;;;-1:-1:-1;52830:26:0;;;52907:24;;52942:28;;;53004:18:::3;::::0;52830:26;;-1:-1:-1;53004:30:0::3;::::0;52907:24;53004:30:::3;:22;:30;:::i;:::-;52983:18;:51:::0;53089:30:::3;::::0;::::3;::::0;53066:18:::3;::::0;:54:::3;::::0;::::3;:22;:54;:::i;:::-;53045:18;:75:::0;53138:62:::3;53147:12;:10;:12::i;:::-;53169:30;::::0;::::3;::::0;53138:62:::3;::::0;;-1:-1:-1;;;;;53138:62:0;;::::3;::::0;;::::3;::::0;::::3;::::0;;;;;;;;;;;;;;;;;;::::3;53297:6;-1:-1:-1::0;;;;;53289:20:0::3;;53310:12;:10;:12::i;:::-;53289:46;::::0;;-1:-1:-1;;;;;;53289:46:0::3;::::0;;;;;;-1:-1:-1;;;;;53289:46:0;;::::3;;::::0;::::3;::::0;;;;;;;;;;;;-1:-1:-1;53289:46:0;;;;;;;;;;;;;;;;;;-1:-1:-1;53289:46:0;;::::3;;::::0;::::3;;;;::::0;::::3;;;;;;;;;;;;::::0;::::3;;;;;;;;;46384:1;;45918::::2;;45379::::1;45441:5:::0;45419;:19;45425:12;:10;:12::i;:::-;-1:-1:-1;;;;;45419:19:0;;;;;;;;;;;;-1:-1:-1;45419:19:0;:27;;-1:-1:-1;;45419:27:0;;;;;;;;;;45290:168;52599:810::o;30667:443::-;30745:4;-1:-1:-1;;;;;30770:23:0;;30762:72;;;;-1:-1:-1;;;30762:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30847:12;30862;:10;:12::i;:::-;30847:27;;30887:56;30905:4;30911;30917:9;30928:6;30887:56;;;;;;;;;;;;;;;;;;;;;;;;:17;:56::i;:::-;30956:44;30962:4;30968;30974:9;30985:6;30956:44;;;;;;;;;;;;;;;;;;;;;;;;:5;:44::i;:::-;31013:65;31033:4;31039;31045:9;31056:6;31013:65;;;;;;;;;;;;;;;;;;;;;;;;31072:5;31013:19;:65::i;54549:1324::-;45293:5;:19;45299:12;:10;:12::i;:::-;-1:-1:-1;;;;;45293:19:0;;;;;;;;;;;;-1:-1:-1;45293:19:0;;;;45290:168;;45360:4;45338:5;:19;45344:12;:10;:12::i;:::-;-1:-1:-1;;;;;45338:19:0;;;;;;;;;;;;;;;;;-1:-1:-1;45338:19:0;;;:26;;-1:-1:-1;;45338:26:0;;;;;;;;;;;45724:27;::::1;::::0;;:12:::1;:27:::0;;;;;:39:::1;;::::0;:27;;45767:12:::1;45724:55;::::0;::::1;::::0;:122:::1;;-1:-1:-1::0;;;;;;45783:27:0;::::1;;::::0;;;:12:::1;:27;::::0;;;;:47:::1;;::::0;45834:12:::1;45783:63;;45724:122;45716:181;;;;-1:-1:-1::0;;;45716:181:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54731:13:::0;54746:4:::2;-1:-1:-1::0;;;;;46156:27:0;::::2;;::::0;;;:12:::2;:27;::::0;;;;:34;46148:91:::2;;;;-1:-1:-1::0;;;46148:91:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54863:12:::3;54848:11;:27;;54840:77;;;;-1:-1:-1::0;;;54840:77:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;54978:27:0;::::3;54938:37;54978:27:::0;;;:12:::3;:27;::::0;;;;55092:37:::3;::::0;::::3;::::0;:51;-1:-1:-1;55084:106:0::3;;;;-1:-1:-1::0;;;55084:106:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55244:12;:10;:12::i;:::-;55209:31;::::0;::::3;::::0;-1:-1:-1;;;;;55209:31:0;;::::3;:47:::0;::::3;;55201:113;;;;-1:-1:-1::0;;;55201:113:0::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55327:18;55348:41;55362:13;55377:11;55348:13;:41::i;:::-;55327:62;;55421:1;55408:10;:14;55400:56;;;::::0;;-1:-1:-1;;;55400:56:0;;::::3;;::::0;::::3;::::0;::::3;::::0;;;;::::3;::::0;;;;;;;;;;;;;::::3;;55477:37;::::0;::::3;:51:::0;;;55571:89:::3;55578:12;:10;:12::i;:::-;55571:89;::::0;;-1:-1:-1;;;;;55571:89:0;;::::3;::::0;;55592:12:::3;55571:89;::::0;::::3;::::0;;;::::3;::::0;;;;;;::::3;::::0;;;;;;;;;;;;;;;;;;;;;;;;::::3;55760:40;55766:13;55781:10;55760:40;;;;;;;;;;;::::0;::::3;;;;;;;;;;;::::0;:5:::3;:40::i;:::-;46384:1;;45918::::2;;45379::::1;45441:5:::0;45419;:19;45425:12;:10;:12::i;:::-;-1:-1:-1;;;;;45419:19:0;;;;;;;;;;;;-1:-1:-1;45419:19:0;:27;;-1:-1:-1;;45419:27:0;;;;;;;;;;-1:-1:-1;;;54549:1324:0:o;61943:547::-;62018:7;62026:4;62031:7;62039;62047;62067:19;62097:6;-1:-1:-1;;;;;62089:29:0;;62127:4;62134:13;62089:59;;;;;;;;;;;;;-1:-1:-1;;;;;62089:59:0;-1:-1:-1;;;;;62089:59:0;;;;;;-1:-1:-1;;;;;62089:59:0;-1:-1:-1;;;;;62089:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;62089:59:0;62180:40;;;-1:-1:-1;;;62180:40:0;;-1:-1:-1;;;;;62180:40:0;;;;;;;;;62089:59;;-1:-1:-1;;;62188:6:0;62180:25;;;;;;:40;;;;;62089:59;;62180:40;;;;;;;;:25;:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;62180:40:0;;-1:-1:-1;62233:15:0;62251:30;62267:13;62251:15;:30::i;:::-;62233:48;;62292:19;62314:16;:14;:16::i;:::-;62365:12;;62393:14;;-1:-1:-1;62423:10:0;;-1:-1:-1;62448:7:0;;-1:-1:-1;62393:14:0;;-1:-1:-1;61943:547:0;;-1:-1:-1;;;61943:547:0:o;31437:320::-;31554:4;31590:11;-1:-1:-1;;;;;31578:23:0;:8;-1:-1:-1;;;;;31578:23:0;;:121;;;-1:-1:-1;;;;;;31619:27:0;;;;;;:17;:27;;;;;;;;:79;;;;-1:-1:-1;;;;;;31651:37:0;;;;;;;:24;:37;;;;;;;;:47;;;;;;;;;;;;31650:48;31619:79;31578:171;;;-1:-1:-1;;;;;;31716:23:0;;;;;;;:10;:23;;;;;;;;:33;;;;;;;;;;;;31578:171;31571:178;31437:320;-1:-1:-1;;;31437:320:0:o;34075:145::-;-1:-1:-1;;;;;34184:19:0;;;34157:7;34184:19;;;:11;:19;;;;;;;;:28;;;;;;;;;;;;;34075:145::o;32313:406::-;32403:12;:10;:12::i;:::-;-1:-1:-1;;;;;32391:24:0;:8;-1:-1:-1;;;;;32391:24:0;;;32383:70;;;;-1:-1:-1;;;32383:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;32470:27:0;;;;;;:17;:27;;;;;;;;32466:189;;;32565:4;32514:24;:38;32539:12;:10;:12::i;:::-;-1:-1:-1;;;;;32514:38:0;;;;;;;;;;;;;;;;;-1:-1:-1;32514:38:0;;;:48;;;;;;;;;:55;;-1:-1:-1;;32514:55:0;;;;;;;;;;32466:189;;;32609:10;:24;32620:12;:10;:12::i;:::-;-1:-1:-1;;;;;32609:24:0;;;;;;;;;;;;;;;;;-1:-1:-1;32609:24:0;;;:34;;;;;;;;;32602:41;;-1:-1:-1;;32602:41:0;;;32466:189;32698:12;:10;:12::i;:::-;-1:-1:-1;;;;;32672:39:0;32688:8;-1:-1:-1;;;;;32672:39:0;;;;;;;;;;;32313:406;:::o;33545:282::-;33681:36;33695:12;:10;:12::i;:::-;33709:7;33681:13;:36::i;:::-;33673:93;;;;-1:-1:-1;;;33673:93:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33777:42;33783:7;33792:6;33800:4;33806:12;33777:5;:42::i;:::-;33545:282;;;;:::o;31247:122::-;31324:37;31330:12;:10;:12::i;:::-;31344:6;31352:4;31324:37;;;;;;;;;;;;:5;:37::i;13707:181::-;13765:7;13797:5;;;13821:6;;;;13813:46;;;;;-1:-1:-1;;;13813:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;804:106;892:10;804:106;:::o;39876:341::-;-1:-1:-1;;;;;39970:20:0;;39962:70;;;;-1:-1:-1;;;39962:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;40051:21:0;;40043:69;;;;-1:-1:-1;;;40043:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;40125:19:0;;;;;;;:11;:19;;;;;;;;:28;;;;;;;;;;;;;:36;;;40177:32;;;;;;;;;;;;;;;;;39876:341;;;:::o;14163:136::-;14221:7;14248:43;14252:1;14255;14248:43;;;;;;;;;;;;;;;;;:3;:43::i;15037:471::-;15095:7;15340:6;15336:47;;-1:-1:-1;15370:1:0;15363:8;;15336:47;15407:5;;;15411:1;15407;:5;:1;15431:5;;;;;:10;15423:56;;;;-1:-1:-1;;;15423:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15976:132;16034:7;16061:39;16065:1;16068;16061:39;;;;;;;;;;;;;;;;;:3;:39::i;40701:498::-;40954:78;;;-1:-1:-1;;;40954:78:0;;-1:-1:-1;;;;;40954:78:0;;;;;;27306:66;40954:78;;;;;;40932:19;;26827:42;;40954:41;;:78;;;;;;;;;;;;;;;26827:42;40954:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40954:78:0;;-1:-1:-1;;;;;;41047:25:0;;;41043:149;;41103:11;-1:-1:-1;;;;;41089:39:0;;41129:8;41139:4;41145:2;41149:6;41157:8;41167:12;41089:91;;;;;;;;;;;;;-1:-1:-1;;;;;41089:91:0;-1:-1:-1;;;;;41089:91:0;;;;;;-1:-1:-1;;;;;41089:91:0;-1:-1:-1;;;;;41089:91:0;;;;;;-1:-1:-1;;;;;41089:91:0;-1:-1:-1;;;;;41089:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41089:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41043:149;40701:498;;;;;;;:::o;39187:544::-;39406:48;39427:8;39437:4;39443:2;39447:6;39406:20;:48::i;:::-;39485:70;39505:6;39485:70;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;39485:15:0;;:9;:15;;;;;;;;;;;;:70;;:19;:70;:::i;:::-;-1:-1:-1;;;;;39467:15:0;;;:9;:15;;;;;;;;;;;:88;;;;39582:13;;;;;;;:25;;39600:6;39582:25;:17;:25;:::i;:::-;39566:9;:13;39576:2;-1:-1:-1;;;;;39566:13:0;-1:-1:-1;;;;;39566:13:0;;;;;;;;;;;;:41;;;;39646:2;-1:-1:-1;;;;;39625:56:0;39640:4;-1:-1:-1;;;;;39625:56:0;39630:8;-1:-1:-1;;;;;39625:56:0;;39650:6;39658:8;39668:12;39625:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;39625:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39712:2;-1:-1:-1;;;;;39697:26:0;39706:4;-1:-1:-1;;;;;39697:26:0;;39716:6;39697:26;;;;;;;;;;;;;;;;;;39187:544;;;;;;:::o;14594:192::-;14680:7;14716:12;14708:6;;;;14700:29;;;;-1:-1:-1;;;14700:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;14752:5:0;;;14594:192::o;41901:705::-;42191:79;;;-1:-1:-1;;;42191:79:0;;-1:-1:-1;;;;;42191:79:0;;;;;;27493:66;42191:79;;;;;;42169:19;;26827:42;;42191:41;;:79;;;;;;;;;;;;;;;26827:42;42191:79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42191:79:0;;-1:-1:-1;;;;;;42285:25:0;;;42281:318;;42344:11;-1:-1:-1;;;;;42327:44:0;;42372:8;42382:4;42388:2;42392:6;42400:8;42410:12;42327:96;;;;;;;;;;;;;-1:-1:-1;;;;;42327:96:0;-1:-1:-1;;;;;42327:96:0;;;;;;-1:-1:-1;;;;;42327:96:0;-1:-1:-1;;;;;42327:96:0;;;;;;-1:-1:-1;;;;;42327:96:0;-1:-1:-1;;;;;42327:96:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42327:96:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42281:318;;;42445:19;42441:158;;;42490:15;:2;-1:-1:-1;;;;;42490:13:0;;:15::i;:::-;42489:16;42481:106;;;;-1:-1:-1;;;42481:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43765;43823:7;43854:1;43850;:5;:13;;43862:1;43850:13;;;-1:-1:-1;43858:1:0;;43765:106;-1:-1:-1;43765:106:0:o;37443:674::-;-1:-1:-1;;;;;37679:18:0;;37671:65;;;;-1:-1:-1;;;37671:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;37755:16:0;;37747:61;;;;;-1:-1:-1;;;37747:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37821:16;37840:12;:10;:12::i;:::-;37821:31;;37865:69;37883:8;37893:4;37899:2;37903:6;37911:8;37921:12;37865:17;:69::i;:::-;37947:57;37953:8;37963:4;37969:2;37973:6;37981:8;37991:12;37947:5;:57::i;:::-;38017:92;38037:8;38047:4;38053:2;38057:6;38065:8;38075:12;38089:19;38017;:92::i;38431:748::-;-1:-1:-1;;;;;38615:18:0;;38607:65;;;;-1:-1:-1;;;38607:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38685:16;38704:12;:10;:12::i;:::-;38685:31;;38729:56;38750:8;38760:4;38774:1;38778:6;38729:20;:56::i;:::-;38798:73;38816:8;38826:4;38840:1;38844:6;38852:4;38858:12;38798:17;:73::i;:::-;38937:66;38957:6;38937:66;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;38937:15:0;;:9;:15;;;;;;;;;;;;:66;;:19;:66;:::i;:::-;-1:-1:-1;;;;;38919:15:0;;:9;:15;;;;;;;;;;:84;39029:12;;:24;;39046:6;39029:24;:16;:24;:::i;:::-;39014:12;:39;;;;39088:4;-1:-1:-1;;;;;39071:50:0;39078:8;-1:-1:-1;;;;;39071:50:0;;39094:6;39102:4;39108:12;39071:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;39071:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39137:34;;;;;;;;39160:1;;-1:-1:-1;;;;;39137:34:0;;;;;;;;;;;;38431:748;;;;;:::o;36209:747::-;-1:-1:-1;;;;;36396:21:0;;36388:66;;;;;-1:-1:-1;;;36388:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36467:16;36486:12;:10;:12::i;:::-;36467:31;;36511:59;36532:8;36550:1;36554:7;36563:6;36511:20;:59::i;:::-;36633:12;;:24;;36650:6;36633:24;:16;:24;:::i;:::-;36618:12;:39;-1:-1:-1;;;;;36689:18:0;;:9;:18;;;;;;;;;;;:30;;36712:6;36689:30;:22;:30;:::i;:::-;-1:-1:-1;;;;;36668:18:0;;:9;:18;;;;;;;;;;:51;;;;36732:88;;36752:8;;36678:7;36783:6;36791:8;36801:12;36815:4;36732:19;:88::i;:::-;36855:7;-1:-1:-1;;;;;36838:57:0;36845:8;-1:-1:-1;;;;;36838:57:0;;36864:6;36872:8;36882:12;36838:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36838:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36911:37;;;;;;;;-1:-1:-1;;;;;36911:37:0;;;36928:1;;36911:37;;;;;;;;;36209:747;;;;;:::o;16596:345::-;16682:7;16784:12;16777:5;16769:28;;;;-1:-1:-1;;;16769:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16808:9;16824:1;16820;:5;;;;;;;16596:345;-1:-1:-1;;;;;16596:345:0:o;18940:619::-;19000:4;19468:20;;19311:66;19508:23;;;;;;:42;;-1:-1:-1;19535:15:0;;;19508:42;19500:51;18940:619;-1:-1:-1;;;;18940:619:0:o

Swarm Source

ipfs://3fc6f0e643f8fd29e42709747a8844e0be38b1542153d3415e0f4e8ed57d9a6c
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.