ETH Price: $1,913.94 (-2.65%)
 

Overview

ETH Balance

0.011712480034067616 ETH

Eth Value

$22.42 (@ $1,913.94/ETH)

Token Holdings

More Info

Private Name Tags

TokenTracker

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Exercise232798652025-09-03 3:21:59173 days ago1756869719IN
0xEd95e4e0...b5bC09De7
0 ETH0.000029410.35
Bet232797562025-09-03 3:00:11173 days ago1756868411IN
0xEd95e4e0...b5bC09De7
0.0006 ETH0.000317441.26106774
Exercise232795602025-09-03 2:20:59173 days ago1756866059IN
0xEd95e4e0...b5bC09De7
0 ETH0.000025210.3
Bet232794622025-09-03 2:01:23173 days ago1756864883IN
0xEd95e4e0...b5bC09De7
0.0011 ETH0.000319731.27012507
Exercise232794412025-09-03 1:57:11173 days ago1756864631IN
0xEd95e4e0...b5bC09De7
0 ETH0.000026540.315895
Bet232794272025-09-03 1:54:23173 days ago1756864463IN
0xEd95e4e0...b5bC09De7
0.002 ETH0.000315061.17199892
Bet232697782025-09-01 17:29:11174 days ago1756747751IN
0xEd95e4e0...b5bC09De7
0.003 ETH0.000914873.63442628
Exercise232697032025-09-01 17:13:59174 days ago1756746839IN
0xEd95e4e0...b5bC09De7
0 ETH0.000319833.80556481
Bet232695492025-09-01 16:42:59174 days ago1756744979IN
0xEd95e4e0...b5bC09De7
0.0055 ETH0.001166644.63462822
Exercise232695122025-09-01 16:35:23174 days ago1756744523IN
0xEd95e4e0...b5bC09De7
0 ETH0.000448115.33179027
Bet232692612025-09-01 15:44:47174 days ago1756741487IN
0xEd95e4e0...b5bC09De7
0.009 ETH0.001964757.80520963
Exercise232692122025-09-01 15:34:59174 days ago1756740899IN
0xEd95e4e0...b5bC09De7
0 ETH0.0006427.6388838
Bet232691702025-09-01 15:26:35174 days ago1756740395IN
0xEd95e4e0...b5bC09De7
0.016 ETH0.002270419.01944668
Exercise232689482025-09-01 14:41:35174 days ago1756737695IN
0xEd95e4e0...b5bC09De7
0 ETH0.0010399712.37406697
Bet232689202025-09-01 14:35:59174 days ago1756737359IN
0xEd95e4e0...b5bC09De7
0.029 ETH0.0032192412.78877408
Exercise232680482025-09-01 11:40:35175 days ago1756726835IN
0xEd95e4e0...b5bC09De7
0 ETH0.000100511.19601386
Bet232680112025-09-01 11:33:11175 days ago1756726391IN
0xEd95e4e0...b5bC09De7
0.051 ETH0.000242820.96465683
Expire232677762025-09-01 10:46:11175 days ago1756723571IN
0xEd95e4e0...b5bC09De7
0 ETH0.00004660.68914521
Bet232677652025-09-01 10:43:59175 days ago1756723439IN
0xEd95e4e0...b5bC09De7
0.03 ETH0.000196120.7790908
Exercise232677442025-09-01 10:39:47175 days ago1756723187IN
0xEd95e4e0...b5bC09De7
0 ETH0.000051350.61106271
Bet232676832025-09-01 10:27:23175 days ago1756722443IN
0xEd95e4e0...b5bC09De7
0.041 ETH0.000128260.50956544
Exercise232672772025-09-01 9:05:59175 days ago1756717559IN
0xEd95e4e0...b5bC09De7
0 ETH0.000076230.90708677
Bet232670292025-09-01 8:16:11175 days ago1756714571IN
0xEd95e4e0...b5bC09De7
0.014 ETH0.000250950.9968269
Exercise232665332025-09-01 6:36:35175 days ago1756708595IN
0xEd95e4e0...b5bC09De7
0 ETH0.00002470.29394606
Bet232665132025-09-01 6:32:35175 days ago1756708355IN
0xEd95e4e0...b5bC09De7
0.004 ETH0.000053820.2137794
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer232798652025-09-03 3:21:59173 days ago1756869719
0xEd95e4e0...b5bC09De7
0.0019104 ETH
Transfer232797562025-09-03 3:00:11173 days ago1756868411
0xEd95e4e0...b5bC09De7
0.000003 ETH
Transfer232795602025-09-03 2:20:59173 days ago1756866059
0xEd95e4e0...b5bC09De7
0.0035024 ETH
Transfer232794622025-09-03 2:01:23173 days ago1756864883
0xEd95e4e0...b5bC09De7
0.0000055 ETH
Transfer232794412025-09-03 1:57:11173 days ago1756864631
0xEd95e4e0...b5bC09De7
0.006368 ETH
Transfer232794272025-09-03 1:54:23173 days ago1756864463
0xEd95e4e0...b5bC09De7
0.00001 ETH
Transfer232697782025-09-01 17:29:11174 days ago1756747751
0xEd95e4e0...b5bC09De7
0.000015 ETH
Transfer232697032025-09-01 17:13:59174 days ago1756746839
0xEd95e4e0...b5bC09De7
0.017512 ETH
Transfer232695492025-09-01 16:42:59174 days ago1756744979
0xEd95e4e0...b5bC09De7
0.0000275 ETH
Transfer232695122025-09-01 16:35:23174 days ago1756744523
0xEd95e4e0...b5bC09De7
0.028656 ETH
Transfer232692612025-09-01 15:44:47174 days ago1756741487
0xEd95e4e0...b5bC09De7
0.000045 ETH
Transfer232692122025-09-01 15:34:59174 days ago1756740899
0xEd95e4e0...b5bC09De7
0.050944 ETH
Transfer232691702025-09-01 15:26:35174 days ago1756740395
0xEd95e4e0...b5bC09De7
0.00008 ETH
Transfer232689482025-09-01 14:41:35174 days ago1756737695
0xEd95e4e0...b5bC09De7
0.092336 ETH
Transfer232689202025-09-01 14:35:59174 days ago1756737359
0xEd95e4e0...b5bC09De7
0.000145 ETH
Transfer232680482025-09-01 11:40:35175 days ago1756726835
0xEd95e4e0...b5bC09De7
0.162384 ETH
Transfer232680112025-09-01 11:33:11175 days ago1756726391
0xEd95e4e0...b5bC09De7
0.000255 ETH
Transfer232677762025-09-01 10:46:11175 days ago1756723571
0xEd95e4e0...b5bC09De7
0.00003404 ETH
Transfer232677652025-09-01 10:43:59175 days ago1756723439
0xEd95e4e0...b5bC09De7
0.00015 ETH
Transfer232677442025-09-01 10:39:47175 days ago1756723187
0xEd95e4e0...b5bC09De7
0.130544 ETH
Transfer232676832025-09-01 10:27:23175 days ago1756722443
0xEd95e4e0...b5bC09De7
0.000205 ETH
Transfer232672772025-09-01 9:05:59175 days ago1756717559
0xEd95e4e0...b5bC09De7
0.040397 ETH
Transfer232670292025-09-01 8:16:11175 days ago1756714571
0xEd95e4e0...b5bC09De7
0.00007 ETH
Transfer232665332025-09-01 6:36:35175 days ago1756708595
0xEd95e4e0...b5bC09De7
0.011542 ETH
Transfer232665132025-09-01 6:32:35175 days ago1756708355
0xEd95e4e0...b5bC09De7
0.00002 ETH
View All Internal Transactions
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
BinaryOptions

Compiler Version
v0.6.6+commit.6c089d02

Optimization Enabled:
Yes with 100000 runs

Other Settings:
default evmVersion, None license
/**
 *Submitted for verification at Etherscan.io on 2021-02-05
*/

pragma solidity ^0.6.6;


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

        return c;
    }

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

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

        return c;
    }

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

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

        return c;
    }

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

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

        return c;
    }

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

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

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view 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 returns (uint8) {
        return _decimals;
    }

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

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view 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 {
        _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 { }
}
contract BIOPToken is ERC20 {
    using SafeMath for uint256;
    address public binaryOptions = 0x0000000000000000000000000000000000000000;
    address public gov;
    address public owner;
    uint256 public earlyClaimsAvailable = 450000000000000000000000000000;
    uint256 public totalClaimsAvailable = 750000000000000000000000000000;
    bool public earlyClaims = true;
    bool public binaryOptionsSet = false;

    constructor(string memory name_, string memory symbol_) public ERC20(name_, symbol_) {
      owner = msg.sender;
    }
    
    modifier onlyBinaryOptions() {
        require(binaryOptions == msg.sender, "Ownable: caller is not the Binary Options Contract");
        _;
    }
    modifier onlyOwner() {
        require(binaryOptions == msg.sender, "Ownable: caller is not the owner");
        _;
    }

    function updateEarlyClaim(uint256 amount) external onlyBinaryOptions {
        require(totalClaimsAvailable.sub(amount) >= 0, "insufficent claims available");
        if (earlyClaims) {
            earlyClaimsAvailable = earlyClaimsAvailable.sub(amount);
            _mint(tx.origin, amount);
            if (earlyClaimsAvailable <= 0) {
                earlyClaims = false;
            }
        } else {
            updateClaim(amount.div(4));
        }
    }

     function updateClaim( uint256 amount) internal {
        require(totalClaimsAvailable.sub(amount) >= 0, "insufficent claims available");
        totalClaimsAvailable.sub(amount);
        _mint(tx.origin, amount);
    }

    function setupBinaryOptions(address payable options_) external {
        require(binaryOptionsSet != true, "binary options is already set");
        binaryOptions = options_;
    }

    function setupGovernance(address payable gov_) external onlyOwner {
        _mint(owner, 100000000000000000000000000000);
        _mint(gov_, 450000000000000000000000000000);
        owner = 0x0000000000000000000000000000000000000000;
    }
}


 /**
 * @title Power function by Bancor
 * @dev https://github.com/bancorprotocol/contracts
 *
 * Modified from the original by Slava Balasanov & Tarrence van As
 *
 * Split Power.sol out from BancorFormula.sol
 * https://github.com/bancorprotocol/contracts/blob/c9adc95e82fdfb3a0ada102514beb8ae00147f5d/solidity/contracts/converter/BancorFormula.sol
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements;
 * and to You under the Apache License, Version 2.0. "
 */
