ERC-20
Source Code
Overview
Max Total Supply
1.321 ERC20 ***
Holders
5
Transfers
-
-
Market
Onchain Market Cap
-
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Loading...
Loading
Loading...
Loading
Loading...
Loading
| # | Exchange | Pair | Price | 24H Volume | % Volume |
|---|
Contract Name:
BinaryOptions
Compiler Version
v0.6.6+commit.6c089d02
Contract Source Code (Solidity)
/**
*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
- No Contract Security Audit Submitted- Submit Audit Here
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"}]Contract Creation Code
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
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.
Add Token to MetaMask (Web3)