ETH Price: $2,816.25 (-4.82%)
 

Overview

Max Total Supply

1,042,920.844926580161431625 xBSX

Holders

6,161

Market

Price

$0.00 @ 0.000000 ETH

Onchain Market Cap

-

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Filtered by Token Holder
hamiid.base.eth
Balance
0.945496101385859385 xBSX

Value
$0.00
0xB259739783eB116dA447C856db409Dd3F76E4F9a
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Contract Source Code Verified (Exact Match)

Contract Name:
xBSX

Compiler Version
v0.7.6+commit.7338295f

Optimization Enabled:
Yes with 5000 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at basescan.org on 2023-08-17
*/

// SPDX-License-Identifier: MIT
pragma solidity =0.7.6;

/*
 * @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.
 */
abstract contract Context {
    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;
    }
}

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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() internal {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

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

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

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

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

/**
 * @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, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

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

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

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

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

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        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) {
        require(b <= a, "SafeMath: subtraction overflow");
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        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, reverting 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) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

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

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

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * 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) {
        require(b > 0, errorMessage);
        return a / b;
    }

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

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

/**
 * @dev Implementation of the {IERC20} 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}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20 {
    using SafeMath for uint256;

    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;
    uint8 private _decimals;

    /**
     * @dev Sets the values for {name} and {symbol}, initializes {decimals} with
     * a default value of 18.
     *
     * To select a different value for {decimals}, use {_setupDecimals}.
     *
     * All three of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) public {
        _name = name_;
        _symbol = symbol_;
        _decimals = 18;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is
     * called.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual returns (uint8) {
        return _decimals;
    }

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

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(
            sender,
            _msgSender(),
            _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")
        );
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        _approve(
            _msgSender(),
            spender,
            _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")
        );
        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

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

        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

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

        _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Sets {decimals} to a value other than the default one of 18.
     *
     * WARNING: This function should only be called from the constructor. Most
     * applications that interact with token contracts will not expect
     * {decimals} to ever change, and may work incorrectly if it does.
     */
    function _setupDecimals(uint8 decimals_) internal virtual {
        _decimals = decimals_;
    }

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

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

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

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

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

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

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

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

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

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) private pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

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

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

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

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

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

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

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

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

interface IProtocolToken is IERC20 {
    function lastEmissionTime() external view returns (uint256);

    function claimMasterRewards(uint256 amount) external returns (uint256 effectiveAmount);

    function masterEmissionRate() external view returns (uint256);

    function burn(uint256 amount) external;
}

interface IXToken is IERC20 {
    function usageAllocations(address userAddress, address usageAddress) external view returns (uint256 allocation);

    function allocateFromUsage(address userAddress, uint256 amount) external;

    function convertTo(uint256 amount, address to) external;

    function deallocateFromUsage(address userAddress, uint256 amount) external;