contract Power {
    string public version = "0.3";

    uint256 private constant ONE = 1;
    uint32 private constant MAX_WEIGHT = 1000000;
    uint8 private constant MIN_PRECISION = 32;
    uint8 private constant MAX_PRECISION = 127;

    /**
      The values below depend on MAX_PRECISION. If you choose to change it:
      Apply the same change in file 'PrintIntScalingFactors.py', run it and paste the results below.
    */
    uint256 private constant FIXED_1 = 0x080000000000000000000000000000000;
    uint256 private constant FIXED_2 = 0x100000000000000000000000000000000;
    uint256 private constant MAX_NUM = 0x200000000000000000000000000000000;

    /**
        Auto-generated via 'PrintLn2ScalingFactors.py'
    */
    uint256 private constant LN2_NUMERATOR   = 0x3f80fe03f80fe03f80fe03f80fe03f8;
    uint256 private constant LN2_DENOMINATOR = 0x5b9de1d10bf4103d647b0955897ba80;

    /**
        Auto-generated via 'PrintFunctionOptimalLog.py' and 'PrintFunctionOptimalExp.py'
    */
    uint256 private constant OPT_LOG_MAX_VAL = 0x15bf0a8b1457695355fb8ac404e7a79e3;
    uint256 private constant OPT_EXP_MAX_VAL = 0x800000000000000000000000000000000;

    /**
      The values below depend on MIN_PRECISION and MAX_PRECISION. If you choose to change either one of them:
      Apply the same change in file 'PrintFunctionBancorFormula.py', run it and paste the results below.
    */
    uint256[128] private maxExpArray;

    constructor() public {
    //  maxExpArray[0] = 0x6bffffffffffffffffffffffffffffffff;
    //  maxExpArray[1] = 0x67ffffffffffffffffffffffffffffffff;
    //  maxExpArray[2] = 0x637fffffffffffffffffffffffffffffff;
    //  maxExpArray[3] = 0x5f6fffffffffffffffffffffffffffffff;
    //  maxExpArray[4] = 0x5b77ffffffffffffffffffffffffffffff;
    //  maxExpArray[5] = 0x57b3ffffffffffffffffffffffffffffff;
    //  maxExpArray[6] = 0x5419ffffffffffffffffffffffffffffff;
    //  maxExpArray[7] = 0x50a2ffffffffffffffffffffffffffffff;
    //  maxExpArray[8] = 0x4d517fffffffffffffffffffffffffffff;
    //  maxExpArray[9] = 0x4a233fffffffffffffffffffffffffffff;
    //  maxExpArray[10] = 0x47165fffffffffffffffffffffffffffff;
    //  maxExpArray[11] = 0x4429afffffffffffffffffffffffffffff;
    //  maxExpArray[12] = 0x415bc7ffffffffffffffffffffffffffff;
    //  maxExpArray[13] = 0x3eab73ffffffffffffffffffffffffffff;
    //  maxExpArray[14] = 0x3c1771ffffffffffffffffffffffffffff;
    //  maxExpArray[15] = 0x399e96ffffffffffffffffffffffffffff;
    //  maxExpArray[16] = 0x373fc47fffffffffffffffffffffffffff;
    //  maxExpArray[17] = 0x34f9e8ffffffffffffffffffffffffffff;
    //  maxExpArray[18] = 0x32cbfd5fffffffffffffffffffffffffff;
    //  maxExpArray[19] = 0x30b5057fffffffffffffffffffffffffff;
    //  maxExpArray[20] = 0x2eb40f9fffffffffffffffffffffffffff;
    //  maxExpArray[21] = 0x2cc8340fffffffffffffffffffffffffff;
    //  maxExpArray[22] = 0x2af09481ffffffffffffffffffffffffff;
    //  maxExpArray[23] = 0x292c5bddffffffffffffffffffffffffff;
    //  maxExpArray[24] = 0x277abdcdffffffffffffffffffffffffff;
    //  maxExpArray[25] = 0x25daf6657fffffffffffffffffffffffff;
    //  maxExpArray[26] = 0x244c49c65fffffffffffffffffffffffff;
    //  maxExpArray[27] = 0x22ce03cd5fffffffffffffffffffffffff;
    //  maxExpArray[28] = 0x215f77c047ffffffffffffffffffffffff;
    //  maxExpArray[29] = 0x1fffffffffffffffffffffffffffffffff;
    //  maxExpArray[30] = 0x1eaefdbdabffffffffffffffffffffffff;
    //  maxExpArray[31] = 0x1d6bd8b2ebffffffffffffffffffffffff;
        maxExpArray[32] = 0x1c35fedd14ffffffffffffffffffffffff;
        maxExpArray[33] = 0x1b0ce43b323fffffffffffffffffffffff;
        maxExpArray[34] = 0x19f0028ec1ffffffffffffffffffffffff;
        maxExpArray[35] = 0x18ded91f0e7fffffffffffffffffffffff;
        maxExpArray[36] = 0x17d8ec7f0417ffffffffffffffffffffff;
        maxExpArray[37] = 0x16ddc6556cdbffffffffffffffffffffff;
        maxExpArray[38] = 0x15ecf52776a1ffffffffffffffffffffff;
        maxExpArray[39] = 0x15060c256cb2ffffffffffffffffffffff;
        maxExpArray[40] = 0x1428a2f98d72ffffffffffffffffffffff;
        maxExpArray[41] = 0x13545598e5c23fffffffffffffffffffff;
        maxExpArray[42] = 0x1288c4161ce1dfffffffffffffffffffff;
        maxExpArray[43] = 0x11c592761c666fffffffffffffffffffff;
        maxExpArray[44] = 0x110a688680a757ffffffffffffffffffff;
        maxExpArray[45] = 0x1056f1b5bedf77ffffffffffffffffffff;
        maxExpArray[46] = 0x0faadceceeff8bffffffffffffffffffff;
        maxExpArray[47] = 0x0f05dc6b27edadffffffffffffffffffff;
        maxExpArray[48] = 0x0e67a5a25da4107fffffffffffffffffff;
        maxExpArray[49] = 0x0dcff115b14eedffffffffffffffffffff;
        maxExpArray[50] = 0x0d3e7a392431239fffffffffffffffffff;
        maxExpArray[51] = 0x0cb2ff529eb71e4fffffffffffffffffff;
        maxExpArray[52] = 0x0c2d415c3db974afffffffffffffffffff;
        maxExpArray[53] = 0x0bad03e7d883f69bffffffffffffffffff;
        maxExpArray[54] = 0x0b320d03b2c343d5ffffffffffffffffff;
        maxExpArray[55] = 0x0abc25204e02828dffffffffffffffffff;
        maxExpArray[56] = 0x0a4b16f74ee4bb207fffffffffffffffff;
        maxExpArray[57] = 0x09deaf736ac1f569ffffffffffffffffff;
        maxExpArray[58] = 0x0976bd9952c7aa957fffffffffffffffff;
        maxExpArray[59] = 0x09131271922eaa606fffffffffffffffff;
        maxExpArray[60] = 0x08b380f3558668c46fffffffffffffffff;
        maxExpArray[61] = 0x0857ddf0117efa215bffffffffffffffff;
        maxExpArray[62] = 0x07ffffffffffffffffffffffffffffffff;
        maxExpArray[63] = 0x07abbf6f6abb9d087fffffffffffffffff;
        maxExpArray[64] = 0x075af62cbac95f7dfa7fffffffffffffff;
        maxExpArray[65] = 0x070d7fb7452e187ac13fffffffffffffff;
        maxExpArray[66] = 0x06c3390ecc8af379295fffffffffffffff;
        maxExpArray[67] = 0x067c00a3b07ffc01fd6fffffffffffffff;
        maxExpArray[68] = 0x0637b647c39cbb9d3d27ffffffffffffff;
        maxExpArray[69] = 0x05f63b1fc104dbd39587ffffffffffffff;
        maxExpArray[70] = 0x05b771955b36e12f7235ffffffffffffff;
        maxExpArray[71] = 0x057b3d49dda84556d6f6ffffffffffffff;
        maxExpArray[72] = 0x054183095b2c8ececf30ffffffffffffff;
        maxExpArray[73] = 0x050a28be635ca2b888f77fffffffffffff;
        maxExpArray[74] = 0x04d5156639708c9db33c3fffffffffffff;
        maxExpArray[75] = 0x04a23105873875bd52dfdfffffffffffff;
        maxExpArray[76] = 0x0471649d87199aa990756fffffffffffff;
        maxExpArray[77] = 0x04429a21a029d4c1457cfbffffffffffff;
        maxExpArray[78] = 0x0415bc6d6fb7dd71af2cb3ffffffffffff;
        maxExpArray[79] = 0x03eab73b3bbfe282243ce1ffffffffffff;
        maxExpArray[80] = 0x03c1771ac9fb6b4c18e229ffffffffffff;
        maxExpArray[81] = 0x0399e96897690418f785257fffffffffff;
        maxExpArray[82] = 0x0373fc456c53bb779bf0ea9fffffffffff;
        maxExpArray[83] = 0x034f9e8e490c48e67e6ab8bfffffffffff;
        maxExpArray[84] = 0x032cbfd4a7adc790560b3337ffffffffff;
        maxExpArray[85] = 0x030b50570f6e5d2acca94613ffffffffff;
        maxExpArray[86] = 0x02eb40f9f620fda6b56c2861ffffffffff;
        maxExpArray[87] = 0x02cc8340ecb0d0f520a6af58ffffffffff;
        maxExpArray[88] = 0x02af09481380a0a35cf1ba02ffffffffff;
        maxExpArray[89] = 0x0292c5bdd3b92ec810287b1b3fffffffff;
        maxExpArray[90] = 0x0277abdcdab07d5a77ac6d6b9fffffffff;
        maxExpArray[91] = 0x025daf6654b1eaa55fd64df5efffffffff;
        maxExpArray[92] = 0x0244c49c648baa98192dce88b7ffffffff;
        maxExpArray[93] = 0x022ce03cd5619a311b2471268bffffffff;
        maxExpArray[94] = 0x0215f77c045fbe885654a44a0fffffffff;
        maxExpArray[95] = 0x01ffffffffffffffffffffffffffffffff;
        maxExpArray[96] = 0x01eaefdbdaaee7421fc4d3ede5ffffffff;
        maxExpArray[97] = 0x01d6bd8b2eb257df7e8ca57b09bfffffff;
        maxExpArray[98] = 0x01c35fedd14b861eb0443f7f133fffffff;
        maxExpArray[99] = 0x01b0ce43b322bcde4a56e8ada5afffffff;
        maxExpArray[100] = 0x019f0028ec1fff007f5a195a39dfffffff;
        maxExpArray[101] = 0x018ded91f0e72ee74f49b15ba527ffffff;
        maxExpArray[102] = 0x017d8ec7f04136f4e5615fd41a63ffffff;
        maxExpArray[103] = 0x016ddc6556cdb84bdc8d12d22e6fffffff;
        maxExpArray[104] = 0x015ecf52776a1155b5bd8395814f7fffff;
        maxExpArray[105] = 0x015060c256cb23b3b3cc3754cf40ffffff;
        maxExpArray[106] = 0x01428a2f98d728ae223ddab715be3fffff;
        maxExpArray[107] = 0x013545598e5c23276ccf0ede68034fffff;
        maxExpArray[108] = 0x01288c4161ce1d6f54b7f61081194fffff;
        maxExpArray[109] = 0x011c592761c666aa641d5a01a40f17ffff;
        maxExpArray[110] = 0x0110a688680a7530515f3e6e6cfdcdffff;
        maxExpArray[111] = 0x01056f1b5bedf75c6bcb2ce8aed428ffff;
        maxExpArray[112] = 0x00faadceceeff8a0890f3875f008277fff;
        maxExpArray[113] = 0x00f05dc6b27edad306388a600f6ba0bfff;
        maxExpArray[114] = 0x00e67a5a25da41063de1495d5b18cdbfff;
        maxExpArray[115] = 0x00dcff115b14eedde6fc3aa5353f2e4fff;
        maxExpArray[116] = 0x00d3e7a3924312399f9aae2e0f868f8fff;
        maxExpArray[117] = 0x00cb2ff529eb71e41582cccd5a1ee26fff;
        maxExpArray[118] = 0x00c2d415c3db974ab32a51840c0b67edff;
        maxExpArray[119] = 0x00bad03e7d883f69ad5b0a186184e06bff;
        maxExpArray[120] = 0x00b320d03b2c343d4829abd6075f0cc5ff;
        maxExpArray[121] = 0x00abc25204e02828d73c6e80bcdb1a95bf;
        maxExpArray[122] = 0x00a4b16f74ee4bb2040a1ec6c15fbbf2df;
        maxExpArray[123] = 0x009deaf736ac1f569deb1b5ae3f36c130f;
        maxExpArray[124] = 0x00976bd9952c7aa957f5937d790ef65037;
        maxExpArray[125] = 0x009131271922eaa6064b73a22d0bd4f2bf;
        maxExpArray[126] = 0x008b380f3558668c46c91c49a2f8e967b9;
        maxExpArray[127] = 0x00857ddf0117efa215952912839f6473e6;
    }

    /**
      General Description:
          Determine a value of precision.
          Calculate an integer approximation of (_baseN / _baseD) ^ (_expN / _expD) * 2 ^ precision.
          Return the result along with the precision used.
      Detailed Description:
          Instead of calculating "base ^ exp", we calculate "e ^ (log(base) * exp)".
          The value of "log(base)" is represented with an integer slightly smaller than "log(base) * 2 ^ precision".
          The larger "precision" is, the more accurately this value represents the real value.
          However, the larger "precision" is, the more bits are required in order to store this value.
          And the exponentiation function, which takes "x" and calculates "e ^ x", is limited to a maximum exponent (maximum value of "x").
          This maximum exponent depends on the "precision" used, and it is given by "maxExpArray[precision] >> (MAX_PRECISION - precision)".
          Hence we need to determine the highest precision which can be used for the given input, before calling the exponentiation function.
          This allows us to compute "base ^ exp" with maximum accuracy and without exceeding 256 bits in any of the intermediate computations.
          This functions assumes that "_expN < 2 ^ 256 / log(MAX_NUM - 1)", otherwise the multiplication should be replaced with a "safeMul".
    */
    function power(
        uint256 _baseN,
        uint256 _baseD,
        uint32 _expN,
        uint32 _expD
    ) internal view returns (uint256, uint8)
    {
        require(_baseN < MAX_NUM, "baseN exceeds max value.");
        require(_baseN >= _baseD, "Bases < 1 are not supported.");

        uint256 baseLog;
        uint256 base = _baseN * FIXED_1 / _baseD;
        if (base < OPT_LOG_MAX_VAL) {
            baseLog = optimalLog(base);
        } else {
            baseLog = generalLog(base);
        }

        uint256 baseLogTimesExp = baseLog * _expN / _expD;
        if (baseLogTimesExp < OPT_EXP_MAX_VAL) {
            return (optimalExp(baseLogTimesExp), MAX_PRECISION);
        } else {
            uint8 precision = findPositionInMaxExpArray(baseLogTimesExp);
            return (generalExp(baseLogTimesExp >> (MAX_PRECISION - precision), precision), precision);
        }
    }

    /**
        Compute log(x / FIXED_1) * FIXED_1.
        This functions assumes that "x >= FIXED_1", because the output would be negative otherwise.
    */
    function generalLog(uint256 _x) internal pure returns (uint256) {
        uint256 res = 0;
        uint256 x = _x;

        // If x >= 2, then we compute the integer part of log2(x), which is larger than 0.
        if (x >= FIXED_2) {
            uint8 count = floorLog2(x / FIXED_1);
            x >>= count; // now x < 2
            res = count * FIXED_1;
        }

        // If x > 1, then we compute the fraction part of log2(x), which is larger than 0.
        if (x > FIXED_1) {
            for (uint8 i = MAX_PRECISION; i > 0; --i) {
                x = (x * x) / FIXED_1; // now 1 < x < 4
                if (x >= FIXED_2) {
                    x >>= 1; // now 1 < x < 2
                    res += ONE << (i - 1);
                }
            }
        }

        return res * LN2_NUMERATOR / LN2_DENOMINATOR;
    }

    /**
      Compute the largest integer smaller than or equal to the binary logarithm of the input.
    */
    function floorLog2(uint256 _n) internal pure returns (uint8) {
        uint8 res = 0;
        uint256 n = _n;

        if (n < 256) {
            // At most 8 iterations
            while (n > 1) {
                n >>= 1;
                res += 1;
            }
        } else {
            // Exactly 8 iterations
            for (uint8 s = 128; s > 0; s >>= 1) {
                if (n >= (ONE << s)) {
                    n >>= s;
                    res |= s;
                }
            }
        }

        return res;
    }

    /**
        The global "maxExpArray" is sorted in descending order, and therefore the following statements are equivalent:
        - This function finds the position of [the smallest value in "maxExpArray" larger than or equal to "x"]
        - This function finds the highest position of [a value in "maxExpArray" larger than or equal to "x"]
    */
    function findPositionInMaxExpArray(uint256 _x)
    internal view returns (uint8)
    {
        uint8 lo = MIN_PRECISION;
        uint8 hi = MAX_PRECISION;

        while (lo + 1 < hi) {
            uint8 mid = (lo + hi) / 2;
            if (maxExpArray[mid] >= _x)
                lo = mid;
            else
                hi = mid;
        }

        if (maxExpArray[hi] >= _x)
            return hi;
        if (maxExpArray[lo] >= _x)
            return lo;

        assert(false);
        return 0;
    }

    /* solhint-disable */
    /**
        This function can be auto-generated by the script 'PrintFunctionGeneralExp.py'.
        It approximates "e ^ x" via maclaurin summation: "(x^0)/0! + (x^1)/1! + ... + (x^n)/n!".
        It returns "e ^ (x / 2 ^ precision) * 2 ^ precision", that is, the result is upshifted for accuracy.
        The global "maxExpArray" maps each "precision" to "((maximumExponent + 1) << (MAX_PRECISION - precision)) - 1".
        The maximum permitted value for "x" is therefore given by "maxExpArray[precision] >> (MAX_PRECISION - precision)".
    */
    function generalExp(uint256 _x, uint8 _precision) internal pure returns (uint256) {
        uint256 xi = _x;
        uint256 res = 0;

        xi = (xi * _x) >> _precision; res += xi * 0x3442c4e6074a82f1797f72ac0000000; // add x^02 * (33! / 02!)
        xi = (xi * _x) >> _precision; res += xi * 0x116b96f757c380fb287fd0e40000000; // add x^03 * (33! / 03!)
        xi = (xi * _x) >> _precision; res += xi * 0x045ae5bdd5f0e03eca1ff4390000000; // add x^04 * (33! / 04!)
        xi = (xi * _x) >> _precision; res += xi * 0x00defabf91302cd95b9ffda50000000; // add x^05 * (33! / 05!)
        xi = (xi * _x) >> _precision; res += xi * 0x002529ca9832b22439efff9b8000000; // add x^06 * (33! / 06!)
        xi = (xi * _x) >> _precision; res += xi * 0x00054f1cf12bd04e516b6da88000000; // add x^07 * (33! / 07!)
        xi = (xi * _x) >> _precision; res += xi * 0x0000a9e39e257a09ca2d6db51000000; // add x^08 * (33! / 08!)
        xi = (xi * _x) >> _precision; res += xi * 0x000012e066e7b839fa050c309000000; // add x^09 * (33! / 09!)
        xi = (xi * _x) >> _precision; res += xi * 0x000001e33d7d926c329a1ad1a800000; // add x^10 * (33! / 10!)
        xi = (xi * _x) >> _precision; res += xi * 0x0000002bee513bdb4a6b19b5f800000; // add x^11 * (33! / 11!)
        xi = (xi * _x) >> _precision; res += xi * 0x00000003a9316fa79b88eccf2a00000; // add x^12 * (33! / 12!)
        xi = (xi * _x) >> _precision; res += xi * 0x0000000048177ebe1fa812375200000; // add x^13 * (33! / 13!)
        xi = (xi * _x) >> _precision; res += xi * 0x0000000005263fe90242dcbacf00000; // add x^14 * (33! / 14!)
        xi = (xi * _x) >> _precision; res += xi * 0x000000000057e22099c030d94100000; // add x^15 * (33! / 15!)
        xi = (xi * _x) >> _precision; res += xi * 0x0000000000057e22099c030d9410000; // add x^16 * (33! / 16!)
        xi = (xi * _x) >> _precision; res += xi * 0x00000000000052b6b54569976310000; // add x^17 * (33! / 17!)
        xi = (xi * _x) >> _precision; res += xi * 0x00000000000004985f67696bf748000; // add x^18 * (33! / 18!)
        xi = (xi * _x) >> _precision; res += xi * 0x000000000000003dea12ea99e498000; // add x^19 * (33! / 19!)
        xi = (xi * _x) >> _precision; res += xi * 0x00000000000000031880f2214b6e000; // add x^20 * (33! / 20!)
        xi = (xi * _x) >> _precision; res += xi * 0x000000000000000025bcff56eb36000; // add x^21 * (33! / 21!)
        xi = (xi * _x) >> _precision; res += xi * 0x000000000000000001b722e10ab1000; // add x^22 * (33! / 22!)
        xi = (xi * _x) >> _precision; res += xi * 0x0000000000000000001317c70077000; // add x^23 * (33! / 23!)
        xi = (xi * _x) >> _precision; res += xi * 0x00000000000000000000cba84aafa00; // add x^24 * (33! / 24!)
        xi = (xi * _x) >> _precision; res += xi * 0x00000000000000000000082573a0a00; // add x^25 * (33! / 25!)
        xi = (xi * _x) >> _precision; res += xi * 0x00000000000000000000005035ad900; // add x^26 * (33! / 26!)
        xi = (xi * _x) >> _precision; res += xi * 0x000000000000000000000002f881b00; // add x^27 * (33! / 27!)
        xi = (xi * _x) >> _precision; res += xi * 0x0000000000000000000000001b29340; // add x^28 * (33! / 28!)
        xi = (xi * _x) >> _precision; res += xi * 0x00000000000000000000000000efc40; // add x^29 * (33! / 29!)
        xi = (xi * _x) >> _precision; res += xi * 0x0000000000000000000000000007fe0; // add x^30 * (33! / 30!)
        xi = (xi * _x) >> _precision; res += xi * 0x0000000000000000000000000000420; // add x^31 * (33! / 31!)
        xi = (xi * _x) >> _precision; res += xi * 0x0000000000000000000000000000021; // add x^32 * (33! / 32!)
        xi = (xi * _x) >> _precision; res += xi * 0x0000000000000000000000000000001; // add x^33 * (33! / 33!)

        return res / 0x688589cc0e9505e2f2fee5580000000 + _x + (ONE << _precision); // divide by 33! and then add x^1 / 1! + x^0 / 0!
    }

    /**
        Return log(x / FIXED_1) * FIXED_1
        Input range: FIXED_1 <= x <= LOG_EXP_MAX_VAL - 1
        Auto-generated via 'PrintFunctionOptimalLog.py'
    */
    function optimalLog(uint256 x) internal pure returns (uint256) {
        uint256 res = 0;

        uint256 y;
        uint256 z;
        uint256 w;

        if (x >= 0xd3094c70f034de4b96ff7d5b6f99fcd8) {res += 0x40000000000000000000000000000000; x = x * FIXED_1 / 0xd3094c70f034de4b96ff7d5b6f99fcd8;}
        if (x >= 0xa45af1e1f40c333b3de1db4dd55f29a7) {res += 0x20000000000000000000000000000000; x = x * FIXED_1 / 0xa45af1e1f40c333b3de1db4dd55f29a7;}
        if (x >= 0x910b022db7ae67ce76b441c27035c6a1) {res += 0x10000000000000000000000000000000; x = x * FIXED_1 / 0x910b022db7ae67ce76b441c27035c6a1;}
        if (x >= 0x88415abbe9a76bead8d00cf112e4d4a8) {res += 0x08000000000000000000000000000000; x = x * FIXED_1 / 0x88415abbe9a76bead8d00cf112e4d4a8;}
        if (x >= 0x84102b00893f64c705e841d5d4064bd3) {res += 0x04000000000000000000000000000000; x = x * FIXED_1 / 0x84102b00893f64c705e841d5d4064bd3;}
        if (x >= 0x8204055aaef1c8bd5c3259f4822735a2) {res += 0x02000000000000000000000000000000; x = x * FIXED_1 / 0x8204055aaef1c8bd5c3259f4822735a2;}
        if (x >= 0x810100ab00222d861931c15e39b44e99) {res += 0x01000000000000000000000000000000; x = x * FIXED_1 / 0x810100ab00222d861931c15e39b44e99;}
        if (x >= 0x808040155aabbbe9451521693554f733) {res += 0x00800000000000000000000000000000; x = x * FIXED_1 / 0x808040155aabbbe9451521693554f733;}

        z = y = x - FIXED_1;
        w = y * y / FIXED_1;
        res += z * (0x100000000000000000000000000000000 - y) / 0x100000000000000000000000000000000; z = z * w / FIXED_1;
        res += z * (0x0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - y) / 0x200000000000000000000000000000000; z = z * w / FIXED_1;
        res += z * (0x099999999999999999999999999999999 - y) / 0x300000000000000000000000000000000; z = z * w / FIXED_1;
        res += z * (0x092492492492492492492492492492492 - y) / 0x400000000000000000000000000000000; z = z * w / FIXED_1;
        res += z * (0x08e38e38e38e38e38e38e38e38e38e38e - y) / 0x500000000000000000000000000000000; z = z * w / FIXED_1;
        res += z * (0x08ba2e8ba2e8ba2e8ba2e8ba2e8ba2e8b - y) / 0x600000000000000000000000000000000; z = z * w / FIXED_1;
        res += z * (0x089d89d89d89d89d89d89d89d89d89d89 - y) / 0x700000000000000000000000000000000; z = z * w / FIXED_1;
        res += z * (0x088888888888888888888888888888888 - y) / 0x800000000000000000000000000000000;

        return res;
    }

    /**
        Return e ^ (x / FIXED_1) * FIXED_1
        Input range: 0 <= x <= OPT_EXP_MAX_VAL - 1
        Auto-generated via 'PrintFunctionOptimalExp.py'
    */
    function optimalExp(uint256 x) internal pure returns (uint256) {
        uint256 res = 0;

        uint256 y;
        uint256 z;

        z = y = x % 0x10000000000000000000000000000000;
        z = z * y / FIXED_1; res += z * 0x10e1b3be415a0000; // add y^02 * (20! / 02!)
        z = z * y / FIXED_1; res += z * 0x05a0913f6b1e0000; // add y^03 * (20! / 03!)
        z = z * y / FIXED_1; res += z * 0x0168244fdac78000; // add y^04 * (20! / 04!)
        z = z * y / FIXED_1; res += z * 0x004807432bc18000; // add y^05 * (20! / 05!)
        z = z * y / FIXED_1; res += z * 0x000c0135dca04000; // add y^06 * (20! / 06!)
        z = z * y / FIXED_1; res += z * 0x0001b707b1cdc000; // add y^07 * (20! / 07!)
        z = z * y / FIXED_1; res += z * 0x000036e0f639b800; // add y^08 * (20! / 08!)
        z = z * y / FIXED_1; res += z * 0x00000618fee9f800; // add y^09 * (20! / 09!)
        z = z * y / FIXED_1; res += z * 0x0000009c197dcc00; // add y^10 * (20! / 10!)
        z = z * y / FIXED_1; res += z * 0x0000000e30dce400; // add y^11 * (20! / 11!)
        z = z * y / FIXED_1; res += z * 0x000000012ebd1300; // add y^12 * (20! / 12!)
        z = z * y / FIXED_1; res += z * 0x0000000017499f00; // add y^13 * (20! / 13!)
        z = z * y / FIXED_1; res += z * 0x0000000001a9d480; // add y^14 * (20! / 14!)
        z = z * y / FIXED_1; res += z * 0x00000000001c6380; // add y^15 * (20! / 15!)
        z = z * y / FIXED_1; res += z * 0x000000000001c638; // add y^16 * (20! / 16!)
        z = z * y / FIXED_1; res += z * 0x0000000000001ab8; // add y^17 * (20! / 17!)
        z = z * y / FIXED_1; res += z * 0x000000000000017c; // add y^18 * (20! / 18!)
        z = z * y / FIXED_1; res += z * 0x0000000000000014; // add y^19 * (20! / 19!)
        z = z * y / FIXED_1; res += z * 0x0000000000000001; // add y^20 * (20! / 20!)
        res = res / 0x21c3677c82b40000 + y + FIXED_1; // divide by 20! and then add y^1 / 1! + y^0 / 0!

        if ((x & 0x010000000000000000000000000000000) != 0) res = res * 0x1c3d6a24ed82218787d624d3e5eba95f9 / 0x18ebef9eac820ae8682b9793ac6d1e776;
        if ((x & 0x020000000000000000000000000000000) != 0) res = res * 0x18ebef9eac820ae8682b9793ac6d1e778 / 0x1368b2fc6f9609fe7aceb46aa619baed4;
        if ((x & 0x040000000000000000000000000000000) != 0) res = res * 0x1368b2fc6f9609fe7aceb46aa619baed5 / 0x0bc5ab1b16779be3575bd8f0520a9f21f;
        if ((x & 0x080000000000000000000000000000000) != 0) res = res * 0x0bc5ab1b16779be3575bd8f0520a9f21e / 0x0454aaa8efe072e7f6ddbab84b40a55c9;
        if ((x & 0x100000000000000000000000000000000) != 0) res = res * 0x0454aaa8efe072e7f6ddbab84b40a55c5 / 0x00960aadc109e7a3bf4578099615711ea;
        if ((x & 0x200000000000000000000000000000000) != 0) res = res * 0x00960aadc109e7a3bf4578099615711d7 / 0x0002bf84208204f5977f9a8cf01fdce3d;
        if ((x & 0x400000000000000000000000000000000) != 0) res = res * 0x0002bf84208204f5977f9a8cf01fdc307 / 0x0000003c6ab775dd0b95b4cbee7e65d11;

        return res;
    }
    /* solhint-enable */
}


/**
* @title Bancor formula by Bancor
*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements;
* and to You under the Apache License, Version 2.0. "
*/
contract BancorFormula is Power {
    using SafeMath for uint256;
    uint32 private constant MAX_RESERVE_RATIO = 1000000;

    /**
    * @dev given a continuous token supply, reserve token balance, reserve ratio, and a deposit amount (in the reserve token),
    * calculates the return for a given conversion (in the continuous token)
    *
    * Formula:
    * Return = _supply * ((1 + _depositAmount / _reserveBalance) ^ (_reserveRatio / MAX_RESERVE_RATIO) - 1)
    *
    * @param _supply              continuous token total supply
    * @param _reserveBalance    total reserve token balance
    * @param _reserveRatio     reserve ratio, represented in ppm, 1-1000000
    * @param _depositAmount       deposit amount, in reserve token
    *
    *  @return purchase return amount
    */
    function calculatePurchaseReturn(
        uint256 _supply,
        uint256 _reserveBalance,
        uint32 _reserveRatio,
        uint256 _depositAmount) public view returns (uint256)
    {
        // validate input
        require(_supply > 0 && _reserveBalance > 0 && _reserveRatio > 0 && _reserveRatio <= MAX_RESERVE_RATIO, "Invalid inputs.");
        // special case for 0 deposit amount
        if (_depositAmount == 0) {
            return 0;
        }
        // special case if the ratio = 100%
        if (_reserveRatio == MAX_RESERVE_RATIO) {
            return _supply.mul(_depositAmount).div(_reserveBalance);
        }
        uint256 result;
        uint8 precision;
        uint256 baseN = _depositAmount.add(_reserveBalance);
        (result, precision) = power(
            baseN, _reserveBalance, _reserveRatio, MAX_RESERVE_RATIO
        );
        uint256 newTokenSupply = _supply.mul(result) >> precision;
        return newTokenSupply.sub(_supply);
    }

    /**
    * @dev given a continuous token supply, reserve token balance, reserve ratio and a sell amount (in the continuous token),
    * calculates the return for a given conversion (in the reserve token)
    *
    * Formula:
    * Return = _reserveBalance * (1 - (1 - _sellAmount / _supply) ^ (1 / (_reserveRatio / MAX_RESERVE_RATIO)))
    *
    * @param _supply              continuous token total supply
    * @param _reserveBalance    total reserve token balance
    * @param _reserveRatio     constant reserve ratio, represented in ppm, 1-1000000
    * @param _sellAmount          sell amount, in the continuous token itself
    *
    * @return sale return amount
    */
    function calculateSaleReturn(
        uint256 _supply,
        uint256 _reserveBalance,
        uint32 _reserveRatio,
        uint256 _sellAmount) public view returns (uint256)
    {
        // validate input
        require(_supply > 0 && _reserveBalance > 0 && _reserveRatio > 0 && _reserveRatio <= MAX_RESERVE_RATIO && _sellAmount <= _supply, "Invalid inputs.");
        // special case for 0 sell amount
        if (_sellAmount == 0) {
            return 0;
        }
        // special case for selling the entire supply
        if (_sellAmount == _supply) {
            return _reserveBalance;
        }
        // special case if the ratio = 100%
        if (_reserveRatio == MAX_RESERVE_RATIO) {
            return _reserveBalance.mul(_sellAmount).div(_supply);
        }
        uint256 result;
        uint8 precision;
        uint256 baseD = _supply.sub(_sellAmount);
        (result, precision) = power(
            _supply, baseD, MAX_RESERVE_RATIO, _reserveRatio
        );
        uint256 oldBalance = _reserveBalance.mul(result);
        uint256 newBalance = _reserveBalance << precision;
        return oldBalance.sub(newBalance).div(result);
    }
}


interface IBondingCurve {
    /**
    * @dev Given a reserve token amount, calculates the amount of continuous tokens returned.
    */
    function getContinuousMintReward(uint _reserveTokenAmount) external view returns (uint);

    /**
    * @dev Given a continuous token amount, calculates the amount of reserve tokens returned.
    */  
    function getContinuousBurnRefund(uint _continuousTokenAmount) external view returns (uint);
}


abstract contract BancorBondingCurve is IBondingCurve, BancorFormula {
    /*
        reserve ratio, represented in ppm, 1-1000000
        1/3 corresponds to y= multiple * x^2
        1/2 corresponds to y= multiple * x
        2/3 corresponds to y= multiple * x^1/2
    */
    uint32 public reserveRatio;

    constructor(uint32 _reserveRatio) public {
        reserveRatio = _reserveRatio;
    }

    function getContinuousMintReward(uint _reserveTokenAmount) public override view returns (uint) {
        return calculatePurchaseReturn(continuousSupply(), reserveBalance(), reserveRatio, _reserveTokenAmount);
    }

    function getContinuousBurnRefund(uint _continuousTokenAmount) public override view returns (uint) {
        return calculateSaleReturn(continuousSupply(), reserveBalance(), reserveRatio, _continuousTokenAmount);
    }

    /**
    * @dev Abstract method that returns continuous token supply
    */
    function continuousSupply() public virtual view returns (uint);

    /**
    * @dev Abstract method that returns reserve token balance
    */    
    function reserveBalance() public virtual view returns (uint);
}

contract BIOPTokenV3 is BancorBondingCurve, ERC20 {
    using SafeMath for uint256;
    address public bO = 0x0000000000000000000000000000000000000000;//binary options
    address payable gov = 0x0000000000000000000000000000000000000000;
    address payable owner;
    address public v2;
    uint256 lEnd;//launch end
    uint256 public tCA = 750000000000000000000000000000;//total claims available
    uint256 public tbca =                 400000000000000000000000000000;//total bonding curve available
                             
    bool public binaryOptionsSet = false;

    uint256 public soldAmount = 0;
    uint256 public buyFee = 2;//10th of percent
    uint256 public sellFee = 0;//10th of percent

    constructor(string memory name_, string memory symbol_, address v2_,  uint32 _reserveRatio) public ERC20(name_, symbol_) BancorBondingCurve(_reserveRatio) {
      owner = msg.sender;
      v2 = v2_;
      lEnd = block.timestamp + 3 days;
      _mint(msg.sender, 100000);
      soldAmount = 100000;
    }


    
    modifier onlyBinaryOptions() {
        require(bO == msg.sender, "Ownable: caller is not the Binary Options Contract");
        _;
    }
    modifier onlyGov() {
        if (gov == 0x0000000000000000000000000000000000000000) {
            require(owner == msg.sender, "Ownable: caller is not the owner");
        } else {
            require(gov == msg.sender, "Ownable: caller is not the owner");
        }
        _;
    }

    /** 
     * @dev a one time function to setup governance
     * @param g_ the new governance address
     */
    function transferGovernance(address payable g_) external onlyGov {
        require(gov == 0x0000000000000000000000000000000000000000);
        require(g_ != 0x0000000000000000000000000000000000000000);
        gov = g_;
    }

    /** 
     * @dev set the fee users pay in ETH to buy BIOP from the bonding curve
     * @param newFee_ the new fee (in tenth percent) for buying on the curve
     */
    function updateBuyFee(uint256 newFee_) external onlyGov {
        require(newFee_ > 0 && newFee_ < 40, "invalid fee");
        buyFee = newFee_;
    }

    /**
     * @dev set the fee users pay in ETH to sell BIOP to the bonding curve
     * @param newFee_ the new fee (in tenth percent) for selling on the curve
     **/
    function updateSellFee(uint256 newFee_) external onlyGov {
        require(newFee_ > 0 && newFee_ < 40, "invalid fee");
        sellFee = newFee_;
    } 

    /**
     * @dev called by the binary options contract to update a users Reward claim
     * @param amount the amount in BIOP to add to this users pending claims
     **/
    function updateEarlyClaim(uint256 amount) external onlyBinaryOptions {
        require(tCA.sub(amount) >= 0, "insufficent claims available");
        if (lEnd < block.timestamp) {
            tCA = tCA.sub(amount);
            _mint(tx.origin, amount.mul(4));
        } else {
            tCA.sub(amount);
            _mint(tx.origin, amount);
        }
    }
     /**
     * @notice one time function used at deployment to configure the connected binary options contract
     * @param options_ the address of the binary options contract
     */
    function setupBinaryOptions(address payable options_) external {
        require(binaryOptionsSet != true, "binary options is already set");
        bO = options_;
        binaryOptionsSet = true;
    }

    /**
     * @dev one time swap of v2 to v3 tokens
     * @notice all v2 tokens will be swapped to v3. This cannot be undone
     */
    function swapv2v3() external {
        BIOPToken b2 = BIOPToken(v2);
        uint256 balance = b2.balanceOf(msg.sender);
        require(balance >= 0, "insufficent biopv2 balance");
        require(b2.transferFrom(msg.sender, address(this), balance), "staking failed");
        _mint(msg.sender, balance);
    }


    


    //bonding curve functions

     /**
    * @dev method that returns BIOP amount sold by curve
    */   
    function continuousSupply() public override view returns (uint) {
        return soldAmount;
    }

    /**
    * @dev method that returns curves ETH (reserve) balance
    */    
    function reserveBalance() public override view returns (uint) {
        return address(this).balance;
    }

    /**
     * @notice purchase BIOP from the bonding curve. 
     the amount you get is based on the amount in the pool and the amount of eth u send.
     */
     function buy() public payable {
        uint256 purchaseAmount = msg.value;
        
         if (buyFee > 0) {
            uint256 fee = purchaseAmount.div(buyFee).div(100);
            if (gov == 0x0000000000000000000000000000000000000000) {
                require(owner.send(fee), "buy fee transfer failed");
            } else {
                require(gov.send(fee), "buy fee transfer failed");
            }
            purchaseAmount = purchaseAmount.sub(fee);
        } 
        uint rewardAmount = getContinuousMintReward(purchaseAmount);
        require(soldAmount.add(rewardAmount) <= tbca, "maximum curve minted");
        
        _mint(msg.sender, rewardAmount);
        soldAmount = soldAmount.add(rewardAmount);
    }

    
     /**
     * @notice sell BIOP to the bonding curve
     * @param amount the amount of BIOP to sell
     */
     function sell(uint256 amount) public returns (uint256){
        require(balanceOf(msg.sender) >= amount, "insufficent BIOP balance");

        uint256 ethToSend = getContinuousBurnRefund(amount);
        if (sellFee > 0) {
            uint256 fee = ethToSend.div(buyFee).div(100);
            if (gov == 0x0000000000000000000000000000000000000000) {
                require(owner.send(fee), "buy fee transfer failed");
            } else {
                require(gov.send(fee), "buy fee transfer failed");
            }
            ethToSend = ethToSend.sub(fee);
        }
        soldAmount = soldAmount.sub(amount);
        _burn(msg.sender, amount);
        require(msg.sender.send(ethToSend), "transfer failed");
        return ethToSend;
        }
}

interface AggregatorInterface {
  function latestAnswer() external view returns (int256);
  function latestTimestamp() external view returns (uint256);
  function latestRound() external view returns (uint256);
  function getAnswer(uint256 roundId) external view returns (int256);
  function getTimestamp(uint256 roundId) external view returns (uint256);

  event AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt);
  event NewRound(uint256 indexed roundId, address indexed startedBy, uint256 startedAt);
}
interface AggregatorV3Interface {

  function decimals() external view returns (uint8);
  function description() external view returns (string memory);
  function version() external view returns (uint256);

  // getRoundData and latestRoundData should both raise "No data present"
  // if they do not have data to report, instead of returning unset values
  // which could be misinterpreted as actual reported values.
  function getRoundData(uint80 _roundId)
    external
    view
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );
  function latestRoundData()
    external
    view
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );

}
interface AggregatorV2V3Interface is AggregatorInterface, AggregatorV3Interface
{
}

/**
 * @title The Owned contract
 * @notice A contract with helpers for basic contract ownership.
 */
contract Owned {

  address public owner;
  address private pendingOwner;

  event OwnershipTransferRequested(
    address indexed from,
    address indexed to
  );
  event OwnershipTransferred(
    address indexed from,
    address indexed to
  );

  constructor() public {
    owner = msg.sender;
  }

  /**
   * @dev Allows an owner to begin transferring ownership to a new address,
   * pending.
   */
  function transferOwnership(address _to)
    external
    onlyOwner()
  {
    pendingOwner = _to;

    emit OwnershipTransferRequested(owner, _to);
  }

  /**
   * @dev Allows an ownership transfer to be completed by the recipient.
   */
  function acceptOwnership()
    external
  {
    require(msg.sender == pendingOwner, "Must be proposed owner");

    address oldOwner = owner;
    owner = msg.sender;
    pendingOwner = address(0);

    emit OwnershipTransferred(oldOwner, msg.sender);
  }

  /**
   * @dev Reverts if called by anyone other than the contract owner.
   */
  modifier onlyOwner() {
    require(msg.sender == owner, "Only callable by owner");
    _;
  }

}
contract AggregatorProxy is AggregatorV2V3Interface, Owned {

  struct Phase {
    uint16 id;
    AggregatorV2V3Interface aggregator;
  }
  Phase private currentPhase;
  AggregatorV2V3Interface public proposedAggregator;
  mapping(uint16 => AggregatorV2V3Interface) public phaseAggregators;

  uint256 constant private PHASE_OFFSET = 64;
  uint256 constant private PHASE_SIZE = 16;
  uint256 constant private MAX_ID = 2**(PHASE_OFFSET+PHASE_SIZE) - 1;

  constructor(address _aggregator) public Owned() {
    setAggregator(_aggregator);
  }

  /**
   * @notice Reads the current answer from aggregator delegated to.
   *
   * @dev #[deprecated] Use latestRoundData instead. This does not error if no
   * answer has been reached, it will simply return 0. Either wait to point to
   * an already answered Aggregator or use the recommended latestRoundData
   * instead which includes better verification information.
   */
  function latestAnswer()
    public
    view
    virtual
    override
    returns (int256 answer)
  {
    return currentPhase.aggregator.latestAnswer();
  }

  /**
   * @notice Reads the last updated height from aggregator delegated to.
   *
   * @dev #[deprecated] Use latestRoundData instead. This does not error if no
   * answer has been reached, it will simply return 0. Either wait to point to
   * an already answered Aggregator or use the recommended latestRoundData
   * instead which includes better verification information.
   */
  function latestTimestamp()
    public
    view
    virtual
    override
    returns (uint256 updatedAt)
  {
    return currentPhase.aggregator.latestTimestamp();
  }

  /**
   * @notice get past rounds answers
   * @param _roundId the answer number to retrieve the answer for
   *
   * @dev #[deprecated] Use getRoundData instead. This does not error if no
   * answer has been reached, it will simply return 0. Either wait to point to
   * an already answered Aggregator or use the recommended getRoundData
   * instead which includes better verification information.
   */
  function getAnswer(uint256 _roundId)
    public
    view
    virtual
    override
    returns (int256 answer)
  {
    if (_roundId > MAX_ID) return 0;

    (uint16 phaseId, uint64 aggregatorRoundId) = parseIds(_roundId);
    AggregatorV2V3Interface aggregator = phaseAggregators[phaseId];
    if (address(aggregator) == address(0)) return 0;

    return aggregator.getAnswer(aggregatorRoundId);
  }

  /**
   * @notice get block timestamp when an answer was last updated
   * @param _roundId the answer number to retrieve the updated timestamp for
   *
   * @dev #[deprecated] Use getRoundData instead. This does not error if no
   * answer has been reached, it will simply return 0. Either wait to point to
   * an already answered Aggregator or use the recommended getRoundData
   * instead which includes better verification information.
   */
  function getTimestamp(uint256 _roundId)
    public
    view
    virtual
    override
    returns (uint256 updatedAt)
  {
    if (_roundId > MAX_ID) return 0;

    (uint16 phaseId, uint64 aggregatorRoundId) = parseIds(_roundId);
    AggregatorV2V3Interface aggregator = phaseAggregators[phaseId];
    if (address(aggregator) == address(0)) return 0;

    return aggregator.getTimestamp(aggregatorRoundId);
  }

  /**
   * @notice get the latest completed round where the answer was updated. This
   * ID includes the proxy's phase, to make sure round IDs increase even when
   * switching to a newly deployed aggregator.
   *
   * @dev #[deprecated] Use latestRoundData instead. This does not error if no
   * answer has been reached, it will simply return 0. Either wait to point to
   * an already answered Aggregator or use the recommended latestRoundData
   * instead which includes better verification information.
   */
  function latestRound()
    public
    view
    virtual
    override
    returns (uint256 roundId)
  {
    Phase memory phase = currentPhase; // cache storage reads
    return addPhase(phase.id, uint64(phase.aggregator.latestRound()));
  }

  /**
   * @notice get data about a round. Consumers are encouraged to check
   * that they're receiving fresh data by inspecting the updatedAt and
   * answeredInRound return values.
   * Note that different underlying implementations of AggregatorV3Interface
   * have slightly different semantics for some of the return values. Consumers
   * should determine what implementations they expect to receive
   * data from and validate that they can properly handle return data from all
   * of them.
   * @param _roundId the requested round ID as presented through the proxy, this
   * is made up of the aggregator's round ID with the phase ID encoded in the
   * two highest order bytes
   * @return roundId is the round ID from the aggregator for which the data was
   * retrieved combined with an phase to ensure that round IDs get larger as
   * time moves forward.
   * @return answer is the answer for the given round
   * @return startedAt is the timestamp when the round was started.
   * (Only some AggregatorV3Interface implementations return meaningful values)
   * @return updatedAt is the timestamp when the round last was updated (i.e.
   * answer was last computed)
   * @return answeredInRound is the round ID of the round in which the answer
   * was computed.
   * (Only some AggregatorV3Interface implementations return meaningful values)
   * @dev Note that answer and updatedAt may change between queries.
   */
  function getRoundData(uint80 _roundId)
    public
    view
    virtual
    override
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    )
  {
    (uint16 phaseId, uint64 aggregatorRoundId) = parseIds(_roundId);

    (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 ansIn
    ) = phaseAggregators[phaseId].getRoundData(aggregatorRoundId);

    return addPhaseIds(roundId, answer, startedAt, updatedAt, ansIn, phaseId);
  }

  /**
   * @notice get data about the latest round. Consumers are encouraged to check
   * that they're receiving fresh data by inspecting the updatedAt and
   * answeredInRound return values.
   * Note that different underlying implementations of AggregatorV3Interface
   * have slightly different semantics for some of the return values. Consumers
   * should determine what implementations they expect to receive
   * data from and validate that they can properly handle return data from all
   * of them.
   * @return roundId is the round ID from the aggregator for which the data was
   * retrieved combined with an phase to ensure that round IDs get larger as
   * time moves forward.
   * @return answer is the answer for the given round
   * @return startedAt is the timestamp when the round was started.
   * (Only some AggregatorV3Interface implementations return meaningful values)
   * @return updatedAt is the timestamp when the round last was updated (i.e.
   * answer was last computed)
   * @return answeredInRound is the round ID of the round in which the answer
   * was computed.
   * (Only some AggregatorV3Interface implementations return meaningful values)
   * @dev Note that answer and updatedAt may change between queries.
   */
  function latestRoundData()
    public
    view
    virtual
    override
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    )
  {
    Phase memory current = currentPhase; // cache storage reads

    (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 ansIn
    ) = current.aggregator.latestRoundData();

    return addPhaseIds(roundId, answer, startedAt, updatedAt, ansIn, current.id);
  }

  /**
   * @notice Used if an aggregator contract has been proposed.
   * @param _roundId the round ID to retrieve the round data for
   * @return roundId is the round ID for which data was retrieved
   * @return answer is the answer for the given round
   * @return startedAt is the timestamp when the round was started.
   * (Only some AggregatorV3Interface implementations return meaningful values)
   * @return updatedAt is the timestamp when the round last was updated (i.e.
   * answer was last computed)
   * @return answeredInRound is the round ID of the round in which the answer
   * was computed.
  */
  function proposedGetRoundData(uint80 _roundId)
    public
    view
    virtual
    hasProposal()
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    )
  {
    return proposedAggregator.getRoundData(_roundId);
  }

  /**
   * @notice Used if an aggregator contract has been proposed.
   * @return roundId is the round ID for which data was retrieved
   * @return answer is the answer for the given round
   * @return startedAt is the timestamp when the round was started.
   * (Only some AggregatorV3Interface implementations return meaningful values)
   * @return updatedAt is the timestamp when the round last was updated (i.e.
   * answer was last computed)
   * @return answeredInRound is the round ID of the round in which the answer
   * was computed.
  */
  function proposedLatestRoundData()
    public
    view
    virtual
    hasProposal()
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    )
  {
    return proposedAggregator.latestRoundData();
  }

  /**
   * @notice returns the current phase's aggregator address.
   */
  function aggregator()
    external
    view
    returns (address)
  {
    return address(currentPhase.aggregator);
  }

  /**
   * @notice returns the current phase's ID.
   */
  function phaseId()
    external
    view
    returns (uint16)
  {
    return currentPhase.id;
  }

  /**
   * @notice represents the number of decimals the aggregator responses represent.
   */
  function decimals()
    external
    view
    override
    returns (uint8)
  {
    return currentPhase.aggregator.decimals();
  }

  /**
   * @notice the version number representing the type of aggregator the proxy
   * points to.
   */
  function version()
    external
    view
    override
    returns (uint256)
  {
    return currentPhase.aggregator.version();
  }

  /**
   * @notice returns the description of the aggregator the proxy points to.
   */
  function description()
    external
    view
    override
    returns (string memory)
  {
    return currentPhase.aggregator.description();
  }

  /**
   * @notice Allows the owner to propose a new address for the aggregator
   * @param _aggregator The new address for the aggregator contract
   */
  function proposeAggregator(address _aggregator)
    external
    onlyOwner()
  {
    proposedAggregator = AggregatorV2V3Interface(_aggregator);
  }

  /**
   * @notice Allows the owner to confirm and change the address
   * to the proposed aggregator
   * @dev Reverts if the given address doesn't match what was previously
   * proposed
   * @param _aggregator The new address for the aggregator contract
   */
  function confirmAggregator(address _aggregator)
    external
    onlyOwner()
  {
    require(_aggregator == address(proposedAggregator), "Invalid proposed aggregator");
    delete proposedAggregator;
    setAggregator(_aggregator);
  }


  /*
   * Internal
   */

  function setAggregator(address _aggregator)
    internal
  {
    uint16 id = currentPhase.id + 1;
    currentPhase = Phase(id, AggregatorV2V3Interface(_aggregator));
    phaseAggregators[id] = AggregatorV2V3Interface(_aggregator);
  }

  function addPhase(
    uint16 _phase,
    uint64 _originalId
  )
    internal
    view
    returns (uint80)
  {
    return uint80(uint256(_phase) << PHASE_OFFSET | _originalId);
  }

  function parseIds(
    uint256 _roundId
  )
    internal
    view
    returns (uint16, uint64)
  {
    uint16 phaseId = uint16(_roundId >> PHASE_OFFSET);
    uint64 aggregatorRoundId = uint64(_roundId);

    return (phaseId, aggregatorRoundId);
  }

  function addPhaseIds(
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound,
      uint16 phaseId
  )
    internal
    view
    returns (uint80, int256, uint256, uint256, uint80)
  {
    return (
      addPhase(phaseId, uint64(roundId)),
      answer,
      startedAt,
      updatedAt,
      addPhase(phaseId, uint64(answeredInRound))
    );
  }

  /*
   * Modifiers
   */

  modifier hasProposal() {
    require(address(proposedAggregator) != address(0), "No proposed aggregator present");
    _;
  }

}

interface IEBOP20 is IERC20 {

    //constructor(string memory name_, string memory symbol_) public ERC20(name_, symbol_)
    /* Skeleton EBOP20 implementation. not useable*/
    function bet(int256 latestPrice, uint256 amount) external virtual returns (uint256, uint256);
    function unlockAndPayExpirer(uint256 lockValue , uint256 purchaseValue, address expirer) external virtual returns (bool);
    function payout(uint256 lockValue,uint256 purchaseValue, address sender, address buyer) external virtual returns (bool);

}
interface IRCD {
    /**
     * @notice Returns the rate to pay out for a given amount
     * @param amount the bet amount to calc a payout for
     * @param maxAvailable the total pooled ETH unlocked and available to bet
     * @param newPrice the current price of the underlying
     * @param t time for the option
     * @param k true for call false for put
     * @return profit total possible profit amount
     *
     */
    function rate(uint256 amount, uint256 maxAvailable, uint256 newPrice, uint256 t, bool k) external view returns (uint256);

}

contract RateCalc is IRCD {
    using SafeMath for uint256;
     /**
     * @notice Calculates maximum option buyer profit
     * @param amount Option amount
     * @param maxAvailable the total pooled ETH unlocked and available to bet
     * @param newPrice the current price of the underlying
     * @param t time for the option
     * @param k true for call false for put
     * @return profit total possible profit amount
     */
    function rate(uint256 amount, uint256 maxAvailable, uint256 newPrice, uint256 t, bool k) external view override returns (uint256)  {
        require(amount <= maxAvailable, "greater then pool funds available");
        
        uint256 oneTenth = amount.div(10);
        uint256 halfMax = maxAvailable.div(2);
        if (amount > halfMax) {
            return amount.mul(2).add(oneTenth).add(oneTenth);
        } else {
            if(oneTenth > 0) {
                return amount.mul(2).sub(oneTenth);
            } else {
                uint256 oneThird = amount.div(4);
                require(oneThird > 0, "invalid bet amount");
                return amount.mul(2).sub(oneThird);
            }
        }
        
    }
}



/**
 * @title Binary Options Eth Pool
 * @author github.com/BIOPset
 * @dev Pool ETH Tokens and use it for optionss
 * Biop
 */