    function isTransferWhitelisted(address account) external view returns (bool);
}

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            bytes32 lastvalue = set._values[lastIndex];

            // Move the last value to the index where the value to delete is
            set._values[toDeleteIndex] = lastvalue;
            // Update the index for the moved value
            set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        require(set._values.length > index, "EnumerableSet: index out of bounds");
        return set._values[index];
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }
}

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() internal {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

/**
 * This is the "plugin" mechanism described in the docs.
 * xToken relies on this interface for connecting different strategies/plugins/etc to the system.
 */
interface IXTokenUsage {
    function allocate(address userAddress, uint256 amount, bytes calldata data) external;

    function deallocate(address userAddress, uint256 amount, bytes calldata data) external;
}

/*
 * xBSX is Baseswaps's escrowed governance token obtainable by converting token to it
 * It's non-transferable, except from/to whitelisted addresses
 * It can be converted back to token through a vesting process
 * This contract is made to receive xToken deposits from users in order to allocate them to Usages (plugins) contracts
 */
contract xBSX is Ownable, ReentrancyGuard, ERC20("Baseswap escrowed token", "xBSX"), IXToken {
    using Address for address;
    using SafeMath for uint256;
    using EnumerableSet for EnumerableSet.AddressSet;
    using SafeERC20 for IProtocolToken;

    struct xTokenBalance {
        uint256 allocatedAmount; // Amount of xToken allocated to a Usage
        uint256 redeemingAmount; // Total amount of xToken currently being redeemed
    }

    struct RedeemInfo {
        uint256 amount; // token amount to receive when vesting has ended
        uint256 xTokenAmount; // xToken amount to redeem
        uint256 endTime;
        IXTokenUsage dividendsAddress;
        uint256 dividendsAllocation; // Share of redeeming xToken to allocate to the Dividends Usage contract
    }

    IProtocolToken public immutable protocolToken; // token to convert to/from
    IXTokenUsage public dividendsAddress; // dividends contract

    EnumerableSet.AddressSet private _transferWhitelist; // addresses allowed to send/receive xToken

    mapping(address => mapping(address => uint256)) public usageApprovals; // Usage approvals to allocate xToken
    mapping(address => mapping(address => uint256)) public override usageAllocations; // Active xToken allocations to usages

    uint256 public constant MAX_DEALLOCATION_FEE = 200; // 2%
    mapping(address => uint256) public usagesDeallocationFee; // Fee paid when deallocating xToken

    uint256 public constant MAX_FIXED_RATIO = 100; // 100%

    // Redeeming min/max settings
    uint256 public minRedeemRatio = 50; // 1:0.5
    uint256 public maxRedeemRatio = 100; // 1:1
    uint256 public minRedeemDuration = 15 days; // 1296000s
    uint256 public maxRedeemDuration = 90 days; // 7776000s
    // Adjusted dividends rewards for redeeming xToken
    uint256 public redeemDividendsAdjustment = 50; // 50%

    mapping(address => xTokenBalance) public xTokenBalances; // User's xToken balances
    mapping(address => RedeemInfo[]) public userRedeems; // User's redeeming instances

    constructor(IProtocolToken token) {
        protocolToken = token;
        _transferWhitelist.add(address(this));
    }

    /********************************************/
    /****************** EVENTS ******************/
    /********************************************/

    event ApproveUsage(address indexed userAddress, address indexed usageAddress, uint256 amount);
    event Convert(address indexed from, address to, uint256 amount);
    event UpdateRedeemSettings(
        uint256 minRedeemRatio,
        uint256 maxRedeemRatio,
        uint256 minRedeemDuration,
        uint256 maxRedeemDuration,
        uint256 redeemDividendsAdjustment
    );
    event UpdateDividendsAddress(address previousDividendsAddress, address newDividendsAddress);
    event UpdateDeallocationFee(address indexed usageAddress, uint256 fee);
    event SetTransferWhitelist(address account, bool add);
    event Redeem(address indexed userAddress, uint256 xTokenAmount, uint256 amount, uint256 duration);
    event FinalizeRedeem(address indexed userAddress, uint256 xTokenAmount, uint256 amount);
    event CancelRedeem(address indexed userAddress, uint256 xTokenAmount);
    event UpdateRedeemDividendsAddress(
        address indexed userAddress,
        uint256 redeemIndex,
        address previousDividendsAddress,
        address newDividendsAddress
    );
    event Allocate(address indexed userAddress, address indexed usageAddress, uint256 amount);
    event Deallocate(address indexed userAddress, address indexed usageAddress, uint256 amount, uint256 fee);

    /***********************************************/
    /****************** MODIFIERS ******************/
    /***********************************************/

    /*
     * @dev Check if a redeem entry exists
     */
    modifier validateRedeem(address userAddress, uint256 redeemIndex) {
        require(redeemIndex < userRedeems[userAddress].length, "validateRedeem: redeem entry does not exist");
        _;
    }

    /**************************************************/
    /****************** PUBLIC VIEWS ******************/
    /**************************************************/

    /*
     * @dev Returns user's xToken balances
     */
    function getxTokenBalance(
        address userAddress
    ) external view returns (uint256 allocatedAmount, uint256 redeemingAmount) {
        xTokenBalance storage balance = xTokenBalances[userAddress];
        return (balance.allocatedAmount, balance.redeemingAmount);
    }

    /*
     * @dev returns redeemable token for "amount" of xToken vested for "duration" seconds
     */
    function getAmountByVestingDuration(uint256 amount, uint256 duration) public view returns (uint256) {
        if (duration < minRedeemDuration) {
            return 0;
        }

        // capped to maxRedeemDuration
        if (duration > maxRedeemDuration) {
            return amount.mul(maxRedeemRatio).div(100);
        }

        uint256 ratio = minRedeemRatio.add(
            (duration.sub(minRedeemDuration)).mul(maxRedeemRatio.sub(minRedeemRatio)).div(
                maxRedeemDuration.sub(minRedeemDuration)
            )
        );

        return amount.mul(ratio).div(100);
    }

    /**
     * @dev returns quantity of "userAddress" pending redeems
     */
    function getUserRedeemsLength(address userAddress) external view returns (uint256) {
        return userRedeems[userAddress].length;
    }

    /**
     * @dev returns "userAddress" info for a pending redeem identified by "redeemIndex"
     */
    function getUserRedeem(
        address userAddress,
        uint256 redeemIndex
    )
        external
        view
        validateRedeem(userAddress, redeemIndex)
        returns (
            uint256 amount,
            uint256 xTokenAmount,
            uint256 endTime,
            address dividendsContract,
            uint256 dividendsAllocation
        )
    {
        RedeemInfo storage _redeem = userRedeems[userAddress][redeemIndex];
        return (
            _redeem.amount,
            _redeem.xTokenAmount,
            _redeem.endTime,
            address(_redeem.dividendsAddress),
            _redeem.dividendsAllocation
        );
    }

    /**
     * @dev returns approved xToken to allocate from "userAddress" to "usageAddress"
     */
    function getUsageApproval(address userAddress, address usageAddress) external view returns (uint256) {
        return usageApprovals[userAddress][usageAddress];
    }

    /**
     * @dev returns allocated xToken from "userAddress" to "usageAddress"
     */
    function getUsageAllocation(address userAddress, address usageAddress) external view returns (uint256) {
        return usageAllocations[userAddress][usageAddress];
    }

    /**
     * @dev returns length of transferWhitelist array
     */
    function transferWhitelistLength() external view returns (uint256) {
        return _transferWhitelist.length();
    }

    /**
     * @dev returns transferWhitelist array item's address for "index"
     */
    function transferWhitelist(uint256 index) external view returns (address) {
        return _transferWhitelist.at(index);
    }

    /**
     * @dev returns if "account" is allowed to send/receive xToken
     */
    function isTransferWhitelisted(address account) external view override returns (bool) {
        return _transferWhitelist.contains(account);
    }

    /*******************************************************/
    /****************** OWNABLE FUNCTIONS ******************/
    /*******************************************************/

    /**
     * @dev Updates all redeem ratios and durations
     *
     * Must only be called by owner
     */
    function updateRedeemSettings(
        uint256 minRedeemRatio_,
        uint256 maxRedeemRatio_,
        uint256 minRedeemDuration_,
        uint256 maxRedeemDuration_,
        uint256 redeemDividendsAdjustment_
    ) external onlyOwner {
        require(minRedeemRatio_ <= maxRedeemRatio_, "updateRedeemSettings: wrong ratio values");
        require(minRedeemDuration_ < maxRedeemDuration_, "updateRedeemSettings: wrong duration values");
        // should never exceed 100%
        require(
            maxRedeemRatio_ <= MAX_FIXED_RATIO && redeemDividendsAdjustment_ <= MAX_FIXED_RATIO,
            "updateRedeemSettings: wrong ratio values"
        );

        minRedeemRatio = minRedeemRatio_;
        maxRedeemRatio = maxRedeemRatio_;
        minRedeemDuration = minRedeemDuration_;
        maxRedeemDuration = maxRedeemDuration_;
        redeemDividendsAdjustment = redeemDividendsAdjustment_;

        emit UpdateRedeemSettings(
            minRedeemRatio_,
            maxRedeemRatio_,
            minRedeemDuration_,
            maxRedeemDuration_,
            redeemDividendsAdjustment_
        );
    }

    /**
     * @dev Updates dividends contract address
     *
     * Must only be called by owner
     */
    function updateDividendsAddress(IXTokenUsage dividendsAddress_) external onlyOwner {
        // if set to 0, also set divs earnings while redeeming to 0
        if (address(dividendsAddress_) == address(0)) {
            redeemDividendsAdjustment = 0;
        }

        emit UpdateDividendsAddress(address(dividendsAddress), address(dividendsAddress_));
        dividendsAddress = dividendsAddress_;
    }

    /**
     * @dev Updates fee paid by users when deallocating from "usageAddress"
     */
    function updateDeallocationFee(address usageAddress, uint256 fee) external onlyOwner {
        require(fee <= MAX_DEALLOCATION_FEE, "updateDeallocationFee: too high");

        usagesDeallocationFee[usageAddress] = fee;
        emit UpdateDeallocationFee(usageAddress, fee);
    }

    /**
     * @dev Adds or removes addresses from the transferWhitelist
     */
    function updateTransferWhitelist(address account, bool add) external onlyOwner {
        require(account != address(this), "updateTransferWhitelist: Cannot remove xToken from whitelist");

        if (add) _transferWhitelist.add(account);
        else _transferWhitelist.remove(account);

        emit SetTransferWhitelist(account, add);
    }

    /*****************************************************************/
    /******************  EXTERNAL PUBLIC FUNCTIONS  ******************/
    /*****************************************************************/

    /**
     * @dev Approves "usage" address to get allocations up to "amount" of xToken from msg.sender
     * IXTokenUsageenUsage is the systems plugin interface.
     */
    function approveUsage(IXTokenUsage usage, uint256 amount) external nonReentrant {
        require(address(usage) != address(0), "approveUsage: approve to the zero address");

        usageApprovals[msg.sender][address(usage)] = amount;
        emit ApproveUsage(msg.sender, address(usage), amount);
    }

    /**
     * @dev Convert caller's "amount" of token to xToken
     */
    function convert(uint256 amount) external nonReentrant {
        _convert(amount, msg.sender);
    }

    /**
     * @dev Convert caller's "amount" of token to xToken to "to" address
     */
    function convertTo(uint256 amount, address to) external override nonReentrant {
        require(address(msg.sender).isContract(), "convertTo: not allowed");
        _convert(amount, to);
    }

    /**
     * @dev Initiates redeem process (xToken to token)
     *
     * Handles dividends' compensation allocation during the vesting process if needed
     */
    function redeem(uint256 xTokenAmount, uint256 duration) external nonReentrant {
        require(xTokenAmount > 0, "redeem: xTokenAmount cannot be null");
        require(duration >= minRedeemDuration, "redeem: duration too low");

        _transfer(msg.sender, address(this), xTokenAmount);
        xTokenBalance storage balance = xTokenBalances[msg.sender];

        // get corresponding token amount
        uint256 amount = getAmountByVestingDuration(xTokenAmount, duration);
        emit Redeem(msg.sender, xTokenAmount, amount, duration);

        // if redeeming is not immediate, go through vesting process
        if (duration > 0) {
            // add to SBT total
            balance.redeemingAmount = balance.redeemingAmount.add(xTokenAmount);

            // handle dividends during the vesting process
            uint256 dividendsAllocation = xTokenAmount.mul(redeemDividendsAdjustment).div(100);
            // only if compensation is active
            if (dividendsAllocation > 0) {
                // allocate to dividends
                dividendsAddress.allocate(msg.sender, dividendsAllocation, new bytes(0));
            }

            // add redeeming entry
            userRedeems[msg.sender].push(
                RedeemInfo(
                    amount,
                    xTokenAmount,
                    _currentBlockTimestamp().add(duration),
                    dividendsAddress,
                    dividendsAllocation
                )
            );
        } else {
            // immediately redeem for token
            _finalizeRedeem(msg.sender, xTokenAmount, amount);
        }
    }

    /**
     * @dev Finalizes redeem process when vesting duration has been reached
     *
     * Can only be called by the redeem entry owner
     */
    function finalizeRedeem(uint256 redeemIndex) external nonReentrant validateRedeem(msg.sender, redeemIndex) {
        xTokenBalance storage balance = xTokenBalances[msg.sender];
        RedeemInfo storage _redeem = userRedeems[msg.sender][redeemIndex];
        require(_currentBlockTimestamp() >= _redeem.endTime, "finalizeRedeem: vesting duration has not ended yet");

        // remove from SBT total
        balance.redeemingAmount = balance.redeemingAmount.sub(_redeem.xTokenAmount);
        _finalizeRedeem(msg.sender, _redeem.xTokenAmount, _redeem.amount);

        // handle dividends compensation if any was active
        if (_redeem.dividendsAllocation > 0) {
            // deallocate from dividends
            IXTokenUsage(_redeem.dividendsAddress).deallocate(msg.sender, _redeem.dividendsAllocation, new bytes(0));
        }

        // remove redeem entry
        _deleteRedeemEntry(redeemIndex);
    }

    /**
     * @dev Updates dividends address for an existing active redeeming process
     *
     * Can only be called by the involved user
     * Should only be used if dividends contract was to be migrated
     */
    function updateRedeemDividendsAddress(
        uint256 redeemIndex
    ) external nonReentrant validateRedeem(msg.sender, redeemIndex) {
        RedeemInfo storage _redeem = userRedeems[msg.sender][redeemIndex];

        // only if the active dividends contract is not the same anymore
        if (dividendsAddress != _redeem.dividendsAddress && address(dividendsAddress) != address(0)) {
            if (_redeem.dividendsAllocation > 0) {
                // deallocate from old dividends contract
                _redeem.dividendsAddress.deallocate(msg.sender, _redeem.dividendsAllocation, new bytes(0));
                // allocate to new used dividends contract
                dividendsAddress.allocate(msg.sender, _redeem.dividendsAllocation, new bytes(0));
            }

            emit UpdateRedeemDividendsAddress(
                msg.sender,
                redeemIndex,
                address(_redeem.dividendsAddress),
                address(dividendsAddress)
            );
            _redeem.dividendsAddress = dividendsAddress;
        }
    }

    /**
     * @dev Cancels an ongoing redeem entry
     *
     * Can only be called by its owner
     */
    function cancelRedeem(uint256 redeemIndex) external nonReentrant validateRedeem(msg.sender, redeemIndex) {
        xTokenBalance storage balance = xTokenBalances[msg.sender];
        RedeemInfo storage _redeem = userRedeems[msg.sender][redeemIndex];

        // make redeeming xToken available again
        balance.redeemingAmount = balance.redeemingAmount.sub(_redeem.xTokenAmount);
        _transfer(address(this), msg.sender, _redeem.xTokenAmount);

        // handle dividends compensation if any was active
        if (_redeem.dividendsAllocation > 0) {
            // deallocate from dividends
            IXTokenUsage(_redeem.dividendsAddress).deallocate(msg.sender, _redeem.dividendsAllocation, new bytes(0));
        }

        emit CancelRedeem(msg.sender, _redeem.xTokenAmount);

        // remove redeem entry
        _deleteRedeemEntry(redeemIndex);
    }

    /**
     * @dev Allocates caller's "amount" of available xToken to "usageAddress" contract
     *
     * args specific to usage contract must be passed into "usageData"
     */
    function allocate(address usageAddress, uint256 amount, bytes calldata usageData) external nonReentrant {
        _allocate(msg.sender, usageAddress, amount);

        // allocates xToken to usageContract
        IXTokenUsage(usageAddress).allocate(msg.sender, amount, usageData);
    }

    /**
     * @dev Allocates "amount" of available xToken from "userAddress" to caller (ie usage contract)
     *
     * Caller must have an allocation approval for the required xToken from "userAddress"
     */
    function allocateFromUsage(address userAddress, uint256 amount) external override nonReentrant {
        _allocate(userAddress, msg.sender, amount);
    }

    /**
     * @dev Deallocates caller's "amount" of available xToken from "usageAddress" contract
     *
     * args specific to usage contract must be passed into "usageData"
     */
    function deallocate(address usageAddress, uint256 amount, bytes calldata usageData) external nonReentrant {
        _deallocate(msg.sender, usageAddress, amount);

        // deallocate xToken into usageContract
        IXTokenUsage(usageAddress).deallocate(msg.sender, amount, usageData);
    }

    /**
     * @dev Deallocates "amount" of allocated xToken belonging to "userAddress" from caller (ie usage contract)
     *
     * Caller can only deallocate xToken from itself
     */
    function deallocateFromUsage(address userAddress, uint256 amount) external override nonReentrant {
        _deallocate(userAddress, msg.sender, amount);
    }

    /********************************************************/
    /****************** INTERNAL FUNCTIONS ******************/
    /********************************************************/

    /**
     * @dev Convert caller's "amount" of token into xToken to "to"
     */
    function _convert(uint256 amount, address to) internal {
        require(amount != 0, "convert: amount cannot be null");

        // mint new xToken
        _mint(to, amount);

        emit Convert(msg.sender, to, amount);
        protocolToken.safeTransferFrom(msg.sender, address(this), amount);
    }

    /**
     * @dev Finalizes the redeeming process for "userAddress" by transferring him "amount" and removing "xTokenAmount" from supply
     *
     * Any vesting check should be ran before calling this
     * token excess is automatically burnt
     */
    function _finalizeRedeem(address userAddress, uint256 xTokenAmount, uint256 amount) internal {
        uint256 excess = xTokenAmount.sub(amount);

        // sends due xToken tokens
        protocolToken.safeTransfer(userAddress, amount);

        // burns token excess if any
        protocolToken.burn(excess);
        _burn(address(this), xTokenAmount);

        emit FinalizeRedeem(userAddress, xTokenAmount, amount);
    }

    /**
     * @dev Allocates "userAddress" user's "amount" of available xToken to "usageAddress" contract
     *
     */
    function _allocate(address userAddress, address usageAddress, uint256 amount) internal {
        require(amount > 0, "allocate: amount cannot be null");

        xTokenBalance storage balance = xTokenBalances[userAddress];

        // approval checks if allocation request amount has been approved by userAddress to be allocated to this usageAddress
        uint256 approvedxToken = usageApprovals[userAddress][usageAddress];
        require(approvedxToken >= amount, "allocate: non authorized amount");

        // remove allocated amount from usage's approved amount
        usageApprovals[userAddress][usageAddress] = approvedxToken.sub(amount);

        // update usage's allocatedAmount for userAddress
        usageAllocations[userAddress][usageAddress] = usageAllocations[userAddress][usageAddress].add(amount);

        // adjust user's xToken balances
        balance.allocatedAmount = balance.allocatedAmount.add(amount);
        _transfer(userAddress, address(this), amount);

        emit Allocate(userAddress, usageAddress, amount);
    }

    /**
     * @dev Deallocates "amount" of available xToken to "usageAddress" contract
     *
     * args specific to usage contract must be passed into "usageData"
     */
    function _deallocate(address userAddress, address usageAddress, uint256 amount) internal {
        require(amount > 0, "deallocate: amount cannot be null");

        // check if there is enough allocated xToken to this usage to deallocate
        uint256 allocatedAmount = usageAllocations[userAddress][usageAddress];
        require(allocatedAmount >= amount, "deallocate: non authorized amount");

        // remove deallocated amount from usage's allocation
        usageAllocations[userAddress][usageAddress] = allocatedAmount.sub(amount);

        uint256 deallocationFeeAmount = amount.mul(usagesDeallocationFee[usageAddress]).div(10000);

        // adjust user's xToken balances
        xTokenBalance storage balance = xTokenBalances[userAddress];
        balance.allocatedAmount = balance.allocatedAmount.sub(amount);
        _transfer(address(this), userAddress, amount.sub(deallocationFeeAmount));
        // burn corresponding token and xToken
        protocolToken.burn(deallocationFeeAmount);
        _burn(address(this), deallocationFeeAmount);

        emit Deallocate(userAddress, usageAddress, amount, deallocationFeeAmount);
    }

    function _deleteRedeemEntry(uint256 index) internal {
        userRedeems[msg.sender][index] = userRedeems[msg.sender][userRedeems[msg.sender].length - 1];
        userRedeems[msg.sender].pop();
    }

    /**
     * @dev Hook override to forbid transfers except from whitelisted addresses and minting
     */
    function _beforeTokenTransfer(address from, address to, uint256 /*amount*/) internal view override {
        require(
            from == address(0) || _transferWhitelist.contains(from) || _transferWhitelist.contains(to),
            "transfer: not allowed"
        );
    }

    /**
     * @dev Utility function to get the current block timestamp
     */
    function _currentBlockTimestamp() internal view virtual returns (uint256) {
        /* solhint-disable not-rely-on-time */
        return block.timestamp;
    }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"contract IProtocolToken","name":"token","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"userAddress","type":"address"},{"indexed":true,"internalType":"address","name":"usageAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Allocate","type":"event"},{"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":"userAddress","type":"address"},{"indexed":true,"internalType":"address","name":"usageAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ApproveUsage","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"userAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"xTokenAmount","type":"uint256"}],"name":"CancelRedeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Convert","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"userAddress","type":"address"},{"indexed":true,"internalType":"address","name":"usageAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"Deallocate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"userAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"xTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FinalizeRedeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"userAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"xTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"}],"name":"Redeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"add","type":"bool"}],"name":"SetTransferWhitelist","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":true,"internalType":"address","name":"usageAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"UpdateDeallocationFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousDividendsAddress","type":"address"},{"indexed":false,"internalType":"address","name":"newDividendsAddress","type":"address"}],"name":"UpdateDividendsAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"userAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"redeemIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"previousDividendsAddress","type":"address"},{"indexed":false,"internalType":"address","name":"newDividendsAddress","type":"address"}],"name":"UpdateRedeemDividendsAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"minRedeemRatio","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxRedeemRatio","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"minRedeemDuration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxRedeemDuration","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"redeemDividendsAdjustment","type":"uint256"}],"name":"UpdateRedeemSettings","type":"event"},{"inputs":[],"name":"MAX_DEALLOCATION_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_FIXED_RATIO","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"usageAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"usageData","type":"bytes"}],"name":"allocate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"allocateFromUsage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","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":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IXTokenUsage","name":"usage","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approveUsage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"redeemIndex","type":"uint256"}],"name":"cancelRedeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"convert","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"convertTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"usageAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"usageData","type":"bytes"}],"name":"deallocate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deallocateFromUsage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"dividendsAddress","outputs":[{"internalType":"contract IXTokenUsage","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"redeemIndex","type":"uint256"}],"name":"finalizeRedeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"getAmountByVestingDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"address","name":"usageAddress","type":"address"}],"name":"getUsageAllocation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"address","name":"usageAddress","type":"address"}],"name":"getUsageApproval","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"redeemIndex","type":"uint256"}],"name":"getUserRedeem","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"xTokenAmount","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"address","name":"dividendsContract","type":"address"},{"internalType":"uint256","name":"dividendsAllocation","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"getUserRedeemsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"getxTokenBalance","outputs":[{"internalType":"uint256","name":"allocatedAmount","type":"uint256"},{"internalType":"uint256","name":"redeemingAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isTransferWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxRedeemDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxRedeemRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minRedeemDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minRedeemRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolToken","outputs":[{"internalType":"contract IProtocolToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"xTokenAmount","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"redeemDividendsAdjustment","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"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":"sender","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":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"transferWhitelist","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"transferWhitelistLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"usageAddress","type":"address"},{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"updateDeallocationFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IXTokenUsage","name":"dividendsAddress_","type":"address"}],"name":"updateDividendsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"redeemIndex","type":"uint256"}],"name":"updateRedeemDividendsAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minRedeemRatio_","type":"uint256"},{"internalType":"uint256","name":"maxRedeemRatio_","type":"uint256"},{"internalType":"uint256","name":"minRedeemDuration_","type":"uint256"},{"internalType":"uint256","name":"maxRedeemDuration_","type":"uint256"},{"internalType":"uint256","name":"redeemDividendsAdjustment_","type":"uint256"}],"name":"updateRedeemSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"add","type":"bool"}],"name":"updateTransferWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"usageAllocations","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"usageApprovals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"usagesDeallocationFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userRedeems","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"xTokenAmount","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"contract IXTokenUsage","name":"dividendsAddress","type":"address"},{"internalType":"uint256","name":"dividendsAllocation","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"xTokenBalances","outputs":[{"internalType":"uint256","name":"allocatedAmount","type":"uint256"},{"internalType":"uint256","name":"redeemingAmount","type":"uint256"}],"stateMutability":"view","type":"function"}]

60a06040526032600d556064600e556213c680600f556276a70060105560326011553480156200002e57600080fd5b506040516200436738038062004367833981810160405260208110156200005457600080fd5b5051604080518082018252601781527f426173657377617020657363726f77656420746f6b656e000000000000000000602082810191909152825180840190935260048352630f084a6b60e31b90830152906000620000b262000170565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35060018055815162000115906005906020850190620001fb565b5080516200012b906006906020840190620001fb565b505060078054601260ff1990911617905550606081901b6001600160601b0319166080526200016860083062000174602090811b620029e717901c565b5050620002a7565b3390565b60006200018b836001600160a01b03841662000194565b90505b92915050565b6000620001a28383620001e3565b620001da575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200018e565b5060006200018e565b60009081526001919091016020526040902054151590565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200023357600085556200027e565b82601f106200024e57805160ff19168380011785556200027e565b828001600101855582156200027e579182015b828111156200027e57825182559160200191906001019062000261565b506200028c92915062000290565b5090565b5b808211156200028c576000815560010162000291565b60805160601c61408e620002d96000398061101152806131f35280613386528061349152806134ba525061408e6000f3fe608060405234801561001057600080fd5b506004361061034c5760003560e01c8063549230c9116101bd578063a3908e1b116100f9578063c4b10766116100a2578063e3a2950b1161007c578063e3a2950b14610b05578063e9ed87f814610b0d578063f2fde38b14610b15578063f7a0a88514610b3b5761034c565b8063c4b1076614610aa3578063cc6c542314610aab578063dd62ed3e14610ad75761034c565b8063aff6cbf1116100d3578063aff6cbf114610a34578063b90c2b5214610a51578063c360ed1c14610a775761034c565b8063a3908e1b146109bf578063a457c2d7146109dc578063a9059cbb14610a085761034c565b80637cbc2373116101665780638da5cb5b116101405780638da5cb5b1461096057806395d89b411461096857806399cd11ea14610970578063a0bdc7cb146109935761034c565b80637cbc2373146108e9578063890836541461090c5780638975f9181461093a5761034c565b8063619ac95b11610197578063619ac95b146108b357806370a08231146108bb578063715018a6146108e15761034c565b8063549230c9146107c35780635a1d34dc146108485780635b7b5281146108745761034c565b80632b4896791161028c5780633b90f9a0116102355780634a5b406e1161020f5780634a5b406e146107215780634b359d38146107295780634f62b7ec14610746578063539ffb77146107a65761034c565b80633b90f9a0146106bf578063488c8303146106eb578063497965ee146107195761034c565b806331124ce31161026657806331124ce314610658578063313ce5671461067557806339509351146106935761034c565b80632b489679146105ce5780632cc2f5ce146105fc5780632e9a76e41461062a5761034c565b8063161aab43116102f95780631c352679116102d35780631c352679146104e55780631c75e369146104ed5780631eee7e601461057257806323b872dd146105985761034c565b8063161aab43146104b157806318160ddd146104b95780631a465fe1146104c15761034c565b8063093220b71161032a578063093220b714610410578063095ea7b3146104455780630f7d3a69146104855761034c565b806302f91e551461035157806306045a211461036b57806306fdde0314610393575b600080fd5b610359610b61565b60408051918252519081900360200190f35b6103916004803603602081101561038157600080fd5b50356001600160a01b0316610b66565b005b61039b610c7a565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103d55781810151838201526020016103bd565b50505050905090810190601f1680156104025780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610391600480360360a081101561042657600080fd5b5080359060208101359060408101359060608101359060800135610d10565b6104716004803603604081101561045b57600080fd5b506001600160a01b038135169060200135610ebc565b604080519115158252519081900360200190f35b6103916004803603604081101561049b57600080fd5b506001600160a01b038135169060200135610eda565b610359610ff8565b610359611009565b6104c961100f565b604080516001600160a01b039092168252519081900360200190f35b610359611033565b6103916004803603606081101561050357600080fd5b6001600160a01b038235169160208101359181019060608101604082013564010000000081111561053357600080fd5b82018360208201111561054557600080fd5b8035906020019184600183028401116401000000008311171561056757600080fd5b509092509050611039565b6104716004803603602081101561058857600080fd5b50356001600160a01b031661114e565b610471600480360360608110156105ae57600080fd5b506001600160a01b0381358116916020810135909116906040013561115b565b610359600480360360408110156105e457600080fd5b506001600160a01b03813581169160200135166111e3565b6103596004803603604081101561061257600080fd5b506001600160a01b038135811691602001351661120e565b6103596004803603604081101561064057600080fd5b506001600160a01b038135811691602001351661122b565b6103916004803603602081101561066e57600080fd5b5035611256565b61067d61162b565b6040805160ff9092168252519081900360200190f35b610471600480360360408110156106a957600080fd5b506001600160a01b038135169060200135611634565b610391600480360360408110156106d557600080fd5b506001600160a01b038135169060200135611682565b6103596004803603604081101561070157600080fd5b506001600160a01b03813581169160200135166116f2565b6104c961170f565b610359611723565b6104c96004803603602081101561073f57600080fd5b5035611729565b6107726004803603604081101561075c57600080fd5b506001600160a01b038135169060200135611736565b604080519586526020860194909452848401929092526001600160a01b031660608401526080830152519081900360a00190f35b610391600480360360208110156107bc57600080fd5b503561178d565b610391600480360360608110156107d957600080fd5b6001600160a01b038235169160208101359181019060608101604082013564010000000081111561080957600080fd5b82018360208201111561081b57600080fd5b8035906020019184600183028401116401000000008311171561083d57600080fd5b509092509050611a02565b6103916004803603604081101561085e57600080fd5b50803590602001356001600160a01b0316611af5565b61089a6004803603602081101561088a57600080fd5b50356001600160a01b0316611bb6565b6040805192835260208301919091528051918290030190f35b610359611bcf565b610359600480360360208110156108d157600080fd5b50356001600160a01b0316611bd4565b610391611bef565b610391600480360360408110156108ff57600080fd5b5080359060200135611cc5565b6103916004803603604081101561092257600080fd5b506001600160a01b038135169060200135151561204b565b6103596004803603602081101561095057600080fd5b50356001600160a01b0316612174565b6104c9612186565b61039b612195565b6103596004803603604081101561098657600080fd5b50803590602001356121f6565b610391600480360360408110156109a957600080fd5b506001600160a01b0381351690602001356122a4565b610391600480360360208110156109d557600080fd5b503561230c565b610471600480360360408110156109f257600080fd5b506001600160a01b03813516906020013561237a565b61047160048036036040811015610a1e57600080fd5b506001600160a01b0381351690602001356123e2565b61039160048036036020811015610a4a57600080fd5b50356123f6565b61035960048036036020811015610a6757600080fd5b50356001600160a01b031661266c565b61039160048036036040811015610a8d57600080fd5b506001600160a01b038135169060200135612687565b61035961278f565b61077260048036036040811015610ac157600080fd5b506001600160a01b038135169060200135612795565b61035960048036036040811015610aed57600080fd5b506001600160a01b0381358116916020013516612861565b61035961288c565b610359612892565b61039160048036036020811015610b2b57600080fd5b50356001600160a01b0316612898565b61089a60048036036020811015610b5157600080fd5b50356001600160a01b03166129c4565b60c881565b610b6e6129fc565b6001600160a01b0316610b7f612186565b6001600160a01b031614610bda576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b038116610bee5760006011555b600754604080516001600160a01b0361010090930483168152918316602083015280517f044c75b8fa43ce72364b4c23fdb8451beafbda46505bf44c76f0853a01ed4ade9281900390910190a1600780546001600160a01b03909216610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff909216919091179055565b60058054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610d065780601f10610cdb57610100808354040283529160200191610d06565b820191906000526020600020905b815481529060010190602001808311610ce957829003601f168201915b5050505050905090565b610d186129fc565b6001600160a01b0316610d29612186565b6001600160a01b031614610d84576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b83851115610dc35760405162461bcd60e51b8152600401808060200182810382526028815260200180613db76028913960400191505060405180910390fd5b818310610e015760405162461bcd60e51b815260040180806020018281038252602b815260200180613ddf602b913960400191505060405180910390fd5b60648411158015610e13575060648111155b610e4e5760405162461bcd60e51b8152600401808060200182810382526028815260200180613db76028913960400191505060405180910390fd5b600d859055600e849055600f839055601082905560118190556040805186815260208101869052808201859052606081018490526080810183905290517f5b37d10782e41a6539b50d59366d4112a880236e4187e85b6d1514d20e07d9b89181900360a00190a15050505050565b6000610ed0610ec96129fc565b8484612a00565b5060015b92915050565b610ee26129fc565b6001600160a01b0316610ef3612186565b6001600160a01b031614610f4e576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b60c8811115610fa4576040805162461bcd60e51b815260206004820152601f60248201527f7570646174654465616c6c6f636174696f6e4665653a20746f6f206869676800604482015290519081900360640190fd5b6001600160a01b0382166000818152600c6020908152604091829020849055815184815291517f6ff024152fc2cd8071bc701f966036513eb03e243863f21d8218646faac0eaef9281900390910190a25050565b60006110046008612aec565b905090565b60045490565b7f000000000000000000000000000000000000000000000000000000000000000081565b600d5481565b60026001541415611091576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026001556110a1338585612af7565b836001600160a01b0316631c75e369338585856040518563ffffffff1660e01b815260040180856001600160a01b03168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b15801561112c57600080fd5b505af1158015611140573d6000803e3d6000fd5b505060018055505050505050565b6000610ed4600883612cb3565b6000611168848484612cc8565b6111d8846111746129fc565b6111d385604051806060016040528060288152602001613ebc602891396001600160a01b038a166000908152600360205260408120906111b26129fc565b6001600160a01b031681526020810191909152604001600020549190612e25565b612a00565b5060015b9392505050565b6001600160a01b039182166000908152600a6020908152604080832093909416825291909152205490565b600b60209081526000928352604080842090915290825290205481565b6001600160a01b039182166000908152600b6020908152604080832093909416825291909152205490565b600260015414156112ae576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260015533600081815260136020526040902054829081106113025760405162461bcd60e51b815260040180806020018281038252602b815260200180613fad602b913960400191505060405180910390fd5b33600090815260136020526040812080548590811061131d57fe5b6000918252602090912060059091020160038101546007549192506001600160a01b039081166101009092041614801590611367575060075461010090046001600160a01b031615155b1561162157600481015415611583576003810154600482015460408051600080825260208201928390527f549230c90000000000000000000000000000000000000000000000000000000083523360248301818152604484018690526060606485019081528451608486018190526001600160a01b039098169763549230c99793969395949293919260a486019291908190849084905b838110156114165781810151838201526020016113fe565b50505050905090810190601f1680156114435780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561146457600080fd5b505af1158015611478573d6000803e3d6000fd5b5050600754600484015460408051600080825260208201928390527f1c75e3690000000000000000000000000000000000000000000000000000000083523360248301818152604484018690526060606485019081528451608486018190526101009098046001600160a01b03169950631c75e3699850919693949093919260a4860192908190849084905b8381101561151c578181015183820152602001611504565b50505050905090810190601f1680156115495780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561156a57600080fd5b505af115801561157e573d6000803e3d6000fd5b505050505b6003810154600754604080518781526001600160a01b03938416602082015261010090920490921681830152905133917fa60c8f9118be22c9277a8129333d64ffda3de44ca7a5831d077a3127f1237a18919081900360600190a26007546003820180546101009092046001600160a01b03167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790555b5050600180555050565b60075460ff1690565b6000610ed06116416129fc565b846111d385600360006116526129fc565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490612ebc565b600260015414156116da576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026001556116ea823383612af7565b505060018055565b600a60209081526000928352604080842090915290825290205481565b60075461010090046001600160a01b031681565b60115481565b6000610ed4600883612f16565b6013602052816000526040600020818154811061175257600080fd5b600091825260209091206005909102018054600182015460028301546003840154600490940154929550909350916001600160a01b03169085565b600260015414156117e5576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260015533600081815260136020526040902054829081106118395760405162461bcd60e51b815260040180806020018281038252602b815260200180613fad602b913960400191505060405180910390fd5b3360009081526012602090815260408083206013909252822080549192918690811061186157fe5b9060005260206000209060050201905061188c81600101548360010154612f2290919063ffffffff16565b82600101819055506118a330338360010154612cc8565b6004810154156119b4576003810154600482015460408051600080825260208201928390527f549230c90000000000000000000000000000000000000000000000000000000083523360248301818152604484018690526060606485019081528451608486018190526001600160a01b039098169763549230c99793969395949293919260a486019291908190849084905b8381101561194d578181015183820152602001611935565b50505050905090810190601f16801561197a5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561199b57600080fd5b505af11580156119af573d6000803e3d6000fd5b505050505b6001810154604080519182525133917f56d7520e387607a8daa892e3fed116badc2a636307bdc794b1c1aed97ae203f4919081900360200190a26119f785612f7f565b505060018055505050565b60026001541415611a5a576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002600155611a6a3385856130bf565b836001600160a01b031663549230c9338585856040518563ffffffff1660e01b815260040180856001600160a01b03168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b15801561112c57600080fd5b60026001541415611b4d576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002600155611b5b336132d4565b611bac576040805162461bcd60e51b815260206004820152601660248201527f636f6e76657274546f3a206e6f7420616c6c6f77656400000000000000000000604482015290519081900360640190fd5b6116ea82826132da565b6012602052600090815260409020805460019091015482565b606481565b6001600160a01b031660009081526002602052604090205490565b611bf76129fc565b6001600160a01b0316611c08612186565b6001600160a01b031614611c63576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b60026001541415611d1d576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260015581611d5e5760405162461bcd60e51b8152600401808060200182810382526023815260200180613ee46023913960400191505060405180910390fd5b600f54811015611db5576040805162461bcd60e51b815260206004820152601860248201527f72656465656d3a206475726174696f6e20746f6f206c6f770000000000000000604482015290519081900360640190fd5b611dc0333084612cc8565b33600090815260126020526040812090611dda84846121f6565b6040805186815260208101839052808201869052905191925033917fbd5034ffbd47e4e72a94baa2cdb74c6fad73cb3bcdc13036b72ec8306f5a76469181900360600190a28215612040576001820154611e349085612ebc565b6001830155601154600090611e5790606490611e519088906133b2565b9061340b565b90508015611f6c5760075461010090046001600160a01b0316631c75e369338360006040519080825280601f01601f191660200182016040528015611ea3576020820181803683370190505b506040518463ffffffff1660e01b815260040180846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015611f05578181015183820152602001611eed565b50505050905090810190601f168015611f325780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015611f5357600080fd5b505af1158015611f67573d6000803e3d6000fd5b505050505b33600090815260136020908152604091829020825160a081018452858152918201889052918101611fa587611f9f613472565b90612ebc565b815260075461010090046001600160a01b0390811660208084019190915260409283019590955283546001808201865560009586529486902084516005909202019081559483015193850193909355810151600284015560608101516003840180547fffffffffffffffffffffffff000000000000000000000000000000000000000016919093161790915560800151600490910155611621565b611621338583613476565b6120536129fc565b6001600160a01b0316612064612186565b6001600160a01b0316146120bf576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b0382163014156121075760405162461bcd60e51b815260040180806020018281038252603c815260200180613f28603c913960400191505060405180910390fd5b801561211e576121186008836129e7565b5061212b565b612129600883613589565b505b604080516001600160a01b0384168152821515602082015281517f3a34209cb941a5d23a56dea730a13738454bc7daefd4bb32e8d7df58c1bd920d929181900390910190a15050565b600c6020526000908152604090205481565b6000546001600160a01b031690565b60068054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610d065780601f10610cdb57610100808354040283529160200191610d06565b6000600f5482101561220a57506000610ed4565b6010548211156122355761222e6064611e51600e54866133b290919063ffffffff16565b9050610ed4565b600061228b612282612254600f54601054612f2290919063ffffffff16565b611e5161226e600d54600e54612f2290919063ffffffff16565b600f5461227c908990612f22565b906133b2565b600d5490612ebc565b905061229c6064611e5186846133b2565b949350505050565b600260015414156122fc576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026001556116ea8233836130bf565b60026001541415612364576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260015561237381336132da565b5060018055565b6000610ed06123876129fc565b846111d38560405180606001604052806025815260200161403460259139600360006123b16129fc565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190612e25565b6000610ed06123ef6129fc565b8484612cc8565b6002600154141561244e576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260015533600081815260136020526040902054829081106124a25760405162461bcd60e51b815260040180806020018281038252602b815260200180613fad602b913960400191505060405180910390fd5b336000908152601260209081526040808320601390925282208054919291869081106124ca57fe5b9060005260206000209060050201905080600201546124e7613472565b10156125245760405162461bcd60e51b8152600401808060200182810382526032815260200180613fd86032913960400191505060405180910390fd5b6001808201549083015461253791612f22565b82600101819055506125523382600101548360000154613476565b600481015415612663576003810154600482015460408051600080825260208201928390527f549230c90000000000000000000000000000000000000000000000000000000083523360248301818152604484018690526060606485019081528451608486018190526001600160a01b039098169763549230c99793969395949293919260a486019291908190849084905b838110156125fc5781810151838201526020016125e4565b50505050905090810190601f1680156126295780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561264a57600080fd5b505af115801561265e573d6000803e3d6000fd5b505050505b6119f785612f7f565b6001600160a01b031660009081526013602052604090205490565b600260015414156126df576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026001556001600160a01b0382166127295760405162461bcd60e51b8152600401808060200182810382526029815260200180613e516029913960400191505060405180910390fd5b336000818152600a602090815260408083206001600160a01b03871680855290835292819020859055805185815290519293927fe75ec259c38e4601f24580968665ec00b21cca4f996689b260ec598aec5c08db929181900390910190a3505060018055565b600f5481565b6001600160a01b03821660009081526013602052604081205481908190819081908790879081106127f75760405162461bcd60e51b815260040180806020018281038252602b815260200180613fad602b913960400191505060405180910390fd5b6001600160a01b038916600090815260136020526040812080548a90811061281b57fe5b600091825260209091206005909102018054600182015460028301546003840154600490940154929e919d509b506001600160a01b039092169950975095505050505050565b6001600160a01b03918216600090815260036020908152604080832093909416825291909152205490565b600e5481565b60105481565b6128a06129fc565b6001600160a01b03166128b1612186565b6001600160a01b03161461290c576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b0381166129515760405162461bcd60e51b8152600401808060200182810382526026815260200180613d6f6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6001600160a01b0316600090815260126020526040902080546001909101549091565b60006111dc836001600160a01b03841661359e565b3390565b6001600160a01b038316612a455760405162461bcd60e51b8152600401808060200182810382526024815260200180613f896024913960400191505060405180910390fd5b6001600160a01b038216612a8a5760405162461bcd60e51b8152600401808060200182810382526022815260200180613d956022913960400191505060405180910390fd5b6001600160a01b03808416600081815260036020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6000610ed4826135e8565b60008111612b4c576040805162461bcd60e51b815260206004820152601f60248201527f616c6c6f636174653a20616d6f756e742063616e6e6f74206265206e756c6c00604482015290519081900360640190fd5b6001600160a01b038084166000908152601260209081526040808320600a835281842094871684529390915290205482811015612bd0576040805162461bcd60e51b815260206004820152601f60248201527f616c6c6f636174653a206e6f6e20617574686f72697a656420616d6f756e7400604482015290519081900360640190fd5b612bda8184612f22565b6001600160a01b038087166000818152600a60209081526040808320948a1680845294825280832095909555918152600b82528381209281529190522054612c229084612ebc565b6001600160a01b038087166000908152600b60209081526040808320938916835292905220558154612c549084612ebc565b8255612c61853085612cc8565b836001600160a01b0316856001600160a01b03167f5168bfb88d6125d4580e2b91ecb103a730312c3e8b0be9c4031a0fc794e2cd5f856040518082815260200191505060405180910390a35050505050565b60006111dc836001600160a01b0384166135ec565b6001600160a01b038316612d0d5760405162461bcd60e51b8152600401808060200182810382526025815260200180613f646025913960400191505060405180910390fd5b6001600160a01b038216612d525760405162461bcd60e51b8152600401808060200182810382526023815260200180613d2a6023913960400191505060405180910390fd5b612d5d838383613604565b612d9a81604051806060016040528060268152602001613e0a602691396001600160a01b0386166000908152600260205260409020549190612e25565b6001600160a01b038085166000908152600260205260408082209390935590841681522054612dc99082612ebc565b6001600160a01b0380841660008181526002602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115612eb45760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612e79578181015183820152602001612e61565b50505050905090810190601f168015612ea65780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000828201838110156111dc576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006111dc8383613687565b600082821115612f79576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b33600090815260136020526040902080546000198101908110612f9e57fe5b906000526020600020906005020160136000336001600160a01b03166001600160a01b031681526020019081526020016000208281548110612fdc57fe5b600091825260208083208454600590930201918255600180850154908301556002808501549083015560038085015490830180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909216919091179055600493840154939091019290925533815260139091526040902080548061306657fe5b60008281526020812060056000199093019283020181815560018101829055600281018290556003810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905560040155905550565b600081116130fe5760405162461bcd60e51b8152600401808060200182810382526021815260200180613e7a6021913960400191505060405180910390fd5b6001600160a01b038084166000908152600b6020908152604080832093861683529290522054818110156131635760405162461bcd60e51b8152600401808060200182810382526021815260200180613e306021913960400191505060405180910390fd5b61316d8183612f22565b6001600160a01b038086166000908152600b60209081526040808320938816835292815282822093909355600c9092528120546131b39061271090611e519086906133b2565b6001600160a01b03861660009081526012602052604090208054919250906131db9085612f22565b81556131f130876131ec8786612f22565b612cc8565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166342966c68836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561325757600080fd5b505af115801561326b573d6000803e3d6000fd5b5050505061327930836136eb565b846001600160a01b0316866001600160a01b03167f7d613f7bd1a777aeeefdd38ae61201003086575188df50618d02482220f5c1478685604051808381526020018281526020019250505060405180910390a3505050505050565b3b151590565b8161332c576040805162461bcd60e51b815260206004820152601e60248201527f636f6e766572743a20616d6f756e742063616e6e6f74206265206e756c6c0000604482015290519081900360640190fd5b61333681836137e7565b604080516001600160a01b038316815260208101849052815133927fccfaeb3043a96a967dc036ab72e078a9632af809671bc2a1ac30a8043645f89e928290030190a26133ae6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163330856138d9565b5050565b6000826133c157506000610ed4565b828202828482816133ce57fe5b04146111dc5760405162461bcd60e51b8152600401808060200182810382526021815260200180613e9b6021913960400191505060405180910390fd5b6000808211613461576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161346a57fe5b049392505050565b4290565b60006134828383612f22565b90506134b86001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168584613967565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166342966c68826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561351e57600080fd5b505af1158015613532573d6000803e3d6000fd5b5050505061354030846136eb565b604080518481526020810184905281516001600160a01b038716927f0da072ebd7a5649099f43a3776eb0cda17aca79426ee9f28aae203f5dfa04eda928290030190a250505050565b60006111dc836001600160a01b0384166139e7565b60006135aa83836135ec565b6135e057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ed4565b506000610ed4565b5490565b60009081526001919091016020526040902054151590565b6001600160a01b03831615806136205750613620600884612cb3565b806136315750613631600883612cb3565b613682576040805162461bcd60e51b815260206004820152601560248201527f7472616e736665723a206e6f7420616c6c6f7765640000000000000000000000604482015290519081900360640190fd5b505050565b815460009082106136c95760405162461bcd60e51b8152600401808060200182810382526022815260200180613d086022913960400191505060405180910390fd5b8260000182815481106136d857fe5b9060005260206000200154905092915050565b6001600160a01b0382166137305760405162461bcd60e51b8152600401808060200182810382526021815260200180613f076021913960400191505060405180910390fd5b61373c82600083613604565b61377981604051806060016040528060228152602001613d4d602291396001600160a01b0385166000908152600260205260409020549190612e25565b6001600160a01b03831660009081526002602052604090205560045461379f9082612f22565b6004556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216613842576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b61384e60008383613604565b60045461385b9082612ebc565b6004556001600160a01b0382166000908152600260205260409020546138819082612ebc565b6001600160a01b03831660008181526002602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052613961908590613aad565b50505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052613682908490613aad565b60008181526001830160205260408120548015613aa35783546000198083019190810190600090879083908110613a1a57fe5b9060005260206000200154905080876000018481548110613a3757fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080613a6757fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610ed4565b6000915050610ed4565b6000613b02826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613b5e9092919063ffffffff16565b80519091501561368257808060200190516020811015613b2157600080fd5b50516136825760405162461bcd60e51b815260040180806020018281038252602a81526020018061400a602a913960400191505060405180910390fd5b606061229c848460008585613b72856132d4565b613bc3576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600080866001600160a01b031685876040518082805190602001908083835b60208310613c1f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613be2565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613c81576040519150601f19603f3d011682016040523d82523d6000602084013e613c86565b606091505b5091509150613c96828286613ca1565b979650505050505050565b60608315613cb05750816111dc565b825115613cc05782518084602001fd5b60405162461bcd60e51b8152602060048201818152845160248401528451859391928392604401919085019080838360008315612e79578181015183820152602001612e6156fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e647345524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e63654f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737375706461746552656465656d53657474696e67733a2077726f6e6720726174696f2076616c75657375706461746552656465656d53657474696e67733a2077726f6e67206475726174696f6e2076616c75657345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e63656465616c6c6f636174653a206e6f6e20617574686f72697a656420616d6f756e74617070726f766555736167653a20617070726f766520746f20746865207a65726f20616464726573736465616c6c6f636174653a20616d6f756e742063616e6e6f74206265206e756c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636572656465656d3a2078546f6b656e416d6f756e742063616e6e6f74206265206e756c6c45524332303a206275726e2066726f6d20746865207a65726f20616464726573737570646174655472616e7366657257686974656c6973743a2043616e6e6f742072656d6f76652078546f6b656e2066726f6d2077686974656c69737445524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737376616c696461746552656465656d3a2072656465656d20656e74727920646f6573206e6f7420657869737466696e616c697a6552656465656d3a2076657374696e67206475726174696f6e20686173206e6f7420656e646564207965745361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656445524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220cec1d853b883c66733761ae4e7b4ec03fc61918e8d873ef6c7d67dd0e20f907a64736f6c63430007060033000000000000000000000000d5046b976188eb40f6de40fb527f89c05b323385

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061034c5760003560e01c8063549230c9116101bd578063a3908e1b116100f9578063c4b10766116100a2578063e3a2950b1161007c578063e3a2950b14610b05578063e9ed87f814610b0d578063f2fde38b14610b15578063f7a0a88514610b3b5761034c565b8063c4b1076614610aa3578063cc6c542314610aab578063dd62ed3e14610ad75761034c565b8063aff6cbf1116100d3578063aff6cbf114610a34578063b90c2b5214610a51578063c360ed1c14610a775761034c565b8063a3908e1b146109bf578063a457c2d7146109dc578063a9059cbb14610a085761034c565b80637cbc2373116101665780638da5cb5b116101405780638da5cb5b1461096057806395d89b411461096857806399cd11ea14610970578063a0bdc7cb146109935761034c565b80637cbc2373146108e9578063890836541461090c5780638975f9181461093a5761034c565b8063619ac95b11610197578063619ac95b146108b357806370a08231146108bb578063715018a6146108e15761034c565b8063549230c9146107c35780635a1d34dc146108485780635b7b5281146108745761034c565b80632b4896791161028c5780633b90f9a0116102355780634a5b406e1161020f5780634a5b406e146107215780634b359d38146107295780634f62b7ec14610746578063539ffb77146107a65761034c565b80633b90f9a0146106bf578063488c8303146106eb578063497965ee146107195761034c565b806331124ce31161026657806331124ce314610658578063313ce5671461067557806339509351146106935761034c565b80632b489679146105ce5780632cc2f5ce146105fc5780632e9a76e41461062a5761034c565b8063161aab43116102f95780631c352679116102d35780631c352679146104e55780631c75e369146104ed5780631eee7e601461057257806323b872dd146105985761034c565b8063161aab43146104b157806318160ddd146104b95780631a465fe1146104c15761034c565b8063093220b71161032a578063093220b714610410578063095ea7b3146104455780630f7d3a69146104855761034c565b806302f91e551461035157806306045a211461036b57806306fdde0314610393575b600080fd5b610359610b61565b60408051918252519081900360200190f35b6103916004803603602081101561038157600080fd5b50356001600160a01b0316610b66565b005b61039b610c7a565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103d55781810151838201526020016103bd565b50505050905090810190601f1680156104025780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610391600480360360a081101561042657600080fd5b5080359060208101359060408101359060608101359060800135610d10565b6104716004803603604081101561045b57600080fd5b506001600160a01b038135169060200135610ebc565b604080519115158252519081900360200190f35b6103916004803603604081101561049b57600080fd5b506001600160a01b038135169060200135610eda565b610359610ff8565b610359611009565b6104c961100f565b604080516001600160a01b039092168252519081900360200190f35b610359611033565b6103916004803603606081101561050357600080fd5b6001600160a01b038235169160208101359181019060608101604082013564010000000081111561053357600080fd5b82018360208201111561054557600080fd5b8035906020019184600183028401116401000000008311171561056757600080fd5b509092509050611039565b6104716004803603602081101561058857600080fd5b50356001600160a01b031661114e565b610471600480360360608110156105ae57600080fd5b506001600160a01b0381358116916020810135909116906040013561115b565b610359600480360360408110156105e457600080fd5b506001600160a01b03813581169160200135166111e3565b6103596004803603604081101561061257600080fd5b506001600160a01b038135811691602001351661120e565b6103596004803603604081101561064057600080fd5b506001600160a01b038135811691602001351661122b565b6103916004803603602081101561066e57600080fd5b5035611256565b61067d61162b565b6040805160ff9092168252519081900360200190f35b610471600480360360408110156106a957600080fd5b506001600160a01b038135169060200135611634565b610391600480360360408110156106d557600080fd5b506001600160a01b038135169060200135611682565b6103596004803603604081101561070157600080fd5b506001600160a01b03813581169160200135166116f2565b6104c961170f565b610359611723565b6104c96004803603602081101561073f57600080fd5b5035611729565b6107726004803603604081101561075c57600080fd5b506001600160a01b038135169060200135611736565b604080519586526020860194909452848401929092526001600160a01b031660608401526080830152519081900360a00190f35b610391600480360360208110156107bc57600080fd5b503561178d565b610391600480360360608110156107d957600080fd5b6001600160a01b038235169160208101359181019060608101604082013564010000000081111561080957600080fd5b82018360208201111561081b57600080fd5b8035906020019184600183028401116401000000008311171561083d57600080fd5b509092509050611a02565b6103916004803603604081101561085e57600080fd5b50803590602001356001600160a01b0316611af5565b61089a6004803603602081101561088a57600080fd5b50356001600160a01b0316611bb6565b6040805192835260208301919091528051918290030190f35b610359611bcf565b610359600480360360208110156108d157600080fd5b50356001600160a01b0316611bd4565b610391611bef565b610391600480360360408110156108ff57600080fd5b5080359060200135611cc5565b6103916004803603604081101561092257600080fd5b506001600160a01b038135169060200135151561204b565b6103596004803603602081101561095057600080fd5b50356001600160a01b0316612174565b6104c9612186565b61039b612195565b6103596004803603604081101561098657600080fd5b50803590602001356121f6565b610391600480360360408110156109a957600080fd5b506001600160a01b0381351690602001356122a4565b610391600480360360208110156109d557600080fd5b503561230c565b610471600480360360408110156109f257600080fd5b506001600160a01b03813516906020013561237a565b61047160048036036040811015610a1e57600080fd5b506001600160a01b0381351690602001356123e2565b61039160048036036020811015610a4a57600080fd5b50356123f6565b61035960048036036020811015610a6757600080fd5b50356001600160a01b031661266c565b61039160048036036040811015610a8d57600080fd5b506001600160a01b038135169060200135612687565b61035961278f565b61077260048036036040811015610ac157600080fd5b506001600160a01b038135169060200135612795565b61035960048036036040811015610aed57600080fd5b506001600160a01b0381358116916020013516612861565b61035961288c565b610359612892565b61039160048036036020811015610b2b57600080fd5b50356001600160a01b0316612898565b61089a60048036036020811015610b5157600080fd5b50356001600160a01b03166129c4565b60c881565b610b6e6129fc565b6001600160a01b0316610b7f612186565b6001600160a01b031614610bda576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b038116610bee5760006011555b600754604080516001600160a01b0361010090930483168152918316602083015280517f044c75b8fa43ce72364b4c23fdb8451beafbda46505bf44c76f0853a01ed4ade9281900390910190a1600780546001600160a01b03909216610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff909216919091179055565b60058054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610d065780601f10610cdb57610100808354040283529160200191610d06565b820191906000526020600020905b815481529060010190602001808311610ce957829003601f168201915b5050505050905090565b610d186129fc565b6001600160a01b0316610d29612186565b6001600160a01b031614610d84576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b83851115610dc35760405162461bcd60e51b8152600401808060200182810382526028815260200180613db76028913960400191505060405180910390fd5b818310610e015760405162461bcd60e51b815260040180806020018281038252602b815260200180613ddf602b913960400191505060405180910390fd5b60648411158015610e13575060648111155b610e4e5760405162461bcd60e51b8152600401808060200182810382526028815260200180613db76028913960400191505060405180910390fd5b600d859055600e849055600f839055601082905560118190556040805186815260208101869052808201859052606081018490526080810183905290517f5b37d10782e41a6539b50d59366d4112a880236e4187e85b6d1514d20e07d9b89181900360a00190a15050505050565b6000610ed0610ec96129fc565b8484612a00565b5060015b92915050565b610ee26129fc565b6001600160a01b0316610ef3612186565b6001600160a01b031614610f4e576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b60c8811115610fa4576040805162461bcd60e51b815260206004820152601f60248201527f7570646174654465616c6c6f636174696f6e4665653a20746f6f206869676800604482015290519081900360640190fd5b6001600160a01b0382166000818152600c6020908152604091829020849055815184815291517f6ff024152fc2cd8071bc701f966036513eb03e243863f21d8218646faac0eaef9281900390910190a25050565b60006110046008612aec565b905090565b60045490565b7f000000000000000000000000d5046b976188eb40f6de40fb527f89c05b32338581565b600d5481565b60026001541415611091576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026001556110a1338585612af7565b836001600160a01b0316631c75e369338585856040518563ffffffff1660e01b815260040180856001600160a01b03168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b15801561112c57600080fd5b505af1158015611140573d6000803e3d6000fd5b505060018055505050505050565b6000610ed4600883612cb3565b6000611168848484612cc8565b6111d8846111746129fc565b6111d385604051806060016040528060288152602001613ebc602891396001600160a01b038a166000908152600360205260408120906111b26129fc565b6001600160a01b031681526020810191909152604001600020549190612e25565b612a00565b5060015b9392505050565b6001600160a01b039182166000908152600a6020908152604080832093909416825291909152205490565b600b60209081526000928352604080842090915290825290205481565b6001600160a01b039182166000908152600b6020908152604080832093909416825291909152205490565b600260015414156112ae576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260015533600081815260136020526040902054829081106113025760405162461bcd60e51b815260040180806020018281038252602b815260200180613fad602b913960400191505060405180910390fd5b33600090815260136020526040812080548590811061131d57fe5b6000918252602090912060059091020160038101546007549192506001600160a01b039081166101009092041614801590611367575060075461010090046001600160a01b031615155b1561162157600481015415611583576003810154600482015460408051600080825260208201928390527f549230c90000000000000000000000000000000000000000000000000000000083523360248301818152604484018690526060606485019081528451608486018190526001600160a01b039098169763549230c99793969395949293919260a486019291908190849084905b838110156114165781810151838201526020016113fe565b50505050905090810190601f1680156114435780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561146457600080fd5b505af1158015611478573d6000803e3d6000fd5b5050600754600484015460408051600080825260208201928390527f1c75e3690000000000000000000000000000000000000000000000000000000083523360248301818152604484018690526060606485019081528451608486018190526101009098046001600160a01b03169950631c75e3699850919693949093919260a4860192908190849084905b8381101561151c578181015183820152602001611504565b50505050905090810190601f1680156115495780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561156a57600080fd5b505af115801561157e573d6000803e3d6000fd5b505050505b6003810154600754604080518781526001600160a01b03938416602082015261010090920490921681830152905133917fa60c8f9118be22c9277a8129333d64ffda3de44ca7a5831d077a3127f1237a18919081900360600190a26007546003820180546101009092046001600160a01b03167fffffffffffffffffffffffff00000000000000000000000000000000000000009092169190911790555b5050600180555050565b60075460ff1690565b6000610ed06116416129fc565b846111d385600360006116526129fc565b6001600160a01b03908116825260208083019390935260409182016000908120918c168152925290205490612ebc565b600260015414156116da576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026001556116ea823383612af7565b505060018055565b600a60209081526000928352604080842090915290825290205481565b60075461010090046001600160a01b031681565b60115481565b6000610ed4600883612f16565b6013602052816000526040600020818154811061175257600080fd5b600091825260209091206005909102018054600182015460028301546003840154600490940154929550909350916001600160a01b03169085565b600260015414156117e5576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260015533600081815260136020526040902054829081106118395760405162461bcd60e51b815260040180806020018281038252602b815260200180613fad602b913960400191505060405180910390fd5b3360009081526012602090815260408083206013909252822080549192918690811061186157fe5b9060005260206000209060050201905061188c81600101548360010154612f2290919063ffffffff16565b82600101819055506118a330338360010154612cc8565b6004810154156119b4576003810154600482015460408051600080825260208201928390527f549230c90000000000000000000000000000000000000000000000000000000083523360248301818152604484018690526060606485019081528451608486018190526001600160a01b039098169763549230c99793969395949293919260a486019291908190849084905b8381101561194d578181015183820152602001611935565b50505050905090810190601f16801561197a5780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561199b57600080fd5b505af11580156119af573d6000803e3d6000fd5b505050505b6001810154604080519182525133917f56d7520e387607a8daa892e3fed116badc2a636307bdc794b1c1aed97ae203f4919081900360200190a26119f785612f7f565b505060018055505050565b60026001541415611a5a576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002600155611a6a3385856130bf565b836001600160a01b031663549230c9338585856040518563ffffffff1660e01b815260040180856001600160a01b03168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b15801561112c57600080fd5b60026001541415611b4d576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002600155611b5b336132d4565b611bac576040805162461bcd60e51b815260206004820152601660248201527f636f6e76657274546f3a206e6f7420616c6c6f77656400000000000000000000604482015290519081900360640190fd5b6116ea82826132da565b6012602052600090815260409020805460019091015482565b606481565b6001600160a01b031660009081526002602052604090205490565b611bf76129fc565b6001600160a01b0316611c08612186565b6001600160a01b031614611c63576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b60026001541415611d1d576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260015581611d5e5760405162461bcd60e51b8152600401808060200182810382526023815260200180613ee46023913960400191505060405180910390fd5b600f54811015611db5576040805162461bcd60e51b815260206004820152601860248201527f72656465656d3a206475726174696f6e20746f6f206c6f770000000000000000604482015290519081900360640190fd5b611dc0333084612cc8565b33600090815260126020526040812090611dda84846121f6565b6040805186815260208101839052808201869052905191925033917fbd5034ffbd47e4e72a94baa2cdb74c6fad73cb3bcdc13036b72ec8306f5a76469181900360600190a28215612040576001820154611e349085612ebc565b6001830155601154600090611e5790606490611e519088906133b2565b9061340b565b90508015611f6c5760075461010090046001600160a01b0316631c75e369338360006040519080825280601f01601f191660200182016040528015611ea3576020820181803683370190505b506040518463ffffffff1660e01b815260040180846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015611f05578181015183820152602001611eed565b50505050905090810190601f168015611f325780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015611f5357600080fd5b505af1158015611f67573d6000803e3d6000fd5b505050505b33600090815260136020908152604091829020825160a081018452858152918201889052918101611fa587611f9f613472565b90612ebc565b815260075461010090046001600160a01b0390811660208084019190915260409283019590955283546001808201865560009586529486902084516005909202019081559483015193850193909355810151600284015560608101516003840180547fffffffffffffffffffffffff000000000000000000000000000000000000000016919093161790915560800151600490910155611621565b611621338583613476565b6120536129fc565b6001600160a01b0316612064612186565b6001600160a01b0316146120bf576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b0382163014156121075760405162461bcd60e51b815260040180806020018281038252603c815260200180613f28603c913960400191505060405180910390fd5b801561211e576121186008836129e7565b5061212b565b612129600883613589565b505b604080516001600160a01b0384168152821515602082015281517f3a34209cb941a5d23a56dea730a13738454bc7daefd4bb32e8d7df58c1bd920d929181900390910190a15050565b600c6020526000908152604090205481565b6000546001600160a01b031690565b60068054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610d065780601f10610cdb57610100808354040283529160200191610d06565b6000600f5482101561220a57506000610ed4565b6010548211156122355761222e6064611e51600e54866133b290919063ffffffff16565b9050610ed4565b600061228b612282612254600f54601054612f2290919063ffffffff16565b611e5161226e600d54600e54612f2290919063ffffffff16565b600f5461227c908990612f22565b906133b2565b600d5490612ebc565b905061229c6064611e5186846133b2565b949350505050565b600260015414156122fc576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026001556116ea8233836130bf565b60026001541415612364576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260015561237381336132da565b5060018055565b6000610ed06123876129fc565b846111d38560405180606001604052806025815260200161403460259139600360006123b16129fc565b6001600160a01b03908116825260208083019390935260409182016000908120918d16815292529020549190612e25565b6000610ed06123ef6129fc565b8484612cc8565b6002600154141561244e576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b600260015533600081815260136020526040902054829081106124a25760405162461bcd60e51b815260040180806020018281038252602b815260200180613fad602b913960400191505060405180910390fd5b336000908152601260209081526040808320601390925282208054919291869081106124ca57fe5b9060005260206000209060050201905080600201546124e7613472565b10156125245760405162461bcd60e51b8152600401808060200182810382526032815260200180613fd86032913960400191505060405180910390fd5b6001808201549083015461253791612f22565b82600101819055506125523382600101548360000154613476565b600481015415612663576003810154600482015460408051600080825260208201928390527f549230c90000000000000000000000000000000000000000000000000000000083523360248301818152604484018690526060606485019081528451608486018190526001600160a01b039098169763549230c99793969395949293919260a486019291908190849084905b838110156125fc5781810151838201526020016125e4565b50505050905090810190601f1680156126295780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561264a57600080fd5b505af115801561265e573d6000803e3d6000fd5b505050505b6119f785612f7f565b6001600160a01b031660009081526013602052604090205490565b600260015414156126df576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026001556001600160a01b0382166127295760405162461bcd60e51b8152600401808060200182810382526029815260200180613e516029913960400191505060405180910390fd5b336000818152600a602090815260408083206001600160a01b03871680855290835292819020859055805185815290519293927fe75ec259c38e4601f24580968665ec00b21cca4f996689b260ec598aec5c08db929181900390910190a3505060018055565b600f5481565b6001600160a01b03821660009081526013602052604081205481908190819081908790879081106127f75760405162461bcd60e51b815260040180806020018281038252602b815260200180613fad602b913960400191505060405180910390fd5b6001600160a01b038916600090815260136020526040812080548a90811061281b57fe5b600091825260209091206005909102018054600182015460028301546003840154600490940154929e919d509b506001600160a01b039092169950975095505050505050565b6001600160a01b03918216600090815260036020908152604080832093909416825291909152205490565b600e5481565b60105481565b6128a06129fc565b6001600160a01b03166128b1612186565b6001600160a01b03161461290c576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b0381166129515760405162461bcd60e51b8152600401808060200182810382526026815260200180613d6f6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0392909216919091179055565b6001600160a01b0316600090815260126020526040902080546001909101549091565b60006111dc836001600160a01b03841661359e565b3390565b6001600160a01b038316612a455760405162461bcd60e51b8152600401808060200182810382526024815260200180613f896024913960400191505060405180910390fd5b6001600160a01b038216612a8a5760405162461bcd60e51b8152600401808060200182810382526022815260200180613d956022913960400191505060405180910390fd5b6001600160a01b03808416600081815260036020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6000610ed4826135e8565b60008111612b4c576040805162461bcd60e51b815260206004820152601f60248201527f616c6c6f636174653a20616d6f756e742063616e6e6f74206265206e756c6c00604482015290519081900360640190fd5b6001600160a01b038084166000908152601260209081526040808320600a835281842094871684529390915290205482811015612bd0576040805162461bcd60e51b815260206004820152601f60248201527f616c6c6f636174653a206e6f6e20617574686f72697a656420616d6f756e7400604482015290519081900360640190fd5b612bda8184612f22565b6001600160a01b038087166000818152600a60209081526040808320948a1680845294825280832095909555918152600b82528381209281529190522054612c229084612ebc565b6001600160a01b038087166000908152600b60209081526040808320938916835292905220558154612c549084612ebc565b8255612c61853085612cc8565b836001600160a01b0316856001600160a01b03167f5168bfb88d6125d4580e2b91ecb103a730312c3e8b0be9c4031a0fc794e2cd5f856040518082815260200191505060405180910390a35050505050565b60006111dc836001600160a01b0384166135ec565b6001600160a01b038316612d0d5760405162461bcd60e51b8152600401808060200182810382526025815260200180613f646025913960400191505060405180910390fd5b6001600160a01b038216612d525760405162461bcd60e51b8152600401808060200182810382526023815260200180613d2a6023913960400191505060405180910390fd5b612d5d838383613604565b612d9a81604051806060016040528060268152602001613e0a602691396001600160a01b0386166000908152600260205260409020549190612e25565b6001600160a01b038085166000908152600260205260408082209390935590841681522054612dc99082612ebc565b6001600160a01b0380841660008181526002602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b60008184841115612eb45760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612e79578181015183820152602001612e61565b50505050905090810190601f168015612ea65780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6000828201838110156111dc576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006111dc8383613687565b600082821115612f79576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b33600090815260136020526040902080546000198101908110612f9e57fe5b906000526020600020906005020160136000336001600160a01b03166001600160a01b031681526020019081526020016000208281548110612fdc57fe5b600091825260208083208454600590930201918255600180850154908301556002808501549083015560038085015490830180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03909216919091179055600493840154939091019290925533815260139091526040902080548061306657fe5b60008281526020812060056000199093019283020181815560018101829055600281018290556003810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905560040155905550565b600081116130fe5760405162461bcd60e51b8152600401808060200182810382526021815260200180613e7a6021913960400191505060405180910390fd5b6001600160a01b038084166000908152600b6020908152604080832093861683529290522054818110156131635760405162461bcd60e51b8152600401808060200182810382526021815260200180613e306021913960400191505060405180910390fd5b61316d8183612f22565b6001600160a01b038086166000908152600b60209081526040808320938816835292815282822093909355600c9092528120546131b39061271090611e519086906133b2565b6001600160a01b03861660009081526012602052604090208054919250906131db9085612f22565b81556131f130876131ec8786612f22565b612cc8565b7f000000000000000000000000d5046b976188eb40f6de40fb527f89c05b3233856001600160a01b03166342966c68836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561325757600080fd5b505af115801561326b573d6000803e3d6000fd5b5050505061327930836136eb565b846001600160a01b0316866001600160a01b03167f7d613f7bd1a777aeeefdd38ae61201003086575188df50618d02482220f5c1478685604051808381526020018281526020019250505060405180910390a3505050505050565b3b151590565b8161332c576040805162461bcd60e51b815260206004820152601e60248201527f636f6e766572743a20616d6f756e742063616e6e6f74206265206e756c6c0000604482015290519081900360640190fd5b61333681836137e7565b604080516001600160a01b038316815260208101849052815133927fccfaeb3043a96a967dc036ab72e078a9632af809671bc2a1ac30a8043645f89e928290030190a26133ae6001600160a01b037f000000000000000000000000d5046b976188eb40f6de40fb527f89c05b323385163330856138d9565b5050565b6000826133c157506000610ed4565b828202828482816133ce57fe5b04146111dc5760405162461bcd60e51b8152600401808060200182810382526021815260200180613e9b6021913960400191505060405180910390fd5b6000808211613461576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161346a57fe5b049392505050565b4290565b60006134828383612f22565b90506134b86001600160a01b037f000000000000000000000000d5046b976188eb40f6de40fb527f89c05b323385168584613967565b7f000000000000000000000000d5046b976188eb40f6de40fb527f89c05b3233856001600160a01b03166342966c68826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561351e57600080fd5b505af1158015613532573d6000803e3d6000fd5b5050505061354030846136eb565b604080518481526020810184905281516001600160a01b038716927f0da072ebd7a5649099f43a3776eb0cda17aca79426ee9f28aae203f5dfa04eda928290030190a250505050565b60006111dc836001600160a01b0384166139e7565b60006135aa83836135ec565b6135e057508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610ed4565b506000610ed4565b5490565b60009081526001919091016020526040902054151590565b6001600160a01b03831615806136205750613620600884612cb3565b806136315750613631600883612cb3565b613682576040805162461bcd60e51b815260206004820152601560248201527f7472616e736665723a206e6f7420616c6c6f7765640000000000000000000000604482015290519081900360640190fd5b505050565b815460009082106136c95760405162461bcd60e51b8152600401808060200182810382526022815260200180613d086022913960400191505060405180910390fd5b8260000182815481106136d857fe5b9060005260206000200154905092915050565b6001600160a01b0382166137305760405162461bcd60e51b8152600401808060200182810382526021815260200180613f076021913960400191505060405180910390fd5b61373c82600083613604565b61377981604051806060016040528060228152602001613d4d602291396001600160a01b0385166000908152600260205260409020549190612e25565b6001600160a01b03831660009081526002602052604090205560045461379f9082612f22565b6004556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216613842576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b61384e60008383613604565b60045461385b9082612ebc565b6004556001600160a01b0382166000908152600260205260409020546138819082612ebc565b6001600160a01b03831660008181526002602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052613961908590613aad565b50505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052613682908490613aad565b60008181526001830160205260408120548015613aa35783546000198083019190810190600090879083908110613a1a57fe5b9060005260206000200154905080876000018481548110613a3757fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080613a6757fe5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610ed4565b6000915050610ed4565b6000613b02826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613b5e9092919063ffffffff16565b80519091501561368257808060200190516020811015613b2157600080fd5b50516136825760405162461bcd60e51b815260040180806020018281038252602a81526020018061400a602a913960400191505060405180910390fd5b606061229c848460008585613b72856132d4565b613bc3576040805162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600080866001600160a01b031685876040518082805190602001908083835b60208310613c1f57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101613be2565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613c81576040519150601f19603f3d011682016040523d82523d6000602084013e613c86565b606091505b5091509150613c96828286613ca1565b979650505050505050565b60608315613cb05750816111dc565b825115613cc05782518084602001fd5b60405162461bcd60e51b8152602060048201818152845160248401528451859391928392604401919085019080838360008315612e79578181015183820152602001612e6156fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e647345524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e63654f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737375706461746552656465656d53657474696e67733a2077726f6e6720726174696f2076616c75657375706461746552656465656d53657474696e67733a2077726f6e67206475726174696f6e2076616c75657345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e63656465616c6c6f636174653a206e6f6e20617574686f72697a656420616d6f756e74617070726f766555736167653a20617070726f766520746f20746865207a65726f20616464726573736465616c6c6f636174653a20616d6f756e742063616e6e6f74206265206e756c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636572656465656d3a2078546f6b656e416d6f756e742063616e6e6f74206265206e756c6c45524332303a206275726e2066726f6d20746865207a65726f20616464726573737570646174655472616e7366657257686974656c6973743a2043616e6e6f742072656d6f76652078546f6b656e2066726f6d2077686974656c69737445524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737376616c696461746552656465656d3a2072656465656d20656e74727920646f6573206e6f7420657869737466696e616c697a6552656465656d3a2076657374696e67206475726174696f6e20686173206e6f7420656e646564207965745361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656445524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220cec1d853b883c66733761ae4e7b4ec03fc61918e8d873ef6c7d67dd0e20f907a64736f6c63430007060033

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

000000000000000000000000d5046b976188eb40f6de40fb527f89c05b323385

-----Decoded View---------------
Arg [0] : token (address): 0xd5046B976188EB40f6DE40fB527F89c05b323385

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000d5046b976188eb40f6de40fb527f89c05b323385


Deployed Bytecode Sourcemap

49921:23332:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51218:50;;;:::i;:::-;;;;;;;;;;;;;;;;59095:414;;;;;;;;;;;;;;;;-1:-1:-1;59095:414:0;-1:-1:-1;;;;;59095:414:0;;:::i;:::-;;15323:91;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57833:1143;;;;;;;;;;;;;;;;-1:-1:-1;57833:1143:0;;;;;;;;;;;;;;;;;;;;;;:::i;17469:169::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;17469:169:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;59612:285;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;59612:285:0;;;;;;;;:::i;56930:120::-;;;:::i;16422:108::-;;;:::i;50725:45::-;;;:::i;:::-;;;;-1:-1:-1;;;;;50725:45:0;;;;;;;;;;;;;;51480:34;;;:::i;66986:291::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;66986:291:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66986:291:0;;-1:-1:-1;66986:291:0;-1:-1:-1;66986:291:0;:::i;57370:148::-;;;;;;;;;;;;;;;;-1:-1:-1;57370:148:0;-1:-1:-1;;;;;57370:148:0;;:::i;18120:371::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;18120:371:0;;;;;;;;;;;;;;;;;:::i;56408:168::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;56408:168:0;;;;;;;;;;:::i;51090:80::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;51090:80:0;;;;;;;;;;:::i;56677:172::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;56677:172:0;;;;;;;;;;:::i;64702:1084::-;;;;;;;;;;;;;;;;-1:-1:-1;64702:1084:0;;:::i;16266:91::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;18900:218;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;18900:218:0;;;;;;;;:::i;67503:156::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;67503:156:0;;;;;;;;:::i;50976:69::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;50976:69:0;;;;;;;;;;:::i;50805:36::-;;;:::i;51757:45::-;;;:::i;57148:128::-;;;;;;;;;;;;;;;;-1:-1:-1;57148:128:0;;:::i;51906:51::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;51906:51:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;51906:51:0;;;;;;;;;;;;;;;;;;65905:887;;;;;;;;;;;;;;;;-1:-1:-1;65905:887:0;;:::i;67857:300::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;67857:300:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;67857:300:0;;-1:-1:-1;67857:300:0;-1:-1:-1;67857:300:0;:::i;61340:195::-;;;;;;;;;;;;;;;;-1:-1:-1;61340:195:0;;;;;;-1:-1:-1;;;;;61340:195:0;;:::i;51818:55::-;;;;;;;;;;;;;;;;-1:-1:-1;51818:55:0;-1:-1:-1;;;;;51818:55:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;51383:45;;;:::i;16593:127::-;;;;;;;;;;;;;;;;-1:-1:-1;16593:127:0;-1:-1:-1;;;;;16593:127:0;;:::i;2624:148::-;;;:::i;61713:1661::-;;;;;;;;;;;;;;;;-1:-1:-1;61713:1661:0;;;;;;;:::i;59989:350::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;59989:350:0;;;;;;;;;;:::i;51281:56::-;;;;;;;;;;;;;;;;-1:-1:-1;51281:56:0;-1:-1:-1;;;;;51281:56:0;;:::i;1973:87::-;;;:::i;15533:95::-;;;:::i;54660:612::-;;;;;;;;;;;;;;;;-1:-1:-1;54660:612:0;;;;;;;:::i;68358:160::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;68358:160:0;;;;;;;;:::i;61138:102::-;;;;;;;;;;;;;;;;-1:-1:-1;61138:102:0;;:::i;19621:319::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;19621:319:0;;;;;;;;:::i;16933:175::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;16933:175:0;;;;;;;;:::i;63538:933::-;;;;;;;;;;;;;;;;-1:-1:-1;63538:933:0;;:::i;55361:140::-;;;;;;;;;;;;;;;;-1:-1:-1;55361:140:0;-1:-1:-1;;;;;55361:140:0;;:::i;60745:309::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;60745:309:0;;;;;;;;:::i;51579:42::-;;;:::i;55616:680::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;55616:680:0;;;;;;;;:::i;17171:151::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;17171:151:0;;;;;;;;;;:::i;51530:35::-;;;:::i;51640:42::-;;;:::i;2927:244::-;;;;;;;;;;;;;;;;-1:-1:-1;2927:244:0;-1:-1:-1;;;;;2927:244:0;;:::i;54262:282::-;;;;;;;;;;;;;;;;-1:-1:-1;54262:282:0;-1:-1:-1;;;;;54262:282:0;;:::i;51218:50::-;51265:3;51218:50;:::o;59095:414::-;2204:12;:10;:12::i;:::-;-1:-1:-1;;;;;2193:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;2193:23:0;;2185:68;;;;;-1:-1:-1;;;2185:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;59262:40:0;::::1;59258:102;;59347:1;59319:25;:29:::0;59258:102:::1;59408:16;::::0;59377:77:::1;::::0;;-1:-1:-1;;;;;59408:16:0::1;::::0;;::::1;::::0;::::1;59377:77:::0;;;;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;;;;;;::::1;59465:16;:36:::0;;-1:-1:-1;;;;;59465:36:0;;::::1;;;::::0;;;::::1;::::0;;;::::1;::::0;;59095:414::o;15323:91::-;15401:5;15394:12;;;;;;;;-1:-1:-1;;15394:12:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15368:13;;15394:12;;15401:5;;15394:12;;15401:5;15394:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15323:91;:::o;57833:1143::-;2204:12;:10;:12::i;:::-;-1:-1:-1;;;;;2193:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;2193:23:0;;2185:68;;;;;-1:-1:-1;;;2185:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58114:15:::1;58095;:34;;58087:87;;;;-1:-1:-1::0;;;58087:87:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58214:18;58193;:39;58185:95;;;;-1:-1:-1::0;;;58185:95:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51425:3;58350:15;:34;;:83;;;;;51425:3;58388:26;:45;;58350:83;58328:173;;;;-1:-1:-1::0;;;58328:173:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58514:14;:32:::0;;;58557:14:::1;:32:::0;;;58600:17:::1;:38:::0;;;58649:17:::1;:38:::0;;;58698:25:::1;:54:::0;;;58770:198:::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;;;;;;;;;;;;;;;;;;;::::1;::::0;;;;;;;::::1;57833:1143:::0;;;;;:::o;17469:169::-;17552:4;17569:39;17578:12;:10;:12::i;:::-;17592:7;17601:6;17569:8;:39::i;:::-;-1:-1:-1;17626:4:0;17469:169;;;;;:::o;59612:285::-;2204:12;:10;:12::i;:::-;-1:-1:-1;;;;;2193:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;2193:23:0;;2185:68;;;;;-1:-1:-1;;;2185:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51265:3:::1;59716;:27;;59708:71;;;::::0;;-1:-1:-1;;;59708:71:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;-1:-1:-1::0;;;;;59792:35:0;::::1;;::::0;;;:21:::1;:35;::::0;;;;;;;;:41;;;59849:40;;;;;;;::::1;::::0;;;;;;;;::::1;59612:285:::0;;:::o;56930:120::-;56988:7;57015:27;:18;:25;:27::i;:::-;57008:34;;56930:120;:::o;16422:108::-;16510:12;;16422:108;:::o;50725:45::-;;;:::o;51480:34::-;;;;:::o;66986:291::-;48239:1;48844:7;;:19;;48836:63;;;;;-1:-1:-1;;;48836:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;48239:1;48977:7;:18;67101:43:::1;67111:10;67123:12:::0;67137:6;67101:9:::1;:43::i;:::-;67216:12;-1:-1:-1::0;;;;;67203:35:0::1;;67239:10;67251:6;67259:9;;67203:66;;;;;;;;;;;;;-1:-1:-1::0;;;;;67203:66:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;48195:1:0;49156:22;;-1:-1:-1;;;;;;66986:291:0:o;57370:148::-;57450:4;57474:36;:18;57502:7;57474:27;:36::i;18120:371::-;18226:4;18243:36;18253:6;18261:9;18272:6;18243:9;:36::i;:::-;18290:171;18313:6;18334:12;:10;:12::i;:::-;18361:89;18399:6;18361:89;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;18361:19:0;;;;;;:11;:19;;;;;;18381:12;:10;:12::i;:::-;-1:-1:-1;;;;;18361:33:0;;;;;;;;;;;;-1:-1:-1;18361:33:0;;;:89;:37;:89::i;:::-;18290:8;:171::i;:::-;-1:-1:-1;18479:4:0;18120:371;;;;;;:::o;56408:168::-;-1:-1:-1;;;;;56527:27:0;;;56500:7;56527:27;;;:14;:27;;;;;;;;:41;;;;;;;;;;;;;56408:168::o;51090:80::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;56677:172::-;-1:-1:-1;;;;;56798:29:0;;;56771:7;56798:29;;;:16;:29;;;;;;;;:43;;;;;;;;;;;;;56677:172::o;64702:1084::-;48239:1;48844:7;;:19;;48836:63;;;;;-1:-1:-1;;;48836:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;48239:1;48977:7;:18;64814:10:::1;53918:24;::::0;;;:11:::1;:24;::::0;;;;:31;64826:11;;53904:45;::::1;53896:101;;;;-1:-1:-1::0;;;53896:101:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64891:10:::2;64850:26;64879:23:::0;;;:11:::2;:23;::::0;;;;:36;;64903:11;;64879:36;::::2;;;;;;::::0;;;::::2;::::0;;;::::2;::::0;;::::2;;65026:24;::::0;::::2;::::0;65006:16:::2;::::0;64879:36;;-1:-1:-1;;;;;;65026:24:0;;::::2;;65006:16:::0;;::::2;;:44;::::0;::::2;::::0;:87:::2;;-1:-1:-1::0;65062:16:0::2;::::0;::::2;::::0;::::2;-1:-1:-1::0;;;;;65062:16:0::2;65054:39:::0;::::2;65006:87;65002:777;;;65114:27;::::0;::::2;::::0;:31;65110:380:::2;;65225:24;::::0;::::2;::::0;65273:27:::2;::::0;::::2;::::0;65302:12:::2;::::0;;65225:24:::2;65302:12:::0;;;::::2;::::0;::::2;::::0;;;;65225:90;;;65261:10:::2;65225:90:::0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;65225:24:0;;::::2;::::0;:35:::2;::::0;65261:10;;65273:27;;65302:12;65225:90;;;;;;;;65302:12;65225:90;;;;;65302:12;;65225:90:::2;;;;;;;::::0;;::::2;::::0;;;::::2;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;-1:-1:-1::0;;65394:16:0::2;::::0;65432:27:::2;::::0;::::2;::::0;65461:12:::2;::::0;;65471:1:::2;65461:12:::0;;;::::2;::::0;::::2;::::0;;;;65394:80;;;65420:10:::2;65394:80:::0;;;;;;;;;;;;;;;;;;;;;;;;;;;:16:::2;::::0;;::::2;-1:-1:-1::0;;;;;65394:16:0::2;::::0;-1:-1:-1;65394:25:0::2;::::0;-1:-1:-1;65420:10:0;;65461:12;;65394:80;;;;;;;;;;;;;65461:12;;65394:80:::2;;;;;;;::::0;;::::2;::::0;;;::::2;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;65110:380;65625:24;::::0;::::2;::::0;65677:16:::2;::::0;65511:198:::2;::::0;;;;;-1:-1:-1;;;;;65625:24:0;;::::2;65511:198;::::0;::::2;::::0;65625:24:::2;65677:16:::0;;::::2;::::0;;::::2;65511:198:::0;;;;;;65558:10:::2;::::0;65511:198:::2;::::0;;;;;;;;::::2;65751:16;::::0;65724:24:::2;::::0;::::2;:43:::0;;65751:16:::2;::::0;;::::2;-1:-1:-1::0;;;;;65751:16:0::2;65724:43:::0;;;::::2;::::0;;;::::2;::::0;;65002:777:::2;-1:-1:-1::0;;48195:1:0;49156:22;;-1:-1:-1;;64702:1084:0:o;16266:91::-;16340:9;;;;16266:91;:::o;18900:218::-;18988:4;19005:83;19014:12;:10;:12::i;:::-;19028:7;19037:50;19076:10;19037:11;:25;19049:12;:10;:12::i;:::-;-1:-1:-1;;;;;19037:25:0;;;;;;;;;;;;;;;;;-1:-1:-1;19037:25:0;;;:34;;;;;;;;;;;:38;:50::i;67503:156::-;48239:1;48844:7;;:19;;48836:63;;;;;-1:-1:-1;;;48836:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;48239:1;48977:7;:18;67609:42:::1;67619:11:::0;67632:10:::1;67644:6:::0;67609:9:::1;:42::i;:::-;-1:-1:-1::0;;48195:1:0;49156:22;;67503:156::o;50976:69::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;50805:36::-;;;;;;-1:-1:-1;;;;;50805:36:0;;:::o;51757:45::-;;;;:::o;57148:128::-;57213:7;57240:28;:18;57262:5;57240:21;:28::i;51906:51::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51906:51:0;;-1:-1:-1;51906:51:0;-1:-1:-1;;;;;51906:51:0;;;:::o;65905:887::-;48239:1;48844:7;;:19;;48836:63;;;;;-1:-1:-1;;;48836:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;48239:1;48977:7;:18;65985:10:::1;53918:24;::::0;;;:11:::1;:24;::::0;;;;:31;65997:11;;53904:45;::::1;53896:101;;;;-1:-1:-1::0;;;53896:101:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66068:10:::2;66021:29;66053:26:::0;;;:14:::2;:26;::::0;;;;;;;66119:11:::2;:23:::0;;;;;:36;;66053:26;;66021:29;66143:11;;66119:36;::::2;;;;;;;;;;;;;;;66090:65;;66244:49;66272:7;:20;;;66244:7;:23;;;:27;;:49;;;;:::i;:::-;66218:7;:23;;:75;;;;66304:58;66322:4;66329:10;66341:7;:20;;;66304:9;:58::i;:::-;66439:27;::::0;::::2;::::0;:31;66435:210:::2;;66542:24;::::0;::::2;::::0;66591:27:::2;::::0;::::2;::::0;66620:12:::2;::::0;;66542:24:::2;66620:12:::0;;;::::2;::::0;::::2;::::0;;;;66529:104;;;66579:10:::2;66529:104:::0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;66542:24:0;;::::2;::::0;66529:49:::2;::::0;66579:10;;66591:27;;66620:12;66529:104;;;;;;;;66620:12;66529:104;;;;;66620:12;;66529:104:::2;;;;;;;::::0;;::::2;::::0;;;::::2;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;66435:210;66687:20;::::0;::::2;::::0;66662:46:::2;::::0;;;;;;66675:10:::2;::::0;66662:46:::2;::::0;;;;;::::2;::::0;;::::2;66753:31;66772:11;66753:18;:31::i;:::-;-1:-1:-1::0;;48195:1:0;49156:22;;-1:-1:-1;;;65905:887:0:o;67857:300::-;48239:1;48844:7;;:19;;48836:63;;;;;-1:-1:-1;;;48836:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;48239:1;48977:7;:18;67974:45:::1;67986:10;67998:12:::0;68012:6;67974:11:::1;:45::i;:::-;68094:12;-1:-1:-1::0;;;;;68081:37:0::1;;68119:10;68131:6;68139:9;;68081:68;;;;;;;;;;;;;-1:-1:-1::0;;;;;68081:68:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;61340:195:::0;48239:1;48844:7;;:19;;48836:63;;;;;-1:-1:-1;;;48836:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;48239:1;48977:7;:18;61437:32:::1;61445:10;61437:30;:32::i;:::-;61429:67;;;::::0;;-1:-1:-1;;;61429:67:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;61507:20;61516:6;61524:2;61507:8;:20::i;51818:55::-:0;;;;;;;;;;;;;;;;;;;:::o;51383:45::-;51425:3;51383:45;:::o;16593:127::-;-1:-1:-1;;;;;16694:18:0;16667:7;16694:18;;;:9;:18;;;;;;;16593:127::o;2624:148::-;2204:12;:10;:12::i;:::-;-1:-1:-1;;;;;2193:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;2193:23:0;;2185:68;;;;;-1:-1:-1;;;2185:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2731:1:::1;2715:6:::0;;2694:40:::1;::::0;-1:-1:-1;;;;;2715:6:0;;::::1;::::0;2694:40:::1;::::0;2731:1;;2694:40:::1;2762:1;2745:19:::0;;;::::1;::::0;;2624:148::o;61713:1661::-;48239:1;48844:7;;:19;;48836:63;;;;;-1:-1:-1;;;48836:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;48239:1;48977:7;:18;61810:16;61802:64:::1;;;;-1:-1:-1::0;;;61802:64:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61897:17;;61885:8;:29;;61877:66;;;::::0;;-1:-1:-1;;;61877:66:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;61956:50;61966:10;61986:4;61993:12;61956:9;:50::i;:::-;62064:10;62017:29;62049:26:::0;;;:14:::1;:26;::::0;;;;;62148:50:::1;62175:12:::0;62189:8;62148:26:::1;:50::i;:::-;62214;::::0;;;;;::::1;::::0;::::1;::::0;;;;;;;;;;;62131:67;;-1:-1:-1;62221:10:0::1;::::0;62214:50:::1;::::0;;;;;;;::::1;62351:12:::0;;62347:1020:::1;;62439:23;::::0;::::1;::::0;:41:::1;::::0;62467:12;62439:27:::1;:41::i;:::-;62413:23;::::0;::::1;:67:::0;62604:25:::1;::::0;62557:27:::1;::::0;62587:52:::1;::::0;62635:3:::1;::::0;62587:43:::1;::::0;:12;;:16:::1;:43::i;:::-;:47:::0;::::1;:52::i;:::-;62557:82:::0;-1:-1:-1;62705:23:0;;62701:178:::1;;62791:16;::::0;::::1;::::0;::::1;-1:-1:-1::0;;;;;62791:16:0::1;:25;62817:10;62829:19:::0;62860:1:::1;62850:12;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;::::1;::::0;::::1;;::::0;-1:-1:-1;62850:12:0::1;;62791:72;;;;;;;;;;;;;-1:-1:-1::0;;;;;62791:72:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;;::::1;::::0;;;::::1;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;62701:178;62943:10;62931:23;::::0;;;:11:::1;:23;::::0;;;;;;;;62978:235;;::::1;::::0;::::1;::::0;;;;;;;::::1;::::0;;;62931:23;62978:235;;63075:38:::1;63104:8:::0;63075:24:::1;:22;:24::i;:::-;:28:::0;::::1;:38::i;:::-;62978:235:::0;;63136:16:::1;::::0;::::1;::::0;::::1;-1:-1:-1::0;;;;;63136:16:0;;::::1;62978:235;::::0;;::::1;::::0;;;;;;;;;;;;62931:297;;63136:16:::1;62931:297:::0;;::::1;::::0;;-1:-1:-1;62931:297:0;;;;;;;;;::::1;::::0;;::::1;;::::0;;;;;::::1;::::0;;;::::1;::::0;;;;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;;::::1;::::0;;;::::1;;::::0;;;::::1;;::::0;::::1;::::0;;::::1;::::0;62347:1020:::1;;;63306:49;63322:10;63334:12;63348:6;63306:15;:49::i;59989:350::-:0;2204:12;:10;:12::i;:::-;-1:-1:-1;;;;;2193:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;2193:23:0;;2185:68;;;;;-1:-1:-1;;;2185:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;60087:24:0;::::1;60106:4;60087:24;;60079:97;;;;-1:-1:-1::0;;;60079:97:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60193:3;60189:90;;;60198:31;:18;60221:7:::0;60198:22:::1;:31::i;:::-;;60189:90;;;60245:34;:18;60271:7:::0;60245:25:::1;:34::i;:::-;;60189:90;60297:34;::::0;;-1:-1:-1;;;;;60297:34:0;::::1;::::0;;;::::1;;;::::0;::::1;::::0;;;::::1;::::0;;;;;;;;;::::1;59989:350:::0;;:::o;51281:56::-;;;;;;;;;;;;;:::o;1973:87::-;2019:7;2046:6;-1:-1:-1;;;;;2046:6:0;1973:87;:::o;15533:95::-;15613:7;15606:14;;;;;;;;-1:-1:-1;;15606:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15580:13;;15606:14;;15613:7;;15606:14;;15613:7;15606:14;;;;;;;;;;;;;;;;;;;;;;;;54660:612;54751:7;54786:17;;54775:8;:28;54771:69;;;-1:-1:-1;54827:1:0;54820:8;;54771:69;54907:17;;54896:8;:28;54892:103;;;54948:35;54979:3;54948:26;54959:14;;54948:6;:10;;:26;;;;:::i;:35::-;54941:42;;;;54892:103;55007:13;55023:195;55056:151;55152:40;55174:17;;55152;;:21;;:40;;;;:::i;:::-;55056:73;55094:34;55113:14;;55094;;:18;;:34;;;;:::i;:::-;55070:17;;55057:31;;:8;;:12;:31::i;:::-;55056:37;;:73::i;:151::-;55023:14;;;:18;:195::i;:::-;55007:211;-1:-1:-1;55238:26:0;55260:3;55238:17;:6;55007:211;55238:10;:17::i;:26::-;55231:33;54660:612;-1:-1:-1;;;;54660:612:0:o;68358:160::-;48239:1;48844:7;;:19;;48836:63;;;;;-1:-1:-1;;;48836:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;48239:1;48977:7;:18;68466:44:::1;68478:11:::0;68491:10:::1;68503:6:::0;68466:11:::1;:44::i;61138:102::-:0;48239:1;48844:7;;:19;;48836:63;;;;;-1:-1:-1;;;48836:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;48239:1;48977:7;:18;61204:28:::1;61213:6:::0;61221:10:::1;61204:8;:28::i;:::-;-1:-1:-1::0;48195:1:0;49156:22;;61138:102::o;19621:319::-;19714:4;19731:179;19754:12;:10;:12::i;:::-;19781:7;19803:96;19842:15;19803:96;;;;;;;;;;;;;;;;;:11;:25;19815:12;:10;:12::i;:::-;-1:-1:-1;;;;;19803:25:0;;;;;;;;;;;;;;;;;-1:-1:-1;19803:25:0;;;:34;;;;;;;;;;;:96;:38;:96::i;16933:175::-;17019:4;17036:42;17046:12;:10;:12::i;:::-;17060:9;17071:6;17036:9;:42::i;63538:933::-;48239:1;48844:7;;:19;;48836:63;;;;;-1:-1:-1;;;48836:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;48239:1;48977:7;:18;63620:10:::1;53918:24;::::0;;;:11:::1;:24;::::0;;;;:31;63632:11;;53904:45;::::1;53896:101;;;;-1:-1:-1::0;;;53896:101:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63703:10:::2;63656:29;63688:26:::0;;;:14:::2;:26;::::0;;;;;;;63754:11:::2;:23:::0;;;;;:36;;63688:26;;63656:29;63778:11;;63754:36;::::2;;;;;;;;;;;;;;;63725:65;;63837:7;:15;;;63809:24;:22;:24::i;:::-;:43;;63801:106;;;;-1:-1:-1::0;;;63801:106:0::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64008:20;::::0;;::::2;::::0;63980:23;;::::2;::::0;:49:::2;::::0;:27:::2;:49::i;:::-;63954:7;:23;;:75;;;;64040:65;64056:10;64068:7;:20;;;64090:7;:14;;;64040:15;:65::i;:::-;64182:27;::::0;::::2;::::0;:31;64178:210:::2;;64285:24;::::0;::::2;::::0;64334:27:::2;::::0;::::2;::::0;64363:12:::2;::::0;;64285:24:::2;64363:12:::0;;;::::2;::::0;::::2;::::0;;;;64272:104;;;64322:10:::2;64272:104:::0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;64285:24:0;;::::2;::::0;64272:49:::2;::::0;64322:10;;64334:27;;64363:12;64272:104;;;;;;;;64363:12;64272:104;;;;;64363:12;;64272:104:::2;;;;;;;::::0;;::::2;::::0;;;::::2;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;64178:210;64432:31;64451:11;64432:18;:31::i;55361:140::-:0;-1:-1:-1;;;;;55462:24:0;55435:7;55462:24;;;:11;:24;;;;;:31;;55361:140::o;60745:309::-;48239:1;48844:7;;:19;;48836:63;;;;;-1:-1:-1;;;48836:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;48239:1;48977:7;:18;-1:-1:-1;;;;;60844:28:0;::::1;60836:82;;;;-1:-1:-1::0;;;60836:82:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60946:10;60931:26;::::0;;;:14:::1;:26;::::0;;;;;;;-1:-1:-1;;;;;60931:42:0;::::1;::::0;;;;;;;;;;:51;;;60998:48;;;;;;;60931:42;;60946:10;60998:48:::1;::::0;;;;;;;;;::::1;-1:-1:-1::0;;48195:1:0;49156:22;;60745:309::o;51579:42::-;;;;:::o;55616:680::-;-1:-1:-1;;;;;53918:24:0;;55820:14;53918:24;;;:11;:24;;;;;:31;55820:14;;;;;;;;55762:11;;55775;;53904:45;;53896:101;;;;-1:-1:-1;;;53896:101:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;56038:24:0;::::1;56009:26;56038:24:::0;;;:11:::1;:24;::::0;;;;:37;;56063:11;;56038:37;::::1;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;;56108:14:::0;;56137:20:::1;::::0;::::1;::::0;56172:15:::1;::::0;::::1;::::0;56210:24:::1;::::0;::::1;::::0;56250:27:::1;::::0;;::::1;::::0;56108:14;;56137:20;;-1:-1:-1;56172:15:0;-1:-1:-1;;;;;;56210:24:0;;::::1;::::0;-1:-1:-1;56250:27:0;-1:-1:-1;55616:680:0;-1:-1:-1;;;;;;55616:680:0:o;17171:151::-;-1:-1:-1;;;;;17287:18:0;;;17260:7;17287:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;17171:151::o;51530:35::-;;;;:::o;51640:42::-;;;;:::o;2927:244::-;2204:12;:10;:12::i;:::-;-1:-1:-1;;;;;2193:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;2193:23:0;;2185:68;;;;;-1:-1:-1;;;2185:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;3016:22:0;::::1;3008:73;;;;-1:-1:-1::0;;;3008:73:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3118:6;::::0;;3097:38:::1;::::0;-1:-1:-1;;;;;3097:38:0;;::::1;::::0;3118:6;::::1;::::0;3097:38:::1;::::0;::::1;3146:6;:17:::0;;;::::1;-1:-1:-1::0;;;;;3146:17:0;;;::::1;::::0;;;::::1;::::0;;2927:244::o;54262:282::-;-1:-1:-1;;;;;54441:27:0;54348:23;54441:27;;;:14;:27;;;;;54487:23;;54512;;;;;54487;;54262:282::o;43512:152::-;43582:4;43606:50;43611:3;-1:-1:-1;;;;;43631:23:0;;43606:4;:50::i;603:106::-;691:10;603:106;:::o;22818:346::-;-1:-1:-1;;;;;22920:19:0;;22912:68;;;;-1:-1:-1;;;22912:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;22999:21:0;;22991:68;;;;-1:-1:-1;;;22991:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;23072:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;23124:32;;;;;;;;;;;;;;;;;22818:346;;;:::o;44337:117::-;44400:7;44427:19;44435:3;44427:7;:19::i;69959:1071::-;70074:1;70065:6;:10;70057:54;;;;;-1:-1:-1;;;70057:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;70156:27:0;;;70124:29;70156:27;;;:14;:27;;;;;;;;70348:14;:27;;;;;:41;;;;;;;;;;;;70408:24;;;;70400:68;;;;;-1:-1:-1;;;70400:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;70590:26;:14;70609:6;70590:18;:26::i;:::-;-1:-1:-1;;;;;70546:27:0;;;;;;;:14;:27;;;;;;;;:41;;;;;;;;;;;;:70;;;;70734:29;;;:16;:29;;;;;:43;;;;;;;;:55;;70782:6;70734:47;:55::i;:::-;-1:-1:-1;;;;;70688:29:0;;;;;;;:16;:29;;;;;;;;:43;;;;;;;;;:101;70870:23;;:35;;70898:6;70870:27;:35::i;:::-;70844:61;;70916:45;70926:11;70947:4;70954:6;70916:9;:45::i;:::-;71001:12;-1:-1:-1;;;;;70979:43:0;70988:11;-1:-1:-1;;;;;70979:43:0;;71015:6;70979:43;;;;;;;;;;;;;;;;;;69959:1071;;;;;:::o;44084:167::-;44164:4;44188:55;44198:3;-1:-1:-1;;;;;44218:23:0;;44188:9;:55::i;20430:539::-;-1:-1:-1;;;;;20536:20:0;;20528:70;;;;-1:-1:-1;;;20528:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;20617:23:0;;20609:71;;;;-1:-1:-1;;;20609:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20693:47;20714:6;20722:9;20733:6;20693:20;:47::i;:::-;20773:71;20795:6;20773:71;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;20773:17:0;;;;;;:9;:17;;;;;;;:71;:21;:71::i;:::-;-1:-1:-1;;;;;20753:17:0;;;;;;;:9;:17;;;;;;:91;;;;20878:20;;;;;;;:32;;20903:6;20878:24;:32::i;:::-;-1:-1:-1;;;;;20855:20:0;;;;;;;:9;:20;;;;;;;;;:55;;;;20926:35;;;;;;;20855:20;;20926:35;;;;;;;;;;;;;20430:539;;;:::o;8709:166::-;8795:7;8831:12;8823:6;;;;8815:29;;;;-1:-1:-1;;;8815:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;8862:5:0;;;8709:166::o;5882:179::-;5940:7;5972:5;;;5996:6;;;;5988:46;;;;;-1:-1:-1;;;5988:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;44808:158;44882:7;44933:22;44937:3;44949:5;44933:3;:22::i;6344:158::-;6402:7;6435:1;6430;:6;;6422:49;;;;;-1:-1:-1;;;6422:49:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6489:5:0;;;6344:158::o;72395:203::-;72503:10;72491:23;;;;:11;:23;;;;;72515:30;;-1:-1:-1;;72515:34:0;;;72491:59;;;;;;;;;;;;;;;;72458:11;:23;72470:10;-1:-1:-1;;;;;72458:23:0;-1:-1:-1;;;;;72458:23:0;;;;;;;;;;;;72482:5;72458:30;;;;;;;;;;;;;;;;:92;;:30;;;;;:92;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;72458:92:0;;;;;;;;;;;;;;;;;;;;;;72573:10;72561:23;;:11;:23;;;;;;:29;;;;;;;;;;;;;;;-1:-1:-1;;72561:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;72395:203:0:o;71217:1170::-;71334:1;71325:6;:10;71317:56;;;;-1:-1:-1;;;71317:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;71494:29:0;;;71468:23;71494:29;;;:16;:29;;;;;;;;:43;;;;;;;;;;71556:25;;;;71548:71;;;;-1:-1:-1;;;71548:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71740:27;:15;71760:6;71740:19;:27::i;:::-;-1:-1:-1;;;;;71694:29:0;;;;;;;:16;:29;;;;;;;;:43;;;;;;;;;;;:73;;;;71823:21;:35;;;;;;71812:58;;71864:5;;71812:47;;:6;;:10;:47::i;:58::-;-1:-1:-1;;;;;71957:27:0;;71925:29;71957:27;;;:14;:27;;;;;72021:23;;71780:90;;-1:-1:-1;71957:27:0;72021:35;;72049:6;72021:27;:35::i;:::-;71995:61;;72067:72;72085:4;72092:11;72105:33;:6;72116:21;72105:10;:33::i;:::-;72067:9;:72::i;:::-;72198:13;-1:-1:-1;;;;;72198:18:0;;72217:21;72198:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72250:43;72264:4;72271:21;72250:5;:43::i;:::-;72335:12;-1:-1:-1;;;;;72311:68:0;72322:11;-1:-1:-1;;;;;72311:68:0;;72349:6;72357:21;72311:68;;;;;;;;;;;;;;;;;;;;;;;;71217:1170;;;;;;:::o;24976:444::-;25356:20;25404:8;;;24976:444::o;68806:311::-;68880:11;68872:54;;;;;-1:-1:-1;;;68872:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;68967:17;68973:2;68977:6;68967:5;:17::i;:::-;69002:31;;;-1:-1:-1;;;;;69002:31:0;;;;;;;;;;;;69010:10;;69002:31;;;;;;;;69044:65;-1:-1:-1;;;;;69044:13:0;:30;69075:10;69095:4;69102:6;69044:30;:65::i;:::-;68806:311;;:::o;6761:220::-;6819:7;6843:6;6839:20;;-1:-1:-1;6858:1:0;6851:8;;6839:20;6882:5;;;6886:1;6882;:5;:1;6906:5;;;;;:10;6898:56;;;;-1:-1:-1;;;6898:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7459:153;7517:7;7549:1;7545;:5;7537:44;;;;;-1:-1:-1;;;7537:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;7603:1;7599;:5;;;;;;;7459:153;-1:-1:-1;;;7459:153:0:o;73087:163::-;73227:15;73087:163;:::o;69387:438::-;69491:14;69508:24;:12;69525:6;69508:16;:24::i;:::-;69491:41;-1:-1:-1;69581:47:0;-1:-1:-1;;;;;69581:13:0;:26;69608:11;69621:6;69581:26;:47::i;:::-;69679:13;-1:-1:-1;;;;;69679:18:0;;69698:6;69679:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69716:34;69730:4;69737:12;69716:5;:34::i;:::-;69768:49;;;;;;;;;;;;;;-1:-1:-1;;;;;69768:49:0;;;;;;;;;;;69387:438;;;;:::o;43840:158::-;43913:4;43937:53;43945:3;-1:-1:-1;;;;;43965:23:0;;43937:7;:53::i;38543:414::-;38606:4;38628:21;38638:3;38643:5;38628:9;:21::i;:::-;38623:327;;-1:-1:-1;38666:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;38849:18;;38827:19;;;:12;;;:19;;;;;;:40;;;;38882:11;;38623:327;-1:-1:-1;38933:5:0;38926:12;;40991:109;41074:18;;40991:109::o;40776:129::-;40849:4;40873:19;;;:12;;;;;:19;;;;;;:24;;;40776:129::o;72717:279::-;-1:-1:-1;;;;;72849:18:0;;;;:55;;-1:-1:-1;72871:33:0;:18;72899:4;72871:27;:33::i;:::-;72849:90;;;-1:-1:-1;72908:31:0;:18;72936:2;72908:27;:31::i;:::-;72827:161;;;;;-1:-1:-1;;;72827:161:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;72717:279;;;:::o;41454:204::-;41549:18;;41521:7;;41549:26;-1:-1:-1;41541:73:0;;;;-1:-1:-1;;;41541:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41632:3;:11;;41644:5;41632:18;;;;;;;;;;;;;;;;41625:25;;41454:204;;;;:::o;21962:418::-;-1:-1:-1;;;;;22046:21:0;;22038:67;;;;-1:-1:-1;;;22038:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22118:49;22139:7;22156:1;22160:6;22118:20;:49::i;:::-;22201:68;22224:6;22201:68;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;22201:18:0;;;;;;:9;:18;;;;;;;:68;:22;:68::i;:::-;-1:-1:-1;;;;;22180:18:0;;;;;;:9;:18;;;;;:89;22295:12;;:24;;22312:6;22295:16;:24::i;:::-;22280:12;:39;22335:37;;;;;;;;22361:1;;-1:-1:-1;;;;;22335:37:0;;;;;;;;;;;;21962:418;;:::o;21251:378::-;-1:-1:-1;;;;;21335:21:0;;21327:65;;;;;-1:-1:-1;;;21327:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;21405:49;21434:1;21438:7;21447:6;21405:20;:49::i;:::-;21482:12;;:24;;21499:6;21482:16;:24::i;:::-;21467:12;:39;-1:-1:-1;;;;;21538:18:0;;;;;;:9;:18;;;;;;:30;;21561:6;21538:22;:30::i;:::-;-1:-1:-1;;;;;21517:18:0;;;;;;:9;:18;;;;;;;;:51;;;;21584:37;;;;;;;21517:18;;;;21584:37;;;;;;;;;;21251:378;;:::o;33183:205::-;33311:68;;;-1:-1:-1;;;;;33311:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33334:27;33311:68;;;33284:96;;33304:5;;33284:19;:96::i;:::-;33183:205;;;;:::o;32998:177::-;33108:58;;;-1:-1:-1;;;;;33108:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33131:23;33108:58;;;33081:86;;33101:5;;33081:19;:86::i;39133:1557::-;39199:4;39338:19;;;:12;;;:19;;;;;;39374:15;;39370:1313;;39822:18;;-1:-1:-1;;39773:14:0;;;;39822:22;;;;39749:21;;39822:3;;:22;;40109;;;;;;;;;;;;;;40089:42;;40255:9;40226:3;:11;;40238:13;40226:26;;;;;;;;;;;;;;;;;;;:38;;;;40332:23;;;40374:1;40332:12;;;:23;;;;;;40358:17;;;40332:43;;40484:17;;40332:3;;40484:17;;;;;;;;;;;;;;;;;;;;;;40579:3;:12;;:19;40592:5;40579:19;;;;;;;;;;;40572:26;;;40622:4;40615:11;;;;;;;;39370:1313;40666:5;40659:12;;;;;35354:774;35778:23;35804:69;35832:4;35804:69;;;;;;;;;;;;;;;;;35812:5;-1:-1:-1;;;;;35804:27:0;;;:69;;;;;:::i;:::-;35888:17;;35778:95;;-1:-1:-1;35888:21:0;35884:237;;36043:10;36032:30;;;;;;;;;;;;;;;-1:-1:-1;36032:30:0;36024:85;;;;-1:-1:-1;;;36024:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27918:229;28055:12;28087:52;28109:6;28117:4;28123:1;28126:12;28055;29299:18;29310:6;29299:10;:18::i;:::-;29291:60;;;;;-1:-1:-1;;;29291:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;29425:12;29439:23;29466:6;-1:-1:-1;;;;;29466:11:0;29486:5;29494:4;29466:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29424:75;;;;29517:52;29535:7;29544:10;29556:12;29517:17;:52::i;:::-;29510:59;29004:573;-1:-1:-1;;;;;;;29004:573:0:o;31655:777::-;31805:12;31834:7;31830:595;;;-1:-1:-1;31865:10:0;31858:17;;31830:595;31979:17;;:21;31975:439;;32242:10;32236:17;32303:15;32290:10;32286:2;32282:19;32275:44;32190:148;32378:20;;-1:-1:-1;;;32378:20:0;;;;;;;;;;;;;;;;;32385:12;;32378:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Swarm Source

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