contract BinaryOptions is ERC20 {
    using SafeMath for uint256;
    address payable public devFund;
    address payable public owner;
    address public biop;
    address public defaultRCAddress;//address of default rate calculator
    mapping(address=>uint256) public nW; //next withdraw (used for pool lock time)
    mapping(address=>address) public ePairs;//enabled pairs. price provider mapped to rate calc
    mapping(address=>uint256) public lW;//last withdraw.used for rewards calc
    mapping(address=>uint256) private pClaims;//pending claims
    mapping(address=>uint256) public iAL;//interchange at last claim 
    mapping(address=>uint256) public lST;//last stake time

    //erc20 pools stuff
    mapping(address=>bool) public ePools;//enabled pools
    mapping(address=>uint256) public altLockedAmount;



    uint256 public minT;//min time
    uint256 public maxT;//max time
    address public defaultPair;
    uint256 public lockedAmount;
    uint256 public exerciserFee = 50;//in tenth percent
    uint256 public expirerFee = 50;//in tenth percent
    uint256 public devFundBetFee = 200;//0.5%
    uint256 public poolLockSeconds = 7 days;
    uint256 public contractCreated;
    bool public open = true;
    Option[] public options;
    
    uint256 public tI = 0;//total interchange
    //reward amounts
    uint256 public fGS =400000000000000;//first gov stake reward
    uint256 public reward =       200000000000000;
    bool public rewEn = true;//rewards enabled


    modifier onlyOwner() {
        require(owner == msg.sender, "Ownable: caller is not the owner");
        _;
    }


    /* Types */
    struct Option {
        address payable holder;
        int256 sP;//strike
        uint256 pV;//purchase 
        uint256 lV;// purchaseAmount+possible reward for correct bet
        uint256 exp;//expiration
        bool dir;//direction (true for call)
        address pP;//price provider
        address aPA;//alt pool address 
    }

    /* Events */
     event Create(
        uint256 indexed id,
        address payable account,
        int256 sP,//strike
        uint256 lV,//locked value
        bool dir
    );
    event Payout(uint256 poolLost, address winner);
    event Exercise(uint256 indexed id);
    event Expire(uint256 indexed id);

      constructor(string memory name_, string memory symbol_, address pp_, address biop_, address rateCalc_) public ERC20(name_, symbol_){
        devFund = msg.sender;
        owner = msg.sender;
        biop = biop_;
        defaultRCAddress = rateCalc_;
        lockedAmount = 0;
        contractCreated = block.timestamp;
        ePairs[pp_] = defaultRCAddress; //default pair ETH/USD
        defaultPair = pp_;
        minT = 900;//15 minutes
        maxT = 60 minutes;
    }


    function getMaxAvailable() public view returns(uint256) {
        uint256 balance = address(this).balance;
        if (balance > lockedAmount) {
            return balance.sub(lockedAmount);
        } else {
            return 0;
        }
    }

    function getAltMaxAvailable(address erc20PoolAddress_) public view returns(uint256) {
        ERC20 alt = ERC20(erc20PoolAddress_);
        uint256 balance = alt.balanceOf(address(this));
        if (balance >  altLockedAmount[erc20PoolAddress_]) {
            return balance.sub( altLockedAmount[erc20PoolAddress_]);
        } else {
            return 0;
        }
    }

    function getOptionCount() public view returns(uint256) {
        return options.length;
    }

    function getStakingTimeBonus(address account) public view returns(uint256) {
        uint256 dif = block.timestamp.sub(lST[account]);
        uint256 bonus = dif.div(777600);//9 days
        if (dif < 777600) {
            return 1;
        }
        return bonus;
    }

    function getPoolBalanceBonus(address account) public view returns(uint256) {
        uint256 balance = balanceOf(account);
        if (balance > 0) {

            if (totalSupply() < 100) { //guard
                return 1;
            }
            

            if (balance >= totalSupply().div(2)) {//50th percentile
                return 20;
            }

            if (balance >= totalSupply().div(4)) {//25th percentile
                return 14;
            }

            if (balance >= totalSupply().div(5)) {//20th percentile
                return 10;
            }

            if (balance >= totalSupply().div(10)) {//10th percentile
                return 8;
            }

            if (balance >= totalSupply().div(20)) {//5th percentile
                return 6;
            }

            if (balance >= totalSupply().div(50)) {//2nd percentile
                return 4;
            }

            if (balance >= totalSupply().div(100)) {//1st percentile
                return 3;
            }
           
           return 2;
        } 
        return 1; 
    }

    function getOptionValueBonus(address account) public view returns(uint256) {
        uint256 dif = tI.sub(iAL[account]);
        uint256 bonus = dif.div(1000000000000000000);//1ETH
        if(bonus > 0){
            return bonus;
        }
        return 0;
    }

    //used for betting/exercise/expire calc
    function getBetSizeBonus(uint256 amount, uint256 base) public view returns(uint256) {
        uint256 betPercent = totalSupply().mul(100).div(amount);
        if(base.mul(betPercent).div(10) > 0){
            return base.mul(betPercent).div(10);
        }
        return base.div(1000);
    }

    function getCombinedStakingBonus(address account) public view returns(uint256) {
        return reward
                .mul(getStakingTimeBonus(account))
                .mul(getPoolBalanceBonus(account))
                .mul(getOptionValueBonus(account));
    }

    function getPendingClaims(address account) public view returns(uint256) {
        if (balanceOf(account) > 1) {
            //staker reward bonus
            //base*(weeks)*(poolBalanceBonus/10)*optionsBacked
            return pClaims[account].add(
                getCombinedStakingBonus(account)
            );
        } else {
            //normal rewards
            return pClaims[account];
        }
    }

    function updateLPmetrics() internal {
        lST[msg.sender] = block.timestamp;
        iAL[msg.sender] = tI;
    }
     /**
     * @dev distribute pending governance token claims to user
     */
    function claimRewards() external {
        
        BIOPTokenV3 b = BIOPTokenV3(biop);
        uint256 claims = getPendingClaims(msg.sender);
        if (balanceOf(msg.sender) > 1) {
            updateLPmetrics();
        }
        pClaims[msg.sender] = 0;
        b.updateEarlyClaim(claims);
    }

    

  

    /**
     * @dev the default price provider. This is a convenience method
     */
    function defaultPriceProvider() public view returns (address) {
        return defaultPair;
    }


    /**
     * @dev add a pool
     * @param newPool_ the address EBOP20 pool to add
     */
    function addAltPool(address newPool_) external onlyOwner {
        ePools[newPool_] = true; 
    }

    /**
     * @dev enable or disable BIOP rewards
     * @param nx_ the new position for the rewEn switch
     */
    function enableRewards(bool nx_) external onlyOwner {
        rewEn = nx_;
    }

    /**
     * @dev remove a pool
     * @param oldPool_ the address EBOP20 pool to remove
     */
    function removeAltPool(address oldPool_) external onlyOwner {
        ePools[oldPool_] = false; 
    }

    /**
     * @dev add or update a price provider to the ePairs list.
     * @param newPP_ the address of the AggregatorProxy price provider contract address to add.
     * @param rateCalc_ the address of the RateCalc to use with this trading pair.
     */
    function addPP(address newPP_, address rateCalc_) external onlyOwner {
        ePairs[newPP_] = rateCalc_; 
    }

   

    /**
     * @dev remove a price provider from the ePairs list
     * @param oldPP_ the address of the AggregatorProxy price provider contract address to remove.
     */
    function removePP(address oldPP_) external onlyOwner {
        ePairs[oldPP_] = 0x0000000000000000000000000000000000000000;
    }

    /**
     * @dev update the max time for option bets
     * @param newMax_ the new maximum time (in seconds) an option may be created for (inclusive).
     */
    function setMaxT(uint256 newMax_) external onlyOwner {
        maxT = newMax_;
    }

    /**
     * @dev update the max time for option bets
     * @param newMin_ the new minimum time (in seconds) an option may be created for (inclusive).
     */
    function setMinT(uint256 newMin_) external onlyOwner {
        minT = newMin_;
    }

    /**
     * @dev address of this contract, convenience method
     */
    function thisAddress() public view returns (address){
        return address(this);
    }

    /**
     * @dev set the fee users can recieve for exercising other users options
     * @param exerciserFee_ the new fee (in tenth percent) for exercising a options itm
     */
    function updateExerciserFee(uint256 exerciserFee_) external onlyOwner {
        require(exerciserFee_ > 1 && exerciserFee_ < 500, "invalid fee");
        exerciserFee = exerciserFee_;
    }

     /**
     * @dev set the fee users can recieve for expiring other users options
     * @param expirerFee_ the new fee (in tenth percent) for expiring a options
     */
    function updateExpirerFee(uint256 expirerFee_) external onlyOwner {
        require(expirerFee_ > 1 && expirerFee_ < 50, "invalid fee");
        expirerFee = expirerFee_;
    }

    /**
     * @dev set the fee users pay to buy an option
     * @param devFundBetFee_ the new fee (in tenth percent) to buy an option
     */
    function updateDevFundBetFee(uint256 devFundBetFee_) external onlyOwner {
        require(devFundBetFee_ == 0 || devFundBetFee_ > 50, "invalid fee");
        devFundBetFee = devFundBetFee_;
    }

     /**
     * @dev update the pool stake lock up time.
     * @param newLockSeconds_ the new lock time, in seconds
     */
    function updatePoolLockSeconds(uint256 newLockSeconds_) external onlyOwner {
        require(newLockSeconds_ >= 0 && newLockSeconds_ < 14 days, "invalid fee");
        poolLockSeconds = newLockSeconds_;
    }

    /**
     * @dev used to transfer ownership
     * @param newOwner_ the address of governance contract which takes over control
     */
    function transferOwner(address payable newOwner_) external onlyOwner {
        owner = newOwner_;
    }

    /**
     * @dev used to transfer devfund 
     * @param newDevFund the address of governance contract which takes over control
     */
    function transferDevFund(address payable newDevFund) external onlyOwner {
        devFund = newDevFund;
    }


     /**
     * @dev used to send this pool into EOL mode when a newer one is open
     */
    function closeStaking() external onlyOwner {
        open = false;
    }

   
    

    /**
     * @dev send ETH to the pool. Recieve pETH token representing your claim.
     * If rewards are available recieve BIOP governance tokens as well.
    */
    function stake() external payable {
        require(open == true, "pool deposits has closed");
        require(msg.value >= 100, "stake to small");
        if (balanceOf(msg.sender) == 0) {
            lW[msg.sender] = block.timestamp;
            pClaims[msg.sender] = pClaims[msg.sender].add(fGS);
        }
        updateLPmetrics();
        nW[msg.sender] = block.timestamp + poolLockSeconds;//this one is seperate because it isn't updated on reward claim
        
        _mint(msg.sender, msg.value);
    }

    /**
     * @dev recieve ETH from the pool. 
     * If the current time is before your next available withdraw a 1% fee will be applied.
     * @param amount The amount of pETH to send the pool.
    */
    function withdraw(uint256 amount) public {
       require (balanceOf(msg.sender) >= amount, "Insufficent Share Balance");
        lW[msg.sender] = block.timestamp;
        uint256 valueToRecieve = amount.mul(address(this).balance).div(totalSupply());
        _burn(msg.sender, amount);
        if (block.timestamp <= nW[msg.sender]) {
            //early withdraw fee
            uint256 penalty = valueToRecieve.div(100);
            require(devFund.send(penalty), "transfer failed");
            require(msg.sender.send(valueToRecieve.sub(penalty)), "transfer failed");
        } else {
            require(msg.sender.send(valueToRecieve), "transfer failed");
        }
    }

     /**
    @dev helper for getting rate
    @param pair the price provider
    @param max max pool available
    @param deposit bet amount
    @param t time
    @param k direction bool, true is call
    @return the rate
    */
    function getRate(address pair,uint256 max, uint256 deposit, int256 currentPrice, uint256 t, bool k) public view returns (uint256) {
        RateCalc rc = RateCalc(ePairs[pair]);
        
        return rc.rate(deposit, max.sub(deposit), uint256(currentPrice), t, k);
    }

     /**
    @dev Open a new call or put options.
    @param k_ type of option to buy (true for call )
    @param pp_ the address of the price provider to use (must be in the list of ePairs)
    @param t_ the time until your options expiration (must be minT < t_ > maxT)
    */
    function bet(bool k_, address pp_, uint256 t_) external payable {
        require(
            t_ >= minT && t_ <= maxT,
            "Invalid time"
        );
        require(ePairs[pp_] != 0x0000000000000000000000000000000000000000, "Invalid  price provider");
        
        AggregatorProxy priceProvider = AggregatorProxy(pp_);
        int256 lA = priceProvider.latestAnswer();
        uint256 dV;
        uint256 lT;
        uint256 oID = options.length;

        
            //normal eth bet
            require(msg.value >= 100, "bet to small");
            require(msg.value <= getMaxAvailable(), "bet to big");


            //an optional (to be choosen by contract owner) fee on each option. 
            //A % of the bet money is sent as a fee. see devFundBetFee
            if (devFundBetFee > 0) {
                    uint256 fee = msg.value.div(devFundBetFee);
                    require(devFund.send(fee), "devFund fee transfer failed");
                    dV = msg.value.sub(fee);
            } else {
                    dV = msg.value;
            }


            uint256 lockValue = getRate(pp_, getMaxAvailable(), dV, lA, t_, k_);
            
            if (rewEn) {
                pClaims[msg.sender] = pClaims[msg.sender].add(getBetSizeBonus(dV, reward));
            }
            lT = lockValue.add(dV);
            lock(lT);
        


        Option memory op = Option(
            msg.sender,
            lA,
            dV,
            lT,
            block.timestamp + t_,//time till expiration
            k_,
            pp_,
            address(this)
        );

        options.push(op);
        tI = tI.add(lT);
        emit Create(oID, msg.sender, lA, lT, k_);
    }

    /**
    @dev Open a new call or put options with a ERC20 pool.
    @param k_ type of option to buy (true for call)
    @param pp_ the address of the price provider to use (must be in the list of ePairs)
    @param t_ the time until your options expiration (must be minT < t_ > maxT)
    @param pa_ address of alt pool
    @param a_ bet amount. 
    */function bet20(bool k_, address pp_, uint256 t_, address pa_,  uint256 a_) external payable {
        require(
            t_ >= minT && t_ <= maxT,
            "Invalid time"
        );
        require(ePairs[pp_] != 0x0000000000000000000000000000000000000000, "Invalid  price provider");
        
        AggregatorProxy priceProvider = AggregatorProxy(pp_);
        int256 lA = priceProvider.latestAnswer();
        uint256 dV;
        uint256 lT;

        require(ePools[pa_], "invalid pool");
        IEBOP20 altPool = IEBOP20(pa_);
        require(altPool.balanceOf(msg.sender) >= a_, "invalid pool");
        (dV, lT) = altPool.bet(lA, a_);
        
        Option memory op = Option(
            msg.sender,
            lA,
            dV,
            lT,
            block.timestamp + t_,//time till expiration
            k_,
            pp_,
            pa_
        );

        options.push(op);
        tI = tI.add(lT);
        emit Create(options.length-1, msg.sender, lA, lT, k_);
    }


    

     /**
     * @notice exercises a option
     * @param oID id of the option to exercise
     */
    function exercise(uint256 oID)
        external
    {
        Option memory option = options[oID];
        require(block.timestamp <= option.exp, "expiration date margin has passed");
        AggregatorProxy priceProvider = AggregatorProxy(option.pP);
        int256 lA = priceProvider.latestAnswer();
        if (option.dir) {
            //call option
            require(lA > option.sP, "price is to low");
        } else {
            //put option
            require(lA < option.sP, "price is to high");
        }


        if (option.aPA != address(this)) {
            IEBOP20 alt = IEBOP20(option.aPA);
            require(alt.payout(option.lV,option.pV, msg.sender, option.holder), "erc20 pool exercise failed");
        } else {
            //option expires ITM, we pay out
            payout(option.lV, msg.sender, option.holder);
            lockedAmount = lockedAmount.sub(option.lV);
        }
        
        emit Exercise(oID);
        if (rewEn) {
            pClaims[msg.sender] = pClaims[msg.sender].add(getBetSizeBonus(option.lV, reward));
        }
    }

     /**
     * @notice expires a option
     * @param oID id of the option to expire
     */
    function expire(uint256 oID)
        external
    {
        Option memory option = options[oID];
        require(block.timestamp > option.exp, "expiration date has not passed");


        if (option.aPA != address(this)) {
            //ERC20 option
            IEBOP20 alt = IEBOP20(option.aPA);
            require(alt.unlockAndPayExpirer(option.lV,option.pV, msg.sender), "erc20 pool exercise failed");
        } else {
            //ETH option
            unlock(option.lV, msg.sender);
            lockedAmount = lockedAmount.sub(option.lV);
        }
        emit Expire(oID);
        if (rewEn) {
            pClaims[msg.sender] = pClaims[msg.sender].add(getBetSizeBonus(option.pV, reward));
        }
    }

    /**
    @dev called by BinaryOptions contract to lock pool value coresponding to new binary options bought. 
    @param amount amount in ETH to lock from the pool total.
    */
    function lock(uint256 amount) internal {
        lockedAmount = lockedAmount.add(amount);
    }

    /**
    @dev called by BinaryOptions contract to unlock pool value coresponding to an option expiring otm. 
    @param amount amount in ETH to unlock
    @param goodSamaritan the user paying to unlock these funds, they recieve a fee
    */
    function unlock(uint256 amount, address payable goodSamaritan) internal {
        require(amount <= lockedAmount, "insufficent locked pool balance to unlock");
        uint256 fee;
        if (amount <= 10000000000000000) {//small options give bigger fee %
            fee = amount.div(exerciserFee.mul(4)).div(100);
        } else {
            fee = amount.div(exerciserFee).div(100);
        } 
        if (fee > 0) {
            require(goodSamaritan.send(fee), "good samaritan transfer failed");
        }
    }

    /**
    @dev called by BinaryOptions contract to payout pool value coresponding to binary options expiring itm. 
    @param amount amount in ETH to unlock
    @param exerciser address calling the exercise/expire function, this may the winner or another user who then earns a fee.
    @param winner address of the winner.
    @notice exerciser fees are subject to change see updateFeePercent above.
    */
    function payout(uint256 amount, address payable exerciser, address payable winner) internal {
        require(amount <= lockedAmount, "insufficent pool balance available to payout");
        require(amount <= address(this).balance, "insufficent balance in pool");
        if (exerciser != winner) {
            //good samaratin fee
            uint256 fee;
            if (amount <= 10000000000000000) {//small options give bigger fee %
                fee = amount.div(exerciserFee.mul(4)).div(100);
            } else {
                fee = amount.div(exerciserFee).div(100);
            } 
            if (fee > 0) {
                require(exerciser.send(fee), "exerciser transfer failed");
                require(winner.send(amount.sub(fee)), "winner transfer failed");
            }
        } else {  
            require(winner.send(amount), "winner transfer failed");
        }
        emit Payout(amount, winner);
    }

}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"address","name":"pp_","type":"address"},{"internalType":"address","name":"biop_","type":"address"},{"internalType":"address","name":"rateCalc_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"address payable","name":"account","type":"address"},{"indexed":false,"internalType":"int256","name":"sP","type":"int256"},{"indexed":false,"internalType":"uint256","name":"lV","type":"uint256"},{"indexed":false,"internalType":"bool","name":"dir","type":"bool"}],"name":"Create","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Exercise","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Expire","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"poolLost","type":"uint256"},{"indexed":false,"internalType":"address","name":"winner","type":"address"}],"name":"Payout","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"},{"inputs":[{"internalType":"address","name":"newPool_","type":"address"}],"name":"addAltPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPP_","type":"address"},{"internalType":"address","name":"rateCalc_","type":"address"}],"name":"addPP","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":"","type":"address"}],"name":"altLockedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"k_","type":"bool"},{"internalType":"address","name":"pp_","type":"address"},{"internalType":"uint256","name":"t_","type":"uint256"}],"name":"bet","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bool","name":"k_","type":"bool"},{"internalType":"address","name":"pp_","type":"address"},{"internalType":"uint256","name":"t_","type":"uint256"},{"internalType":"address","name":"pa_","type":"address"},{"internalType":"uint256","name":"a_","type":"uint256"}],"name":"bet20","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"biop","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"closeStaking","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractCreated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"defaultPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultPriceProvider","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultRCAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"devFund","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"devFundBetFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"ePairs","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"ePools","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"nx_","type":"bool"}],"name":"enableRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"oID","type":"uint256"}],"name":"exercise","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"exerciserFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"oID","type":"uint256"}],"name":"expire","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"expirerFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fGS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc20PoolAddress_","type":"address"}],"name":"getAltMaxAvailable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"base","type":"uint256"}],"name":"getBetSizeBonus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getCombinedStakingBonus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxAvailable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOptionCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getOptionValueBonus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getPendingClaims","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getPoolBalanceBonus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"uint256","name":"max","type":"uint256"},{"internalType":"uint256","name":"deposit","type":"uint256"},{"internalType":"int256","name":"currentPrice","type":"int256"},{"internalType":"uint256","name":"t","type":"uint256"},{"internalType":"bool","name":"k","type":"bool"}],"name":"getRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getStakingTimeBonus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"iAL","outputs":[{"internalType":"uint256","name":"","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":"","type":"address"}],"name":"lST","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lW","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nW","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":"open","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"options","outputs":[{"internalType":"address payable","name":"holder","type":"address"},{"internalType":"int256","name":"sP","type":"int256"},{"internalType":"uint256","name":"pV","type":"uint256"},{"internalType":"uint256","name":"lV","type":"uint256"},{"internalType":"uint256","name":"exp","type":"uint256"},{"internalType":"bool","name":"dir","type":"bool"},{"internalType":"address","name":"pP","type":"address"},{"internalType":"address","name":"aPA","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLockSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"oldPool_","type":"address"}],"name":"removeAltPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"oldPP_","type":"address"}],"name":"removePP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewEn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMax_","type":"uint256"}],"name":"setMaxT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMin_","type":"uint256"}],"name":"setMinT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stake","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tI","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"thisAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"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 payable","name":"newDevFund","type":"address"}],"name":"transferDevFund","outputs":[],"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 payable","name":"newOwner_","type":"address"}],"name":"transferOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"devFundBetFee_","type":"uint256"}],"name":"updateDevFundBetFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"exerciserFee_","type":"uint256"}],"name":"updateExerciserFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"expirerFee_","type":"uint256"}],"name":"updateExpirerFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newLockSeconds_","type":"uint256"}],"name":"updatePoolLockSeconds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526032601581905560165560c860175562093a80601855601a8054600160ff1991821681179092556000601c5566016bcc41e90000601d5565b5e620f48000601e55601f805490911690911790553480156200005e57600080fd5b506040516200544b3803806200544b833981810160405260a08110156200008457600080fd5b8101908080516040519392919084640100000000821115620000a557600080fd5b908301906020820185811115620000bb57600080fd5b8251640100000000811182820188101715620000d657600080fd5b82525081516020918201929091019080838360005b8381101562000105578181015183820152602001620000eb565b50505050905090810190601f168015620001335780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200015757600080fd5b9083019060208201858111156200016d57600080fd5b82516401000000008111828201881017156200018857600080fd5b82525081516020918201929091019080838360005b83811015620001b75781810151838201526020016200019d565b50505050905090810190601f168015620001e55780820380516001836020036101000a031916815260200191505b506040908152602082810151918301516060909301518751929550929350869186916200021891600391850190620002dd565b5080516200022e906004906020840190620002dd565b505060058054601260ff199091168117610100600160a81b0319166101003390810291909117909255600680546001600160a01b031990811690931790556007805483166001600160a01b0396871617905560088054831694861694909417938490556000601481905542601955958516808752600a60205260409096208054949095169382169390931790935550601380549092169092179055610384601155610e10905550620003829050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200032057805160ff191683800117855562000350565b8280016001018555821562000350579182015b828111156200035057825182559160200191906001019062000333565b506200035e92915062000362565b5090565b6200037f91905b808211156200035e576000815560010162000369565b90565b6150b980620003926000396000f3fe6080604052600436106104655760003560e01c806383880e5111610243578063b551572511610143578063db05c547116100bb578063e56e03cc1161008a578063f4a6e1e21161006f578063f4a6e1e214611123578063fcfff16f14611163578063fd4cbc051461117857610465565b8063e56e03cc146110a3578063f200fb20146110e357610465565b8063db05c54714610ff1578063dd62ed3e14611006578063de46101f1461104e578063e4523ef91461108e57610465565b8063bf81bf4311610112578063d25b00d0116100f7578063d25b00d014610fb2578063d32a8f6714610fc7578063d4dca69b14610fdc57610465565b8063bf81bf4314610f73578063c897239114610f9d57610465565b8063b551572514610ec1578063b6148fd214610f01578063bac2e6db14610f16578063bc08621514610f2b57610465565b80639aae9708116101d6578063a9059cbb116101a5578063ad33648a1161018a578063ad33648a14610e2d578063b07f0a4114610e57578063b0ed9d8c14610e8157610465565b8063a9059cbb14610dd2578063a9493ced14610e1857610465565b80639aae970814610d365780639b1559c314610d4b578063a457c2d714610d77578063a6bd542714610dbd57610465565b8063902d9e9311610212578063902d9e9314610c8c57806395d89b4114610ccc57806398cfe58714610ce157806399f9140514610cf657610465565b806383880e5114610bf85780638a0c6d2614610c0d5780638a300e6814610c375780638da5cb5b14610c7757610465565b8063374028e3116103695780634fce9c84116102e157806360baaaae116102b05780636ab28bc8116102955780636ab28bc814610b635780636f3f661814610b7857806370a0823114610bb857610465565b806360baaaae14610b0e5780636342987e14610b2357610465565b80634fce9c8414610a5a5780635009a61314610a6f57806350724c7d14610a99578063602d860814610af957610465565b8063409e220511610338578063470534b11161031d578063470534b11461098b5780634cd6278d146109cb5780634fb2e45d14610a1a57610465565b8063409e2205146108ec5780634390d2a81461097657610465565b8063374028e31461083657806337637f4514610874578063395093511461089e5780633a4b66f1146108e457610465565b80631bd8eca8116103fc57806323b872dd116103cb5780632e1a7d4d116103b05780632e1a7d4d146107cc578063313ce567146107f6578063372500ab1461082157610465565b806323b872dd1461073b5780632927989f1461078b57610465565b80631bd8eca81461067a5780631d37c76c146106bc5780631d983e23146106fc578063228cb7331461072657610465565b806318160ddd1161043857806318160ddd146105b557806319174be6146105ca5780631a4d56bd1461060a5780631baba7061461063a57610465565b806306fdde031461046a578063095ea7b3146104f4578063108e184d1461054e57806318126dce146105a0575b600080fd5b34801561047657600080fd5b5061047f6111a2565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104b95781810151838201526020016104a1565b50505050905090810190601f1680156104e65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561050057600080fd5b5061053a6004803603604081101561051757600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611257565b604080519115158252519081900360200190f35b34801561055a57600080fd5b5061058e6004803603602081101561057157600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611275565b60408051918252519081900360200190f35b3480156105ac57600080fd5b5061058e611287565b3480156105c157600080fd5b5061058e61128d565b3480156105d657600080fd5b5061058e600480360360208110156105ed57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611293565b34801561061657600080fd5b5061058e6004803603604081101561062d57600080fd5b50803590602001356112a5565b34801561064657600080fd5b5061058e6004803603602081101561065d57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611327565b34801561068657600080fd5b506106ba6004803603602081101561069d57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611339565b005b3480156106c857600080fd5b5061053a600480360360208110156106df57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661140b565b34801561070857600080fd5b506106ba6004803603602081101561071f57600080fd5b5035611420565b34801561073257600080fd5b5061058e6114ab565b34801561074757600080fd5b5061053a6004803603606081101561075e57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356114b1565b6106ba600480360360608110156107a157600080fd5b50803515159073ffffffffffffffffffffffffffffffffffffffff6020820135169060400135611558565b3480156107d857600080fd5b506106ba600480360360208110156107ef57600080fd5b5035611bba565b34801561080257600080fd5b5061080b611e61565b6040805160ff9092168252519081900360200190f35b34801561082d57600080fd5b506106ba611e6a565b34801561084257600080fd5b5061084b611f40565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561088057600080fd5b506106ba6004803603602081101561089757600080fd5b5035611f5c565b3480156108aa57600080fd5b5061053a600480360360408110156108c157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611fe7565b6106ba612048565b3480156108f857600080fd5b506109166004803603602081101561090f57600080fd5b50356121a9565b6040805173ffffffffffffffffffffffffffffffffffffffff998a16815260208101989098528781019690965260608701949094526080860192909252151560a0850152841660c084015290921660e08201529051908190036101000190f35b34801561098257600080fd5b5061084b61221b565b34801561099757600080fd5b5061084b600480360360208110156109ae57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661223c565b6106ba600480360360a08110156109e157600080fd5b50803515159073ffffffffffffffffffffffffffffffffffffffff60208201358116916040810135916060820135169060800135612264565b348015610a2657600080fd5b506106ba60048036036020811015610a3d57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166128a6565b348015610a6657600080fd5b5061058e612973565b348015610a7b57600080fd5b506106ba60048036036020811015610a9257600080fd5b5035612979565b348015610aa557600080fd5b5061058e600480360360c0811015610abc57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060208101359060408101359060608101359060808101359060a001351515612a75565b348015610b0557600080fd5b5061058e612b45565b348015610b1a57600080fd5b5061058e612b4b565b348015610b2f57600080fd5b5061058e60048036036020811015610b4657600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16612b51565b348015610b6f57600080fd5b5061058e612bc2565b348015610b8457600080fd5b5061058e60048036036020811015610b9b57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16612bc8565b348015610bc457600080fd5b5061058e60048036036020811015610bdb57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16612c3a565b348015610c0457600080fd5b5061053a612c62565b348015610c1957600080fd5b506106ba60048036036020811015610c3057600080fd5b5035612c6b565b348015610c4357600080fd5b5061058e60048036036020811015610c5a57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16612d72565b348015610c8357600080fd5b5061084b612d84565b348015610c9857600080fd5b5061058e60048036036020811015610caf57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16612da0565b348015610cd857600080fd5b5061047f612ea3565b348015610ced57600080fd5b506106ba612f22565b348015610d0257600080fd5b5061058e60048036036020811015610d1957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16612fd2565b348015610d4257600080fd5b5061084b613056565b348015610d5757600080fd5b506106ba60048036036020811015610d6e57600080fd5b50351515613072565b348015610d8357600080fd5b5061053a60048036036040811015610d9a57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135613129565b348015610dc957600080fd5b5061058e6131a4565b348015610dde57600080fd5b5061053a60048036036040811015610df557600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356131aa565b348015610e2457600080fd5b5061058e6131be565b348015610e3957600080fd5b506106ba60048036036020811015610e5057600080fd5b50356131c4565b348015610e6357600080fd5b506106ba60048036036020811015610e7a57600080fd5b50356132c7565b348015610e8d57600080fd5b5061058e60048036036020811015610ea457600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661371d565b348015610ecd57600080fd5b506106ba60048036036020811015610ee457600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16613838565b348015610f0d57600080fd5b5061058e61390d565b348015610f2257600080fd5b5061058e613913565b348015610f3757600080fd5b506106ba60048036036040811015610f4e57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516613948565b348015610f7f57600080fd5b506106ba60048036036020811015610f9657600080fd5b5035613a21565b348015610fa957600080fd5b5061058e613d02565b348015610fbe57600080fd5b5061058e613d08565b348015610fd357600080fd5b5061084b613d0e565b348015610fe857600080fd5b5061084b613d2a565b348015610ffd57600080fd5b5061058e613d2e565b34801561101257600080fd5b5061058e6004803603604081101561102957600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516613d34565b34801561105a57600080fd5b5061058e6004803603602081101561107157600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16613d6c565b34801561109a57600080fd5b5061084b613da1565b3480156110af57600080fd5b5061058e600480360360208110156110c657600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16613dbd565b3480156110ef57600080fd5b506106ba6004803603602081101561110657600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16613dcf565b34801561112f57600080fd5b506106ba6004803603602081101561114657600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16613ea1565b34801561116f57600080fd5b5061053a613f73565b34801561118457600080fd5b506106ba6004803603602081101561119b57600080fd5b5035613f7c565b60038054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561124c5780601f106112215761010080835404028352916020019161124c565b820191906000526020600020905b81548152906001019060200180831161122f57829003601f168201915b505050505090505b90565b600061126b611264614082565b8484614086565b5060015b92915050565b600e6020526000908152604090205481565b60125481565b60025490565b600d6020526000908152604090205481565b6000806112d1846112c560646112b961128d565b9063ffffffff6141cd16565b9063ffffffff61424716565b905060006112ea600a6112c5868563ffffffff6141cd16565b111561130d57611305600a6112c5858463ffffffff6141cd16565b91505061126f565b61131f836103e863ffffffff61424716565b949350505050565b60106020526000908152604090205481565b60065473ffffffffffffffffffffffffffffffffffffffff1633146113bf57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff166000908152600f6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600f6020526000908152604090205460ff1681565b60065473ffffffffffffffffffffffffffffffffffffffff1633146114a657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b601255565b601e5481565b60006114be848484614289565b61154e846114ca614082565b61154985604051806060016040528060288152602001614fcd6028913973ffffffffffffffffffffffffffffffffffffffff8a16600090815260016020526040812090611515614082565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002054919063ffffffff61446516565b614086565b5060019392505050565b601154811015801561156c57506012548111155b6115d757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f496e76616c69642074696d650000000000000000000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600a60205260409020541661166a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f496e76616c6964202070726963652070726f7669646572000000000000000000604482015290519081900360640190fd5b600082905060008173ffffffffffffffffffffffffffffffffffffffff166350d25bcd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156116b757600080fd5b505afa1580156116cb573d6000803e3d6000fd5b505050506040513d60208110156116e157600080fd5b5051601b549091506000908190606434101561175e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f62657420746f20736d616c6c0000000000000000000000000000000000000000604482015290519081900360640190fd5b611766613913565b3411156117d457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f62657420746f2062696700000000000000000000000000000000000000000000604482015290519081900360640190fd5b601754156118b25760006117f36017543461424790919063ffffffff16565b600554604051919250610100900473ffffffffffffffffffffffffffffffffffffffff16906108fc8315029083906000818181858888f1935050505061189a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f64657646756e6420666565207472616e73666572206661696c65640000000000604482015290519081900360640190fd5b6118aa348263ffffffff61451616565b9350506118b6565b3492505b60006118cd886118c4613913565b86888b8e612a75565b601f5490915060ff1615611917576119066118ea85601e546112a5565b336000908152600c60205260409020549063ffffffff61455816565b336000908152600c60205260409020555b611927818563ffffffff61455816565b9250611932836145cc565b61193a614e1f565b506040805161010080820183523382526020820188815292820187815260608301878152428c01608085019081528e151560a0860190815273ffffffffffffffffffffffffffffffffffffffff8f811660c088019081523060e08901908152601b8054600181018255600091909152895160079091027f3ad8aa4f87544323a9d1e5dd902f40c356527a7955687113db5f9a85ad579dc1810180549286167fffffffffffffffffffffffff00000000000000000000000000000000000000009384161790559a517f3ad8aa4f87544323a9d1e5dd902f40c356527a7955687113db5f9a85ad579dc28c015596517f3ad8aa4f87544323a9d1e5dd902f40c356527a7955687113db5f9a85ad579dc38b015594517f3ad8aa4f87544323a9d1e5dd902f40c356527a7955687113db5f9a85ad579dc48a015592517f3ad8aa4f87544323a9d1e5dd902f40c356527a7955687113db5f9a85ad579dc589015590517f3ad8aa4f87544323a9d1e5dd902f40c356527a7955687113db5f9a85ad579dc688018054935183169096027fffffffffffffffffffffff0000000000000000000000000000000000000000ff9115157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909416939093171691909117909355517f3ad8aa4f87544323a9d1e5dd902f40c356527a7955687113db5f9a85ad579dc7909401805494909216931692909217909155601c54611b60908563ffffffff61455816565b601c5560408051338152602081018890528082018690528b15156060820152905184917fc22159e9c70f40218804cbfbacf5359485a13c00fd742df591f32bfda9878825919081900360800190a250505050505050505050565b80611bc433612c3a565b1015611c3157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f496e737566666963656e742053686172652042616c616e636500000000000000604482015290519081900360640190fd5b336000908152600b60205260408120429055611c5e611c4e61128d565b6112c5844763ffffffff6141cd16565b9050611c6a33836145e5565b336000908152600960205260409020544211611dd6576000611c9382606463ffffffff61424716565b600554604051919250610100900473ffffffffffffffffffffffffffffffffffffffff16906108fc8315029083906000818181858888f19350505050611d3a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f7472616e73666572206661696c65640000000000000000000000000000000000604482015290519081900360640190fd5b336108fc611d4e848463ffffffff61451616565b6040518115909202916000818181858888f19350505050611dd057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f7472616e73666572206661696c65640000000000000000000000000000000000604482015290519081900360640190fd5b50611e5d565b604051339082156108fc029083906000818181858888f19350505050611e5d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f7472616e73666572206661696c65640000000000000000000000000000000000604482015290519081900360640190fd5b5050565b60055460ff1690565b60075473ffffffffffffffffffffffffffffffffffffffff166000611e8e33612fd2565b90506001611e9b33612c3a565b1115611ea957611ea961473b565b336000908152600c602052604080822082905580517f750a7ea300000000000000000000000000000000000000000000000000000000815260048101849052905173ffffffffffffffffffffffffffffffffffffffff85169263750a7ea3926024808201939182900301818387803b158015611f2457600080fd5b505af1158015611f38573d6000803e3d6000fd5b505050505050565b60085473ffffffffffffffffffffffffffffffffffffffff1681565b60065473ffffffffffffffffffffffffffffffffffffffff163314611fe257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b601155565b600061126b611ff4614082565b846115498560016000612005614082565b73ffffffffffffffffffffffffffffffffffffffff908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff61455816565b601a5460ff1615156001146120be57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f706f6f6c206465706f736974732068617320636c6f7365640000000000000000604482015290519081900360640190fd5b606434101561212e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b6520746f20736d616c6c000000000000000000000000000000000000604482015290519081900360640190fd5b61213733612c3a565b61217c57336000908152600b60209081526040808320429055601d54600c9092529091205461216b9163ffffffff61455816565b336000908152600c60205260409020555b61218461473b565b601854336000818152600960205260409020429092019091556121a7903461475e565b565b601b81815481106121b657fe5b6000918252602090912060079091020180546001820154600283015460038401546004850154600586015460069096015473ffffffffffffffffffffffffffffffffffffffff9586169750939592949193909260ff8116926101009091048116911688565b600554610100900473ffffffffffffffffffffffffffffffffffffffff1681565b600a6020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b601154831015801561227857506012548311155b6122e357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f496e76616c69642074696d650000000000000000000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8085166000908152600a60205260409020541661237657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f496e76616c6964202070726963652070726f7669646572000000000000000000604482015290519081900360640190fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166350d25bcd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156123c357600080fd5b505afa1580156123d7573d6000803e3d6000fd5b505050506040513d60208110156123ed57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff85166000908152600f602052604081205491925090819060ff1661248957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f696e76616c696420706f6f6c0000000000000000000000000000000000000000604482015290519081900360640190fd5b604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518791879173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b1580156124f957600080fd5b505afa15801561250d573d6000803e3d6000fd5b505050506040513d602081101561252357600080fd5b5051101561259257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f696e76616c696420706f6f6c0000000000000000000000000000000000000000604482015290519081900360640190fd5b604080517f4bf9ed1e0000000000000000000000000000000000000000000000000000000081526004810186905260248101889052815173ffffffffffffffffffffffffffffffffffffffff841692634bf9ed1e92604480820193918290030181600087803b15801561260457600080fd5b505af1158015612618573d6000803e3d6000fd5b505050506040513d604081101561262e57600080fd5b5080516020909101519093509150612644614e1f565b6040518061010001604052803373ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018581526020018481526020018a420181526020018c151581526020018b73ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff168152509050601b81908060018154018082558091505060019003906000526020600020906007020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a08201518160050160006101000a81548160ff02191690831515021790555060c08201518160050160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060e08201518160060160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505061282683601c5461455890919063ffffffff16565b601c55601b5460408051338152602081018890528082018690528d1515606082015290517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201917fc22159e9c70f40218804cbfbacf5359485a13c00fd742df591f32bfda98788259181900360800190a25050505050505050505050565b60065473ffffffffffffffffffffffffffffffffffffffff16331461292c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60195481565b60065473ffffffffffffffffffffffffffffffffffffffff1633146129ff57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b621275008110612a7057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f696e76616c696420666565000000000000000000000000000000000000000000604482015290519081900360640190fd5b601855565b73ffffffffffffffffffffffffffffffffffffffff8087166000908152600a60205260408120549091168063ea7044ed87612ab68a8263ffffffff61451616565b8888886040518663ffffffff1660e01b815260040180868152602001858152602001848152602001838152602001821515151581526020019550505050505060206040518083038186803b158015612b0d57600080fd5b505afa158015612b21573d6000803e3d6000fd5b505050506040513d6020811015612b3757600080fd5b505198975050505050505050565b60185481565b60165481565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600e60205260408120548190612b8a90429063ffffffff61451616565b90506000612ba182620bdd8063ffffffff61424716565b9050620bdd80821015612bb957600192505050612bbd565b9150505b919050565b60145481565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d6020526040812054601c548291612c03919063ffffffff61451616565b90506000612c1f82670de0b6b3a764000063ffffffff61424716565b90508015612c30579150612bbd9050565b5060009392505050565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b601f5460ff1681565b60065473ffffffffffffffffffffffffffffffffffffffff163314612cf157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600181118015612d0257506101f481105b612d6d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f696e76616c696420666565000000000000000000000000000000000000000000604482015290519081900360640190fd5b601555565b60096020526000908152604090205481565b60065473ffffffffffffffffffffffffffffffffffffffff1681565b600080612dac83612c3a565b9050801561126b576064612dbe61128d565b1015612dce576001915050612bbd565b612ddb60026112c561128d565b8110612deb576014915050612bbd565b612df860046112c561128d565b8110612e0857600e915050612bbd565b612e1560056112c561128d565b8110612e2557600a915050612bbd565b612e32600a6112c561128d565b8110612e42576008915050612bbd565b612e4f60146112c561128d565b8110612e5f576006915050612bbd565b612e6c60326112c561128d565b8110612e7c576004915050612bbd565b612e8960646112c561128d565b8110612e99576003915050612bbd565b6002915050612bbd565b60048054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561124c5780601f106112215761010080835404028352916020019161124c565b60065473ffffffffffffffffffffffffffffffffffffffff163314612fa857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b601a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60006001612fdf83612c3a565b111561302a57613023612ff183613d6c565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600c60205260409020549063ffffffff61455816565b9050612bbd565b5073ffffffffffffffffffffffffffffffffffffffff81166000908152600c6020526040902054612bbd565b60135473ffffffffffffffffffffffffffffffffffffffff1690565b60065473ffffffffffffffffffffffffffffffffffffffff1633146130f857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b601f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b600061126b613136614082565b846115498560405180606001604052806025815260200161505f6025913960016000613160614082565b73ffffffffffffffffffffffffffffffffffffffff908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff61446516565b601b5490565b600061126b6131b7614082565b8484614289565b60175481565b60065473ffffffffffffffffffffffffffffffffffffffff16331461324a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b8015806132575750603281115b6132c257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f696e76616c696420666565000000000000000000000000000000000000000000604482015290519081900360640190fd5b601755565b6132cf614e1f565b601b82815481106132dc57fe5b60009182526020918290206040805161010080820183526007909402909201805473ffffffffffffffffffffffffffffffffffffffff908116845260018201549584019590955260028101549183019190915260038101546060830152600481015460808301819052600582015460ff8116151560a085015293909304841660c08301526006015490921660e08301529091504211156133c7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614f8b6021913960400191505060405180910390fd5b60008160c00151905060008173ffffffffffffffffffffffffffffffffffffffff166350d25bcd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561341857600080fd5b505afa15801561342c573d6000803e3d6000fd5b505050506040513d602081101561344257600080fd5b505160a0840151909150156134c857826020015181136134c357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f707269636520697320746f206c6f770000000000000000000000000000000000604482015290519081900360640190fd5b61353a565b8260200151811261353a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f707269636520697320746f206869676800000000000000000000000000000000604482015290519081900360640190fd5b60e083015173ffffffffffffffffffffffffffffffffffffffff16301461368f5760e08301516060840151604080860151865182517f513cfb940000000000000000000000000000000000000000000000000000000081526004810194909452602484019190915233604484015273ffffffffffffffffffffffffffffffffffffffff908116606484015290519083169163513cfb949160848083019260209291908290030181600087803b1580156135f257600080fd5b505af1158015613606573d6000803e3d6000fd5b505050506040513d602081101561361c57600080fd5b505161368957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f657263323020706f6f6c206578657263697365206661696c6564000000000000604482015290519081900360640190fd5b506136bd565b6136a2836060015133856000015161489b565b60608301516014546136b99163ffffffff61451616565b6014555b60405184907fa2a53c7cb82eeb7994ccbbab71bea210cd63cfeb7823972fb5b6a49c3b0e1d4c90600090a2601f5460ff1615613717576137066118ea8460600151601e546112a5565b336000908152600c60205260409020555b50505050565b604080517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290516000918391839173ffffffffffffffffffffffffffffffffffffffff8416916370a0823191602480820192602092909190829003018186803b15801561379157600080fd5b505afa1580156137a5573d6000803e3d6000fd5b505050506040513d60208110156137bb57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff851660009081526010602052604090205490915081111561382d5773ffffffffffffffffffffffffffffffffffffffff841660009081526010602052604090205461382490829063ffffffff61451616565b92505050612bbd565b600092505050612bbd565b60065473ffffffffffffffffffffffffffffffffffffffff1633146138be57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff166000908152600f6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b601d5481565b601454600090479081111561393e5760145461393690829063ffffffff61451616565b915050611254565b6000915050611254565b60065473ffffffffffffffffffffffffffffffffffffffff1633146139ce57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff9182166000908152600a6020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001691909216179055565b613a29614e1f565b601b8281548110613a3657fe5b60009182526020918290206040805161010080820183526007909402909201805473ffffffffffffffffffffffffffffffffffffffff908116845260018201549584019590955260028101549183019190915260038101546060830152600481015460808301819052600582015460ff8116151560a085015293909304841660c08301526006015490921660e08301529091504211613b3657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f65787069726174696f6e206461746520686173206e6f74207061737365640000604482015290519081900360640190fd5b60e081015173ffffffffffffffffffffffffffffffffffffffff163014613c7c5760e0810151606082015160408084015181517f9a5f2000000000000000000000000000000000000000000000000000000000008152600481019390935260248301523360448301525173ffffffffffffffffffffffffffffffffffffffff831691639a5f20009160648083019260209291908290030181600087803b158015613bdf57600080fd5b505af1158015613bf3573d6000803e3d6000fd5b505050506040513d6020811015613c0957600080fd5b5051613c7657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f657263323020706f6f6c206578657263697365206661696c6564000000000000604482015290519081900360640190fd5b50613ca5565b613c8a816060015133614c3e565b6060810151601454613ca19163ffffffff61451616565b6014555b60405182907fa33fd53ba34795ffefaea3759c71f87d38b89ae12e40bc434c826fae0ca5358390600090a2601f5460ff1615611e5d57613cee6118ea8260400151601e546112a5565b336000908152600c60205260409020555050565b60115481565b60155481565b60135473ffffffffffffffffffffffffffffffffffffffff1681565b3090565b601c5481565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b600061126f613d7a83612bc8565b6112b9613d8685612da0565b6112b9613d9287612b51565b601e549063ffffffff6141cd16565b60075473ffffffffffffffffffffffffffffffffffffffff1681565b600b6020526000908152604090205481565b60065473ffffffffffffffffffffffffffffffffffffffff163314613e5557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6005805473ffffffffffffffffffffffffffffffffffffffff909216610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff909216919091179055565b60065473ffffffffffffffffffffffffffffffffffffffff163314613f2757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff166000908152600a6020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b601a5460ff1681565b60065473ffffffffffffffffffffffffffffffffffffffff16331461400257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001811180156140125750603281105b61407d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f696e76616c696420666565000000000000000000000000000000000000000000604482015290519081900360640190fd5b601655565b3390565b73ffffffffffffffffffffffffffffffffffffffff83166140f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602481526020018061503b6024913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821661415e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180614eee6022913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6000826141dc5750600061126f565b828202828482816141e957fe5b0414614240576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614fac6021913960400191505060405180910390fd5b9392505050565b600061424083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614da0565b73ffffffffffffffffffffffffffffffffffffffff83166142f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806150166025913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216614361576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180614ea96023913960400191505060405180910390fd5b61436c838383614d9b565b6143bc81604051806060016040528060268152602001614f106026913973ffffffffffffffffffffffffffffffffffffffff8616600090815260208190526040902054919063ffffffff61446516565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526020819052604080822093909355908416815220546143fe908263ffffffff61455816565b73ffffffffffffffffffffffffffffffffffffffff8084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b6000818484111561450e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156144d35781810151838201526020016144bb565b50505050905090810190601f1680156145005780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600061424083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614465565b60008282018381101561424057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6014546145df908263ffffffff61455816565b60145550565b73ffffffffffffffffffffffffffffffffffffffff8216614651576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614ff56021913960400191505060405180910390fd5b61465d82600083614d9b565b6146ad81604051806060016040528060228152602001614ecc6022913973ffffffffffffffffffffffffffffffffffffffff8516600090815260208190526040902054919063ffffffff61446516565b73ffffffffffffffffffffffffffffffffffffffff83166000908152602081905260409020556002546146e6908263ffffffff61451616565b60025560408051828152905160009173ffffffffffffffffffffffffffffffffffffffff8516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b336000908152600e60209081526040808320429055601c54600d90925290912055565b73ffffffffffffffffffffffffffffffffffffffff82166147e057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b6147ec60008383614d9b565b6002546147ff908263ffffffff61455816565b60025573ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054614838908263ffffffff61455816565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6014548311156148f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180614f36602c913960400191505060405180910390fd5b4783111561496557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f696e737566666963656e742062616c616e636520696e20706f6f6c0000000000604482015290519081900360640190fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614614b4c576000662386f26fc1000084116149da576149d360646112c56149c660046015546141cd90919063ffffffff16565b879063ffffffff61424716565b90506149f7565b6149f460646112c56015548761424790919063ffffffff16565b90505b8015614b465760405173ffffffffffffffffffffffffffffffffffffffff84169082156108fc029083906000818181858888f19350505050614a9a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f657865726369736572207472616e73666572206661696c656400000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff82166108fc614ac4868463ffffffff61451616565b6040518115909202916000818181858888f19350505050614b4657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f77696e6e6572207472616e73666572206661696c656400000000000000000000604482015290519081900360640190fd5b50614be9565b60405173ffffffffffffffffffffffffffffffffffffffff82169084156108fc029085906000818181858888f19350505050614be957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f77696e6e6572207472616e73666572206661696c656400000000000000000000604482015290519081900360640190fd5b6040805184815273ffffffffffffffffffffffffffffffffffffffff8316602082015281517f9b5d1a613fa5f0790b36b13103706e31fca06b229d87e9915b29fc20c1d76490929181900390910190a1505050565b601454821115614c99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180614f626029913960400191505060405180910390fd5b6000662386f26fc100008311614cdb57614cd460646112c5614cc760046015546141cd90919063ffffffff16565b869063ffffffff61424716565b9050614cf8565b614cf560646112c56015548661424790919063ffffffff16565b90505b8015614d9b5760405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050614d9b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f676f6f642073616d61726974616e207472616e73666572206661696c65640000604482015290519081900360640190fd5b505050565b60008183614e09576040517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482018181528351602484015283519092839260449091019190850190808383600083156144d35781810151838201526020016144bb565b506000838581614e1557fe5b0495945050505050565b604051806101000160405280600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081526020016000815260200160008152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152509056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365696e737566666963656e7420706f6f6c2062616c616e636520617661696c61626c6520746f207061796f7574696e737566666963656e74206c6f636b656420706f6f6c2062616c616e636520746f20756e6c6f636b65787069726174696f6e2064617465206d617267696e2068617320706173736564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa264697066735822122049851b08581df436a7483ac7095517014e22632c3132616a7f18c2602d36a39964736f6c6343000606003300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000009326bfa02add2366b30bacb125260af64103133100000000000000000000000048fbf22f027438d95defc40814a0cc49570fbb5e00000000000000000000000085de67979509ad4da0c8e57ea30dfa213156836e0000000000000000000000000000000000000000000000000000000000000004704554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000047045544800000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106104655760003560e01c806383880e5111610243578063b551572511610143578063db05c547116100bb578063e56e03cc1161008a578063f4a6e1e21161006f578063f4a6e1e214611123578063fcfff16f14611163578063fd4cbc051461117857610465565b8063e56e03cc146110a3578063f200fb20146110e357610465565b8063db05c54714610ff1578063dd62ed3e14611006578063de46101f1461104e578063e4523ef91461108e57610465565b8063bf81bf4311610112578063d25b00d0116100f7578063d25b00d014610fb2578063d32a8f6714610fc7578063d4dca69b14610fdc57610465565b8063bf81bf4314610f73578063c897239114610f9d57610465565b8063b551572514610ec1578063b6148fd214610f01578063bac2e6db14610f16578063bc08621514610f2b57610465565b80639aae9708116101d6578063a9059cbb116101a5578063ad33648a1161018a578063ad33648a14610e2d578063b07f0a4114610e57578063b0ed9d8c14610e8157610465565b8063a9059cbb14610dd2578063a9493ced14610e1857610465565b80639aae970814610d365780639b1559c314610d4b578063a457c2d714610d77578063a6bd542714610dbd57610465565b8063902d9e9311610212578063902d9e9314610c8c57806395d89b4114610ccc57806398cfe58714610ce157806399f9140514610cf657610465565b806383880e5114610bf85780638a0c6d2614610c0d5780638a300e6814610c375780638da5cb5b14610c7757610465565b8063374028e3116103695780634fce9c84116102e157806360baaaae116102b05780636ab28bc8116102955780636ab28bc814610b635780636f3f661814610b7857806370a0823114610bb857610465565b806360baaaae14610b0e5780636342987e14610b2357610465565b80634fce9c8414610a5a5780635009a61314610a6f57806350724c7d14610a99578063602d860814610af957610465565b8063409e220511610338578063470534b11161031d578063470534b11461098b5780634cd6278d146109cb5780634fb2e45d14610a1a57610465565b8063409e2205146108ec5780634390d2a81461097657610465565b8063374028e31461083657806337637f4514610874578063395093511461089e5780633a4b66f1146108e457610465565b80631bd8eca8116103fc57806323b872dd116103cb5780632e1a7d4d116103b05780632e1a7d4d146107cc578063313ce567146107f6578063372500ab1461082157610465565b806323b872dd1461073b5780632927989f1461078b57610465565b80631bd8eca81461067a5780631d37c76c146106bc5780631d983e23146106fc578063228cb7331461072657610465565b806318160ddd1161043857806318160ddd146105b557806319174be6146105ca5780631a4d56bd1461060a5780631baba7061461063a57610465565b806306fdde031461046a578063095ea7b3146104f4578063108e184d1461054e57806318126dce146105a0575b600080fd5b34801561047657600080fd5b5061047f6111a2565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104b95781810151838201526020016104a1565b50505050905090810190601f1680156104e65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561050057600080fd5b5061053a6004803603604081101561051757600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611257565b604080519115158252519081900360200190f35b34801561055a57600080fd5b5061058e6004803603602081101561057157600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611275565b60408051918252519081900360200190f35b3480156105ac57600080fd5b5061058e611287565b3480156105c157600080fd5b5061058e61128d565b3480156105d657600080fd5b5061058e600480360360208110156105ed57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611293565b34801561061657600080fd5b5061058e6004803603604081101561062d57600080fd5b50803590602001356112a5565b34801561064657600080fd5b5061058e6004803603602081101561065d57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611327565b34801561068657600080fd5b506106ba6004803603602081101561069d57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611339565b005b3480156106c857600080fd5b5061053a600480360360208110156106df57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661140b565b34801561070857600080fd5b506106ba6004803603602081101561071f57600080fd5b5035611420565b34801561073257600080fd5b5061058e6114ab565b34801561074757600080fd5b5061053a6004803603606081101561075e57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356114b1565b6106ba600480360360608110156107a157600080fd5b50803515159073ffffffffffffffffffffffffffffffffffffffff6020820135169060400135611558565b3480156107d857600080fd5b506106ba600480360360208110156107ef57600080fd5b5035611bba565b34801561080257600080fd5b5061080b611e61565b6040805160ff9092168252519081900360200190f35b34801561082d57600080fd5b506106ba611e6a565b34801561084257600080fd5b5061084b611f40565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561088057600080fd5b506106ba6004803603602081101561089757600080fd5b5035611f5c565b3480156108aa57600080fd5b5061053a600480360360408110156108c157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611fe7565b6106ba612048565b3480156108f857600080fd5b506109166004803603602081101561090f57600080fd5b50356121a9565b6040805173ffffffffffffffffffffffffffffffffffffffff998a16815260208101989098528781019690965260608701949094526080860192909252151560a0850152841660c084015290921660e08201529051908190036101000190f35b34801561098257600080fd5b5061084b61221b565b34801561099757600080fd5b5061084b600480360360208110156109ae57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661223c565b6106ba600480360360a08110156109e157600080fd5b50803515159073ffffffffffffffffffffffffffffffffffffffff60208201358116916040810135916060820135169060800135612264565b348015610a2657600080fd5b506106ba60048036036020811015610a3d57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166128a6565b348015610a6657600080fd5b5061058e612973565b348015610a7b57600080fd5b506106ba60048036036020811015610a9257600080fd5b5035612979565b348015610aa557600080fd5b5061058e600480360360c0811015610abc57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060208101359060408101359060608101359060808101359060a001351515612a75565b348015610b0557600080fd5b5061058e612b45565b348015610b1a57600080fd5b5061058e612b4b565b348015610b2f57600080fd5b5061058e60048036036020811015610b4657600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16612b51565b348015610b6f57600080fd5b5061058e612bc2565b348015610b8457600080fd5b5061058e60048036036020811015610b9b57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16612bc8565b348015610bc457600080fd5b5061058e60048036036020811015610bdb57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16612c3a565b348015610c0457600080fd5b5061053a612c62565b348015610c1957600080fd5b506106ba60048036036020811015610c3057600080fd5b5035612c6b565b348015610c4357600080fd5b5061058e60048036036020811015610c5a57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16612d72565b348015610c8357600080fd5b5061084b612d84565b348015610c9857600080fd5b5061058e60048036036020811015610caf57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16612da0565b348015610cd857600080fd5b5061047f612ea3565b348015610ced57600080fd5b506106ba612f22565b348015610d0257600080fd5b5061058e60048036036020811015610d1957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16612fd2565b348015610d4257600080fd5b5061084b613056565b348015610d5757600080fd5b506106ba60048036036020811015610d6e57600080fd5b50351515613072565b348015610d8357600080fd5b5061053a60048036036040811015610d9a57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135613129565b348015610dc957600080fd5b5061058e6131a4565b348015610dde57600080fd5b5061053a60048036036040811015610df557600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356131aa565b348015610e2457600080fd5b5061058e6131be565b348015610e3957600080fd5b506106ba60048036036020811015610e5057600080fd5b50356131c4565b348015610e6357600080fd5b506106ba60048036036020811015610e7a57600080fd5b50356132c7565b348015610e8d57600080fd5b5061058e60048036036020811015610ea457600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661371d565b348015610ecd57600080fd5b506106ba60048036036020811015610ee457600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16613838565b348015610f0d57600080fd5b5061058e61390d565b348015610f2257600080fd5b5061058e613913565b348015610f3757600080fd5b506106ba60048036036040811015610f4e57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516613948565b348015610f7f57600080fd5b506106ba60048036036020811015610f9657600080fd5b5035613a21565b348015610fa957600080fd5b5061058e613d02565b348015610fbe57600080fd5b5061058e613d08565b348015610fd357600080fd5b5061084b613d0e565b348015610fe857600080fd5b5061084b613d2a565b348015610ffd57600080fd5b5061058e613d2e565b34801561101257600080fd5b5061058e6004803603604081101561102957600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516613d34565b34801561105a57600080fd5b5061058e6004803603602081101561107157600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16613d6c565b34801561109a57600080fd5b5061084b613da1565b3480156110af57600080fd5b5061058e600480360360208110156110c657600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16613dbd565b3480156110ef57600080fd5b506106ba6004803603602081101561110657600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16613dcf565b34801561112f57600080fd5b506106ba6004803603602081101561114657600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16613ea1565b34801561116f57600080fd5b5061053a613f73565b34801561118457600080fd5b506106ba6004803603602081101561119b57600080fd5b5035613f7c565b60038054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561124c5780601f106112215761010080835404028352916020019161124c565b820191906000526020600020905b81548152906001019060200180831161122f57829003601f168201915b505050505090505b90565b600061126b611264614082565b8484614086565b5060015b92915050565b600e6020526000908152604090205481565b60125481565b60025490565b600d6020526000908152604090205481565b6000806112d1846112c560646112b961128d565b9063ffffffff6141cd16565b9063ffffffff61424716565b905060006112ea600a6112c5868563ffffffff6141cd16565b111561130d57611305600a6112c5858463ffffffff6141cd16565b91505061126f565b61131f836103e863ffffffff61424716565b949350505050565b60106020526000908152604090205481565b60065473ffffffffffffffffffffffffffffffffffffffff1633146113bf57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff166000908152600f6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b600f6020526000908152604090205460ff1681565b60065473ffffffffffffffffffffffffffffffffffffffff1633146114a657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b601255565b601e5481565b60006114be848484614289565b61154e846114ca614082565b61154985604051806060016040528060288152602001614fcd6028913973ffffffffffffffffffffffffffffffffffffffff8a16600090815260016020526040812090611515614082565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002054919063ffffffff61446516565b614086565b5060019392505050565b601154811015801561156c57506012548111155b6115d757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f496e76616c69642074696d650000000000000000000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8083166000908152600a60205260409020541661166a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f496e76616c6964202070726963652070726f7669646572000000000000000000604482015290519081900360640190fd5b600082905060008173ffffffffffffffffffffffffffffffffffffffff166350d25bcd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156116b757600080fd5b505afa1580156116cb573d6000803e3d6000fd5b505050506040513d60208110156116e157600080fd5b5051601b549091506000908190606434101561175e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f62657420746f20736d616c6c0000000000000000000000000000000000000000604482015290519081900360640190fd5b611766613913565b3411156117d457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f62657420746f2062696700000000000000000000000000000000000000000000604482015290519081900360640190fd5b601754156118b25760006117f36017543461424790919063ffffffff16565b600554604051919250610100900473ffffffffffffffffffffffffffffffffffffffff16906108fc8315029083906000818181858888f1935050505061189a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f64657646756e6420666565207472616e73666572206661696c65640000000000604482015290519081900360640190fd5b6118aa348263ffffffff61451616565b9350506118b6565b3492505b60006118cd886118c4613913565b86888b8e612a75565b601f5490915060ff1615611917576119066118ea85601e546112a5565b336000908152600c60205260409020549063ffffffff61455816565b336000908152600c60205260409020555b611927818563ffffffff61455816565b9250611932836145cc565b61193a614e1f565b506040805161010080820183523382526020820188815292820187815260608301878152428c01608085019081528e151560a0860190815273ffffffffffffffffffffffffffffffffffffffff8f811660c088019081523060e08901908152601b8054600181018255600091909152895160079091027f3ad8aa4f87544323a9d1e5dd902f40c356527a7955687113db5f9a85ad579dc1810180549286167fffffffffffffffffffffffff00000000000000000000000000000000000000009384161790559a517f3ad8aa4f87544323a9d1e5dd902f40c356527a7955687113db5f9a85ad579dc28c015596517f3ad8aa4f87544323a9d1e5dd902f40c356527a7955687113db5f9a85ad579dc38b015594517f3ad8aa4f87544323a9d1e5dd902f40c356527a7955687113db5f9a85ad579dc48a015592517f3ad8aa4f87544323a9d1e5dd902f40c356527a7955687113db5f9a85ad579dc589015590517f3ad8aa4f87544323a9d1e5dd902f40c356527a7955687113db5f9a85ad579dc688018054935183169096027fffffffffffffffffffffff0000000000000000000000000000000000000000ff9115157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00909416939093171691909117909355517f3ad8aa4f87544323a9d1e5dd902f40c356527a7955687113db5f9a85ad579dc7909401805494909216931692909217909155601c54611b60908563ffffffff61455816565b601c5560408051338152602081018890528082018690528b15156060820152905184917fc22159e9c70f40218804cbfbacf5359485a13c00fd742df591f32bfda9878825919081900360800190a250505050505050505050565b80611bc433612c3a565b1015611c3157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f496e737566666963656e742053686172652042616c616e636500000000000000604482015290519081900360640190fd5b336000908152600b60205260408120429055611c5e611c4e61128d565b6112c5844763ffffffff6141cd16565b9050611c6a33836145e5565b336000908152600960205260409020544211611dd6576000611c9382606463ffffffff61424716565b600554604051919250610100900473ffffffffffffffffffffffffffffffffffffffff16906108fc8315029083906000818181858888f19350505050611d3a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f7472616e73666572206661696c65640000000000000000000000000000000000604482015290519081900360640190fd5b336108fc611d4e848463ffffffff61451616565b6040518115909202916000818181858888f19350505050611dd057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f7472616e73666572206661696c65640000000000000000000000000000000000604482015290519081900360640190fd5b50611e5d565b604051339082156108fc029083906000818181858888f19350505050611e5d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f7472616e73666572206661696c65640000000000000000000000000000000000604482015290519081900360640190fd5b5050565b60055460ff1690565b60075473ffffffffffffffffffffffffffffffffffffffff166000611e8e33612fd2565b90506001611e9b33612c3a565b1115611ea957611ea961473b565b336000908152600c602052604080822082905580517f750a7ea300000000000000000000000000000000000000000000000000000000815260048101849052905173ffffffffffffffffffffffffffffffffffffffff85169263750a7ea3926024808201939182900301818387803b158015611f2457600080fd5b505af1158015611f38573d6000803e3d6000fd5b505050505050565b60085473ffffffffffffffffffffffffffffffffffffffff1681565b60065473ffffffffffffffffffffffffffffffffffffffff163314611fe257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b601155565b600061126b611ff4614082565b846115498560016000612005614082565b73ffffffffffffffffffffffffffffffffffffffff908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff61455816565b601a5460ff1615156001146120be57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f706f6f6c206465706f736974732068617320636c6f7365640000000000000000604482015290519081900360640190fd5b606434101561212e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374616b6520746f20736d616c6c000000000000000000000000000000000000604482015290519081900360640190fd5b61213733612c3a565b61217c57336000908152600b60209081526040808320429055601d54600c9092529091205461216b9163ffffffff61455816565b336000908152600c60205260409020555b61218461473b565b601854336000818152600960205260409020429092019091556121a7903461475e565b565b601b81815481106121b657fe5b6000918252602090912060079091020180546001820154600283015460038401546004850154600586015460069096015473ffffffffffffffffffffffffffffffffffffffff9586169750939592949193909260ff8116926101009091048116911688565b600554610100900473ffffffffffffffffffffffffffffffffffffffff1681565b600a6020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b601154831015801561227857506012548311155b6122e357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f496e76616c69642074696d650000000000000000000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8085166000908152600a60205260409020541661237657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f496e76616c6964202070726963652070726f7669646572000000000000000000604482015290519081900360640190fd5b600084905060008173ffffffffffffffffffffffffffffffffffffffff166350d25bcd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156123c357600080fd5b505afa1580156123d7573d6000803e3d6000fd5b505050506040513d60208110156123ed57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff85166000908152600f602052604081205491925090819060ff1661248957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f696e76616c696420706f6f6c0000000000000000000000000000000000000000604482015290519081900360640190fd5b604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518791879173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b1580156124f957600080fd5b505afa15801561250d573d6000803e3d6000fd5b505050506040513d602081101561252357600080fd5b5051101561259257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f696e76616c696420706f6f6c0000000000000000000000000000000000000000604482015290519081900360640190fd5b604080517f4bf9ed1e0000000000000000000000000000000000000000000000000000000081526004810186905260248101889052815173ffffffffffffffffffffffffffffffffffffffff841692634bf9ed1e92604480820193918290030181600087803b15801561260457600080fd5b505af1158015612618573d6000803e3d6000fd5b505050506040513d604081101561262e57600080fd5b5080516020909101519093509150612644614e1f565b6040518061010001604052803373ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018581526020018481526020018a420181526020018c151581526020018b73ffffffffffffffffffffffffffffffffffffffff1681526020018973ffffffffffffffffffffffffffffffffffffffff168152509050601b81908060018154018082558091505060019003906000526020600020906007020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506020820151816001015560408201518160020155606082015181600301556080820151816004015560a08201518160050160006101000a81548160ff02191690831515021790555060c08201518160050160016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060e08201518160060160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505061282683601c5461455890919063ffffffff16565b601c55601b5460408051338152602081018890528082018690528d1515606082015290517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201917fc22159e9c70f40218804cbfbacf5359485a13c00fd742df591f32bfda98788259181900360800190a25050505050505050505050565b60065473ffffffffffffffffffffffffffffffffffffffff16331461292c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60195481565b60065473ffffffffffffffffffffffffffffffffffffffff1633146129ff57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b621275008110612a7057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f696e76616c696420666565000000000000000000000000000000000000000000604482015290519081900360640190fd5b601855565b73ffffffffffffffffffffffffffffffffffffffff8087166000908152600a60205260408120549091168063ea7044ed87612ab68a8263ffffffff61451616565b8888886040518663ffffffff1660e01b815260040180868152602001858152602001848152602001838152602001821515151581526020019550505050505060206040518083038186803b158015612b0d57600080fd5b505afa158015612b21573d6000803e3d6000fd5b505050506040513d6020811015612b3757600080fd5b505198975050505050505050565b60185481565b60165481565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600e60205260408120548190612b8a90429063ffffffff61451616565b90506000612ba182620bdd8063ffffffff61424716565b9050620bdd80821015612bb957600192505050612bbd565b9150505b919050565b60145481565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600d6020526040812054601c548291612c03919063ffffffff61451616565b90506000612c1f82670de0b6b3a764000063ffffffff61424716565b90508015612c30579150612bbd9050565b5060009392505050565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b601f5460ff1681565b60065473ffffffffffffffffffffffffffffffffffffffff163314612cf157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600181118015612d0257506101f481105b612d6d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f696e76616c696420666565000000000000000000000000000000000000000000604482015290519081900360640190fd5b601555565b60096020526000908152604090205481565b60065473ffffffffffffffffffffffffffffffffffffffff1681565b600080612dac83612c3a565b9050801561126b576064612dbe61128d565b1015612dce576001915050612bbd565b612ddb60026112c561128d565b8110612deb576014915050612bbd565b612df860046112c561128d565b8110612e0857600e915050612bbd565b612e1560056112c561128d565b8110612e2557600a915050612bbd565b612e32600a6112c561128d565b8110612e42576008915050612bbd565b612e4f60146112c561128d565b8110612e5f576006915050612bbd565b612e6c60326112c561128d565b8110612e7c576004915050612bbd565b612e8960646112c561128d565b8110612e99576003915050612bbd565b6002915050612bbd565b60048054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018816150201909516949094049384018190048102820181019092528281526060939092909183018282801561124c5780601f106112215761010080835404028352916020019161124c565b60065473ffffffffffffffffffffffffffffffffffffffff163314612fa857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b601a80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60006001612fdf83612c3a565b111561302a57613023612ff183613d6c565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600c60205260409020549063ffffffff61455816565b9050612bbd565b5073ffffffffffffffffffffffffffffffffffffffff81166000908152600c6020526040902054612bbd565b60135473ffffffffffffffffffffffffffffffffffffffff1690565b60065473ffffffffffffffffffffffffffffffffffffffff1633146130f857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b601f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b600061126b613136614082565b846115498560405180606001604052806025815260200161505f6025913960016000613160614082565b73ffffffffffffffffffffffffffffffffffffffff908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff61446516565b601b5490565b600061126b6131b7614082565b8484614289565b60175481565b60065473ffffffffffffffffffffffffffffffffffffffff16331461324a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b8015806132575750603281115b6132c257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f696e76616c696420666565000000000000000000000000000000000000000000604482015290519081900360640190fd5b601755565b6132cf614e1f565b601b82815481106132dc57fe5b60009182526020918290206040805161010080820183526007909402909201805473ffffffffffffffffffffffffffffffffffffffff908116845260018201549584019590955260028101549183019190915260038101546060830152600481015460808301819052600582015460ff8116151560a085015293909304841660c08301526006015490921660e08301529091504211156133c7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614f8b6021913960400191505060405180910390fd5b60008160c00151905060008173ffffffffffffffffffffffffffffffffffffffff166350d25bcd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561341857600080fd5b505afa15801561342c573d6000803e3d6000fd5b505050506040513d602081101561344257600080fd5b505160a0840151909150156134c857826020015181136134c357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f707269636520697320746f206c6f770000000000000000000000000000000000604482015290519081900360640190fd5b61353a565b8260200151811261353a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f707269636520697320746f206869676800000000000000000000000000000000604482015290519081900360640190fd5b60e083015173ffffffffffffffffffffffffffffffffffffffff16301461368f5760e08301516060840151604080860151865182517f513cfb940000000000000000000000000000000000000000000000000000000081526004810194909452602484019190915233604484015273ffffffffffffffffffffffffffffffffffffffff908116606484015290519083169163513cfb949160848083019260209291908290030181600087803b1580156135f257600080fd5b505af1158015613606573d6000803e3d6000fd5b505050506040513d602081101561361c57600080fd5b505161368957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f657263323020706f6f6c206578657263697365206661696c6564000000000000604482015290519081900360640190fd5b506136bd565b6136a2836060015133856000015161489b565b60608301516014546136b99163ffffffff61451616565b6014555b60405184907fa2a53c7cb82eeb7994ccbbab71bea210cd63cfeb7823972fb5b6a49c3b0e1d4c90600090a2601f5460ff1615613717576137066118ea8460600151601e546112a5565b336000908152600c60205260409020555b50505050565b604080517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015290516000918391839173ffffffffffffffffffffffffffffffffffffffff8416916370a0823191602480820192602092909190829003018186803b15801561379157600080fd5b505afa1580156137a5573d6000803e3d6000fd5b505050506040513d60208110156137bb57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff851660009081526010602052604090205490915081111561382d5773ffffffffffffffffffffffffffffffffffffffff841660009081526010602052604090205461382490829063ffffffff61451616565b92505050612bbd565b600092505050612bbd565b60065473ffffffffffffffffffffffffffffffffffffffff1633146138be57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff166000908152600f6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b601d5481565b601454600090479081111561393e5760145461393690829063ffffffff61451616565b915050611254565b6000915050611254565b60065473ffffffffffffffffffffffffffffffffffffffff1633146139ce57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff9182166000908152600a6020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001691909216179055565b613a29614e1f565b601b8281548110613a3657fe5b60009182526020918290206040805161010080820183526007909402909201805473ffffffffffffffffffffffffffffffffffffffff908116845260018201549584019590955260028101549183019190915260038101546060830152600481015460808301819052600582015460ff8116151560a085015293909304841660c08301526006015490921660e08301529091504211613b3657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f65787069726174696f6e206461746520686173206e6f74207061737365640000604482015290519081900360640190fd5b60e081015173ffffffffffffffffffffffffffffffffffffffff163014613c7c5760e0810151606082015160408084015181517f9a5f2000000000000000000000000000000000000000000000000000000000008152600481019390935260248301523360448301525173ffffffffffffffffffffffffffffffffffffffff831691639a5f20009160648083019260209291908290030181600087803b158015613bdf57600080fd5b505af1158015613bf3573d6000803e3d6000fd5b505050506040513d6020811015613c0957600080fd5b5051613c7657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f657263323020706f6f6c206578657263697365206661696c6564000000000000604482015290519081900360640190fd5b50613ca5565b613c8a816060015133614c3e565b6060810151601454613ca19163ffffffff61451616565b6014555b60405182907fa33fd53ba34795ffefaea3759c71f87d38b89ae12e40bc434c826fae0ca5358390600090a2601f5460ff1615611e5d57613cee6118ea8260400151601e546112a5565b336000908152600c60205260409020555050565b60115481565b60155481565b60135473ffffffffffffffffffffffffffffffffffffffff1681565b3090565b601c5481565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b600061126f613d7a83612bc8565b6112b9613d8685612da0565b6112b9613d9287612b51565b601e549063ffffffff6141cd16565b60075473ffffffffffffffffffffffffffffffffffffffff1681565b600b6020526000908152604090205481565b60065473ffffffffffffffffffffffffffffffffffffffff163314613e5557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6005805473ffffffffffffffffffffffffffffffffffffffff909216610100027fffffffffffffffffffffff0000000000000000000000000000000000000000ff909216919091179055565b60065473ffffffffffffffffffffffffffffffffffffffff163314613f2757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff166000908152600a6020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b601a5460ff1681565b60065473ffffffffffffffffffffffffffffffffffffffff16331461400257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001811180156140125750603281105b61407d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f696e76616c696420666565000000000000000000000000000000000000000000604482015290519081900360640190fd5b601655565b3390565b73ffffffffffffffffffffffffffffffffffffffff83166140f2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602481526020018061503b6024913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821661415e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180614eee6022913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6000826141dc5750600061126f565b828202828482816141e957fe5b0414614240576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614fac6021913960400191505060405180910390fd5b9392505050565b600061424083836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614da0565b73ffffffffffffffffffffffffffffffffffffffff83166142f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806150166025913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216614361576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180614ea96023913960400191505060405180910390fd5b61436c838383614d9b565b6143bc81604051806060016040528060268152602001614f106026913973ffffffffffffffffffffffffffffffffffffffff8616600090815260208190526040902054919063ffffffff61446516565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526020819052604080822093909355908416815220546143fe908263ffffffff61455816565b73ffffffffffffffffffffffffffffffffffffffff8084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b6000818484111561450e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156144d35781810151838201526020016144bb565b50505050905090810190601f1680156145005780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600061424083836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614465565b60008282018381101561424057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6014546145df908263ffffffff61455816565b60145550565b73ffffffffffffffffffffffffffffffffffffffff8216614651576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614ff56021913960400191505060405180910390fd5b61465d82600083614d9b565b6146ad81604051806060016040528060228152602001614ecc6022913973ffffffffffffffffffffffffffffffffffffffff8516600090815260208190526040902054919063ffffffff61446516565b73ffffffffffffffffffffffffffffffffffffffff83166000908152602081905260409020556002546146e6908263ffffffff61451616565b60025560408051828152905160009173ffffffffffffffffffffffffffffffffffffffff8516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b336000908152600e60209081526040808320429055601c54600d90925290912055565b73ffffffffffffffffffffffffffffffffffffffff82166147e057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b6147ec60008383614d9b565b6002546147ff908263ffffffff61455816565b60025573ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054614838908263ffffffff61455816565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6014548311156148f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180614f36602c913960400191505060405180910390fd5b4783111561496557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f696e737566666963656e742062616c616e636520696e20706f6f6c0000000000604482015290519081900360640190fd5b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614614b4c576000662386f26fc1000084116149da576149d360646112c56149c660046015546141cd90919063ffffffff16565b879063ffffffff61424716565b90506149f7565b6149f460646112c56015548761424790919063ffffffff16565b90505b8015614b465760405173ffffffffffffffffffffffffffffffffffffffff84169082156108fc029083906000818181858888f19350505050614a9a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f657865726369736572207472616e73666572206661696c656400000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff82166108fc614ac4868463ffffffff61451616565b6040518115909202916000818181858888f19350505050614b4657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f77696e6e6572207472616e73666572206661696c656400000000000000000000604482015290519081900360640190fd5b50614be9565b60405173ffffffffffffffffffffffffffffffffffffffff82169084156108fc029085906000818181858888f19350505050614be957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f77696e6e6572207472616e73666572206661696c656400000000000000000000604482015290519081900360640190fd5b6040805184815273ffffffffffffffffffffffffffffffffffffffff8316602082015281517f9b5d1a613fa5f0790b36b13103706e31fca06b229d87e9915b29fc20c1d76490929181900390910190a1505050565b601454821115614c99576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180614f626029913960400191505060405180910390fd5b6000662386f26fc100008311614cdb57614cd460646112c5614cc760046015546141cd90919063ffffffff16565b869063ffffffff61424716565b9050614cf8565b614cf560646112c56015548661424790919063ffffffff16565b90505b8015614d9b5760405173ffffffffffffffffffffffffffffffffffffffff83169082156108fc029083906000818181858888f19350505050614d9b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f676f6f642073616d61726974616e207472616e73666572206661696c65640000604482015290519081900360640190fd5b505050565b60008183614e09576040517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482018181528351602484015283519092839260449091019190850190808383600083156144d35781810151838201526020016144bb565b506000838581614e1557fe5b0495945050505050565b604051806101000160405280600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001600081526020016000815260200160008152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152509056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e636545524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365696e737566666963656e7420706f6f6c2062616c616e636520617661696c61626c6520746f207061796f7574696e737566666963656e74206c6f636b656420706f6f6c2062616c616e636520746f20756e6c6f636b65787069726174696f6e2064617465206d617267696e2068617320706173736564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa264697066735822122049851b08581df436a7483ac7095517014e22632c3132616a7f18c2602d36a39964736f6c63430006060033

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

00000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000009326bfa02add2366b30bacb125260af64103133100000000000000000000000048fbf22f027438d95defc40814a0cc49570fbb5e00000000000000000000000085de67979509ad4da0c8e57ea30dfa213156836e0000000000000000000000000000000000000000000000000000000000000004704554480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000047045544800000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : name_ (string): pETH
Arg [1] : symbol_ (string): pETH
Arg [2] : pp_ (address): 0x9326BFA02ADD2366b30bacB125260Af641031331
Arg [3] : biop_ (address): 0x48fbF22F027438d95deFc40814A0cc49570FBb5e
Arg [4] : rateCalc_ (address): 0x85dE67979509Ad4Da0c8e57EA30dfa213156836E

-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [2] : 0000000000000000000000009326bfa02add2366b30bacb125260af641031331
Arg [3] : 00000000000000000000000048fbf22f027438d95defc40814a0cc49570fbb5e
Arg [4] : 00000000000000000000000085de67979509ad4da0c8e57ea30dfa213156836e
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [6] : 7045544800000000000000000000000000000000000000000000000000000000
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [8] : 7045544800000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

76343:21368:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;9;2:12;9839:83:0;;5:9:-1;2:2;;;27:1;24;17:12;2:2;9839:83:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;9839:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11945:169;;5:9:-1;2:2;;;27:1;24;17:12;2:2;11945:169:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;11945:169:0;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;76982:36;;5:9:-1;2:2;;;27:1;24;17:12;2:2;76982:36:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;76982:36:0;;;;:::i;:::-;;;;;;;;;;;;;;;;77224:19;;5:9:-1;2:2;;;27:1;24;17:12;2:2;77224:19:0;;;:::i;10914:100::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;10914:100:0;;;:::i;76911:36::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;76911:36:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;76911:36:0;;;;:::i;81684:298::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;81684:298:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;81684:298:0;;;;;;;:::i;77127:48::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;77127:48:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;77127:48:0;;;;:::i;83947:104::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;83947:104:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;83947:104:0;;;;:::i;:::-;;77069:36;;5:9:-1;2:2;;;27:1;24;17:12;2:2;77069:36:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;77069:36:0;;;;:::i;84933:86::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;84933:86:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;84933:86:0;;:::i;77770:45::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;77770:45:0;;;:::i;12596:321::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;12596:321:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;12596:321:0;;;;;;;;;;;;;;;;;;:::i;90035:1762::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;90035:1762:0;;;;;;;;;;;;;;;;:::i;88531:690::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;88531:690:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;88531:690:0;;:::i;10766:83::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;10766:83:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;82904:307;;5:9:-1;2:2;;;27:1;24;17:12;2:2;82904:307:0;;;:::i;76513:31::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;76513:31:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;85193:86;;5:9:-1;2:2;;;27:1;24;17:12;2:2;85193:86:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;85193:86:0;;:::i;13326:218::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;13326:218:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;13326:218:0;;;;;;;;;:::i;87790:523::-;;;:::i;77599:23::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;77599:23:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;77599:23:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76415:30;;5:9:-1;2:2;;;27:1;24;17:12;2:2;76415:30:0;;;:::i;76671:39::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;76671:39:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;76671:39:0;;;;:::i;92163:1031::-;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;92163:1031:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;87055:105::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;87055:105:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;87055:105:0;;;;:::i;77532:30::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;77532:30:0;;;:::i;86693:211::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;86693:211:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;86693:211:0;;:::i;89467:276::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;89467:276:0;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;89467:276:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;77486:39::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;77486:39:0;;;:::i;77384:30::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;77384:30:0;;;:::i;79941:277::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;79941:277:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;79941:277:0;;;;:::i;77293:27::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;77293:27:0;;;:::i;81361:270::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;81361:270:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;81361:270:0;;;;:::i;11077:119::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;11077:119:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;11077:119:0;;;;:::i;77822:24::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;77822:24:0;;;:::i;85647:192::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;85647:192:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;85647:192:0;;:::i;76587:35::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;76587:35:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;76587:35:0;;;;:::i;76452:28::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;76452:28:0;;;:::i;80226:1127::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;80226:1127:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;80226:1127:0;;;;:::i;10041:87::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;10041:87:0;;;:::i;87526:74::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;87526:74:0;;;:::i;82265:423::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;82265:423:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;82265:423:0;;;;:::i;83321:99::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;83321:99:0;;;:::i;83754:82::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;83754:82:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;83754:82:0;;;;:::i;14047:269::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;14047:269:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;14047:269:0;;;;;;;;;:::i;79838:95::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;79838:95:0;;;:::i;11409:175::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;11409:175:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;11409:175:0;;;;;;;;;:::i;77439:34::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;77439:34:0;;;:::i;86358:198::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;86358:198:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;86358:198:0;;:::i;93314:1105::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;93314:1105:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;93314:1105:0;;:::i;79450:380::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;79450:380:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;79450:380:0;;;;:::i;83527:100::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;83527:100:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;83527:100:0;;;;:::i;77704:35::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;77704:35:0;;;:::i;79190:252::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;79190:252:0;;;:::i;84322:115::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;84322:115:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;84322:115:0;;;;;;;;;;;:::i;94525:734::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;94525:734:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;94525:734:0;;:::i;77188:19::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;77188:19:0;;;:::i;77327:32::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;77327:32:0;;;:::i;77260:26::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;77260:26:0;;;:::i;85363:91::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;85363:91:0;;;:::i;77635:21::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;77635:21:0;;;:::i;11647:151::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;11647:151:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;11647:151:0;;;;;;;;;;;:::i;81990:267::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;81990:267:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;81990:267:0;;;;:::i;76487:19::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;76487:19:0;;;:::i;76768:35::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;76768:35:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;76768:35:0;;;;:::i;87311:111::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;87311:111:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;87311:111:0;;;;:::i;84628:131::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;84628:131:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;84628:131:0;;;;:::i;77569:23::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;77569:23:0;;;:::i;86023:179::-;;5:9:-1;2:2;;;27:1;24;17:12;2:2;86023:179:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;86023:179:0;;:::i;9839:83::-;9909:5;9902:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9876:13;;9902:12;;9909:5;;9902:12;;9909:5;9902:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9839:83;;:::o;11945:169::-;12028:4;12045:39;12054:12;:10;:12::i;:::-;12068:7;12077:6;12045:8;:39::i;:::-;-1:-1:-1;12102:4:0;11945:169;;;;;:::o;76982:36::-;;;;;;;;;;;;;:::o;77224:19::-;;;;:::o;10914:100::-;10994:12;;10914:100;:::o;76911:36::-;;;;;;;;;;;;;:::o;81684:298::-;81759:7;81779:18;81800:34;81827:6;81800:22;81818:3;81800:13;:11;:13::i;:::-;:17;:22;:17;:22;:::i;:::-;:26;:34;:26;:34;:::i;:::-;81779:55;-1:-1:-1;81879:1:0;81848:28;81873:2;81848:20;:4;81779:55;81848:20;:8;:20;:::i;:28::-;:32;81845:98;;;81903:28;81928:2;81903:20;:4;81912:10;81903:20;:8;:20;:::i;:28::-;81896:35;;;;;81845:98;81960:14;:4;81969;81960:14;:8;:14;:::i;:::-;81953:21;81684:298;-1:-1:-1;;;;81684:298:0:o;77127:48::-;;;;;;;;;;;;;:::o;83947:104::-;77914:5;;:19;:5;77923:10;77914:19;77906:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84018:16:::1;;84037:5;84018:16:::0;;;:6:::1;:16;::::0;;;;:24;;;::::1;::::0;;83947:104::o;77069:36::-;;;;;;;;;;;;;;;:::o;84933:86::-;77914:5;;:19;:5;77923:10;77914:19;77906:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84997:4:::1;:14:::0;84933:86::o;77770:45::-;;;;:::o;12596:321::-;12702:4;12719:36;12729:6;12737:9;12748:6;12719:9;:36::i;:::-;12766:121;12775:6;12783:12;:10;:12::i;:::-;12797:89;12835:6;12797:89;;;;;;;;;;;;;;;;;:19;;;;;;;:11;:19;;;;;;12817:12;:10;:12::i;:::-;12797:33;;;;;;;;;;;;;-1:-1:-1;12797:33:0;;;:89;;:37;:89;:::i;:::-;12766:8;:121::i;:::-;-1:-1:-1;12905:4:0;12596:321;;;;;:::o;90035:1762::-;90138:4;;90132:2;:10;;:24;;;;;90152:4;;90146:2;:10;;90132:24;90110:86;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90215:11;;;;;;;;:6;:11;;;;;;;90207:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90321:29;90369:3;90321:52;;90384:9;90396:13;:26;;;:28;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;90396:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;90396:28:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;90396:28:0;90491:7;:14;90396:28;;-1:-1:-1;90435:10:0;;;;90583:3;90570:9;:16;;90562:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90639:17;:15;:17::i;:::-;90626:9;:30;;90618:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90848:13;;:17;90844:289;;90890:11;90904:28;90918:13;;90904:9;:13;;:28;;;;:::i;:::-;90963:7;;:17;;90890:42;;-1:-1:-1;90963:7:0;;;;;;:17;;;;;90890:42;;90963:17;;;;90890:42;90963:7;:17;;;;;;;90955:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91040:18;:9;91054:3;91040:18;:13;:18;:::i;:::-;91035:23;;90844:289;;;;91108:9;91103:14;;90844:289;91151:17;91171:47;91179:3;91184:17;:15;:17::i;:::-;91203:2;91207;91211;91215;91171:7;:47::i;:::-;91251:5;;91151:67;;-1:-1:-1;91251:5:0;;91247:120;;;91299:52;91323:27;91339:2;91343:6;;91323:15;:27::i;:::-;91307:10;91299:19;;;;:7;:19;;;;;;;:52;:23;:52;:::i;:::-;91285:10;91277:19;;;;:7;:19;;;;;:74;91247:120;91386:17;:9;91400:2;91386:17;:13;:17;:::i;:::-;91381:22;;91418:8;91423:2;91418:4;:8::i;:::-;91451:16;;:::i;:::-;-1:-1:-1;91470:213:0;;;;;;;;;91491:10;91470:213;;;;;;;;;;;;;;;;;;;;91567:15;:20;;91470:213;;;;;;;;;;;;;;;;;;;;;;;;;91667:4;91470:213;;;;;;91696:7;27:10:-1;;39:1;23:18;;45:23;;-1:-1;91696:16:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91728:2;;:10;;91550:2;91728:10;:6;:10;:::i;:::-;91723:2;:15;91754:35;;;91766:10;91754:35;;;;;;;;;;;;;;;;;;;;;;;91761:3;;91754:35;;;;;;;;;;90035:1762;;;;;;;;;;:::o;88531:690::-;88616:6;88591:21;88601:10;88591:9;:21::i;:::-;:31;;88582:70;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88666:10;88663:14;;;;:2;:14;;;;;88680:15;88663:32;;88731:52;88769:13;:11;:13::i;:::-;88731:33;:6;88742:21;88731:33;:10;:33;:::i;:52::-;88706:77;;88794:25;88800:10;88812:6;88794:5;:25::i;:::-;88856:10;88853:14;;;;:2;:14;;;;;;88834:15;:33;88830:384;;88918:15;88936:23;:14;88955:3;88936:23;:18;:23;:::i;:::-;88982:7;;:21;;88918:41;;-1:-1:-1;88982:7:0;;;;;;:21;;;;;88918:41;;88982:21;;;;88918:41;88982:7;:21;;;;;;;88974:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89046:10;:44;89062:27;:14;89081:7;89062:27;:18;:27;:::i;:::-;89046:44;;;;;;;;;;;;;;;;;;;;;89038:72;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88830:384;;;;89151:31;;:10;;:31;;;;;89167:14;;89151:31;;;;89167:14;89151:10;:31;;;;;;;89143:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88531:690;;:::o;10766:83::-;10832:9;;;;10766:83;:::o;82904:307::-;82986:4;;;;82958:13;83019:28;83036:10;83019:16;:28::i;:::-;83002:45;;83086:1;83062:21;83072:10;83062:9;:21::i;:::-;:25;83058:75;;;83104:17;:15;:17::i;:::-;83151:10;83165:1;83143:19;;;:7;:19;;;;;;:23;;;83177:26;;;;;;;;;;;;;83143:19;83177:18;;;;;:26;;;;;;;;;;;83165:1;83177:18;:26;;;2:2:-1;;;;27:1;24;17:12;2:2;83177:26:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;83177:26:0;;;;82904:307;;:::o;76513:31::-;;;;;;:::o;85193:86::-;77914:5;;:19;:5;77923:10;77914:19;77906:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85257:4:::1;:14:::0;85193:86::o;13326:218::-;13414:4;13431:83;13440:12;:10;:12::i;:::-;13454:7;13463:50;13502:10;13463:11;:25;13475:12;:10;:12::i;:::-;13463:25;;;;;;;;;;;;;;;;;;-1:-1:-1;13463:25:0;;;:34;;;;;;;;;;;:50;:38;:50;:::i;87790:523::-;87843:4;;;;:12;;:4;:12;87835:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87916:3;87903:9;:16;;87895:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87953:21;87963:10;87953:9;:21::i;:::-;87949:156;;87999:10;87996:14;;;;:2;:14;;;;;;;;88013:15;87996:32;;88089:3;;88065:7;:19;;;;;;;:28;;;:23;:28;:::i;:::-;88051:10;88043:19;;;;:7;:19;;;;;:50;87949:156;88115:17;:15;:17::i;:::-;88178:15;;88146:10;88143:14;;;;:2;:14;;;;;88160:15;:33;;;88143:50;;;88277:28;;88295:9;88277:5;:28::i;:::-;87790:523::o;77599:23::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;77599:23:0;;;;;;;;;;;;;;;;;;;;;:::o;76415:30::-;;;;;;;;;:::o;76671:39::-;;;;;;;;;;;;;;;:::o;92163:1031::-;92294:4;;92288:2;:10;;:24;;;;;92308:4;;92302:2;:10;;92288:24;92266:86;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92371:11;;;;;;;;:6;:11;;;;;;;92363:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92477:29;92525:3;92477:52;;92540:9;92552:13;:26;;;:28;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;92552:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;92552:28:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;92552:28:0;92643:11;;;92591:10;92643:11;;;:6;92552:28;92643:11;;;;;92552:28;;-1:-1:-1;92591:10:0;;;92643:11;;92635:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92731:29;;;;;;92749:10;92731:29;;;;;;92708:3;;92764:2;;92731:17;;;;;;:29;;;;;;;;;;;;;;:17;:29;;;2:2:-1;;;;27:1;24;17:12;2:2;92731:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;92731:29:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;92731:29:0;:35;;92723:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92805:19;;;;;;;;;;;;;;;;;;;;:11;;;;;;:19;;;;;;;;;;;-1:-1:-1;92805:11:0;:19;;;2:2:-1;;;;27:1;24;17:12;2:2;92805:19:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;92805:19:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;92805:19:0;;;;;;;;;-1:-1:-1;92805:19:0;-1:-1:-1;92845:16:0;;:::i;:::-;92864:203;;;;;;;;92885:10;92864:203;;;;;;92910:2;92864:203;;;;92927:2;92864:203;;;;92944:2;92864:203;;;;92979:2;92961:15;:20;92864:203;;;;93018:2;92864:203;;;;;;93035:3;92864:203;;;;;;93053:3;92864:203;;;;;92845:222;;93080:7;93093:2;93080:16;;39:1:-1;33:3;27:10;23:18;57:10;52:3;45:23;79:10;72:17;;0:93;93080:16:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93112:10;93119:2;93112;;:6;;:10;;;;:::i;:::-;93107:2;:15;93145:7;:14;93138:48;;;93163:10;93138:48;;;;;;;;;;;;;;;;;;;;;;;93145:16;;;;;93138:48;;;;;;;;;92163:1031;;;;;;;;;;;:::o;87055:105::-;77914:5;;:19;:5;77923:10;77914:19;77906:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87135:5:::1;:17:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;87055:105::o;77532:30::-;;;;:::o;86693:211::-;77914:5;;:19;:5;77923:10;77914:19;77906:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86829:7:::1;86811:15;:25;86779:73;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;86863:15;:33:::0;86693:211::o;89467:276::-;89631:12;;;;89588:7;89631:12;;;:6;:12;;;;;;89588:7;;89631:12;;89672:7;89680;89689:16;:3;89680:7;89689:16;:7;:16;:::i;:::-;89715:12;89730:1;89733;89672:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;89672:63:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;89672:63:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;89672:63:0;;89467:276;-1:-1:-1;;;;;;;;89467:276:0:o;77486:39::-;;;;:::o;77384:30::-;;;;:::o;79941:277::-;80061:12;;;80007:7;80061:12;;;:3;:12;;;;;;80007:7;;80041:33;;:15;;:33;:19;:33;:::i;:::-;80027:47;-1:-1:-1;80085:13:0;80101:15;80027:47;80109:6;80101:15;:7;:15;:::i;:::-;80085:31;;80145:6;80139:3;:12;80135:53;;;80175:1;80168:8;;;;;;80135:53;80205:5;-1:-1:-1;;79941:277:0;;;;:::o;77293:27::-;;;;:::o;81361:270::-;81468:12;;;81427:7;81468:12;;;:3;:12;;;;;;81461:2;;81427:7;;81461:20;;:2;:20;:6;:20;:::i;:::-;81447:34;-1:-1:-1;81492:13:0;81508:28;81447:34;81516:19;81508:28;:7;:28;:::i;:::-;81492:44;-1:-1:-1;81556:9:0;;81553:52;;81588:5;-1:-1:-1;81581:12:0;;-1:-1:-1;81581:12:0;81553:52;-1:-1:-1;81622:1:0;;81361:270;-1:-1:-1;;;81361:270:0:o;11077:119::-;11170:18;;11143:7;11170:18;;;;;;;;;;;;11077:119::o;77822:24::-;;;;;;:::o;85647:192::-;77914:5;;:19;:5;77923:10;77914:19;77906:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85752:1:::1;85736:13;:17;:40;;;;;85773:3;85757:13;:19;85736:40;85728:64;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;85803:12;:28:::0;85647:192::o;76587:35::-;;;;;;;;;;;;;:::o;76452:28::-;;;;;;:::o;80226:1127::-;80292:7;80312:15;80330:18;80340:7;80330:9;:18::i;:::-;80312:36;-1:-1:-1;80363:11:0;;80359:966;;80413:3;80397:13;:11;:13::i;:::-;:19;80393:76;;;80452:1;80445:8;;;;;80393:76;80514:20;80532:1;80514:13;:11;:13::i;:20::-;80503:7;:31;80499:98;;80579:2;80572:9;;;;;80499:98;80628:20;80646:1;80628:13;:11;:13::i;:20::-;80617:7;:31;80613:98;;80693:2;80686:9;;;;;80613:98;80742:20;80760:1;80742:13;:11;:13::i;:20::-;80731:7;:31;80727:98;;80807:2;80800:9;;;;;80727:98;80856:21;80874:2;80856:13;:11;:13::i;:21::-;80845:7;:32;80841:98;;80922:1;80915:8;;;;;80841:98;80970:21;80988:2;80970:13;:11;:13::i;:21::-;80959:7;:32;80955:97;;81035:1;81028:8;;;;;80955:97;81083:21;81101:2;81083:13;:11;:13::i;:21::-;81072:7;:32;81068:97;;81148:1;81141:8;;;;;81068:97;81196:22;81214:3;81196:13;:11;:13::i;:22::-;81185:7;:33;81181:98;;81262:1;81255:8;;;;;81181:98;81312:1;81305:8;;;;;10041:87;10113:7;10106:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10080:13;;10106:14;;10113:7;;10106:14;;10113:7;10106:14;;;;;;;;;;;;;;;;;;;;;;;;87526:74;77914:5;;:19;:5;77923:10;77914:19;77906:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87580:4:::1;:12:::0;;;::::1;::::0;;87526:74::o;82265:423::-;82328:7;82373:1;82352:18;82362:7;82352:9;:18::i;:::-;:22;82348:333;;;82497:86;82536:32;82560:7;82536:23;:32::i;:::-;82497:16;;;;;;;:7;:16;;;;;;;:86;:20;:86;:::i;:::-;82490:93;;;;82348:333;-1:-1:-1;82653:16:0;;;;;;;:7;:16;;;;;;82646:23;;83321:99;83401:11;;;;83321:99;:::o;83754:82::-;77914:5;;:19;:5;77923:10;77914:19;77906:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83817:5:::1;:11:::0;;;::::1;::::0;::::1;;::::0;;;::::1;::::0;;83754:82::o;14047:269::-;14140:4;14157:129;14166:12;:10;:12::i;:::-;14180:7;14189:96;14228:15;14189:96;;;;;;;;;;;;;;;;;:11;:25;14201:12;:10;:12::i;:::-;14189:25;;;;;;;;;;;;;;;;;;-1:-1:-1;14189:25:0;;;:34;;;;;;;;;;;:96;;:38;:96;:::i;79838:95::-;79911:7;:14;79838:95;:::o;11409:175::-;11495:4;11512:42;11522:12;:10;:12::i;:::-;11536:9;11547:6;11512:9;:42::i;77439:34::-;;;;:::o;86358:198::-;77914:5;;:19;:5;77923:10;77914:19;77906:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86449:19;;;:42:::1;;;86489:2;86472:14;:19;86449:42;86441:66;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;86518:13;:30:::0;86358:198::o;93314:1105::-;93379:20;;:::i;:::-;93402:7;93410:3;93402:12;;;;;;;;;;;;;;;;;93379:35;;;;;;;;;93402:12;;;;;;;93379:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;93433:15:0;:29;;93425:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93511:29;93559:6;:9;;;93511:58;;93580:9;93592:13;:26;;;:28;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;93592:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;93592:28:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;93592:28:0;93635:10;;;;93592:28;;-1:-1:-1;93631:214:0;;;93702:6;:9;;;93697:2;:14;93689:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93631:214;;;93803:6;:9;;;93798:2;:14;93790:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93863:10;;;;:27;;93885:4;93863:27;93859:385;;93929:10;;;;93974:9;;;;93984;;;;;94007:13;;93963:58;;;;;;;;;;;;;;;;;;;93995:10;93963:58;;;;:10;:58;;;;;;;;;:10;;;;;;:58;;;;;;;;;;;;;;93907:11;93963:10;:58;;;2:2:-1;;;;27:1;24;17:12;2:2;93963:58:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;93963:58:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;93963:58:0;93955:97;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93859:385;;;;94131:44;94138:6;:9;;;94149:10;94161:6;:13;;;94131:6;:44::i;:::-;94222:9;;;;94205:12;;:27;;;:16;:27;:::i;:::-;94190:12;:42;93859:385;94269:13;;94278:3;;94269:13;;;;;94297:5;;;;94293:119;;;94341:59;94365:34;94381:6;:9;;;94392:6;;94365:15;:34::i;94341:59::-;94327:10;94319:19;;;;:7;:19;;;;;:81;94293:119;93314:1105;;;;:::o;79450:380::-;79610:28;;;;;;79632:4;79610:28;;;;;;79525:7;;79563:17;;79525:7;;79610:13;;;;;;:28;;;;;;;;;;;;;;;:13;:28;;;2:2:-1;;;;27:1;24;17:12;2:2;79610:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;79610:28:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;79610:28:0;79664:34;;;;;;;:15;79610:28;79664:34;;;;;79610:28;;-1:-1:-1;79653:45:0;;79649:174;;;79735:34;;;;;;;:15;:34;;;;;;79722:48;;:7;;:48;:11;:48;:::i;:::-;79715:55;;;;;;79649:174;79810:1;79803:8;;;;;;83527:100;77914:5;;:19;:5;77923:10;77914:19;77906:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83595:16:::1;;;::::0;;;:6:::1;:16;::::0;;;;:23;;;::::1;83614:4;83595:23;::::0;;83527:100::o;77704:35::-;;;;:::o;79190:252::-;79321:12;;79237:7;;79275:21;;79311:22;;79307:128;;;79369:12;;79357:25;;:7;;:25;:11;:25;:::i;:::-;79350:32;;;;;79307:128;79422:1;79415:8;;;;;84322:115;77914:5;;:19;:5;77923:10;77914:19;77906:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84402:14:::1;::::0;;::::1;;::::0;;;:6:::1;:14;::::0;;;;:26;;;::::1;::::0;;;::::1;;::::0;;84322:115::o;94525:734::-;94588:20;;:::i;:::-;94611:7;94619:3;94611:12;;;;;;;;;;;;;;;;;94588:35;;;;;;;;;94611:12;;;;;;;94588:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;94642:15:0;:28;94634:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94724:10;;;;:27;;94746:4;94724:27;94720:376;;94818:10;;;;94876:9;;;;94886;;;;;94852:56;;;;;;;;;;;;;;;;94897:10;94852:56;;;;;:23;;;;;;:56;;;;;;;;;;;;;;94796:11;94852:23;:56;;;2:2:-1;;;;27:1;24;17:12;2:2;94852:56:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;94852:56:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;94852:56:0;94844:95;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94720:376;;;;94998:29;95005:6;:9;;;95016:10;94998:6;:29::i;:::-;95074:9;;;;95057:12;;:27;;;:16;:27;:::i;:::-;95042:12;:42;94720:376;95111:11;;95118:3;;95111:11;;;;;95137:5;;;;95133:119;;;95181:59;95205:34;95221:6;:9;;;95232:6;;95205:15;:34::i;95181:59::-;95167:10;95159:19;;;;:7;:19;;;;;:81;94525:734;;:::o;77188:19::-;;;;:::o;77327:32::-;;;;:::o;77260:26::-;;;;;;:::o;85363:91::-;85441:4;85363:91;:::o;77635:21::-;;;;:::o;11647:151::-;11763:18;;;;11736:7;11763:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;11647:151::o;81990:267::-;82060:7;82087:162;82220:28;82240:7;82220:19;:28::i;:::-;82087:110;82168:28;82188:7;82168:19;:28::i;:::-;82087:58;82116:28;82136:7;82116:19;:28::i;:::-;82087:6;;;:58;:28;:58;:::i;76487:19::-;;;;;;:::o;76768:35::-;;;;;;;;;;;;;:::o;87311:111::-;77914:5;;:19;:5;77923:10;77914:19;77906:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87394:7:::1;:20:::0;;::::1;::::0;;::::1;;;::::0;;;::::1;::::0;;;::::1;::::0;;87311:111::o;84628:131::-;77914:5;;:19;:5;77923:10;77914:19;77906:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84692:14:::1;;84709:42;84692:14:::0;;;:6:::1;:14;::::0;;;;:59;;;::::1;::::0;;84628:131::o;77569:23::-;;;;;;:::o;86023:179::-;77914:5;;:19;:5;77923:10;77914:19;77906:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86122:1:::1;86108:11;:15;:35;;;;;86141:2;86127:11;:16;86108:35;86100:59;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;86170:10;:24:::0;86023:179::o;4783:106::-;4871:10;4783:106;:::o;17194:346::-;17296:19;;;17288:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17375:21;;;17367:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17448:18;;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;17500:32;;;;;;;;;;;;;;;;;17194:346;;;:::o;1646:471::-;1704:7;1949:6;1945:47;;-1:-1:-1;1979:1:0;1972:8;;1945:47;2016:5;;;2020:1;2016;:5;:1;2040:5;;;;;:10;2032:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2108:1;1646:471;-1:-1:-1;;;1646:471:0:o;2593:132::-;2651:7;2678:39;2682:1;2685;2678:39;;;;;;;;;;;;;;;;;:3;:39::i;14806:539::-;14912:20;;;14904:70;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14993:23;;;14985:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15069:47;15090:6;15098:9;15109:6;15069:20;:47::i;:::-;15149:71;15171:6;15149:71;;;;;;;;;;;;;;;;;:17;;;:9;:17;;;;;;;;;;;;:71;;:21;:71;:::i;:::-;15129:17;;;;:9;:17;;;;;;;;;;;:91;;;;15254:20;;;;;;;:32;;15279:6;15254:32;:24;:32;:::i;:::-;15231:20;;;;:9;:20;;;;;;;;;;;;:55;;;;15302:35;;;;;;;15231:20;;15302:35;;;;;;;;;;;;;14806:539;;;:::o;1195:192::-;1281:7;1317:12;1309:6;;;;1301:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;1301:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;1353:5:0;;;1195:192::o;756:136::-;814:7;841:43;845:1;848;841:43;;;;;;;;;;;;;;;;;:3;:43::i;292:181::-;350:7;382:5;;;406:6;;;;398:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;95452:97;95517:12;;:24;;95534:6;95517:24;:16;:24;:::i;:::-;95502:12;:39;-1:-1:-1;95452:97:0:o;16338:418::-;16422:21;;;16414:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16494:49;16515:7;16532:1;16536:6;16494:20;:49::i;:::-;16577:68;16600:6;16577:68;;;;;;;;;;;;;;;;;:18;;;:9;:18;;;;;;;;;;;;:68;;:22;:68;:::i;:::-;16556:18;;;:9;:18;;;;;;;;;;:89;16671:12;;:24;;16688:6;16671:24;:16;:24;:::i;:::-;16656:12;:39;16711:37;;;;;;;;16737:1;;16711:37;;;;;;;;;;;;;16338:418;;:::o;82696:119::-;82747:10;82743:15;;;;:3;:15;;;;;;;;82761;82743:33;;82805:2;;82787:3;:15;;;;;;:20;82696:119::o;15627:378::-;15711:21;;;15703:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15781:49;15810:1;15814:7;15823:6;15781:20;:49::i;:::-;15858:12;;:24;;15875:6;15858:24;:16;:24;:::i;:::-;15843:12;:39;15914:18;;;:9;:18;;;;;;;;;;;:30;;15937:6;15914:30;:22;:30;:::i;:::-;15893:18;;;:9;:18;;;;;;;;;;;:51;;;;15960:37;;;;;;;15893:18;;:9;;15960:37;;;;;;;;;;15627:378;;:::o;96757:949::-;96878:12;;96868:6;:22;;96860:79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96968:21;96958:6;:31;;96950:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97049:6;97036:19;;:9;:19;;;97032:629;;97106:11;97146:17;97136:6;:27;97132:227;;97223:40;97259:3;97223:31;97234:19;97251:1;97234:12;;:16;;:19;;;;:::i;:::-;97223:6;;:31;:10;:31;:::i;:40::-;97217:46;;97132:227;;;97310:33;97339:3;97310:24;97321:12;;97310:6;:10;;:24;;;;:::i;:33::-;97304:39;;97132:227;97378:7;;97374:187;;97414:19;;:14;;;;:19;;;;;97429:3;;97414:19;;;;97429:3;97414:14;:19;;;;;;;97406:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97490:11;;;:28;97502:15;:6;97513:3;97502:15;:10;:15;:::i;:::-;97490:28;;;;;;;;;;;;;;;;;;;;;97482:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97032:629;;;;97603:19;;:11;;;;:19;;;;;97615:6;;97603:19;;;;97615:6;97603:11;:19;;;;;;;97595:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97676:22;;;;;;;;;;;;;;;;;;;;;;;;;;96757:949;;;:::o;95806:527::-;95907:12;;95897:6;:22;;95889:76;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;95976:11;96012:17;96002:6;:27;95998:211;;96085:40;96121:3;96085:31;96096:19;96113:1;96096:12;;:16;;:19;;;;:::i;:::-;96085:6;;:31;:10;:31;:::i;:40::-;96079:46;;95998:211;;;96164:33;96193:3;96164:24;96175:12;;96164:6;:10;;:24;;;;:::i;:33::-;96158:39;;95998:211;96224:7;;96220:106;;96256:23;;:18;;;;:23;;;;;96275:3;;96256:23;;;;96275:3;96256:18;:23;;;;;;;96248:66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;95806:527;;;:::o;3221:278::-;3307:7;3342:12;3335:5;3327:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27:10:-1;;8:100;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;3327:28:0;;3366:9;3382:1;3378;:5;;;;;;;3221:278;-1:-1:-1;;;;;3221:278:0:o;76343:21368::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o

Swarm Source

ipfs://49851b08581df436a7483ac7095517014e22632c3132616a7f18c2602d36a399

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.