Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 47 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Redeem Vault Bal... | 10338578 | 2080 days ago | IN | 0 ETH | 0.0008463 | ||||
| Redeem Vault Bal... | 9795552 | 2164 days ago | IN | 0 ETH | 0.00023696 | ||||
| Redeem Vault Bal... | 9781800 | 2166 days ago | IN | 0 ETH | 0.00026163 | ||||
| Redeem Vault Bal... | 9774923 | 2167 days ago | IN | 0 ETH | 0.00023696 | ||||
| Remove Underlyin... | 9754157 | 2170 days ago | IN | 0 ETH | 0.00016654 | ||||
| Exercise | 9747361 | 2171 days ago | IN | 0.001 ETH | 0.00079263 | ||||
| Add And Sell ERC... | 9747354 | 2171 days ago | IN | 0 ETH | 0.00115162 | ||||
| Approve | 9747341 | 2171 days ago | IN | 0 ETH | 0.00030856 | ||||
| Remove Collatera... | 9735799 | 2173 days ago | IN | 0 ETH | 0.00020218 | ||||
| Burn O Tokens | 9735754 | 2173 days ago | IN | 0 ETH | 0.00006552 | ||||
| Approve | 9732775 | 2173 days ago | IN | 0 ETH | 0.00020356 | ||||
| Create And Sell ... | 9732775 | 2173 days ago | IN | 0 ETH | 0.00069786 | ||||
| Approve | 9732727 | 2173 days ago | IN | 0 ETH | 0.00030856 | ||||
| Exercise | 9728685 | 2174 days ago | IN | 0.00001 ETH | 0.00064298 | ||||
| Remove Underlyin... | 9725612 | 2174 days ago | IN | 0 ETH | 0.00016654 | ||||
| Remove Underlyin... | 9725207 | 2174 days ago | IN | 0 ETH | 0.00016654 | ||||
| Exercise | 9718486 | 2176 days ago | IN | 0.001 ETH | 0.00056617 | ||||
| Approve | 9718474 | 2176 days ago | IN | 0 ETH | 0.00017455 | ||||
| Add ERC20Collate... | 9711923 | 2177 days ago | IN | 0 ETH | 0.0007958 | ||||
| Create ERC20Coll... | 9710647 | 2177 days ago | IN | 0 ETH | 0.00137755 | ||||
| Create And Sell ... | 9710298 | 2177 days ago | IN | 0 ETH | 0.00173319 | ||||
| Remove Collatera... | 9707244 | 2177 days ago | IN | 0 ETH | 0.00054081 | ||||
| Burn O Tokens | 9707192 | 2177 days ago | IN | 0 ETH | 0.00010129 | ||||
| Exercise | 9706808 | 2177 days ago | IN | 0.01 ETH | 0.00069811 | ||||
| Approve | 9706804 | 2177 days ago | IN | 0 ETH | 0.00030856 |
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
oToken
Compiler Version
v0.5.10+commit.5a6ea5b1
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2020-03-16
*/
// File: @openzeppelin/contracts/GSN/Context.sol
pragma solidity ^0.5.0;
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
contract Context {
// Empty internal constructor, to prevent people from mistakenly deploying
// an instance of this contract, which should be used via inheritance.
constructor () internal { }
// solhint-disable-previous-line no-empty-blocks
function _msgSender() internal view returns (address payable) {
return msg.sender;
}
function _msgData() internal view returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
// File: @openzeppelin/contracts/token/ERC20/IERC20.sol
pragma solidity ^0.5.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP. Does not include
* the optional functions; to access them see {ERC20Detailed}.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
// File: @openzeppelin/contracts/math/SafeMath.sol
pragma solidity ^0.5.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*
* _Available since v2.4.0._
*/
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.
*
* _Available since v2.4.0._
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*
* _Available since v2.4.0._
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
// File: @openzeppelin/contracts/token/ERC20/ERC20.sol
pragma solidity ^0.5.0;
/**
* @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 {ERC20Mintable}.
*
* 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;
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view 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 returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public 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 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 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 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 {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_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 {
require(account != address(0), "ERC20: mint to the zero address");
_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 {
require(account != address(0), "ERC20: burn from the zero address");
_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 is 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 {
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 Destroys `amount` tokens from `account`.`amount` is then deducted
* from the caller's allowance.
*
* See {_burn} and {_approve}.
*/
function _burnFrom(address account, uint256 amount) internal {
_burn(account, amount);
_approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, "ERC20: burn amount exceeds allowance"));
}
}
// File: contracts/lib/CompoundOracleInterface.sol
pragma solidity ^0.5.0;
// AT MAINNET ADDRESS: 0x02557a5E05DeFeFFD4cAe6D83eA3d173B272c904
contract CompoundOracleInterface {
// returns asset:eth -- to get USDC:eth, have to do 10**24/result,
constructor() public {
}
/**
* @notice retrieves price of an asset
* @dev function to get price for an asset
* @param asset Asset for which to get the price
* @return uint mantissa of asset price (scaled by 1e18) or zero if unset or contract paused
*/
function getPrice(address asset) public view returns (uint);
function getUnderlyingPrice(ERC20 cToken) public view returns (uint);
// function getPrice(address asset) public view returns (uint) {
// return 527557000000000;
// }
}
// File: contracts/lib/UniswapExchangeInterface.sol
pragma solidity 0.5.10;
// Solidity Interface
contract UniswapExchangeInterface {
// Address of ERC20 token sold on this exchange
function tokenAddress() external view returns (address token);
// Address of Uniswap Factory
function factoryAddress() external view returns (address factory);
// Provide Liquidity
function addLiquidity(uint256 min_liquidity, uint256 max_tokens, uint256 deadline) external payable returns (uint256);
function removeLiquidity(uint256 amount, uint256 min_eth, uint256 min_tokens, uint256 deadline) external returns (uint256, uint256);
// Get Prices
function getEthToTokenInputPrice(uint256 eth_sold) external view returns (uint256 tokens_bought);
function getEthToTokenOutputPrice(uint256 tokens_bought) external view returns (uint256 eth_sold);
function getTokenToEthInputPrice(uint256 tokens_sold) external view returns (uint256 eth_bought);
function getTokenToEthOutputPrice(uint256 eth_bought) external view returns (uint256 tokens_sold);
// Trade ETH to ERC20
function ethToTokenSwapInput(uint256 min_tokens, uint256 deadline) external payable returns (uint256 tokens_bought);
function ethToTokenTransferInput(uint256 min_tokens, uint256 deadline, address recipient) external payable returns (uint256 tokens_bought);
function ethToTokenSwapOutput(uint256 tokens_bought, uint256 deadline) external payable returns (uint256 eth_sold);
function ethToTokenTransferOutput(uint256 tokens_bought, uint256 deadline, address recipient) external payable returns (uint256 eth_sold);
// Trade ERC20 to ETH
function tokenToEthSwapInput(uint256 tokens_sold, uint256 min_eth, uint256 deadline) external returns (uint256 eth_bought);
function tokenToEthTransferInput(uint256 tokens_sold, uint256 min_eth, uint256 deadline, address recipient) external returns (uint256 eth_bought);
function tokenToEthSwapOutput(uint256 eth_bought, uint256 max_tokens, uint256 deadline) external returns (uint256 tokens_sold);
function tokenToEthTransferOutput(uint256 eth_bought, uint256 max_tokens, uint256 deadline, address recipient) external returns (uint256 tokens_sold);
// Trade ERC20 to ERC20
function tokenToTokenSwapInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address token_addr) external returns (uint256 tokens_bought);
function tokenToTokenTransferInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address recipient, address token_addr) external returns (uint256 tokens_bought);
function tokenToTokenSwapOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address token_addr) external returns (uint256 tokens_sold);
function tokenToTokenTransferOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address recipient, address token_addr) external returns (uint256 tokens_sold);
// Trade ERC20 to Custom Pool
function tokenToExchangeSwapInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address exchange_addr) external returns (uint256 tokens_bought);
function tokenToExchangeTransferInput(uint256 tokens_sold, uint256 min_tokens_bought, uint256 min_eth_bought, uint256 deadline, address recipient, address exchange_addr) external returns (uint256 tokens_bought);
function tokenToExchangeSwapOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address exchange_addr) external returns (uint256 tokens_sold);
function tokenToExchangeTransferOutput(uint256 tokens_bought, uint256 max_tokens_sold, uint256 max_eth_sold, uint256 deadline, address recipient, address exchange_addr) external returns (uint256 tokens_sold);
// ERC20 comaptibility for liquidity tokens
bytes32 public name;
bytes32 public symbol;
uint256 public decimals;
function transfer(address _to, uint256 _value) external returns (bool);
function transferFrom(address _from, address _to, uint256 value) external returns (bool);
function approve(address _spender, uint256 _value) external returns (bool);
function allowance(address _owner, address _spender) external view returns (uint256);
function balanceOf(address _owner) external view returns (uint256);
function totalSupply() external view returns (uint256);
// Never use
function setup(address token_addr) external;
}
// File: contracts/lib/UniswapFactoryInterface.sol
pragma solidity 0.5.10;
// Solidity Interface
contract UniswapFactoryInterface {
// Public Variables
address public exchangeTemplate;
uint256 public tokenCount;
// // Create Exchange
function createExchange(address token) external returns (address exchange);
// Get Exchange and Token Info
function getExchange(address token) external view returns (address exchange);
function getToken(address exchange) external view returns (address token);
function getTokenWithId(uint256 tokenId) external view returns (address token);
// Never use
function initializeFactory(address template) external;
// function createExchange(address token) external returns (address exchange) {
// return 0x06D014475F84Bb45b9cdeD1Cf3A1b8FE3FbAf128;
// }
// // Get Exchange and Token Info
// function getExchange(address token) external view returns (address exchange){
// return 0x06D014475F84Bb45b9cdeD1Cf3A1b8FE3FbAf128;
// }
// function getToken(address exchange) external view returns (address token) {
// return 0x06D014475F84Bb45b9cdeD1Cf3A1b8FE3FbAf128;
// }
// function getTokenWithId(uint256 tokenId) external view returns (address token) {
// return 0x06D014475F84Bb45b9cdeD1Cf3A1b8FE3FbAf128;
// }
}
// File: contracts/OptionsUtils.sol
pragma solidity 0.5.10;
contract OptionsUtils {
// defauls are for mainnet
UniswapFactoryInterface public UNISWAP_FACTORY;
CompoundOracleInterface public COMPOUND_ORACLE;
constructor(address _uniswapFactory, address _compoundOracle) public {
UNISWAP_FACTORY = UniswapFactoryInterface(_uniswapFactory);
COMPOUND_ORACLE = CompoundOracleInterface(_compoundOracle);
}
// TODO: for now gets Uniswap, later update to get other exchanges
function getExchange(address _token)
public
view
returns (UniswapExchangeInterface)
{
if (address(UNISWAP_FACTORY.getExchange(_token)) == address(0)) {
revert("No payout exchange");
}
UniswapExchangeInterface exchange = UniswapExchangeInterface(
UNISWAP_FACTORY.getExchange(_token)
);
return exchange;
}
function isETH(IERC20 _ierc20) public pure returns (bool) {
return _ierc20 == IERC20(0);
}
}
// File: contracts/OptionsExchange.sol
pragma solidity 0.5.10;
contract OptionsExchange {
uint256 constant LARGE_BLOCK_SIZE = 1651753129000;
uint256 constant LARGE_APPROVAL_NUMBER = 10**30;
UniswapFactoryInterface public UNISWAP_FACTORY;
constructor(address _uniswapFactory) public {
UNISWAP_FACTORY = UniswapFactoryInterface(_uniswapFactory);
}
/*** Events ***/
event SellOTokens(
address seller,
address payable receiver,
address oTokenAddress,
address payoutTokenAddress,
uint256 oTokensToSell,
uint256 payoutTokensReceived
);
event BuyOTokens(
address buyer,
address payable receiver,
address oTokenAddress,
address paymentTokenAddress,
uint256 oTokensToBuy,
uint256 premiumPaid
);
/**
* @notice This function sells oTokens on Uniswap and sends back payoutTokens to the receiver
* @param receiver The address to send the payout tokens back to
* @param oTokenAddress The address of the oToken to sell
* @param payoutTokenAddress The address of the token to receive the premiums in
* @param oTokensToSell The number of oTokens to sell
*/
function sellOTokens(
address payable receiver,
address oTokenAddress,
address payoutTokenAddress,
uint256 oTokensToSell
) public {
// @note: first need to bootstrap the uniswap exchange to get the address.
IERC20 oToken = IERC20(oTokenAddress);
IERC20 payoutToken = IERC20(payoutTokenAddress);
oToken.transferFrom(msg.sender, address(this), oTokensToSell);
uint256 payoutTokensReceived = uniswapSellOToken(
oToken,
payoutToken,
oTokensToSell,
receiver
);
emit SellOTokens(
msg.sender,
receiver,
oTokenAddress,
payoutTokenAddress,
oTokensToSell,
payoutTokensReceived
);
}
/**
* @notice This function buys oTokens on Uniswap and using paymentTokens from the receiver
* @param receiver The address to send the oTokens back to
* @param oTokenAddress The address of the oToken to buy
* @param paymentTokenAddress The address of the token to pay the premiums in
* @param oTokensToBuy The number of oTokens to buy
*/
function buyOTokens(
address payable receiver,
address oTokenAddress,
address paymentTokenAddress,
uint256 oTokensToBuy
) public payable {
IERC20 oToken = IERC20(oTokenAddress);
IERC20 paymentToken = IERC20(paymentTokenAddress);
uniswapBuyOToken(paymentToken, oToken, oTokensToBuy, receiver);
}
/**
* @notice This function calculates the amount of premiums that the seller
* will receive if they sold oTokens on Uniswap
* @param oTokenAddress The address of the oToken to sell
* @param payoutTokenAddress The address of the token to receive the premiums in
* @param oTokensToSell The number of oTokens to sell
*/
function premiumReceived(
address oTokenAddress,
address payoutTokenAddress,
uint256 oTokensToSell
) public view returns (uint256) {
// get the amount of ETH that will be paid out if oTokensToSell is sold.
UniswapExchangeInterface oTokenExchange = getExchange(oTokenAddress);
uint256 ethReceived = oTokenExchange.getTokenToEthInputPrice(
oTokensToSell
);
if (!isETH(IERC20(payoutTokenAddress))) {
// get the amount of payout tokens that will be received if the ethRecieved is sold.
UniswapExchangeInterface payoutExchange = getExchange(
payoutTokenAddress
);
return payoutExchange.getEthToTokenInputPrice(ethReceived);
}
return ethReceived;
}
/**
* @notice This function calculates the premiums to be paid if a buyer wants to
* buy oTokens on Uniswap
* @param oTokenAddress The address of the oToken to buy
* @param paymentTokenAddress The address of the token to pay the premiums in
* @param oTokensToBuy The number of oTokens to buy
*/
function premiumToPay(
address oTokenAddress,
address paymentTokenAddress,
uint256 oTokensToBuy
) public view returns (uint256) {
// get the amount of ETH that needs to be paid for oTokensToBuy.
UniswapExchangeInterface oTokenExchange = getExchange(oTokenAddress);
uint256 ethToPay = oTokenExchange.getEthToTokenOutputPrice(
oTokensToBuy
);
if (!isETH(IERC20(paymentTokenAddress))) {
// get the amount of paymentTokens that needs to be paid to get the desired ethToPay.
UniswapExchangeInterface paymentTokenExchange = getExchange(
paymentTokenAddress
);
return paymentTokenExchange.getTokenToEthOutputPrice(ethToPay);
}
return ethToPay;
}
function uniswapSellOToken(
IERC20 oToken,
IERC20 payoutToken,
uint256 _amt,
address payable _transferTo
) internal returns (uint256) {
require(!isETH(oToken), "Can only sell oTokens");
UniswapExchangeInterface exchange = getExchange(address(oToken));
if (isETH(payoutToken)) {
//Token to ETH
oToken.approve(address(exchange), _amt);
return
exchange.tokenToEthTransferInput(
_amt,
1,
LARGE_BLOCK_SIZE,
_transferTo
);
} else {
//Token to Token
oToken.approve(address(exchange), _amt);
return
exchange.tokenToTokenTransferInput(
_amt,
1,
1,
LARGE_BLOCK_SIZE,
_transferTo,
address(payoutToken)
);
}
}
function uniswapBuyOToken(
IERC20 paymentToken,
IERC20 oToken,
uint256 _amt,
address payable _transferTo
) public returns (uint256) {
require(!isETH(oToken), "Can only buy oTokens");
if (!isETH(paymentToken)) {
UniswapExchangeInterface exchange = getExchange(
address(paymentToken)
);
uint256 paymentTokensToTransfer = premiumToPay(
address(oToken),
address(paymentToken),
_amt
);
paymentToken.transferFrom(
msg.sender,
address(this),
paymentTokensToTransfer
);
// Token to Token
paymentToken.approve(address(exchange), LARGE_APPROVAL_NUMBER);
emit BuyOTokens(
msg.sender,
_transferTo,
address(oToken),
address(paymentToken),
_amt,
paymentTokensToTransfer
);
return
exchange.tokenToTokenTransferInput(
paymentTokensToTransfer,
1,
1,
LARGE_BLOCK_SIZE,
_transferTo,
address(oToken)
);
} else {
// ETH to Token
UniswapExchangeInterface exchange = UniswapExchangeInterface(
UNISWAP_FACTORY.getExchange(address(oToken))
);
uint256 ethToTransfer = exchange.getEthToTokenOutputPrice(_amt);
emit BuyOTokens(
msg.sender,
_transferTo,
address(oToken),
address(paymentToken),
_amt,
ethToTransfer
);
return
exchange.ethToTokenTransferOutput.value(ethToTransfer)(
_amt,
LARGE_BLOCK_SIZE,
_transferTo
);
}
}
function getExchange(address _token)
internal
view
returns (UniswapExchangeInterface)
{
UniswapExchangeInterface exchange = UniswapExchangeInterface(
UNISWAP_FACTORY.getExchange(_token)
);
if (address(exchange) == address(0)) {
revert("No payout exchange");
}
return exchange;
}
function isETH(IERC20 _ierc20) internal pure returns (bool) {
return _ierc20 == IERC20(0);
}
function() external payable {
// to get ether from uniswap exchanges
}
}
// File: @openzeppelin/contracts/token/ERC20/ERC20Detailed.sol
pragma solidity ^0.5.0;
/**
* @dev Optional functions from the ERC20 standard.
*/
contract ERC20Detailed is IERC20 {
string private _name;
string private _symbol;
uint8 private _decimals;
/**
* @dev Sets the values for `name`, `symbol`, and `decimals`. All three of
* these values are immutable: they can only be set once during
* construction.
*/
constructor (string memory name, string memory symbol, uint8 decimals) public {
_name = name;
_symbol = symbol;
_decimals = decimals;
}
/**
* @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.
*
* 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;
}
}
// File: @openzeppelin/contracts/ownership/Ownable.sol
pragma solidity ^0.5.0;
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor () internal {
_owner = _msgSender();
emit OwnershipTransferred(address(0), _owner);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(isOwner(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Returns true if the caller is the current owner.
*/
function isOwner() public view returns (bool) {
return _msgSender() == _owner;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public onlyOwner {
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
*/
function _transferOwnership(address newOwner) internal {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
// File: contracts/OptionsContract.sol
pragma solidity 0.5.10;
/**
* @title Opyn's Options Contract
* @author Opyn
*/
contract OptionsContract is Ownable, ERC20 {
using SafeMath for uint256;
/* represents floting point numbers, where number = value * 10 ** exponent
i.e 0.1 = 10 * 10 ** -3 */
struct Number {
uint256 value;
int32 exponent;
}
// Keeps track of the weighted collateral and weighted debt for each vault.
struct Vault {
uint256 collateral;
uint256 oTokensIssued;
uint256 underlying;
bool owned;
}
OptionsExchange public optionsExchange;
mapping(address => Vault) internal vaults;
address payable[] internal vaultOwners;
// 10 is 0.01 i.e. 1% incentive.
Number public liquidationIncentive = Number(10, -3);
// 100 is egs. 0.1 i.e. 10%.
Number public transactionFee = Number(0, -3);
/* 500 is 0.5. Max amount that a Vault can be liquidated by i.e.
max collateral that can be taken in one function call */
Number public liquidationFactor = Number(500, -3);
/* 16 means 1.6. The minimum ratio of a Vault's collateral to insurance promised.
The ratio is calculated as below:
vault.collateral / (Vault.oTokensIssued * strikePrice) */
Number public minCollateralizationRatio = Number(16, -1);
// The amount of insurance promised per oToken
Number public strikePrice;
// The amount of underlying that 1 oToken protects.
Number public oTokenExchangeRate;
/* UNIX time.
Exercise period starts at `(expiry - windowSize)` and ends at `expiry` */
uint256 internal windowSize;
/* The total fees accumulated in the contract any time liquidate or exercise is called */
uint256 internal totalFee;
// The time of expiry of the options contract
uint256 public expiry;
// The precision of the collateral
int32 public collateralExp = -18;
// The precision of the underlying
int32 public underlyingExp = -18;
// The collateral asset
IERC20 public collateral;
// The asset being protected by the insurance
IERC20 public underlying;
// The asset in which insurance is denominated in.
IERC20 public strike;
// The Oracle used for the contract
CompoundOracleInterface public COMPOUND_ORACLE;
// The name of the contract
string public name;
// The symbol of the contract
string public symbol;
// The number of decimals of the contract
uint8 public decimals;
/**
* @param _collateral The collateral asset
* @param _collExp The precision of the collateral (-18 if ETH)
* @param _underlying The asset that is being protected
* @param _underlyingExp The precision of the underlying asset
* @param _oTokenExchangeExp The precision of the `amount of underlying` that 1 oToken protects
* @param _strikePrice The amount of strike asset that will be paid out per oToken
* @param _strikeExp The precision of the strike price.
* @param _strike The asset in which the insurance is calculated
* @param _expiry The time at which the insurance expires
* @param _optionsExchange The contract which interfaces with the exchange + oracle
* @param _oracleAddress The address of the oracle
* @param _windowSize UNIX time. Exercise window is from `expiry - _windowSize` to `expiry`.
*/
constructor(
IERC20 _collateral,
int32 _collExp,
IERC20 _underlying,
int32 _underlyingExp,
int32 _oTokenExchangeExp,
uint256 _strikePrice,
int32 _strikeExp,
IERC20 _strike,
uint256 _expiry,
OptionsExchange _optionsExchange,
address _oracleAddress,
uint256 _windowSize
) public {
require(block.timestamp < _expiry, "Can't deploy an expired contract");
require(
_windowSize <= _expiry,
"Exercise window can't be longer than the contract's lifespan"
);
require(
isWithinExponentRange(_collExp),
"collateral exponent not within expected range"
);
require(
isWithinExponentRange(_underlyingExp),
"underlying exponent not within expected range"
);
require(
isWithinExponentRange(_strikeExp),
"strike price exponent not within expected range"
);
require(
isWithinExponentRange(_oTokenExchangeExp),
"oToken exchange rate exponent not within expected range"
);
collateral = _collateral;
collateralExp = _collExp;
underlying = _underlying;
underlyingExp = _underlyingExp;
oTokenExchangeRate = Number(1, _oTokenExchangeExp);
strikePrice = Number(_strikePrice, _strikeExp);
strike = _strike;
expiry = _expiry;
COMPOUND_ORACLE = CompoundOracleInterface(_oracleAddress);
optionsExchange = _optionsExchange;
windowSize = _windowSize;
}
/*** Events ***/
event VaultOpened(address payable vaultOwner);
event ETHCollateralAdded(
address payable vaultOwner,
uint256 amount,
address payer
);
event ERC20CollateralAdded(
address payable vaultOwner,
uint256 amount,
address payer
);
event IssuedOTokens(
address issuedTo,
uint256 oTokensIssued,
address payable vaultOwner
);
event Liquidate(
uint256 amtCollateralToPay,
address payable vaultOwner,
address payable liquidator
);
event Exercise(
uint256 amtUnderlyingToPay,
uint256 amtCollateralToPay,
address payable exerciser,
address payable vaultExercisedFrom
);
event RedeemVaultBalance(
uint256 amtCollateralRedeemed,
uint256 amtUnderlyingRedeemed,
address payable vaultOwner
);
event BurnOTokens(address payable vaultOwner, uint256 oTokensBurned);
event RemoveCollateral(uint256 amtRemoved, address payable vaultOwner);
event UpdateParameters(
uint256 liquidationIncentive,
uint256 liquidationFactor,
uint256 transactionFee,
uint256 minCollateralizationRatio,
address owner
);
event TransferFee(address payable to, uint256 fees);
event RemoveUnderlying(
uint256 amountUnderlying,
address payable vaultOwner
);
/**
* @dev Throws if called Options contract is expired.
*/
modifier notExpired() {
require(!hasExpired(), "Options contract expired");
_;
}
/**
* @notice This function gets the array of vaultOwners
*/
function getVaultOwners() public view returns (address payable[] memory) {
address payable[] memory owners;
uint256 index = 0;
for (uint256 i = 0; i < vaultOwners.length; i++) {
if (hasVault(vaultOwners[i])) {
owners[index] = vaultOwners[i];
index++;
}
}
return owners;
}
/**
* @notice Can only be called by owner. Used to update the fees, minminCollateralizationRatio, etc
* @param _liquidationIncentive The incentive paid to liquidator. 10 is 0.01 i.e. 1% incentive.
* @param _liquidationFactor Max amount that a Vault can be liquidated by. 500 is 0.5.
* @param _transactionFee The fees paid to our protocol every time a execution happens. 100 is egs. 0.1 i.e. 10%.
* @param _minCollateralizationRatio The minimum ratio of a Vault's collateral to insurance promised. 16 means 1.6.
*/
function updateParameters(
uint256 _liquidationIncentive,
uint256 _liquidationFactor,
uint256 _transactionFee,
uint256 _minCollateralizationRatio
) public onlyOwner {
require(
_liquidationIncentive <= 200,
"Can't have >20% liquidation incentive"
);
require(
_liquidationFactor <= 1000,
"Can't liquidate more than 100% of the vault"
);
require(_transactionFee <= 100, "Can't have transaction fee > 10%");
require(
_minCollateralizationRatio >= 10,
"Can't have minCollateralizationRatio < 1"
);
liquidationIncentive.value = _liquidationIncentive;
liquidationFactor.value = _liquidationFactor;
transactionFee.value = _transactionFee;
minCollateralizationRatio.value = _minCollateralizationRatio;
emit UpdateParameters(
_liquidationIncentive,
_liquidationFactor,
_transactionFee,
_minCollateralizationRatio,
owner()
);
}
/**
* @notice Can only be called by owner. Used to set the name, symbol and decimals of the contract
* @param _name The name of the contract
* @param _symbol The symbol of the contract
*/
function setDetails(string memory _name, string memory _symbol)
public
onlyOwner
{
name = _name;
symbol = _symbol;
decimals = uint8(-1 * oTokenExchangeRate.exponent);
require(
decimals >= 0,
"1 oToken cannot protect less than the smallest unit of the asset"
);
}
/**
* @notice Can only be called by owner. Used to take out the protocol fees from the contract.
* @param _address The address to send the fee to.
*/
function transferFee(address payable _address) public onlyOwner {
uint256 fees = totalFee;
totalFee = 0;
transferCollateral(_address, fees);
emit TransferFee(_address, fees);
}
/**
* @notice Checks if a `owner` has already created a Vault
* @param owner The address of the supposed owner
* @return true or false
*/
function hasVault(address payable owner) public view returns (bool) {
return vaults[owner].owned;
}
/**
* @notice Creates a new empty Vault and sets the owner of the vault to be the msg.sender.
*/
function openVault() public notExpired returns (bool) {
require(!hasVault(msg.sender), "Vault already created");
vaults[msg.sender] = Vault(0, 0, 0, true);
vaultOwners.push(msg.sender);
emit VaultOpened(msg.sender);
return true;
}
/**
* @notice If the collateral type is ETH, anyone can call this function any time before
* expiry to increase the amount of collateral in a Vault. Will fail if ETH is not the
* collateral asset.
* Remember that adding ETH collateral even if no oTokens have been created can put the owner at a
* risk of losing the collateral if an exercise event happens.
* Ensure that you issue and immediately sell oTokens to allow the owner to earn premiums.
* (Either call the createAndSell function in the oToken contract or batch the
* addERC20Collateral, issueOTokens and sell transactions and ensure they happen atomically to protect
* the end user).
* @param vaultOwner the index of the Vault to which collateral will be added.
*/
function addETHCollateral(address payable vaultOwner)
public
payable
notExpired
returns (uint256)
{
require(isETH(collateral), "ETH is not the specified collateral type");
require(hasVault(vaultOwner), "Vault does not exist");
emit ETHCollateralAdded(vaultOwner, msg.value, msg.sender);
return _addCollateral(vaultOwner, msg.value);
}
/**
* @notice If the collateral type is any ERC20, anyone can call this function any time before
* expiry to increase the amount of collateral in a Vault. Can only transfer in the collateral asset.
* Will fail if ETH is the collateral asset.
* The user has to allow the contract to handle their ERC20 tokens on his behalf before these
* functions are called.
* Remember that adding ERC20 collateral even if no oTokens have been created can put the owner at a
* risk of losing the collateral. Ensure that you issue and immediately sell the oTokens!
* (Either call the createAndSell function in the oToken contract or batch the
* addERC20Collateral, issueOTokens and sell transactions and ensure they happen atomically to protect
* the end user).
* @param vaultOwner the index of the Vault to which collateral will be added.
* @param amt the amount of collateral to be transferred in.
*/
function addERC20Collateral(address payable vaultOwner, uint256 amt)
public
notExpired
returns (uint256)
{
require(
collateral.transferFrom(msg.sender, address(this), amt),
"Could not transfer in collateral tokens"
);
require(hasVault(vaultOwner), "Vault does not exist");
emit ERC20CollateralAdded(vaultOwner, amt, msg.sender);
return _addCollateral(vaultOwner, amt);
}
/**
* @notice Returns the amount of underlying to be transferred during an exercise call
*/
function underlyingRequiredToExercise(uint256 oTokensToExercise)
public
view
returns (uint256)
{
uint64 underlyingPerOTokenExp = uint64(
oTokenExchangeRate.exponent - underlyingExp
);
return oTokensToExercise.mul(10**underlyingPerOTokenExp);
}
/**
* @notice Returns true if exercise can be called
*/
function isExerciseWindow() public view returns (bool) {
return ((block.timestamp >= expiry.sub(windowSize)) &&
(block.timestamp < expiry));
}
/**
* @notice Returns true if the oToken contract has expired
*/
function hasExpired() public view returns (bool) {
return (block.timestamp >= expiry);
}
/**
* @notice Called by anyone holding the oTokens and underlying during the
* exercise window i.e. from `expiry - windowSize` time to `expiry` time. The caller
* transfers in their oTokens and corresponding amount of underlying and gets
* `strikePrice * oTokens` amount of collateral out. The collateral paid out is taken from
* the each vault owner starting with the first and iterating until the oTokens to exercise
* are found.
* NOTE: This uses a for loop and hence could run out of gas if the array passed in is too big!
* @param oTokensToExercise the number of oTokens being exercised.
* @param vaultsToExerciseFrom the array of vaults to exercise from.
*/
function exercise(
uint256 oTokensToExercise,
address payable[] memory vaultsToExerciseFrom
) public payable {
for (uint256 i = 0; i < vaultsToExerciseFrom.length; i++) {
address payable vaultOwner = vaultsToExerciseFrom[i];
require(
hasVault(vaultOwner),
"Cannot exercise from a vault that doesn't exist"
);
Vault storage vault = vaults[vaultOwner];
if (oTokensToExercise == 0) {
return;
} else if (vault.oTokensIssued >= oTokensToExercise) {
_exercise(oTokensToExercise, vaultOwner);
return;
} else {
oTokensToExercise = oTokensToExercise.sub(vault.oTokensIssued);
_exercise(vault.oTokensIssued, vaultOwner);
}
}
require(
oTokensToExercise == 0,
"Specified vaults have insufficient collateral"
);
}
/**
* @notice This function allows the vault owner to remove their share of underlying after an exercise
*/
function removeUnderlying() public {
require(hasVault(msg.sender), "Vault does not exist");
Vault storage vault = vaults[msg.sender];
require(vault.underlying > 0, "No underlying balance");
uint256 underlyingToTransfer = vault.underlying;
vault.underlying = 0;
transferUnderlying(msg.sender, underlyingToTransfer);
emit RemoveUnderlying(underlyingToTransfer, msg.sender);
}
/**
* @notice This function is called to issue the option tokens. Remember that issuing oTokens even if they
* haven't been sold can put the owner at a risk of not making premiums on the oTokens. Ensure that you
* issue and immidiately sell the oTokens! (Either call the createAndSell function in the oToken contract
* of batch the issueOTokens transaction with a sell transaction and ensure it happens atomically).
* @dev The owner of a Vault should only be able to have a max of
* repo.collateral * collateralToStrike / (minminCollateralizationRatio * strikePrice) tokens issued.
* @param oTokensToIssue The number of o tokens to issue
* @param receiver The address to send the oTokens to
*/
function issueOTokens(uint256 oTokensToIssue, address receiver)
public
notExpired
{
//check that we're properly collateralized to mint this number, then call _mint(address account, uint256 amount)
require(hasVault(msg.sender), "Vault does not exist");
Vault storage vault = vaults[msg.sender];
// checks that the vault is sufficiently collateralized
uint256 newOTokensBalance = vault.oTokensIssued.add(oTokensToIssue);
require(isSafe(vault.collateral, newOTokensBalance), "unsafe to mint");
// issue the oTokens
vault.oTokensIssued = newOTokensBalance;
_mint(receiver, oTokensToIssue);
emit IssuedOTokens(receiver, oTokensToIssue, msg.sender);
return;
}
/**
* @notice Returns the vault for a given address
* @param vaultOwner the owner of the Vault to return
*/
function getVault(address payable vaultOwner)
public
view
returns (uint256, uint256, uint256, bool)
{
Vault storage vault = vaults[vaultOwner];
return (
vault.collateral,
vault.oTokensIssued,
vault.underlying,
vault.owned
);
}
/**
* @notice Returns true if the given ERC20 is ETH.
* @param _ierc20 the ERC20 asset.
*/
function isETH(IERC20 _ierc20) public pure returns (bool) {
return _ierc20 == IERC20(0);
}
/**
* @notice allows the owner to burn their oTokens to increase the collateralization ratio of
* their vault.
* @param amtToBurn number of oTokens to burn
* @dev only want to call this function before expiry. After expiry, no benefit to calling it.
*/
function burnOTokens(uint256 amtToBurn) public notExpired {
require(hasVault(msg.sender), "Vault does not exist");
Vault storage vault = vaults[msg.sender];
vault.oTokensIssued = vault.oTokensIssued.sub(amtToBurn);
_burn(msg.sender, amtToBurn);
emit BurnOTokens(msg.sender, amtToBurn);
}
/**
* @notice allows the owner to remove excess collateral from the vault before expiry. Removing collateral lowers
* the collateralization ratio of the vault.
* @param amtToRemove Amount of collateral to remove in 10^-18.
*/
function removeCollateral(uint256 amtToRemove) public notExpired {
require(amtToRemove > 0, "Cannot remove 0 collateral");
require(hasVault(msg.sender), "Vault does not exist");
Vault storage vault = vaults[msg.sender];
require(
amtToRemove <= getCollateral(msg.sender),
"Can't remove more collateral than owned"
);
// check that vault will remain safe after removing collateral
uint256 newCollateralBalance = vault.collateral.sub(amtToRemove);
require(
isSafe(newCollateralBalance, vault.oTokensIssued),
"Vault is unsafe"
);
// remove the collateral
vault.collateral = newCollateralBalance;
transferCollateral(msg.sender, amtToRemove);
emit RemoveCollateral(amtToRemove, msg.sender);
}
/**
* @notice after expiry, each vault holder can get back their proportional share of collateral
* from vaults that they own.
* @dev The owner gets all of their collateral back if no exercise event took their collateral.
*/
function redeemVaultBalance() public {
require(hasExpired(), "Can't collect collateral until expiry");
require(hasVault(msg.sender), "Vault does not exist");
// pay out owner their share
Vault storage vault = vaults[msg.sender];
// To deal with lower precision
uint256 collateralToTransfer = vault.collateral;
uint256 underlyingToTransfer = vault.underlying;
vault.collateral = 0;
vault.oTokensIssued = 0;
vault.underlying = 0;
transferCollateral(msg.sender, collateralToTransfer);
transferUnderlying(msg.sender, underlyingToTransfer);
emit RedeemVaultBalance(
collateralToTransfer,
underlyingToTransfer,
msg.sender
);
}
/**
* This function returns the maximum amount of collateral liquidatable if the given vault is unsafe
* @param vaultOwner The index of the vault to be liquidated
*/
function maxOTokensLiquidatable(address payable vaultOwner)
public
view
returns (uint256)
{
if (isUnsafe(vaultOwner)) {
Vault storage vault = vaults[vaultOwner];
uint256 maxCollateralLiquidatable = vault
.collateral
.mul(liquidationFactor.value)
.div(10**uint256(-liquidationFactor.exponent));
uint256 one = 10**uint256(-liquidationIncentive.exponent);
Number memory liqIncentive = Number(
liquidationIncentive.value.add(one),
liquidationIncentive.exponent
);
return calculateOTokens(maxCollateralLiquidatable, liqIncentive);
} else {
return 0;
}
}
/**
* @notice This function can be called by anyone who notices a vault is undercollateralized.
* The caller gets a reward for reducing the amount of oTokens in circulation.
* @dev Liquidator comes with _oTokens. They get _oTokens * strikePrice * (incentive + fee)
* amount of collateral out. They can liquidate a max of liquidationFactor * vault.collateral out
* in one function call i.e. partial liquidations.
* @param vaultOwner The index of the vault to be liquidated
* @param oTokensToLiquidate The number of oTokens being taken out of circulation
*/
function liquidate(address payable vaultOwner, uint256 oTokensToLiquidate)
public
notExpired
{
require(hasVault(vaultOwner), "Vault does not exist");
Vault storage vault = vaults[vaultOwner];
// cannot liquidate a safe vault.
require(isUnsafe(vaultOwner), "Vault is safe");
// Owner can't liquidate themselves
require(msg.sender != vaultOwner, "Owner can't liquidate themselves");
uint256 amtCollateral = calculateCollateralToPay(
oTokensToLiquidate,
Number(1, 0)
);
uint256 amtIncentive = calculateCollateralToPay(
oTokensToLiquidate,
liquidationIncentive
);
uint256 amtCollateralToPay = amtCollateral.add(amtIncentive);
// calculate the maximum amount of collateral that can be liquidated
uint256 maxCollateralLiquidatable = vault.collateral.mul(
liquidationFactor.value
);
if (liquidationFactor.exponent > 0) {
maxCollateralLiquidatable = maxCollateralLiquidatable.mul(
10**uint256(liquidationFactor.exponent)
);
} else {
maxCollateralLiquidatable = maxCollateralLiquidatable.div(
10**uint256(-1 * liquidationFactor.exponent)
);
}
require(
amtCollateralToPay <= maxCollateralLiquidatable,
"Can only liquidate liquidation factor at any given time"
);
// deduct the collateral and oTokensIssued
vault.collateral = vault.collateral.sub(amtCollateralToPay);
vault.oTokensIssued = vault.oTokensIssued.sub(oTokensToLiquidate);
// transfer the collateral and burn the _oTokens
_burn(msg.sender, oTokensToLiquidate);
transferCollateral(msg.sender, amtCollateralToPay);
emit Liquidate(amtCollateralToPay, vaultOwner, msg.sender);
}
/**
* @notice checks if a vault is unsafe. If so, it can be liquidated
* @param vaultOwner The number of the vault to check
* @return true or false
*/
function isUnsafe(address payable vaultOwner) public view returns (bool) {
bool stillUnsafe = !isSafe(
getCollateral(vaultOwner),
getOTokensIssued(vaultOwner)
);
return stillUnsafe;
}
/**
* @notice This function returns if an -30 <= exponent <= 30
*/
function isWithinExponentRange(int32 val) internal pure returns (bool) {
return ((val <= 30) && (val >= -30));
}
/**
* @notice This function calculates and returns the amount of collateral in the vault
*/
function getCollateral(address payable vaultOwner)
internal
view
returns (uint256)
{
Vault storage vault = vaults[vaultOwner];
return vault.collateral;
}
/**
* @notice This function calculates and returns the amount of puts issued by the Vault
*/
function getOTokensIssued(address payable vaultOwner)
internal
view
returns (uint256)
{
Vault storage vault = vaults[vaultOwner];
return vault.oTokensIssued;
}
/**
* @notice Called by anyone holding the oTokens and underlying during the
* exercise window i.e. from `expiry - windowSize` time to `expiry` time. The caller
* transfers in their oTokens and corresponding amount of underlying and gets
* `strikePrice * oTokens` amount of collateral out. The collateral paid out is taken from
* the specified vault holder. At the end of the expiry window, the vault holder can redeem their balance
* of collateral. The vault owner can withdraw their underlying at any time.
* The user has to allow the contract to handle their oTokens and underlying on his behalf before these functions are called.
* @param oTokensToExercise the number of oTokens being exercised.
* @param vaultToExerciseFrom the address of the vaultOwner to take collateral from.
* @dev oTokenExchangeRate is the number of underlying tokens that 1 oToken protects.
*/
function _exercise(
uint256 oTokensToExercise,
address payable vaultToExerciseFrom
) internal {
// 1. before exercise window: revert
require(
isExerciseWindow(),
"Can't exercise outside of the exercise window"
);
require(hasVault(vaultToExerciseFrom), "Vault does not exist");
Vault storage vault = vaults[vaultToExerciseFrom];
require(oTokensToExercise > 0, "Can't exercise 0 oTokens");
// Check correct amount of oTokens passed in)
require(
oTokensToExercise <= vault.oTokensIssued,
"Can't exercise more oTokens than the owner has"
);
// Ensure person calling has enough oTokens
require(
balanceOf(msg.sender) >= oTokensToExercise,
"Not enough oTokens"
);
// 1. Check sufficient underlying
// 1.1 update underlying balances
uint256 amtUnderlyingToPay = underlyingRequiredToExercise(
oTokensToExercise
);
vault.underlying = vault.underlying.add(amtUnderlyingToPay);
// 2. Calculate Collateral to pay
// 2.1 Payout enough collateral to get (strikePrice * oTokens) amount of collateral
uint256 amtCollateralToPay = calculateCollateralToPay(
oTokensToExercise,
Number(1, 0)
);
// 2.2 Take a small fee on every exercise
uint256 amtFee = calculateCollateralToPay(
oTokensToExercise,
transactionFee
);
totalFee = totalFee.add(amtFee);
uint256 totalCollateralToPay = amtCollateralToPay.add(amtFee);
require(
totalCollateralToPay <= vault.collateral,
"Vault underwater, can't exercise"
);
// 3. Update collateral + oToken balances
vault.collateral = vault.collateral.sub(totalCollateralToPay);
vault.oTokensIssued = vault.oTokensIssued.sub(oTokensToExercise);
// 4. Transfer in underlying, burn oTokens + pay out collateral
// 4.1 Transfer in underlying
if (isETH(underlying)) {
require(msg.value == amtUnderlyingToPay, "Incorrect msg.value");
} else {
require(
underlying.transferFrom(
msg.sender,
address(this),
amtUnderlyingToPay
),
"Could not transfer in tokens"
);
}
// 4.2 burn oTokens
_burn(msg.sender, oTokensToExercise);
// 4.3 Pay out collateral
transferCollateral(msg.sender, amtCollateralToPay);
emit Exercise(
amtUnderlyingToPay,
amtCollateralToPay,
msg.sender,
vaultToExerciseFrom
);
}
/**
* @notice adds `_amt` collateral to `vaultOwner` and returns the new balance of the vault
* @param vaultOwner the index of the vault
* @param amt the amount of collateral to add
*/
function _addCollateral(address payable vaultOwner, uint256 amt)
internal
notExpired
returns (uint256)
{
Vault storage vault = vaults[vaultOwner];
vault.collateral = vault.collateral.add(amt);
return vault.collateral;
}
/**
* @notice checks if a hypothetical vault is safe with the given collateralAmt and oTokensIssued
* @param collateralAmt The amount of collateral the hypothetical vault has
* @param oTokensIssued The amount of oTokens generated by the hypothetical vault
* @return true or false
*/
function isSafe(uint256 collateralAmt, uint256 oTokensIssued)
internal
view
returns (bool)
{
// get price from Oracle
uint256 collateralToEthPrice = getPrice(address(collateral));
uint256 strikeToEthPrice = getPrice(address(strike));
// check `oTokensIssued * minCollateralizationRatio * strikePrice <= collAmt * collateralToStrikePrice`
uint256 leftSideVal = oTokensIssued
.mul(minCollateralizationRatio.value)
.mul(strikePrice.value);
int32 leftSideExp = minCollateralizationRatio.exponent +
strikePrice.exponent;
uint256 rightSideVal = (collateralAmt.mul(collateralToEthPrice)).div(
strikeToEthPrice
);
int32 rightSideExp = collateralExp;
uint256 exp = 0;
bool stillSafe = false;
if (rightSideExp < leftSideExp) {
exp = uint256(leftSideExp - rightSideExp);
stillSafe = leftSideVal.mul(10**exp) <= rightSideVal;
} else {
exp = uint256(rightSideExp - leftSideExp);
stillSafe = leftSideVal <= rightSideVal.mul(10**exp);
}
return stillSafe;
}
/**
* This function returns the maximum amount of oTokens that can safely be issued against the specified amount of collateral.
* @param collateralAmt The amount of collateral against which oTokens will be issued.
*/
function maxOTokensIssuable(uint256 collateralAmt)
public
view
returns (uint256)
{
return calculateOTokens(collateralAmt, minCollateralizationRatio);
}
/**
* @notice This function is used to calculate the amount of tokens that can be issued.
* @dev The amount of oTokens is determined by:
* oTokensIssued <= collateralAmt * collateralToStrikePrice / (proportion * strikePrice)
* @param collateralAmt The amount of collateral
* @param proportion The proportion of the collateral to pay out. If 100% of collateral
* should be paid out, pass in Number(1, 0). The proportion might be less than 100% if
* you are calculating fees.
*/
function calculateOTokens(uint256 collateralAmt, Number memory proportion)
internal
view
returns (uint256)
{
uint256 collateralToEthPrice = getPrice(address(collateral));
uint256 strikeToEthPrice = getPrice(address(strike));
// oTokensIssued <= collAmt * collateralToStrikePrice / (proportion * strikePrice)
uint256 denomVal = proportion.value.mul(strikePrice.value);
int32 denomExp = proportion.exponent + strikePrice.exponent;
uint256 numeratorVal = (collateralAmt.mul(collateralToEthPrice)).div(
strikeToEthPrice
);
int32 numeratorExp = collateralExp;
uint256 exp = 0;
uint256 numOptions = 0;
if (numeratorExp < denomExp) {
exp = uint256(denomExp - numeratorExp);
numOptions = numeratorVal.div(denomVal.mul(10**exp));
} else {
exp = uint256(numeratorExp - denomExp);
numOptions = numeratorVal.mul(10**exp).div(denomVal);
}
return numOptions;
}
/**
* @notice This function calculates the amount of collateral to be paid out.
* @dev The amount of collateral to paid out is determined by:
* (proportion * strikePrice * strikeToCollateralPrice * oTokens) amount of collateral.
* @param _oTokens The number of oTokens.
* @param proportion The proportion of the collateral to pay out. If 100% of collateral
* should be paid out, pass in Number(1, 0). The proportion might be less than 100% if
* you are calculating fees.
*/
function calculateCollateralToPay(
uint256 _oTokens,
Number memory proportion
) internal view returns (uint256) {
// Get price from oracle
uint256 collateralToEthPrice = getPrice(address(collateral));
uint256 strikeToEthPrice = getPrice(address(strike));
// calculate how much should be paid out
uint256 amtCollateralToPayInEthNum = _oTokens
.mul(strikePrice.value)
.mul(proportion.value)
.mul(strikeToEthPrice);
int32 amtCollateralToPayExp = strikePrice.exponent +
proportion.exponent -
collateralExp;
uint256 amtCollateralToPay = 0;
if (amtCollateralToPayExp > 0) {
uint32 exp = uint32(amtCollateralToPayExp);
amtCollateralToPay = amtCollateralToPayInEthNum.mul(10**exp).div(
collateralToEthPrice
);
} else {
uint32 exp = uint32(-1 * amtCollateralToPayExp);
amtCollateralToPay = (amtCollateralToPayInEthNum.div(10**exp)).div(
collateralToEthPrice
);
}
return amtCollateralToPay;
}
/**
* @notice This function transfers `amt` collateral to `_addr`
* @param _addr The address to send the collateral to
* @param _amt The amount of the collateral to pay out.
*/
function transferCollateral(address payable _addr, uint256 _amt) internal {
if (isETH(collateral)) {
_addr.transfer(_amt);
} else {
collateral.transfer(_addr, _amt);
}
}
/**
* @notice This function transfers `amt` underlying to `_addr`
* @param _addr The address to send the underlying to
* @param _amt The amount of the underlying to pay out.
*/
function transferUnderlying(address payable _addr, uint256 _amt) internal {
if (isETH(underlying)) {
_addr.transfer(_amt);
} else {
underlying.transfer(_addr, _amt);
}
}
/**
* @notice This function gets the price ETH (wei) to asset price.
* @param asset The address of the asset to get the price of
*/
function getPrice(address asset) internal view returns (uint256) {
if (address(collateral) == address(strike)) {
return 1;
} else if (asset == address(0)) {
return (10**18);
} else {
return COMPOUND_ORACLE.getPrice(asset);
}
}
}
// File: contracts/oToken.sol
pragma solidity 0.5.10;
/**
* @title Opyn's Options Contract
* @author Opyn
*/
contract oToken is OptionsContract {
/**
* @param _collateral The collateral asset
* @param _collExp The precision of the collateral (-18 if ETH)
* @param _underlying The asset that is being protected
* @param _underlyingExp The precision of the underlying asset
* @param _oTokenExchangeExp The precision of the `amount of underlying` that 1 oToken protects
* @param _strikePrice The amount of strike asset that will be paid out
* @param _strikeExp The precision of the strike asset (-18 if ETH)
* @param _strike The asset in which the insurance is calculated
* @param _expiry The time at which the insurance expires
* @param _optionsExchange The contract which interfaces with the exchange + oracle
* @param _oracleAddress The address of the oracle
* @param _windowSize UNIX time. Exercise window is from `expiry - _windowSize` to `expiry`.
*/
constructor(
IERC20 _collateral,
int32 _collExp,
IERC20 _underlying,
int32 _underlyingExp,
int32 _oTokenExchangeExp,
uint256 _strikePrice,
int32 _strikeExp,
IERC20 _strike,
uint256 _expiry,
OptionsExchange _optionsExchange,
address _oracleAddress,
uint256 _windowSize
)
public
OptionsContract(
_collateral,
_collExp,
_underlying,
_underlyingExp,
_oTokenExchangeExp,
_strikePrice,
_strikeExp,
_strike,
_expiry,
_optionsExchange,
_oracleAddress,
_windowSize
)
{}
/**
* @notice opens a Vault, adds ETH collateral, and mints new oTokens in one step
* Remember that creating oTokens can put the owner at a risk of losing the collateral
* if an exercise event happens.
* The sell function provides the owner a chance to earn premiums.
* Ensure that you create and immediately sell oTokens atmoically.
* @param amtToCreate number of oTokens to create
* @param receiver address to send the Options to
*/
function createETHCollateralOption(uint256 amtToCreate, address receiver)
external
payable
{
openVault();
addETHCollateralOption(amtToCreate, receiver);
}
/**
* @notice adds ETH collateral, and mints new oTokens in one step to an existing Vault
* Remember that creating oTokens can put the owner at a risk of losing the collateral
* if an exercise event happens.
* The sell function provides the owner a chance to earn premiums.
* Ensure that you create and immediately sell oTokens atmoically.
* @param amtToCreate number of oTokens to create
* @param receiver address to send the Options to
*/
function addETHCollateralOption(uint256 amtToCreate, address receiver)
public
payable
{
addETHCollateral(msg.sender);
issueOTokens(amtToCreate, receiver);
}
/**
* @notice opens a Vault, adds ETH collateral, mints new oTokens and sell in one step
* @param amtToCreate number of oTokens to create
* @param receiver address to receive the premiums
*/
function createAndSellETHCollateralOption(
uint256 amtToCreate,
address payable receiver
) external payable {
openVault();
addETHCollateralOption(amtToCreate, address(this));
this.approve(address(optionsExchange), amtToCreate);
optionsExchange.sellOTokens(
receiver,
address(this),
address(0),
amtToCreate
);
}
/**
* @notice adds ETH collateral to an existing Vault, and mints new oTokens and sells the oTokens in one step
* @param amtToCreate number of oTokens to create
* @param receiver address to send the Options to
*/
function addAndSellETHCollateralOption(
uint256 amtToCreate,
address payable receiver
) public payable {
addETHCollateral(msg.sender);
issueOTokens(amtToCreate, address(this));
this.approve(address(optionsExchange), amtToCreate);
optionsExchange.sellOTokens(
receiver,
address(this),
address(0),
amtToCreate
);
}
/**
* @notice opens a Vault, adds ERC20 collateral, and mints new oTokens in one step
* Remember that creating oTokens can put the owner at a risk of losing the collateral
* if an exercise event happens.
* The sell function provides the owner a chance to earn premiums.
* Ensure that you create and immediately sell oTokens atmoically.
* @param amtToCreate number of oTokens to create
* @param amtCollateral amount of collateral added
* @param receiver address to send the Options to
*/
function createERC20CollateralOption(
uint256 amtToCreate,
uint256 amtCollateral,
address receiver
) external {
openVault();
addERC20CollateralOption(amtToCreate, amtCollateral, receiver);
}
/**
* @notice adds ERC20 collateral, and mints new oTokens in one step
* Remember that creating oTokens can put the owner at a risk of losing the collateral
* if an exercise event happens.
* The sell function provides the owner a chance to earn premiums.
* Ensure that you create and immediately sell oTokens atmoically.
* @param amtToCreate number of oTokens to create
* @param amtCollateral amount of collateral added
* @param receiver address to send the Options to
*/
function addERC20CollateralOption(
uint256 amtToCreate,
uint256 amtCollateral,
address receiver
) public {
addERC20Collateral(msg.sender, amtCollateral);
issueOTokens(amtToCreate, receiver);
}
/**
* @notice opens a Vault, adds ERC20 collateral, mints new oTokens and sells the oTokens in one step
* @param amtToCreate number of oTokens to create
* @param amtCollateral amount of collateral added
* @param receiver address to send the Options to
*/
function createAndSellERC20CollateralOption(
uint256 amtToCreate,
uint256 amtCollateral,
address payable receiver
) external {
openVault();
addERC20CollateralOption(amtToCreate, amtCollateral, address(this));
this.approve(address(optionsExchange), amtToCreate);
optionsExchange.sellOTokens(
receiver,
address(this),
address(0),
amtToCreate
);
}
/**
* @notice adds ERC20 collateral, mints new oTokens and sells the oTokens in one step
* @param amtToCreate number of oTokens to create
* @param amtCollateral amount of collateral added
* @param receiver address to send the Options to
*/
function addAndSellERC20CollateralOption(
uint256 amtToCreate,
uint256 amtCollateral,
address payable receiver
) public {
addERC20Collateral(msg.sender, amtCollateral);
issueOTokens(amtToCreate, address(this));
this.approve(address(optionsExchange), amtToCreate);
optionsExchange.sellOTokens(
receiver,
address(this),
address(0),
amtToCreate
);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"constant":false,"inputs":[{"name":"vaultOwner","type":"address"},{"name":"amt","type":"uint256"}],"name":"addERC20Collateral","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getVaultOwners","outputs":[{"name":"","type":"address[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"amount","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"hasVault","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isExerciseWindow","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"vaultOwner","type":"address"}],"name":"getVault","outputs":[{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"uint256"},{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"oTokensToIssue","type":"uint256"},{"name":"receiver","type":"address"}],"name":"issueOTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"sender","type":"address"},{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"amtToCreate","type":"uint256"},{"name":"amtCollateral","type":"uint256"},{"name":"receiver","type":"address"}],"name":"addAndSellERC20CollateralOption","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"amtToRemove","type":"uint256"}],"name":"removeCollateral","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"liquidationFactor","outputs":[{"name":"value","type":"uint256"},{"name":"exponent","type":"int32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"amtToCreate","type":"uint256"},{"name":"receiver","type":"address"}],"name":"createAndSellETHCollateralOption","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"optionsExchange","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"amtToCreate","type":"uint256"},{"name":"amtCollateral","type":"uint256"},{"name":"receiver","type":"address"}],"name":"createERC20CollateralOption","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"oTokensToExercise","type":"uint256"},{"name":"vaultsToExerciseFrom","type":"address[]"}],"name":"exercise","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"amtToCreate","type":"uint256"},{"name":"amtCollateral","type":"uint256"},{"name":"receiver","type":"address"}],"name":"addERC20CollateralOption","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"collateralAmt","type":"uint256"}],"name":"maxOTokensIssuable","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"underlying","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"oTokensToExercise","type":"uint256"}],"name":"underlyingRequiredToExercise","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"openVault","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"COMPOUND_ORACLE","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"liquidationIncentive","outputs":[{"name":"value","type":"uint256"},{"name":"exponent","type":"int32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"hasExpired","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"vaultOwner","type":"address"}],"name":"addETHCollateral","outputs":[{"name":"","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"transactionFee","outputs":[{"name":"value","type":"uint256"},{"name":"exponent","type":"int32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"strike","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"underlyingExp","outputs":[{"name":"","type":"int32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"collateralExp","outputs":[{"name":"","type":"int32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"oTokenExchangeRate","outputs":[{"name":"value","type":"uint256"},{"name":"exponent","type":"int32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"redeemVaultBalance","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_symbol","type":"string"}],"name":"setDetails","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"amtToCreate","type":"uint256"},{"name":"receiver","type":"address"}],"name":"addETHCollateralOption","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"minCollateralizationRatio","outputs":[{"name":"value","type":"uint256"},{"name":"exponent","type":"int32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"vaultOwner","type":"address"},{"name":"oTokensToLiquidate","type":"uint256"}],"name":"liquidate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"strikePrice","outputs":[{"name":"value","type":"uint256"},{"name":"exponent","type":"int32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"amtToCreate","type":"uint256"},{"name":"amtCollateral","type":"uint256"},{"name":"receiver","type":"address"}],"name":"createAndSellERC20CollateralOption","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"vaultOwner","type":"address"}],"name":"isUnsafe","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"amtToCreate","type":"uint256"},{"name":"receiver","type":"address"}],"name":"addAndSellETHCollateralOption","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"collateral","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"vaultOwner","type":"address"}],"name":"maxOTokensLiquidatable","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"expiry","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_address","type":"address"}],"name":"transferFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"amtToBurn","type":"uint256"}],"name":"burnOTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"amtToCreate","type":"uint256"},{"name":"receiver","type":"address"}],"name":"createETHCollateralOption","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_liquidationIncentive","type":"uint256"},{"name":"_liquidationFactor","type":"uint256"},{"name":"_transactionFee","type":"uint256"},{"name":"_minCollateralizationRatio","type":"uint256"}],"name":"updateParameters","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_ierc20","type":"address"}],"name":"isETH","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[],"name":"removeUnderlying","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_collateral","type":"address"},{"name":"_collExp","type":"int32"},{"name":"_underlying","type":"address"},{"name":"_underlyingExp","type":"int32"},{"name":"_oTokenExchangeExp","type":"int32"},{"name":"_strikePrice","type":"uint256"},{"name":"_strikeExp","type":"int32"},{"name":"_strike","type":"address"},{"name":"_expiry","type":"uint256"},{"name":"_optionsExchange","type":"address"},{"name":"_oracleAddress","type":"address"},{"name":"_windowSize","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"vaultOwner","type":"address"}],"name":"VaultOpened","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"vaultOwner","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"payer","type":"address"}],"name":"ETHCollateralAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"vaultOwner","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"payer","type":"address"}],"name":"ERC20CollateralAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"issuedTo","type":"address"},{"indexed":false,"name":"oTokensIssued","type":"uint256"},{"indexed":false,"name":"vaultOwner","type":"address"}],"name":"IssuedOTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amtCollateralToPay","type":"uint256"},{"indexed":false,"name":"vaultOwner","type":"address"},{"indexed":false,"name":"liquidator","type":"address"}],"name":"Liquidate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amtUnderlyingToPay","type":"uint256"},{"indexed":false,"name":"amtCollateralToPay","type":"uint256"},{"indexed":false,"name":"exerciser","type":"address"},{"indexed":false,"name":"vaultExercisedFrom","type":"address"}],"name":"Exercise","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amtCollateralRedeemed","type":"uint256"},{"indexed":false,"name":"amtUnderlyingRedeemed","type":"uint256"},{"indexed":false,"name":"vaultOwner","type":"address"}],"name":"RedeemVaultBalance","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"vaultOwner","type":"address"},{"indexed":false,"name":"oTokensBurned","type":"uint256"}],"name":"BurnOTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amtRemoved","type":"uint256"},{"indexed":false,"name":"vaultOwner","type":"address"}],"name":"RemoveCollateral","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"liquidationIncentive","type":"uint256"},{"indexed":false,"name":"liquidationFactor","type":"uint256"},{"indexed":false,"name":"transactionFee","type":"uint256"},{"indexed":false,"name":"minCollateralizationRatio","type":"uint256"},{"indexed":false,"name":"owner","type":"address"}],"name":"UpdateParameters","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"to","type":"address"},{"indexed":false,"name":"fees","type":"uint256"}],"name":"TransferFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amountUnderlying","type":"uint256"},{"indexed":false,"name":"vaultOwner","type":"address"}],"name":"RemoveUnderlying","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]Contract Creation Code
600a608081905260021960a081905260078290556008805463ffffffff1990811663fffffffd908117909255600060c081905260e08490526009558354811682179093556101f461010081905261012092909252600b91909155600c805483169091179055610180604052601061014081905260001961016052600d55600e805463ffffffff9083161790556016805490911663ffffffee1763ffffffff60201b191667ffffffee00000000179055348015620000bb57600080fd5b506040516200489c3803806200489c8339818101604052610180811015620000e257600080fd5b508051602082015160408301516060840151608085015160a086015160c087015160e08801516101008901516101208a01516101408b0151610160909b0151999a9899979896979596949593949293919290918b8b8b8b8b8b8b8b8b8b8b8b620001546001600160e01b03620005ec16565b600080546001600160a01b0319166001600160a01b03928316178082556040519216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38342106200020b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f43616e2774206465706c6f7920616e206578706972656420636f6e7472616374604482015290519081900360640190fd5b8381111562000266576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180620047a0603c913960400191505060405180910390fd5b6200027a8b6001600160e01b03620005f016565b620002d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d815260200180620047dc602d913960400191505060405180910390fd5b620002e5896001600160e01b03620005f016565b6200033c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d8152602001806200486f602d913960400191505060405180910390fd5b62000350866001600160e01b03620005f016565b620003a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f81526020018062004840602f913960400191505060405180910390fd5b620003bb886001600160e01b03620005f016565b62000412576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526037815260200180620048096037913960400191505060405180910390fd5b8b601660086101000a8154816001600160a01b0302191690836001600160a01b031602179055508a601660006101000a81548163ffffffff021916908360030b63ffffffff16021790555089601760006101000a8154816001600160a01b0302191690836001600160a01b0316021790555088601660046101000a81548163ffffffff021916908360030b63ffffffff1602179055506040518060400160405280600181526020018960030b81525060116000820151816000015560208201518160010160006101000a81548163ffffffff021916908360030b63ffffffff16021790555090505060405180604001604052808881526020018760030b815250600f6000820151816000015560208201518160010160006101000a81548163ffffffff021916908360030b63ffffffff16021790555090505084601860006101000a8154816001600160a01b0302191690836001600160a01b031602179055508360158190555081601960006101000a8154816001600160a01b0302191690836001600160a01b0316021790555082600460006101000a8154816001600160a01b0302191690836001600160a01b031602179055508060138190555050505050505050505050505050505050505050505050505062000612565b3390565b6000601e8260030b131580156200060c5750601d198260030b12155b92915050565b61417e80620006226000396000f3fe6080604052600436106103975760003560e01c806390e64d13116101dc578063c52987cf11610102578063e184c9be116100a0578063ee1eab4f1161006f578063ee1eab4f14610ed3578063f2fde38b14610f0f578063f70a250814610f42578063faa2041f14610f7557610397565b8063e184c9be14610e35578063ea8c4bcf14610e4a578063eaa376b514610e7d578063ed1f41c314610ea757610397565b8063cfbea789116100dc578063cfbea78914610d86578063d8dfeb4514610db2578063dd62ed3e14610dc7578063dec44c0b14610e0257610397565b8063c52987cf14610cff578063c56749ce14610d14578063cdb4b5c214610d5357610397565b8063b2c2b13f1161017a578063b7b090ee11610149578063b7b090ee14610b4f578063b96661ba14610c85578063ba1be55414610cb1578063bcbaf48714610cc657610397565b8063b2c2b13f14610ae2578063b6e61c0814610b10578063b736554014610b25578063b76fdb6c14610b3a57610397565b80639ed3edf0116101b65780639ed3edf014610a46578063a457c2d714610a5b578063a9059cbb14610a94578063ad8f500814610acd57610397565b806390e64d13146109f657806395d89b4114610a0b5780639ce0725114610a2057610397565b806339509351116102c15780636fd865f91161025f5780638a5e8cc71161022e5780638a5e8cc7146109a25780638c765e94146109b75780638da5cb5b146109cc5780638f32d59b146109e157610397565b80636fd865f91461091b57806370a0823114610945578063715018a61461097857806386f547121461098d57610397565b806358b36dac1161029b57806358b36dac146107f55780635ca7c8a61461089d578063686c1e21146108dc5780636f307dc31461090657610397565b8063395093511461074c5780633bd33f621461078557806352f89fe3146107b657610397565b806318160ddd116103395780633226052d116103085780633226052d146106845780633237c158146106c3578063352ade55146106ed5780633667429f1461072057610397565b806318160ddd146105c65780631a0e21bd146105db57806323b872dd14610616578063313ce5671461065957610397565b8063095ea7b311610375578063095ea7b3146104d65780630d453efb146105235780630d6cd8aa146105565780630eb9af381461056b57610397565b806301b4a3c11461039c578063060ab2ea146103e757806306fdde031461044c575b600080fd5b3480156103a857600080fd5b506103d5600480360360408110156103bf57600080fd5b506001600160a01b038135169060200135610f8a565b60408051918252519081900360200190f35b3480156103f357600080fd5b506103fc61113e565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610438578181015183820152602001610420565b505050509050019250505060405180910390f35b34801561045857600080fd5b506104616111e5565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561049b578181015183820152602001610483565b50505050905090810190601f1680156104c85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156104e257600080fd5b5061050f600480360360408110156104f957600080fd5b506001600160a01b038135169060200135611273565b604080519115158252519081900360200190f35b34801561052f57600080fd5b5061050f6004803603602081101561054657600080fd5b50356001600160a01b0316611290565b34801561056257600080fd5b5061050f6112b5565b34801561057757600080fd5b5061059e6004803603602081101561058e57600080fd5b50356001600160a01b03166112e3565b6040805194855260208501939093528383019190915215156060830152519081900360800190f35b3480156105d257600080fd5b506103d5611317565b3480156105e757600080fd5b50610614600480360360408110156105fe57600080fd5b50803590602001356001600160a01b031661131d565b005b34801561062257600080fd5b5061050f6004803603606081101561063957600080fd5b506001600160a01b03813581169160208101359091169060400135611486565b34801561066557600080fd5b5061066e611513565b6040805160ff9092168252519081900360200190f35b34801561069057600080fd5b50610614600480360360608110156106a757600080fd5b50803590602081013590604001356001600160a01b031661151c565b3480156106cf57600080fd5b50610614600480360360208110156106e657600080fd5b5035611634565b3480156106f957600080fd5b50610702611824565b60408051928352600391820b90910b60208301528051918290030190f35b6106146004803603604081101561073657600080fd5b50803590602001356001600160a01b0316611830565b34801561075857600080fd5b5061050f6004803603604081101561076f57600080fd5b506001600160a01b038135169060200135611945565b34801561079157600080fd5b5061079a611999565b604080516001600160a01b039092168252519081900360200190f35b3480156107c257600080fd5b50610614600480360360608110156107d957600080fd5b50803590602081013590604001356001600160a01b03166119a8565b6106146004803603604081101561080b57600080fd5b81359190810190604081016020820135600160201b81111561082c57600080fd5b82018360208201111561083e57600080fd5b803590602001918460208302840111600160201b8311171561085f57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506119c1945050505050565b3480156108a957600080fd5b50610614600480360360608110156108c057600080fd5b50803590602081013590604001356001600160a01b0316611ad9565b3480156108e857600080fd5b506103d5600480360360208110156108ff57600080fd5b5035611aee565b34801561091257600080fd5b5061079a611b1c565b34801561092757600080fd5b506103d56004803603602081101561093e57600080fd5b5035611b2b565b34801561095157600080fd5b506103d56004803603602081101561096857600080fd5b50356001600160a01b0316611b6f565b34801561098457600080fd5b50610614611b8a565b34801561099957600080fd5b5061050f611c1b565b3480156109ae57600080fd5b5061079a611d88565b3480156109c357600080fd5b50610702611d97565b3480156109d857600080fd5b5061079a611da3565b3480156109ed57600080fd5b5061050f611db2565b348015610a0257600080fd5b5061050f611dd6565b348015610a1757600080fd5b50610461611ddf565b6103d560048036036020811015610a3657600080fd5b50356001600160a01b0316611e3a565b348015610a5257600080fd5b50610702611f74565b348015610a6757600080fd5b5061050f60048036036040811015610a7e57600080fd5b506001600160a01b038135169060200135611f80565b348015610aa057600080fd5b5061050f60048036036040811015610ab757600080fd5b506001600160a01b038135169060200135611fee565b348015610ad957600080fd5b5061079a612002565b348015610aee57600080fd5b50610af7612011565b60408051600392830b90920b8252519081900360200190f35b348015610b1c57600080fd5b50610af7612021565b348015610b3157600080fd5b5061070261202a565b348015610b4657600080fd5b50610614612036565b348015610b5b57600080fd5b5061061460048036036040811015610b7257600080fd5b810190602081018135600160201b811115610b8c57600080fd5b820183602082011115610b9e57600080fd5b803590602001918460018302840111600160201b83111715610bbf57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b811115610c1157600080fd5b820183602082011115610c2357600080fd5b803590602001918460018302840111600160201b83111715610c4457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612142945050505050565b61061460048036036040811015610c9b57600080fd5b50803590602001356001600160a01b03166121d3565b348015610cbd57600080fd5b506107026121e7565b348015610cd257600080fd5b5061061460048036036040811015610ce957600080fd5b506001600160a01b0381351690602001356121f3565b348015610d0b57600080fd5b506107026124f7565b348015610d2057600080fd5b5061061460048036036060811015610d3757600080fd5b50803590602081013590604001356001600160a01b0316612503565b348015610d5f57600080fd5b5061050f60048036036020811015610d7657600080fd5b50356001600160a01b0316612517565b61061460048036036040811015610d9c57600080fd5b50803590602001356001600160a01b031661253c565b348015610dbe57600080fd5b5061079a612550565b348015610dd357600080fd5b506103d560048036036040811015610dea57600080fd5b506001600160a01b0381358116916020013516612566565b348015610e0e57600080fd5b506103d560048036036020811015610e2557600080fd5b50356001600160a01b0316612591565b348015610e4157600080fd5b506103d561265c565b348015610e5657600080fd5b5061061460048036036020811015610e6d57600080fd5b50356001600160a01b0316612662565b348015610e8957600080fd5b5061061460048036036020811015610ea057600080fd5b5035612704565b61061460048036036040811015610ebd57600080fd5b50803590602001356001600160a01b0316612806565b348015610edf57600080fd5b5061061460048036036080811015610ef657600080fd5b5080359060208101359060408101359060600135612819565b348015610f1b57600080fd5b5061061460048036036020811015610f3257600080fd5b50356001600160a01b03166129f1565b348015610f4e57600080fd5b5061050f60048036036020811015610f6557600080fd5b50356001600160a01b0316612a44565b348015610f8157600080fd5b50610614612a51565b6000610f94611dd6565b15610fd4576040805162461bcd60e51b81526020600482015260186024820152600080516020614105833981519152604482015290519081900360640190fd5b601654604080516323b872dd60e01b8152336004820152306024820152604481018590529051600160401b9092046001600160a01b0316916323b872dd916064808201926020929091908290030181600087803b15801561103457600080fd5b505af1158015611048573d6000803e3d6000fd5b505050506040513d602081101561105e57600080fd5b505161109b5760405162461bcd60e51b8152600401808060200182810382526027815260200180613e8b6027913960400191505060405180910390fd5b6110a483611290565b6110e3576040805162461bcd60e51b81526020600482015260146024820152600080516020613eb2833981519152604482015290519081900360640190fd5b604080516001600160a01b038516815260208101849052338183015290517f2199418ea9428ed3ff7d460860e1edaf5831452fa4ea0f8d1a60d63c603487829181900360600190a16111358383612b49565b90505b92915050565b6060806000805b6006548110156111dc576111796006828154811061115f57fe5b6000918252602090912001546001600160a01b0316611290565b156111d4576006818154811061118b57fe5b9060005260206000200160009054906101000a90046001600160a01b03168383815181106111b557fe5b6001600160a01b03909216602092830291909101909101526001909101905b600101611145565b50909150505b90565b601a805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561126b5780601f106112405761010080835404028352916020019161126b565b820191906000526020600020905b81548152906001019060200180831161124e57829003601f168201915b505050505081565b6000611287611280612bc8565b8484612bcc565b50600192915050565b6001600160a01b03811660009081526005602052604090206003015460ff165b919050565b60006112ce601354601554612cb890919063ffffffff16565b42101580156112de575060155442105b905090565b6001600160a01b03166000908152600560205260409020805460018201546002830154600390930154919390929160ff1690565b60035490565b611325611dd6565b15611365576040805162461bcd60e51b81526020600482015260186024820152600080516020614105833981519152604482015290519081900360640190fd5b61136e33611290565b6113ad576040805162461bcd60e51b81526020600482015260146024820152600080516020613eb2833981519152604482015290519081900360640190fd5b33600090815260056020526040812060018101549091906113d4908563ffffffff612cfa16565b90506113e4826000015482612d54565b611426576040805162461bcd60e51b815260206004820152600e60248201526d1d5b9cd85999481d1bc81b5a5b9d60921b604482015290519081900360640190fd5b600182018190556114378385612e59565b604080516001600160a01b038516815260208101869052338183015290517f5e5aaabf04e3760968ffb551bdf9708f4dbf95d53ad98539e91a56b125e88f089181900360600190a150505b5050565b6000611493848484612f4b565b6115098461149f612bc8565b61150485604051806060016040528060288152602001613ff6602891396001600160a01b038a166000908152600260205260408120906114dd612bc8565b6001600160a01b03168152602081019190915260400160002054919063ffffffff6130a916565b612bcc565b5060019392505050565b601c5460ff1681565b6115263383610f8a565b50611531833061131d565b600480546040805163095ea7b360e01b81526001600160a01b0390921692820192909252602481018590529051309163095ea7b39160448083019260209291908290030181600087803b15801561158757600080fd5b505af115801561159b573d6000803e3d6000fd5b505050506040513d60208110156115b157600080fd5b50506004805460408051637dafae5960e01b81526001600160a01b03858116948201949094523060248201526000604482018190526064820188905291519390921692637dafae5992608480820193929182900301818387803b15801561161757600080fd5b505af115801561162b573d6000803e3d6000fd5b50505050505050565b61163c611dd6565b1561167c576040805162461bcd60e51b81526020600482015260186024820152600080516020614105833981519152604482015290519081900360640190fd5b600081116116d1576040805162461bcd60e51b815260206004820152601a60248201527f43616e6e6f742072656d6f7665203020636f6c6c61746572616c000000000000604482015290519081900360640190fd5b6116da33611290565b611719576040805162461bcd60e51b81526020600482015260146024820152600080516020613eb2833981519152604482015290519081900360640190fd5b3360008181526005602052604090209061173290613140565b8211156117705760405162461bcd60e51b8152600401808060200182810382526027815260200180613fa26027913960400191505060405180910390fd5b8054600090611785908463ffffffff612cb816565b9050611795818360010154612d54565b6117d8576040805162461bcd60e51b815260206004820152600f60248201526e5661756c7420697320756e7361666560881b604482015290519081900360640190fd5b8082556117e5338461315b565b6040805184815233602082015281517f5a945309b3c58e9bb259128c2a530a6579dc75ac1d7d61b3db4c0b8305a16821929181900390910190a1505050565b600b54600c5460030b82565b611838611c1b565b5061184382306121d3565b600480546040805163095ea7b360e01b81526001600160a01b0390921692820192909252602481018490529051309163095ea7b39160448083019260209291908290030181600087803b15801561189957600080fd5b505af11580156118ad573d6000803e3d6000fd5b505050506040513d60208110156118c357600080fd5b50506004805460408051637dafae5960e01b81526001600160a01b03858116948201949094523060248201526000604482018190526064820187905291519390921692637dafae5992608480820193929182900301818387803b15801561192957600080fd5b505af115801561193d573d6000803e3d6000fd5b505050505050565b6000611287611952612bc8565b846115048560026000611963612bc8565b6001600160a01b03908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff612cfa16565b6004546001600160a01b031681565b6119b0611c1b565b506119bc838383611ad9565b505050565b60005b8151811015611a9b5760008282815181106119db57fe5b602002602001015190506119ee81611290565b611a295760405162461bcd60e51b815260040180806020018281038252602f81526020018061405f602f913960400191505060405180910390fd5b6001600160a01b038116600090815260056020526040902084611a4e57505050611482565b84816001015410611a6b57611a638583613246565b505050611482565b6001810154611a8190869063ffffffff612cb816565b9450611a91816001015483613246565b50506001016119c4565b5081156114825760405162461bcd60e51b815260040180806020018281038252602d815260200180613f1d602d913960400191505060405180910390fd5b611ae33383610f8a565b506119bc838261131d565b60408051808201909152600d548152600e54600390810b810b900b60208201526000906111389083906136a9565b6017546001600160a01b031681565b601654601254600091600160201b9004600390810b91810b91909103900b611b688367ffffffffffffffff808416600a0a1663ffffffff6137a416565b9392505050565b6001600160a01b031660009081526001602052604090205490565b611b92611db2565b611bd1576040805162461bcd60e51b8152602060048201819052602482015260008051602061401e833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000611c25611dd6565b15611c65576040805162461bcd60e51b81526020600482015260186024820152600080516020614105833981519152604482015290519081900360640190fd5b611c6e33611290565b15611cb8576040805162461bcd60e51b815260206004820152601560248201527415985d5b1d08185b1c9958591e4818dc99585d1959605a1b604482015290519081900360640190fd5b60408051608081018252600080825260208083018281528385018381526001606086018181523380875260058652888720975188559351878301559151600287015590516003909501805460ff1916951515959095179094556006805494850181559092527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f90920180546001600160a01b03191682179055825190815291517f66a872561db77eb92ef3079a44a5af00c68c3a09e0976814a95bd91721f57c2f9281900390910190a150600190565b6019546001600160a01b031681565b60075460085460030b82565b6000546001600160a01b031690565b600080546001600160a01b0316611dc7612bc8565b6001600160a01b031614905090565b60155442101590565b601b805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561126b5780601f106112405761010080835404028352916020019161126b565b6000611e44611dd6565b15611e84576040805162461bcd60e51b81526020600482015260186024820152600080516020614105833981519152604482015290519081900360640190fd5b601654611ea090600160401b90046001600160a01b0316612a44565b611edb5760405162461bcd60e51b8152600401808060200182810382526028815260200180613df66028913960400191505060405180910390fd5b611ee482611290565b611f23576040805162461bcd60e51b81526020600482015260146024820152600080516020613eb2833981519152604482015290519081900360640190fd5b604080516001600160a01b0384168152346020820152338183015290517ff24ce6016de57e90501829715846e26ac283a0aabfc160647e0ae8b05e0f433d9181900360600190a16111388234612b49565b600954600a5460030b82565b6000611287611f8d612bc8565b84611504856040518060600160405280602581526020016141256025913960026000611fb7612bc8565b6001600160a01b03908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff6130a916565b6000611287611ffb612bc8565b8484612f4b565b6018546001600160a01b031681565b601654600160201b900460030b81565b60165460030b81565b60115460125460030b82565b61203e611dd6565b6120795760405162461bcd60e51b8152600401808060200182810382526025815260200180613e666025913960400191505060405180910390fd5b61208233611290565b6120c1576040805162461bcd60e51b81526020600482015260146024820152600080516020613eb2833981519152604482015290519081900360640190fd5b33600081815260056020526040812080546002820180548484556001840185905593905590929091906120f4908361315b565b6120fe33826137fd565b6040805183815260208101839052338183015290517fe481532a3f7d078365ca0145442ed0a0a3e0443f3c0bae0c29cff131112678389181900360600190a1505050565b61214a611db2565b612189576040805162461bcd60e51b8152602060048201819052602482015260008051602061401e833981519152604482015290519081900360640190fd5b815161219c90601a906020850190613cae565b5080516121b090601b906020840190613cae565b50601254601c805460ff191660039290920b60000360ff16919091179055611482565b6121dc33611e3a565b50611482828261131d565b600d54600e5460030b82565b6121fb611dd6565b1561223b576040805162461bcd60e51b81526020600482015260186024820152600080516020614105833981519152604482015290519081900360640190fd5b61224482611290565b612283576040805162461bcd60e51b81526020600482015260146024820152600080516020613eb2833981519152604482015290519081900360640190fd5b6001600160a01b03821660009081526005602052604090206122a483612517565b6122e5576040805162461bcd60e51b815260206004820152600d60248201526c5661756c74206973207361666560981b604482015290519081900360640190fd5b336001600160a01b0384161415612343576040805162461bcd60e51b815260206004820181905260248201527f4f776e65722063616e2774206c6971756964617465207468656d73656c766573604482015290519081900360640190fd5b600061236883604051806040016040528060018152602001600060030b8152506138a3565b604080518082019091526007548152600854600390810b810b900b60208201529091506000906123999085906138a3565b905060006123ad838363ffffffff612cfa16565b600b5485549192506000916123c79163ffffffff6137a416565b600c549091506000600391820b90910b131561240257600c546123fb908290600390810b900b600a0a63ffffffff6137a416565b9050612426565b600c54612423908290600390810b600003900b600a0a63ffffffff61398516565b90505b808211156124655760405162461bcd60e51b8152600401808060200182810382526037815260200180613f4a6037913960400191505060405180910390fd5b8454612477908363ffffffff612cb816565b8555600185015461248e908763ffffffff612cb816565b600186015561249d33876139c7565b6124a7338361315b565b604080518381526001600160a01b0389166020820152338183015290517fcab8e1abb9f8235c6db895cf185336dc9461aecf477b98c1be83687ee549e66a9181900360600190a150505050505050565b600f5460105460030b82565b61250b611c1b565b50611531838330611ad9565b60008061253461252684613140565b61252f85613ac3565b612d54565b159392505050565b61254533611e3a565b50611843823061131d565b601654600160401b90046001600160a01b031681565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b600061259c82612517565b15612654576001600160a01b0382166000908152600560205260408120600c54600b5482549293926125f192600390810b8503900b600a0a916125e5919063ffffffff6137a416565b9063ffffffff61398516565b600854909150600390810b600003900b600a0a61260c613d2c565b60408051808201909152600754819061262b908563ffffffff612cfa16565b8152600854600390810b900b602090910152905061264983826136a9565b9450505050506112b0565b5060006112b0565b60155481565b61266a611db2565b6126a9576040805162461bcd60e51b8152602060048201819052602482015260008051602061401e833981519152604482015290519081900360640190fd5b6014805460009091556126bc828261315b565b604080516001600160a01b03841681526020810183905281517f88b171bb78d3ac5e1caa8e729dddce4e1322e84c80c093ebbe52507b62c77d98929181900390910190a15050565b61270c611dd6565b1561274c576040805162461bcd60e51b81526020600482015260186024820152600080516020614105833981519152604482015290519081900360640190fd5b61275533611290565b612794576040805162461bcd60e51b81526020600482015260146024820152600080516020613eb2833981519152604482015290519081900360640190fd5b33600090815260056020526040902060018101546127b8908363ffffffff612cb816565b60018201556127c733836139c7565b604080513381526020810184905281517fdf8cebdea6ef1fd20576b80bc951377c0e61e2a8169153a1f836673ccce80e62929181900390910190a15050565b61280e611c1b565b5061148282826121d3565b612821611db2565b612860576040805162461bcd60e51b8152602060048201819052602482015260008051602061401e833981519152604482015290519081900360640190fd5b60c88411156128a05760405162461bcd60e51b8152600401808060200182810382526025815260200180613ef86025913960400191505060405180910390fd5b6103e88311156128e15760405162461bcd60e51b815260040180806020018281038252602b815260200180613da9602b913960400191505060405180910390fd5b6064821115612937576040805162461bcd60e51b815260206004820181905260248201527f43616e27742068617665207472616e73616374696f6e20666565203e20313025604482015290519081900360640190fd5b600a8110156129775760405162461bcd60e51b8152600401808060200182810382526028815260200180613d816028913960400191505060405180910390fd5b6007849055600b8390556009829055600d8190557f3450d20c21ea671871fed271900cc8ff03badafa9b6fe2ff7f86991950e86b6b848484846129b8611da3565b6040805195865260208601949094528484019290925260608401526001600160a01b03166080830152519081900360a00190a150505050565b6129f9611db2565b612a38576040805162461bcd60e51b8152602060048201819052602482015260008051602061401e833981519152604482015290519081900360640190fd5b612a4181613ae1565b50565b6001600160a01b03161590565b612a5a33611290565b612a99576040805162461bcd60e51b81526020600482015260146024820152600080516020613eb2833981519152604482015290519081900360640190fd5b3360009081526005602052604090206002810154612af6576040805162461bcd60e51b81526020600482015260156024820152744e6f20756e6465726c79696e672062616c616e636560581b604482015290519081900360640190fd5b6002810180546000909155612b0b33826137fd565b6040805182815233602082015281517fea0bff65fa9380b944e9a761f9c6a665ad2d31e74706a52773ddb45c8a57c83d929181900390910190a15050565b6000612b53611dd6565b15612b93576040805162461bcd60e51b81526020600482015260186024820152600080516020614105833981519152604482015290519081900360640190fd5b6001600160a01b03831660009081526005602052604090208054612bbd908463ffffffff612cfa16565b908190559392505050565b3390565b6001600160a01b038316612c115760405162461bcd60e51b81526004018080602001828103825260248152602001806140b36024913960400191505060405180910390fd5b6001600160a01b038216612c565760405162461bcd60e51b8152600401808060200182810382526022815260200180613e446022913960400191505060405180910390fd5b6001600160a01b03808416600081815260026020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b600061113583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506130a9565b600082820183811015611135576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600080612d75601660089054906101000a90046001600160a01b0316613b81565b601854909150600090612d90906001600160a01b0316613b81565b600f54600d54919250600091612dbe9190612db290889063ffffffff6137a416565b9063ffffffff6137a416565b601054600e54919250600391820b910b016000612de5846125e58a8863ffffffff6137a416565b601654909150600390810b90600090819085810b9084900b1215612e295782850360030b915083612e2087600a85900a63ffffffff6137a416565b11159050612e4b565b84830360030b9150612e4584600a84900a63ffffffff6137a416565b86111590505b9a9950505050505050505050565b6001600160a01b038216612eb4576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b600354612ec7908263ffffffff612cfa16565b6003556001600160a01b038216600090815260016020526040902054612ef3908263ffffffff612cfa16565b6001600160a01b03831660008181526001602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6001600160a01b038316612f905760405162461bcd60e51b815260040180806020018281038252602581526020018061408e6025913960400191505060405180910390fd5b6001600160a01b038216612fd55760405162461bcd60e51b8152600401808060200182810382526023815260200180613d5e6023913960400191505060405180910390fd5b61301881604051806060016040528060268152602001613ed2602691396001600160a01b038616600090815260016020526040902054919063ffffffff6130a916565b6001600160a01b03808516600090815260016020526040808220939093559084168152205461304d908263ffffffff612cfa16565b6001600160a01b0380841660008181526001602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600081848411156131385760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156130fd5781810151838201526020016130e5565b50505050905090810190601f16801561312a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6001600160a01b031660009081526005602052604090205490565b60165461317790600160401b90046001600160a01b0316612a44565b156131b8576040516001600160a01b0383169082156108fc029083906000818181858888f193505050501580156131b2573d6000803e3d6000fd5b50611482565b6016546040805163a9059cbb60e01b81526001600160a01b038581166004830152602482018590529151600160401b9093049091169163a9059cbb916044808201926020929091908290030181600087803b15801561321657600080fd5b505af115801561322a573d6000803e3d6000fd5b505050506040513d602081101561324057600080fd5b50505050565b61324e6112b5565b6132895760405162461bcd60e51b815260040180806020018281038252602d815260200180613fc9602d913960400191505060405180910390fd5b61329281611290565b6132d1576040805162461bcd60e51b81526020600482015260146024820152600080516020613eb2833981519152604482015290519081900360640190fd5b6001600160a01b03811660009081526005602052604090208261333b576040805162461bcd60e51b815260206004820152601860248201527f43616e27742065786572636973652030206f546f6b656e730000000000000000604482015290519081900360640190fd5b806001015483111561337e5760405162461bcd60e51b815260040180806020018281038252602e8152602001806140d7602e913960400191505060405180910390fd5b8261338833611b6f565b10156133d0576040805162461bcd60e51b81526020600482015260126024820152714e6f7420656e6f756768206f546f6b656e7360701b604482015290519081900360640190fd5b60006133db84611b2b565b60028301549091506133f3908263ffffffff612cfa16565b600283015560408051808201909152600181526000602082018190529061341b9086906138a3565b604080518082019091526009548152600a54600390810b810b900b602082015290915060009061344c9087906138a3565b601454909150613462908263ffffffff612cfa16565b6014556000613477838363ffffffff612cfa16565b85549091508111156134d0576040805162461bcd60e51b815260206004820181905260248201527f5661756c7420756e64657277617465722c2063616e2774206578657263697365604482015290519081900360640190fd5b84546134e2908263ffffffff612cb816565b855560018501546134f9908863ffffffff612cb816565b6001860155601754613513906001600160a01b0316612a44565b1561356757833414613562576040805162461bcd60e51b8152602060048201526013602482015272496e636f7272656374206d73672e76616c756560681b604482015290519081900360640190fd5b61363e565b601754604080516323b872dd60e01b81523360048201523060248201526044810187905290516001600160a01b03909216916323b872dd916064808201926020929091908290030181600087803b1580156135c157600080fd5b505af11580156135d5573d6000803e3d6000fd5b505050506040513d60208110156135eb57600080fd5b505161363e576040805162461bcd60e51b815260206004820152601c60248201527f436f756c64206e6f74207472616e7366657220696e20746f6b656e7300000000604482015290519081900360640190fd5b61364833886139c7565b613652338461315b565b604080518581526020810185905233818301526001600160a01b038816606082015290517ffa7bab37479e50a9b24a9412b879d400de9bcaa1e3a2b343e90bb370d85bbaa79181900360800190a150505050505050565b6000806136ca601660089054906101000a90046001600160a01b0316613b81565b6018549091506000906136e5906001600160a01b0316613b81565b600f5485519192506000916136ff9163ffffffff6137a416565b601054602087015191925060030b016000613724846125e58a8863ffffffff6137a416565b601654909150600390810b90600090819085810b9084900b12156137755782850360030b915061376e61376187600a85900a63ffffffff6137a416565b859063ffffffff61398516565b9050612e4b565b84830360030b9150613795866125e586600a86900a63ffffffff6137a416565b9b9a5050505050505050505050565b6000826137b357506000611138565b828202828482816137c057fe5b04146111355760405162461bcd60e51b8152600401808060200182810382526021815260200180613f816021913960400191505060405180910390fd5b601754613812906001600160a01b0316612a44565b1561384d576040516001600160a01b0383169082156108fc029083906000818181858888f193505050501580156131b2573d6000803e3d6000fd5b6017546040805163a9059cbb60e01b81526001600160a01b038581166004830152602482018590529151919092169163a9059cbb9160448083019260209291908290030181600087803b15801561321657600080fd5b6000806138c4601660089054906101000a90046001600160a01b0316613b81565b6018549091506000906138df906001600160a01b0316613b81565b9050600061390782612db28760000151612db2600f600001548b6137a490919063ffffffff16565b6016546020870151601054929350600391820b92820b01919091039060009082900b811215613955578161394d866125e58663ffffffff808616600a0a8116906137a416565b91505061397a565b6000829003613976866125e58663ffffffff808616600a0a81169061398516565b9150505b979650505050505050565b600061113583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613c49565b6001600160a01b038216613a0c5760405162461bcd60e51b815260040180806020018281038252602181526020018061403e6021913960400191505060405180910390fd5b613a4f81604051806060016040528060228152602001613dd4602291396001600160a01b038516600090815260016020526040902054919063ffffffff6130a916565b6001600160a01b038316600090815260016020526040902055600354613a7b908263ffffffff612cb816565b6003556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b031660009081526005602052604090206001015490565b6001600160a01b038116613b265760405162461bcd60e51b8152600401808060200182810382526026815260200180613e1e6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6018546016546000916001600160a01b03908116600160401b909204161415613bac575060016112b0565b6001600160a01b038216613bc95750670de0b6b3a76400006112b0565b601954604080516341976e0960e01b81526001600160a01b038581166004830152915191909216916341976e09916024808301926020929190829003018186803b158015613c1657600080fd5b505afa158015613c2a573d6000803e3d6000fd5b505050506040513d6020811015613c4057600080fd5b505190506112b0565b60008183613c985760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156130fd5781810151838201526020016130e5565b506000838581613ca457fe5b0495945050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613cef57805160ff1916838001178555613d1c565b82800160010185558215613d1c579182015b82811115613d1c578251825591602001919060010190613d01565b50613d28929150613d43565b5090565b604080518082019091526000808252602082015290565b6111e291905b80821115613d285760008155600101613d4956fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737343616e27742068617665206d696e436f6c6c61746572616c697a6174696f6e526174696f203c203143616e2774206c6971756964617465206d6f7265207468616e2031303025206f6620746865207661756c7445524332303a206275726e20616d6f756e7420657863656564732062616c616e6365455448206973206e6f74207468652073706563696669656420636f6c6c61746572616c20747970654f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737343616e277420636f6c6c65637420636f6c6c61746572616c20756e74696c20657870697279436f756c64206e6f74207472616e7366657220696e20636f6c6c61746572616c20746f6b656e735661756c7420646f6573206e6f7420657869737400000000000000000000000045524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636543616e27742068617665203e323025206c69717569646174696f6e20696e63656e74697665537065636966696564207661756c7473206861766520696e73756666696369656e7420636f6c6c61746572616c43616e206f6e6c79206c6971756964617465206c69717569646174696f6e20666163746f7220617420616e7920676976656e2074696d65536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7743616e27742072656d6f7665206d6f726520636f6c6c61746572616c207468616e206f776e656443616e2774206578657263697365206f757473696465206f66207468652065786572636973652077696e646f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657245524332303a206275726e2066726f6d20746865207a65726f206164647265737343616e6e6f742065786572636973652066726f6d2061207661756c74207468617420646f65736e277420657869737445524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737343616e2774206578657263697365206d6f7265206f546f6b656e73207468616e20746865206f776e6572206861734f7074696f6e7320636f6e74726163742065787069726564000000000000000045524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa265627a7a7230582024408987c6dcfcda4c0e73ff0354366a3d057faa494c86e0ef89208047b75fda64736f6c634300050a003245786572636973652077696e646f772063616e2774206265206c6f6e676572207468616e2074686520636f6e74726163742773206c6966657370616e636f6c6c61746572616c206578706f6e656e74206e6f742077697468696e2065787065637465642072616e67656f546f6b656e2065786368616e67652072617465206578706f6e656e74206e6f742077697468696e2065787065637465642072616e6765737472696b65207072696365206578706f6e656e74206e6f742077697468696e2065787065637465642072616e6765756e6465726c79696e67206578706f6e656e74206e6f742077697468696e2065787065637465642072616e6765000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000000000000000000000000000000000000000000000000000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000005e81368000000000000000000000000039246c4f3f6592c974ebc44f80ba6dc69b817c710000000000000000000000007054e08461e3ecb7718b63540addb3c3a1746415000000000000000000000000000000000000000000000000000000005e813680
Deployed Bytecode
0x6080604052600436106103975760003560e01c806390e64d13116101dc578063c52987cf11610102578063e184c9be116100a0578063ee1eab4f1161006f578063ee1eab4f14610ed3578063f2fde38b14610f0f578063f70a250814610f42578063faa2041f14610f7557610397565b8063e184c9be14610e35578063ea8c4bcf14610e4a578063eaa376b514610e7d578063ed1f41c314610ea757610397565b8063cfbea789116100dc578063cfbea78914610d86578063d8dfeb4514610db2578063dd62ed3e14610dc7578063dec44c0b14610e0257610397565b8063c52987cf14610cff578063c56749ce14610d14578063cdb4b5c214610d5357610397565b8063b2c2b13f1161017a578063b7b090ee11610149578063b7b090ee14610b4f578063b96661ba14610c85578063ba1be55414610cb1578063bcbaf48714610cc657610397565b8063b2c2b13f14610ae2578063b6e61c0814610b10578063b736554014610b25578063b76fdb6c14610b3a57610397565b80639ed3edf0116101b65780639ed3edf014610a46578063a457c2d714610a5b578063a9059cbb14610a94578063ad8f500814610acd57610397565b806390e64d13146109f657806395d89b4114610a0b5780639ce0725114610a2057610397565b806339509351116102c15780636fd865f91161025f5780638a5e8cc71161022e5780638a5e8cc7146109a25780638c765e94146109b75780638da5cb5b146109cc5780638f32d59b146109e157610397565b80636fd865f91461091b57806370a0823114610945578063715018a61461097857806386f547121461098d57610397565b806358b36dac1161029b57806358b36dac146107f55780635ca7c8a61461089d578063686c1e21146108dc5780636f307dc31461090657610397565b8063395093511461074c5780633bd33f621461078557806352f89fe3146107b657610397565b806318160ddd116103395780633226052d116103085780633226052d146106845780633237c158146106c3578063352ade55146106ed5780633667429f1461072057610397565b806318160ddd146105c65780631a0e21bd146105db57806323b872dd14610616578063313ce5671461065957610397565b8063095ea7b311610375578063095ea7b3146104d65780630d453efb146105235780630d6cd8aa146105565780630eb9af381461056b57610397565b806301b4a3c11461039c578063060ab2ea146103e757806306fdde031461044c575b600080fd5b3480156103a857600080fd5b506103d5600480360360408110156103bf57600080fd5b506001600160a01b038135169060200135610f8a565b60408051918252519081900360200190f35b3480156103f357600080fd5b506103fc61113e565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610438578181015183820152602001610420565b505050509050019250505060405180910390f35b34801561045857600080fd5b506104616111e5565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561049b578181015183820152602001610483565b50505050905090810190601f1680156104c85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156104e257600080fd5b5061050f600480360360408110156104f957600080fd5b506001600160a01b038135169060200135611273565b604080519115158252519081900360200190f35b34801561052f57600080fd5b5061050f6004803603602081101561054657600080fd5b50356001600160a01b0316611290565b34801561056257600080fd5b5061050f6112b5565b34801561057757600080fd5b5061059e6004803603602081101561058e57600080fd5b50356001600160a01b03166112e3565b6040805194855260208501939093528383019190915215156060830152519081900360800190f35b3480156105d257600080fd5b506103d5611317565b3480156105e757600080fd5b50610614600480360360408110156105fe57600080fd5b50803590602001356001600160a01b031661131d565b005b34801561062257600080fd5b5061050f6004803603606081101561063957600080fd5b506001600160a01b03813581169160208101359091169060400135611486565b34801561066557600080fd5b5061066e611513565b6040805160ff9092168252519081900360200190f35b34801561069057600080fd5b50610614600480360360608110156106a757600080fd5b50803590602081013590604001356001600160a01b031661151c565b3480156106cf57600080fd5b50610614600480360360208110156106e657600080fd5b5035611634565b3480156106f957600080fd5b50610702611824565b60408051928352600391820b90910b60208301528051918290030190f35b6106146004803603604081101561073657600080fd5b50803590602001356001600160a01b0316611830565b34801561075857600080fd5b5061050f6004803603604081101561076f57600080fd5b506001600160a01b038135169060200135611945565b34801561079157600080fd5b5061079a611999565b604080516001600160a01b039092168252519081900360200190f35b3480156107c257600080fd5b50610614600480360360608110156107d957600080fd5b50803590602081013590604001356001600160a01b03166119a8565b6106146004803603604081101561080b57600080fd5b81359190810190604081016020820135600160201b81111561082c57600080fd5b82018360208201111561083e57600080fd5b803590602001918460208302840111600160201b8311171561085f57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506119c1945050505050565b3480156108a957600080fd5b50610614600480360360608110156108c057600080fd5b50803590602081013590604001356001600160a01b0316611ad9565b3480156108e857600080fd5b506103d5600480360360208110156108ff57600080fd5b5035611aee565b34801561091257600080fd5b5061079a611b1c565b34801561092757600080fd5b506103d56004803603602081101561093e57600080fd5b5035611b2b565b34801561095157600080fd5b506103d56004803603602081101561096857600080fd5b50356001600160a01b0316611b6f565b34801561098457600080fd5b50610614611b8a565b34801561099957600080fd5b5061050f611c1b565b3480156109ae57600080fd5b5061079a611d88565b3480156109c357600080fd5b50610702611d97565b3480156109d857600080fd5b5061079a611da3565b3480156109ed57600080fd5b5061050f611db2565b348015610a0257600080fd5b5061050f611dd6565b348015610a1757600080fd5b50610461611ddf565b6103d560048036036020811015610a3657600080fd5b50356001600160a01b0316611e3a565b348015610a5257600080fd5b50610702611f74565b348015610a6757600080fd5b5061050f60048036036040811015610a7e57600080fd5b506001600160a01b038135169060200135611f80565b348015610aa057600080fd5b5061050f60048036036040811015610ab757600080fd5b506001600160a01b038135169060200135611fee565b348015610ad957600080fd5b5061079a612002565b348015610aee57600080fd5b50610af7612011565b60408051600392830b90920b8252519081900360200190f35b348015610b1c57600080fd5b50610af7612021565b348015610b3157600080fd5b5061070261202a565b348015610b4657600080fd5b50610614612036565b348015610b5b57600080fd5b5061061460048036036040811015610b7257600080fd5b810190602081018135600160201b811115610b8c57600080fd5b820183602082011115610b9e57600080fd5b803590602001918460018302840111600160201b83111715610bbf57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050600160201b811115610c1157600080fd5b820183602082011115610c2357600080fd5b803590602001918460018302840111600160201b83111715610c4457600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612142945050505050565b61061460048036036040811015610c9b57600080fd5b50803590602001356001600160a01b03166121d3565b348015610cbd57600080fd5b506107026121e7565b348015610cd257600080fd5b5061061460048036036040811015610ce957600080fd5b506001600160a01b0381351690602001356121f3565b348015610d0b57600080fd5b506107026124f7565b348015610d2057600080fd5b5061061460048036036060811015610d3757600080fd5b50803590602081013590604001356001600160a01b0316612503565b348015610d5f57600080fd5b5061050f60048036036020811015610d7657600080fd5b50356001600160a01b0316612517565b61061460048036036040811015610d9c57600080fd5b50803590602001356001600160a01b031661253c565b348015610dbe57600080fd5b5061079a612550565b348015610dd357600080fd5b506103d560048036036040811015610dea57600080fd5b506001600160a01b0381358116916020013516612566565b348015610e0e57600080fd5b506103d560048036036020811015610e2557600080fd5b50356001600160a01b0316612591565b348015610e4157600080fd5b506103d561265c565b348015610e5657600080fd5b5061061460048036036020811015610e6d57600080fd5b50356001600160a01b0316612662565b348015610e8957600080fd5b5061061460048036036020811015610ea057600080fd5b5035612704565b61061460048036036040811015610ebd57600080fd5b50803590602001356001600160a01b0316612806565b348015610edf57600080fd5b5061061460048036036080811015610ef657600080fd5b5080359060208101359060408101359060600135612819565b348015610f1b57600080fd5b5061061460048036036020811015610f3257600080fd5b50356001600160a01b03166129f1565b348015610f4e57600080fd5b5061050f60048036036020811015610f6557600080fd5b50356001600160a01b0316612a44565b348015610f8157600080fd5b50610614612a51565b6000610f94611dd6565b15610fd4576040805162461bcd60e51b81526020600482015260186024820152600080516020614105833981519152604482015290519081900360640190fd5b601654604080516323b872dd60e01b8152336004820152306024820152604481018590529051600160401b9092046001600160a01b0316916323b872dd916064808201926020929091908290030181600087803b15801561103457600080fd5b505af1158015611048573d6000803e3d6000fd5b505050506040513d602081101561105e57600080fd5b505161109b5760405162461bcd60e51b8152600401808060200182810382526027815260200180613e8b6027913960400191505060405180910390fd5b6110a483611290565b6110e3576040805162461bcd60e51b81526020600482015260146024820152600080516020613eb2833981519152604482015290519081900360640190fd5b604080516001600160a01b038516815260208101849052338183015290517f2199418ea9428ed3ff7d460860e1edaf5831452fa4ea0f8d1a60d63c603487829181900360600190a16111358383612b49565b90505b92915050565b6060806000805b6006548110156111dc576111796006828154811061115f57fe5b6000918252602090912001546001600160a01b0316611290565b156111d4576006818154811061118b57fe5b9060005260206000200160009054906101000a90046001600160a01b03168383815181106111b557fe5b6001600160a01b03909216602092830291909101909101526001909101905b600101611145565b50909150505b90565b601a805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561126b5780601f106112405761010080835404028352916020019161126b565b820191906000526020600020905b81548152906001019060200180831161124e57829003601f168201915b505050505081565b6000611287611280612bc8565b8484612bcc565b50600192915050565b6001600160a01b03811660009081526005602052604090206003015460ff165b919050565b60006112ce601354601554612cb890919063ffffffff16565b42101580156112de575060155442105b905090565b6001600160a01b03166000908152600560205260409020805460018201546002830154600390930154919390929160ff1690565b60035490565b611325611dd6565b15611365576040805162461bcd60e51b81526020600482015260186024820152600080516020614105833981519152604482015290519081900360640190fd5b61136e33611290565b6113ad576040805162461bcd60e51b81526020600482015260146024820152600080516020613eb2833981519152604482015290519081900360640190fd5b33600090815260056020526040812060018101549091906113d4908563ffffffff612cfa16565b90506113e4826000015482612d54565b611426576040805162461bcd60e51b815260206004820152600e60248201526d1d5b9cd85999481d1bc81b5a5b9d60921b604482015290519081900360640190fd5b600182018190556114378385612e59565b604080516001600160a01b038516815260208101869052338183015290517f5e5aaabf04e3760968ffb551bdf9708f4dbf95d53ad98539e91a56b125e88f089181900360600190a150505b5050565b6000611493848484612f4b565b6115098461149f612bc8565b61150485604051806060016040528060288152602001613ff6602891396001600160a01b038a166000908152600260205260408120906114dd612bc8565b6001600160a01b03168152602081019190915260400160002054919063ffffffff6130a916565b612bcc565b5060019392505050565b601c5460ff1681565b6115263383610f8a565b50611531833061131d565b600480546040805163095ea7b360e01b81526001600160a01b0390921692820192909252602481018590529051309163095ea7b39160448083019260209291908290030181600087803b15801561158757600080fd5b505af115801561159b573d6000803e3d6000fd5b505050506040513d60208110156115b157600080fd5b50506004805460408051637dafae5960e01b81526001600160a01b03858116948201949094523060248201526000604482018190526064820188905291519390921692637dafae5992608480820193929182900301818387803b15801561161757600080fd5b505af115801561162b573d6000803e3d6000fd5b50505050505050565b61163c611dd6565b1561167c576040805162461bcd60e51b81526020600482015260186024820152600080516020614105833981519152604482015290519081900360640190fd5b600081116116d1576040805162461bcd60e51b815260206004820152601a60248201527f43616e6e6f742072656d6f7665203020636f6c6c61746572616c000000000000604482015290519081900360640190fd5b6116da33611290565b611719576040805162461bcd60e51b81526020600482015260146024820152600080516020613eb2833981519152604482015290519081900360640190fd5b3360008181526005602052604090209061173290613140565b8211156117705760405162461bcd60e51b8152600401808060200182810382526027815260200180613fa26027913960400191505060405180910390fd5b8054600090611785908463ffffffff612cb816565b9050611795818360010154612d54565b6117d8576040805162461bcd60e51b815260206004820152600f60248201526e5661756c7420697320756e7361666560881b604482015290519081900360640190fd5b8082556117e5338461315b565b6040805184815233602082015281517f5a945309b3c58e9bb259128c2a530a6579dc75ac1d7d61b3db4c0b8305a16821929181900390910190a1505050565b600b54600c5460030b82565b611838611c1b565b5061184382306121d3565b600480546040805163095ea7b360e01b81526001600160a01b0390921692820192909252602481018490529051309163095ea7b39160448083019260209291908290030181600087803b15801561189957600080fd5b505af11580156118ad573d6000803e3d6000fd5b505050506040513d60208110156118c357600080fd5b50506004805460408051637dafae5960e01b81526001600160a01b03858116948201949094523060248201526000604482018190526064820187905291519390921692637dafae5992608480820193929182900301818387803b15801561192957600080fd5b505af115801561193d573d6000803e3d6000fd5b505050505050565b6000611287611952612bc8565b846115048560026000611963612bc8565b6001600160a01b03908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff612cfa16565b6004546001600160a01b031681565b6119b0611c1b565b506119bc838383611ad9565b505050565b60005b8151811015611a9b5760008282815181106119db57fe5b602002602001015190506119ee81611290565b611a295760405162461bcd60e51b815260040180806020018281038252602f81526020018061405f602f913960400191505060405180910390fd5b6001600160a01b038116600090815260056020526040902084611a4e57505050611482565b84816001015410611a6b57611a638583613246565b505050611482565b6001810154611a8190869063ffffffff612cb816565b9450611a91816001015483613246565b50506001016119c4565b5081156114825760405162461bcd60e51b815260040180806020018281038252602d815260200180613f1d602d913960400191505060405180910390fd5b611ae33383610f8a565b506119bc838261131d565b60408051808201909152600d548152600e54600390810b810b900b60208201526000906111389083906136a9565b6017546001600160a01b031681565b601654601254600091600160201b9004600390810b91810b91909103900b611b688367ffffffffffffffff808416600a0a1663ffffffff6137a416565b9392505050565b6001600160a01b031660009081526001602052604090205490565b611b92611db2565b611bd1576040805162461bcd60e51b8152602060048201819052602482015260008051602061401e833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000611c25611dd6565b15611c65576040805162461bcd60e51b81526020600482015260186024820152600080516020614105833981519152604482015290519081900360640190fd5b611c6e33611290565b15611cb8576040805162461bcd60e51b815260206004820152601560248201527415985d5b1d08185b1c9958591e4818dc99585d1959605a1b604482015290519081900360640190fd5b60408051608081018252600080825260208083018281528385018381526001606086018181523380875260058652888720975188559351878301559151600287015590516003909501805460ff1916951515959095179094556006805494850181559092527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f90920180546001600160a01b03191682179055825190815291517f66a872561db77eb92ef3079a44a5af00c68c3a09e0976814a95bd91721f57c2f9281900390910190a150600190565b6019546001600160a01b031681565b60075460085460030b82565b6000546001600160a01b031690565b600080546001600160a01b0316611dc7612bc8565b6001600160a01b031614905090565b60155442101590565b601b805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561126b5780601f106112405761010080835404028352916020019161126b565b6000611e44611dd6565b15611e84576040805162461bcd60e51b81526020600482015260186024820152600080516020614105833981519152604482015290519081900360640190fd5b601654611ea090600160401b90046001600160a01b0316612a44565b611edb5760405162461bcd60e51b8152600401808060200182810382526028815260200180613df66028913960400191505060405180910390fd5b611ee482611290565b611f23576040805162461bcd60e51b81526020600482015260146024820152600080516020613eb2833981519152604482015290519081900360640190fd5b604080516001600160a01b0384168152346020820152338183015290517ff24ce6016de57e90501829715846e26ac283a0aabfc160647e0ae8b05e0f433d9181900360600190a16111388234612b49565b600954600a5460030b82565b6000611287611f8d612bc8565b84611504856040518060600160405280602581526020016141256025913960026000611fb7612bc8565b6001600160a01b03908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff6130a916565b6000611287611ffb612bc8565b8484612f4b565b6018546001600160a01b031681565b601654600160201b900460030b81565b60165460030b81565b60115460125460030b82565b61203e611dd6565b6120795760405162461bcd60e51b8152600401808060200182810382526025815260200180613e666025913960400191505060405180910390fd5b61208233611290565b6120c1576040805162461bcd60e51b81526020600482015260146024820152600080516020613eb2833981519152604482015290519081900360640190fd5b33600081815260056020526040812080546002820180548484556001840185905593905590929091906120f4908361315b565b6120fe33826137fd565b6040805183815260208101839052338183015290517fe481532a3f7d078365ca0145442ed0a0a3e0443f3c0bae0c29cff131112678389181900360600190a1505050565b61214a611db2565b612189576040805162461bcd60e51b8152602060048201819052602482015260008051602061401e833981519152604482015290519081900360640190fd5b815161219c90601a906020850190613cae565b5080516121b090601b906020840190613cae565b50601254601c805460ff191660039290920b60000360ff16919091179055611482565b6121dc33611e3a565b50611482828261131d565b600d54600e5460030b82565b6121fb611dd6565b1561223b576040805162461bcd60e51b81526020600482015260186024820152600080516020614105833981519152604482015290519081900360640190fd5b61224482611290565b612283576040805162461bcd60e51b81526020600482015260146024820152600080516020613eb2833981519152604482015290519081900360640190fd5b6001600160a01b03821660009081526005602052604090206122a483612517565b6122e5576040805162461bcd60e51b815260206004820152600d60248201526c5661756c74206973207361666560981b604482015290519081900360640190fd5b336001600160a01b0384161415612343576040805162461bcd60e51b815260206004820181905260248201527f4f776e65722063616e2774206c6971756964617465207468656d73656c766573604482015290519081900360640190fd5b600061236883604051806040016040528060018152602001600060030b8152506138a3565b604080518082019091526007548152600854600390810b810b900b60208201529091506000906123999085906138a3565b905060006123ad838363ffffffff612cfa16565b600b5485549192506000916123c79163ffffffff6137a416565b600c549091506000600391820b90910b131561240257600c546123fb908290600390810b900b600a0a63ffffffff6137a416565b9050612426565b600c54612423908290600390810b600003900b600a0a63ffffffff61398516565b90505b808211156124655760405162461bcd60e51b8152600401808060200182810382526037815260200180613f4a6037913960400191505060405180910390fd5b8454612477908363ffffffff612cb816565b8555600185015461248e908763ffffffff612cb816565b600186015561249d33876139c7565b6124a7338361315b565b604080518381526001600160a01b0389166020820152338183015290517fcab8e1abb9f8235c6db895cf185336dc9461aecf477b98c1be83687ee549e66a9181900360600190a150505050505050565b600f5460105460030b82565b61250b611c1b565b50611531838330611ad9565b60008061253461252684613140565b61252f85613ac3565b612d54565b159392505050565b61254533611e3a565b50611843823061131d565b601654600160401b90046001600160a01b031681565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b600061259c82612517565b15612654576001600160a01b0382166000908152600560205260408120600c54600b5482549293926125f192600390810b8503900b600a0a916125e5919063ffffffff6137a416565b9063ffffffff61398516565b600854909150600390810b600003900b600a0a61260c613d2c565b60408051808201909152600754819061262b908563ffffffff612cfa16565b8152600854600390810b900b602090910152905061264983826136a9565b9450505050506112b0565b5060006112b0565b60155481565b61266a611db2565b6126a9576040805162461bcd60e51b8152602060048201819052602482015260008051602061401e833981519152604482015290519081900360640190fd5b6014805460009091556126bc828261315b565b604080516001600160a01b03841681526020810183905281517f88b171bb78d3ac5e1caa8e729dddce4e1322e84c80c093ebbe52507b62c77d98929181900390910190a15050565b61270c611dd6565b1561274c576040805162461bcd60e51b81526020600482015260186024820152600080516020614105833981519152604482015290519081900360640190fd5b61275533611290565b612794576040805162461bcd60e51b81526020600482015260146024820152600080516020613eb2833981519152604482015290519081900360640190fd5b33600090815260056020526040902060018101546127b8908363ffffffff612cb816565b60018201556127c733836139c7565b604080513381526020810184905281517fdf8cebdea6ef1fd20576b80bc951377c0e61e2a8169153a1f836673ccce80e62929181900390910190a15050565b61280e611c1b565b5061148282826121d3565b612821611db2565b612860576040805162461bcd60e51b8152602060048201819052602482015260008051602061401e833981519152604482015290519081900360640190fd5b60c88411156128a05760405162461bcd60e51b8152600401808060200182810382526025815260200180613ef86025913960400191505060405180910390fd5b6103e88311156128e15760405162461bcd60e51b815260040180806020018281038252602b815260200180613da9602b913960400191505060405180910390fd5b6064821115612937576040805162461bcd60e51b815260206004820181905260248201527f43616e27742068617665207472616e73616374696f6e20666565203e20313025604482015290519081900360640190fd5b600a8110156129775760405162461bcd60e51b8152600401808060200182810382526028815260200180613d816028913960400191505060405180910390fd5b6007849055600b8390556009829055600d8190557f3450d20c21ea671871fed271900cc8ff03badafa9b6fe2ff7f86991950e86b6b848484846129b8611da3565b6040805195865260208601949094528484019290925260608401526001600160a01b03166080830152519081900360a00190a150505050565b6129f9611db2565b612a38576040805162461bcd60e51b8152602060048201819052602482015260008051602061401e833981519152604482015290519081900360640190fd5b612a4181613ae1565b50565b6001600160a01b03161590565b612a5a33611290565b612a99576040805162461bcd60e51b81526020600482015260146024820152600080516020613eb2833981519152604482015290519081900360640190fd5b3360009081526005602052604090206002810154612af6576040805162461bcd60e51b81526020600482015260156024820152744e6f20756e6465726c79696e672062616c616e636560581b604482015290519081900360640190fd5b6002810180546000909155612b0b33826137fd565b6040805182815233602082015281517fea0bff65fa9380b944e9a761f9c6a665ad2d31e74706a52773ddb45c8a57c83d929181900390910190a15050565b6000612b53611dd6565b15612b93576040805162461bcd60e51b81526020600482015260186024820152600080516020614105833981519152604482015290519081900360640190fd5b6001600160a01b03831660009081526005602052604090208054612bbd908463ffffffff612cfa16565b908190559392505050565b3390565b6001600160a01b038316612c115760405162461bcd60e51b81526004018080602001828103825260248152602001806140b36024913960400191505060405180910390fd5b6001600160a01b038216612c565760405162461bcd60e51b8152600401808060200182810382526022815260200180613e446022913960400191505060405180910390fd5b6001600160a01b03808416600081815260026020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b600061113583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506130a9565b600082820183811015611135576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600080612d75601660089054906101000a90046001600160a01b0316613b81565b601854909150600090612d90906001600160a01b0316613b81565b600f54600d54919250600091612dbe9190612db290889063ffffffff6137a416565b9063ffffffff6137a416565b601054600e54919250600391820b910b016000612de5846125e58a8863ffffffff6137a416565b601654909150600390810b90600090819085810b9084900b1215612e295782850360030b915083612e2087600a85900a63ffffffff6137a416565b11159050612e4b565b84830360030b9150612e4584600a84900a63ffffffff6137a416565b86111590505b9a9950505050505050505050565b6001600160a01b038216612eb4576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b600354612ec7908263ffffffff612cfa16565b6003556001600160a01b038216600090815260016020526040902054612ef3908263ffffffff612cfa16565b6001600160a01b03831660008181526001602090815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b6001600160a01b038316612f905760405162461bcd60e51b815260040180806020018281038252602581526020018061408e6025913960400191505060405180910390fd5b6001600160a01b038216612fd55760405162461bcd60e51b8152600401808060200182810382526023815260200180613d5e6023913960400191505060405180910390fd5b61301881604051806060016040528060268152602001613ed2602691396001600160a01b038616600090815260016020526040902054919063ffffffff6130a916565b6001600160a01b03808516600090815260016020526040808220939093559084168152205461304d908263ffffffff612cfa16565b6001600160a01b0380841660008181526001602090815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600081848411156131385760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156130fd5781810151838201526020016130e5565b50505050905090810190601f16801561312a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b6001600160a01b031660009081526005602052604090205490565b60165461317790600160401b90046001600160a01b0316612a44565b156131b8576040516001600160a01b0383169082156108fc029083906000818181858888f193505050501580156131b2573d6000803e3d6000fd5b50611482565b6016546040805163a9059cbb60e01b81526001600160a01b038581166004830152602482018590529151600160401b9093049091169163a9059cbb916044808201926020929091908290030181600087803b15801561321657600080fd5b505af115801561322a573d6000803e3d6000fd5b505050506040513d602081101561324057600080fd5b50505050565b61324e6112b5565b6132895760405162461bcd60e51b815260040180806020018281038252602d815260200180613fc9602d913960400191505060405180910390fd5b61329281611290565b6132d1576040805162461bcd60e51b81526020600482015260146024820152600080516020613eb2833981519152604482015290519081900360640190fd5b6001600160a01b03811660009081526005602052604090208261333b576040805162461bcd60e51b815260206004820152601860248201527f43616e27742065786572636973652030206f546f6b656e730000000000000000604482015290519081900360640190fd5b806001015483111561337e5760405162461bcd60e51b815260040180806020018281038252602e8152602001806140d7602e913960400191505060405180910390fd5b8261338833611b6f565b10156133d0576040805162461bcd60e51b81526020600482015260126024820152714e6f7420656e6f756768206f546f6b656e7360701b604482015290519081900360640190fd5b60006133db84611b2b565b60028301549091506133f3908263ffffffff612cfa16565b600283015560408051808201909152600181526000602082018190529061341b9086906138a3565b604080518082019091526009548152600a54600390810b810b900b602082015290915060009061344c9087906138a3565b601454909150613462908263ffffffff612cfa16565b6014556000613477838363ffffffff612cfa16565b85549091508111156134d0576040805162461bcd60e51b815260206004820181905260248201527f5661756c7420756e64657277617465722c2063616e2774206578657263697365604482015290519081900360640190fd5b84546134e2908263ffffffff612cb816565b855560018501546134f9908863ffffffff612cb816565b6001860155601754613513906001600160a01b0316612a44565b1561356757833414613562576040805162461bcd60e51b8152602060048201526013602482015272496e636f7272656374206d73672e76616c756560681b604482015290519081900360640190fd5b61363e565b601754604080516323b872dd60e01b81523360048201523060248201526044810187905290516001600160a01b03909216916323b872dd916064808201926020929091908290030181600087803b1580156135c157600080fd5b505af11580156135d5573d6000803e3d6000fd5b505050506040513d60208110156135eb57600080fd5b505161363e576040805162461bcd60e51b815260206004820152601c60248201527f436f756c64206e6f74207472616e7366657220696e20746f6b656e7300000000604482015290519081900360640190fd5b61364833886139c7565b613652338461315b565b604080518581526020810185905233818301526001600160a01b038816606082015290517ffa7bab37479e50a9b24a9412b879d400de9bcaa1e3a2b343e90bb370d85bbaa79181900360800190a150505050505050565b6000806136ca601660089054906101000a90046001600160a01b0316613b81565b6018549091506000906136e5906001600160a01b0316613b81565b600f5485519192506000916136ff9163ffffffff6137a416565b601054602087015191925060030b016000613724846125e58a8863ffffffff6137a416565b601654909150600390810b90600090819085810b9084900b12156137755782850360030b915061376e61376187600a85900a63ffffffff6137a416565b859063ffffffff61398516565b9050612e4b565b84830360030b9150613795866125e586600a86900a63ffffffff6137a416565b9b9a5050505050505050505050565b6000826137b357506000611138565b828202828482816137c057fe5b04146111355760405162461bcd60e51b8152600401808060200182810382526021815260200180613f816021913960400191505060405180910390fd5b601754613812906001600160a01b0316612a44565b1561384d576040516001600160a01b0383169082156108fc029083906000818181858888f193505050501580156131b2573d6000803e3d6000fd5b6017546040805163a9059cbb60e01b81526001600160a01b038581166004830152602482018590529151919092169163a9059cbb9160448083019260209291908290030181600087803b15801561321657600080fd5b6000806138c4601660089054906101000a90046001600160a01b0316613b81565b6018549091506000906138df906001600160a01b0316613b81565b9050600061390782612db28760000151612db2600f600001548b6137a490919063ffffffff16565b6016546020870151601054929350600391820b92820b01919091039060009082900b811215613955578161394d866125e58663ffffffff808616600a0a8116906137a416565b91505061397a565b6000829003613976866125e58663ffffffff808616600a0a81169061398516565b9150505b979650505050505050565b600061113583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613c49565b6001600160a01b038216613a0c5760405162461bcd60e51b815260040180806020018281038252602181526020018061403e6021913960400191505060405180910390fd5b613a4f81604051806060016040528060228152602001613dd4602291396001600160a01b038516600090815260016020526040902054919063ffffffff6130a916565b6001600160a01b038316600090815260016020526040902055600354613a7b908263ffffffff612cb816565b6003556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b031660009081526005602052604090206001015490565b6001600160a01b038116613b265760405162461bcd60e51b8152600401808060200182810382526026815260200180613e1e6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6018546016546000916001600160a01b03908116600160401b909204161415613bac575060016112b0565b6001600160a01b038216613bc95750670de0b6b3a76400006112b0565b601954604080516341976e0960e01b81526001600160a01b038581166004830152915191909216916341976e09916024808301926020929190829003018186803b158015613c1657600080fd5b505afa158015613c2a573d6000803e3d6000fd5b505050506040513d6020811015613c4057600080fd5b505190506112b0565b60008183613c985760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156130fd5781810151838201526020016130e5565b506000838581613ca457fe5b0495945050505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10613cef57805160ff1916838001178555613d1c565b82800160010185558215613d1c579182015b82811115613d1c578251825591602001919060010190613d01565b50613d28929150613d43565b5090565b604080518082019091526000808252602082015290565b6111e291905b80821115613d285760008155600101613d4956fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737343616e27742068617665206d696e436f6c6c61746572616c697a6174696f6e526174696f203c203143616e2774206c6971756964617465206d6f7265207468616e2031303025206f6620746865207661756c7445524332303a206275726e20616d6f756e7420657863656564732062616c616e6365455448206973206e6f74207468652073706563696669656420636f6c6c61746572616c20747970654f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737343616e277420636f6c6c65637420636f6c6c61746572616c20756e74696c20657870697279436f756c64206e6f74207472616e7366657220696e20636f6c6c61746572616c20746f6b656e735661756c7420646f6573206e6f7420657869737400000000000000000000000045524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636543616e27742068617665203e323025206c69717569646174696f6e20696e63656e74697665537065636966696564207661756c7473206861766520696e73756666696369656e7420636f6c6c61746572616c43616e206f6e6c79206c6971756964617465206c69717569646174696f6e20666163746f7220617420616e7920676976656e2074696d65536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7743616e27742072656d6f7665206d6f726520636f6c6c61746572616c207468616e206f776e656443616e2774206578657263697365206f757473696465206f66207468652065786572636973652077696e646f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63654f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657245524332303a206275726e2066726f6d20746865207a65726f206164647265737343616e6e6f742065786572636973652066726f6d2061207661756c74207468617420646f65736e277420657869737445524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737343616e2774206578657263697365206d6f7265206f546f6b656e73207468616e20746865206f776e6572206861734f7074696f6e7320636f6e74726163742065787069726564000000000000000045524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa265627a7a7230582024408987c6dcfcda4c0e73ff0354366a3d057faa494c86e0ef89208047b75fda64736f6c634300050a0032
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000000000000000000000000000000000000000000000000000001fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000005e81368000000000000000000000000039246c4f3f6592c974ebc44f80ba6dc69b817c710000000000000000000000007054e08461e3ecb7718b63540addb3c3a1746415000000000000000000000000000000000000000000000000000000005e813680
-----Decoded View---------------
Arg [0] : _collateral (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [1] : _collExp (int32): -6
Arg [2] : _underlying (address): 0x0000000000000000000000000000000000000000
Arg [3] : _underlyingExp (int32): -18
Arg [4] : _oTokenExchangeExp (int32): -8
Arg [5] : _strikePrice (uint256): 1
Arg [6] : _strikeExp (int32): -6
Arg [7] : _strike (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [8] : _expiry (uint256): 1585526400
Arg [9] : _optionsExchange (address): 0x39246c4F3F6592C974EBC44F80bA6dC69b817c71
Arg [10] : _oracleAddress (address): 0x7054e08461e3eCb7718B63540adDB3c3A1746415
Arg [11] : _windowSize (uint256): 1585526400
-----Encoded View---------------
12 Constructor Arguments found :
Arg [0] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [1] : fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [3] : ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffee
Arg [4] : fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [6] : fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa
Arg [7] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [8] : 000000000000000000000000000000000000000000000000000000005e813680
Arg [9] : 00000000000000000000000039246c4f3f6592c974ebc44f80ba6dc69b817c71
Arg [10] : 0000000000000000000000007054e08461e3ecb7718b63540addb3c3a1746415
Arg [11] : 000000000000000000000000000000000000000000000000000000005e813680
Deployed Bytecode Sourcemap
76622:7558:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51764:480;;8:9:-1;5:2;;;30:1;27;20:12;5:2;51764:480:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;51764:480:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;45813:383;;8:9:-1;5:2;;;30:1;27;20:12;5:2;45813:383: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;45813:383:0;;;;;;;;;;;;;;;;;41356:18;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41356:18: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;41356:18:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12136:152;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12136:152:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;12136:152:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;49046:113;;8:9:-1;5:2;;;30:1;27;20:12;5:2;49046:113:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;49046:113:0;-1:-1:-1;;;;;49046:113:0;;:::i;52762:169::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52762:169:0;;;:::i;57143:342::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57143:342:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;57143:342:0;-1:-1:-1;;;;;57143:342:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11157:91;;8:9:-1;5:2;;;30:1;27;20:12;5:2;11157:91:0;;;:::i;56216:788::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56216:788:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;56216:788:0;;;;;;-1:-1:-1;;;;;56216:788:0;;:::i;:::-;;12760:304;;8:9:-1;5:2;;;30:1;27;20:12;5:2;12760:304:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;12760:304:0;;;;;;;;;;;;;;;;;:::i;41495:21::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41495:21:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;83697:480;;8:9:-1;5:2;;;30:1;27;20:12;5:2;83697:480:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;83697:480:0;;;;;;;;;;;-1:-1:-1;;;;;83697:480:0;;:::i;58613:870::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58613:870:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;58613:870:0;;:::i;39993:49::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39993:49:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;79931:435;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;79931:435:0;;;;;;-1:-1:-1;;;;;79931:435:0;;:::i;13473:210::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;13473:210:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;13473:210:0;;;;;;;;:::i;39532:38::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39532:38:0;;;:::i;:::-;;;;-1:-1:-1;;;;;39532:38:0;;;;;;;;;;;;;;81607:245;;8:9:-1;5:2;;;30:1;27;20:12;5:2;81607:245:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;81607:245:0;;;;;;;;;;;-1:-1:-1;;;;;81607:245:0;;:::i;53860:1013::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;53860:1013:0;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;53860:1013:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;53860:1013:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;53860:1013:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;53860:1013:0;;-1:-1:-1;53860:1013:0;;-1:-1:-1;;;;;53860:1013:0:i;82391:247::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;82391:247:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;82391:247:0;;;;;;;;;;;-1:-1:-1;;;;;82391:247:0;;:::i;71588:199::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;71588:199:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;71588:199:0;;:::i;41108:24::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41108:24:0;;;:::i;52361:320::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52361:320:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;52361:320:0;;:::i;11311:110::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;11311:110:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;11311:110:0;-1:-1:-1;;;;;11311:110:0;;:::i;38138:140::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38138:140:0;;;:::i;49281:284::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;49281:284:0;;;:::i;41267:46::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41267:46:0;;;:::i;39714:51::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39714:51:0;;;:::i;37327:79::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37327:79:0;;;:::i;37693:94::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;37693:94:0;;;:::i;53021:102::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53021:102:0;;;:::i;41419:20::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41419:20:0;;;:::i;50369:418::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;50369:418:0;-1:-1:-1;;;;;50369:418:0;;:::i;39808:44::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;39808:44:0;;;:::i;14186:261::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;14186:261:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;14186:261:0;;;;;;;;:::i;11634:158::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;11634:158:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;11634:158:0;;;;;;;;:::i;41197:20::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41197:20:0;;;:::i;40954:32::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40954:32:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;40873;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40873:32:0;;;:::i;40448:::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40448:32:0;;;:::i;59745:800::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59745:800:0;;;:::i;48110:361::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48110:361:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;48110:361:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;48110:361:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;48110:361:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;48110:361:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;48110:361:0;;;;;;;;-1:-1:-1;48110:361:0;;-1:-1:-1;;;;;5:28;;2:2;;;46:1;43;36:12;2:2;48110:361:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;48110:361:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;48110:361:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;48110:361:0;;-1:-1:-1;48110:361:0;;-1:-1:-1;;;;;48110:361:0:i;79501:202::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;79501:202:0;;;;;;-1:-1:-1;;;;;79501:202:0;;:::i;40240:56::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40240:56:0;;;:::i;62149:1984::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62149:1984:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;62149:1984:0;;;;;;;;:::i;40357:25::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40357:25:0;;;:::i;82936:478::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;82936:478:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;82936:478:0;;;;;;;;;;;-1:-1:-1;;;;;82936:478:0;;:::i;64321:241::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64321:241:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;64321:241:0;-1:-1:-1;;;;;64321:241:0;;:::i;80616:437::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;80616:437:0;;;;;;-1:-1:-1;;;;;80616:437:0;;:::i;41024:24::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41024:24:0;;;:::i;11855:134::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;11855:134:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;11855:134:0;;;;;;;;;;:::i;60742:790::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;60742:790:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;60742:790:0;-1:-1:-1;;;;;60742:790:0;;:::i;40803:21::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;40803:21:0;;;:::i;48652:219::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;48652:219:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;48652:219:0;-1:-1:-1;;;;;48652:219:0;;:::i;58007:343::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58007:343:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;58007:343:0;;:::i;78799:200::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;78799:200:0;;;;;;-1:-1:-1;;;;;78799:200:0;;:::i;46759:1126::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;46759:1126:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;46759:1126:0;;;;;;;;;;;;;;;;;:::i;38433:109::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;38433:109:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;38433:109:0;-1:-1:-1;;;;;38433:109:0;;:::i;57607:104::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57607:104:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;57607:104:0;-1:-1:-1;;;;;57607:104:0;;:::i;55006:449::-;;8:9:-1;5:2;;;30:1;27;20:12;5:2;55006:449:0;;;:::i;51764:480::-;51887:7;45666:12;:10;:12::i;:::-;45665:13;45657:50;;;;;-1:-1:-1;;;45657:50:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45657:50:0;;;;;;;;;;;;;;;51934:10;;:55;;;-1:-1:-1;;;51934:55:0;;51958:10;51934:55;;;;51978:4;51934:55;;;;;;;;;;;;-1:-1:-1;;;51934:10:0;;;-1:-1:-1;;;;;51934:10:0;;:23;;:55;;;;;;;;;;;;;;;-1:-1:-1;51934:10:0;:55;;;5:2:-1;;;;30:1;27;20:12;5:2;51934:55:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51934:55:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;51934:55:0;51912:144;;;;-1:-1:-1;;;51912:144:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52075:20;52084:10;52075:8;:20::i;:::-;52067:53;;;;;-1:-1:-1;;;52067:53:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;52067:53:0;;;;;;;;;;;;;;;52138:49;;;-1:-1:-1;;;;;52138:49:0;;;;;;;;;;52176:10;52138:49;;;;;;;;;;;;;;;52205:31;52220:10;52232:3;52205:14;:31::i;:::-;52198:38;;45718:1;51764:480;;;;:::o;45813:383::-;45860:24;;45939:13;;45967:196;45991:11;:18;45987:22;;45967:196;;;46035:24;46044:11;46056:1;46044:14;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;46044:14:0;46035:8;:24::i;:::-;46031:121;;;46096:11;46108:1;46096:14;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;46096:14:0;46080:6;46087:5;46080:13;;;;;;;;-1:-1:-1;;;;;46080:30:0;;;:13;;;;;;;;;;;:30;46129:7;;;;;46031:121;46011:3;;45967:196;;;-1:-1:-1;46182:6:0;;-1:-1:-1;;45813:383:0;;:::o;41356:18::-;;;;;;;;;;;;;;;-1:-1:-1;;41356:18:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;12136:152::-;12202:4;12219:39;12228:12;:10;:12::i;:::-;12242:7;12251:6;12219:8;:39::i;:::-;-1:-1:-1;12276:4:0;12136:152;;;;:::o;49046:113::-;-1:-1:-1;;;;;49132:13:0;;49108:4;49132:13;;;:6;:13;;;;;:19;;;;;49046:113;;;;:::o;52762:169::-;52811:4;52856:22;52867:10;;52856:6;;:10;;:22;;;;:::i;:::-;52837:15;:41;;52836:86;;;;;52915:6;;52897:15;:24;52836:86;52828:95;;52762:169;:::o;57143:342::-;-1:-1:-1;;;;;57308:18:0;57237:7;57308:18;;;:6;:18;;;;;57359:16;;57390:19;;;;57424:16;;;;57455:11;;;;;57359:16;;57390:19;;57424:16;57455:11;;;57143:342::o;11157:91::-;11228:12;;11157:91;:::o;56216:788::-;45666:12;:10;:12::i;:::-;45665:13;45657:50;;;;;-1:-1:-1;;;45657:50:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45657:50:0;;;;;;;;;;;;;;;56462:20;56471:10;56462:8;:20::i;:::-;56454:53;;;;;-1:-1:-1;;;56454:53:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56454:53:0;;;;;;;;;;;;;;;56549:10;56520:19;56542:18;;;:6;:18;;;;;56666:19;;;;56542:18;;56520:19;56666:39;;56690:14;56666:39;:23;:39;:::i;:::-;56638:67;;56724:43;56731:5;:16;;;56749:17;56724:6;:43::i;:::-;56716:70;;;;;-1:-1:-1;;;56716:70:0;;;;;;;;;;;;-1:-1:-1;;;56716:70:0;;;;;;;;;;;;;;;56829:19;;;:39;;;56879:31;56885:8;56895:14;56879:5;:31::i;:::-;56928:51;;;-1:-1:-1;;;;;56928:51:0;;;;;;;;;;56968:10;56928:51;;;;;;;;;;;;;;;56990:7;;45718:1;56216:788;;:::o;12760:304::-;12849:4;12866:36;12876:6;12884:9;12895:6;12866:9;:36::i;:::-;12913:121;12922:6;12930:12;:10;:12::i;:::-;12944:89;12982:6;12944:89;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;12944:19:0;;;;;;:11;:19;;;;;;12964:12;:10;:12::i;:::-;-1:-1:-1;;;;;12944:33:0;;;;;;;;;;;;-1:-1:-1;12944:33:0;;;:89;;:37;:89;:::i;:::-;12913:8;:121::i;:::-;-1:-1:-1;13052:4:0;12760:304;;;;;:::o;41495:21::-;;;;;;:::o;83697:480::-;83860:45;83879:10;83891:13;83860:18;:45::i;:::-;;83916:40;83929:11;83950:4;83916:12;:40::i;:::-;83988:15;;;83967:51;;;-1:-1:-1;;;83967:51:0;;-1:-1:-1;;;;;83988:15:0;;;83967:51;;;;;;;;;;;;;;;:4;;:12;;:51;;;;;;;;;;;;;;-1:-1:-1;83967:4:0;:51;;;5:2:-1;;;;30:1;27;20:12;5:2;83967:51:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;83967:51:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;84029:15:0;;;:140;;;-1:-1:-1;;;84029:140:0;;-1:-1:-1;;;;;84029:140:0;;;;;;;;;;84102:4;84029:140;;;;:15;:140;;;;;;;;;;;;;;:15;;;;;:27;;:140;;;;;:15;:140;;;;;;:15;;:140;;;5:2:-1;;;;30:1;27;20:12;5:2;84029:140:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;84029:140:0;;;;83697:480;;;:::o;58613:870::-;45666:12;:10;:12::i;:::-;45665:13;45657:50;;;;;-1:-1:-1;;;45657:50:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45657:50:0;;;;;;;;;;;;;;;58711:1;58697:11;:15;58689:54;;;;;-1:-1:-1;;;58689:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;58762:20;58771:10;58762:8;:20::i;:::-;58754:53;;;;;-1:-1:-1;;;58754:53:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;58754:53:0;;;;;;;;;;;;;;;58849:10;58820:19;58842:18;;;:6;:18;;;;;;58908:25;;:13;:25::i;:::-;58893:11;:40;;58871:129;;;;-1:-1:-1;;;58871:129:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59116:16;;59085:28;;59116:33;;59137:11;59116:33;:20;:33;:::i;:::-;59085:64;;59184:49;59191:20;59213:5;:19;;;59184:6;:49::i;:::-;59162:114;;;;;-1:-1:-1;;;59162:114:0;;;;;;;;;;;;-1:-1:-1;;;59162:114:0;;;;;;;;;;;;;;;59323:39;;;59373:43;59392:10;59404:11;59373:18;:43::i;:::-;59434:41;;;;;;59464:10;59434:41;;;;;;;;;;;;;;;;;45718:1;;58613:870;:::o;39993:49::-;;;;;;;;:::o;79931:435::-;80073:11;:9;:11::i;:::-;;80095:50;80118:11;80139:4;80095:22;:50::i;:::-;80177:15;;;80156:51;;;-1:-1:-1;;;80156:51:0;;-1:-1:-1;;;;;80177:15:0;;;80156:51;;;;;;;;;;;;;;;:4;;:12;;:51;;;;;;;;;;;;;;-1:-1:-1;80156:4:0;:51;;;5:2:-1;;;;30:1;27;20:12;5:2;80156:51:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;80156:51:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;80218:15:0;;;:140;;;-1:-1:-1;;;80218:140:0;;-1:-1:-1;;;;;80218:140:0;;;;;;;;;;80291:4;80218:140;;;;:15;:140;;;;;;;;;;;;;;:15;;;;;:27;;:140;;;;;:15;:140;;;;;;:15;;:140;;;5:2:-1;;;;30:1;27;20:12;5:2;80218:140:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;80218:140:0;;;;79931:435;;:::o;13473:210::-;13553:4;13570:83;13579:12;:10;:12::i;:::-;13593:7;13602:50;13641:10;13602:11;:25;13614:12;:10;:12::i;:::-;-1:-1:-1;;;;;13602:25:0;;;;;;;;;;;;;;;;;-1:-1:-1;13602:25:0;;;:34;;;;;;;;;;;:50;:38;:50;:::i;39532:38::-;;;-1:-1:-1;;;;;39532:38:0;;:::o;81607:245::-;81760:11;:9;:11::i;:::-;;81782:62;81807:11;81820:13;81835:8;81782:24;:62::i;:::-;81607:245;;;:::o;53860:1013::-;54008:9;54003:735;54027:20;:27;54023:1;:31;54003:735;;;54076:26;54105:20;54126:1;54105:23;;;;;;;;;;;;;;54076:52;;54169:20;54178:10;54169:8;:20::i;:::-;54143:129;;;;-1:-1:-1;;;54143:129:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;54309:18:0;;54287:19;54309:18;;;:6;:18;;;;;54346:22;54342:385;;54389:7;;;;;54342:385;54444:17;54421:5;:19;;;:40;54417:310;;54482:40;54492:17;54511:10;54482:9;:40::i;:::-;54541:7;;;;;54417:310;54630:19;;;;54608:42;;:17;;:42;:21;:42;:::i;:::-;54588:62;;54669:42;54679:5;:19;;;54700:10;54669:9;:42::i;:::-;-1:-1:-1;;54056:3:0;;54003:735;;;-1:-1:-1;54770:22:0;;54748:117;;;;-1:-1:-1;;;54748:117:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82391:247;82539:45;82558:10;82570:13;82539:18;:45::i;:::-;;82595:35;82608:11;82621:8;82595:12;:35::i;71588:199::-;71719:58;;;;;;;;;71751:25;71719:58;;;;;;;;;;;;;;;;;71687:7;;71719:58;;71736:13;;71719:16;:58::i;41108:24::-;;;-1:-1:-1;;;;;41108:24:0;;:::o;52361:320::-;52582:13;;52552:27;;52474:7;;-1:-1:-1;;;52582:13:0;;;;;;52552:27;;;:43;;;;52531:75;;52624:49;:17;52646:26;;;;:2;:26;52624:49;;:21;:49;:::i;:::-;52617:56;52361:320;-1:-1:-1;;;52361:320:0:o;11311:110::-;-1:-1:-1;;;;;11395:18:0;11368:7;11395:18;;;:9;:18;;;;;;;11311:110::o;38138:140::-;37539:9;:7;:9::i;:::-;37531:54;;;;;-1:-1:-1;;;37531:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;37531:54:0;;;;;;;;;;;;;;;38237:1;38221:6;;38200:40;;-1:-1:-1;;;;;38221:6:0;;;;38200:40;;38237:1;;38200:40;38268:1;38251:19;;-1:-1:-1;;;;;;38251:19:0;;;38138:140::o;49281:284::-;49329:4;45666:12;:10;:12::i;:::-;45665:13;45657:50;;;;;-1:-1:-1;;;45657:50:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45657:50:0;;;;;;;;;;;;;;;49355:20;49364:10;49355:8;:20::i;:::-;49354:21;49346:55;;;;;-1:-1:-1;;;49346:55:0;;;;;;;;;;;;-1:-1:-1;;;49346:55:0;;;;;;;;;;;;;;;49435:20;;;;;;;;-1:-1:-1;49435:20:0;;;;;;;;;;;;;;;;49450:4;49435:20;;;;;;49421:10;49414:18;;;:6;:18;;;;;:41;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;49414:41:0;;;;;;;;;;;49466:11;27:10:-1;;23:18;;;45:23;;49466:28:0;;;;;;;;;-1:-1:-1;;;;;;49466:28:0;;;;;49512:23;;;;;;;;;;;;;;;;;-1:-1:-1;49553:4:0;49281:284;:::o;41267:46::-;;;-1:-1:-1;;;;;41267:46:0;;:::o;39714:51::-;;;;;;;;:::o;37327:79::-;37365:7;37392:6;-1:-1:-1;;;;;37392:6:0;37327:79;:::o;37693:94::-;37733:4;37773:6;;-1:-1:-1;;;;;37773:6:0;37757:12;:10;:12::i;:::-;-1:-1:-1;;;;;37757:22:0;;37750:29;;37693:94;:::o;53021:102::-;53108:6;;53089:15;:25;;53021:102;:::o;41419:20::-;;;;;;;;;;;;;;;-1:-1:-1;;41419:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50369:418;50494:7;45666:12;:10;:12::i;:::-;45665:13;45657:50;;;;;-1:-1:-1;;;45657:50:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45657:50:0;;;;;;;;;;;;;;;50533:10;;50527:17;;-1:-1:-1;;;50533:10:0;;-1:-1:-1;;;;;50533:10:0;50527:5;:17::i;:::-;50519:70;;;;-1:-1:-1;;;50519:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50608:20;50617:10;50608:8;:20::i;:::-;50600:53;;;;;-1:-1:-1;;;50600:53:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;50600:53:0;;;;;;;;;;;;;;;50671;;;-1:-1:-1;;;;;50671:53:0;;;;50702:9;50671:53;;;;50713:10;50671:53;;;;;;;;;;;;;;;50742:37;50757:10;50769:9;50742:14;:37::i;39808:44::-;;;;;;;;:::o;14186:261::-;14271:4;14288:129;14297:12;:10;:12::i;:::-;14311:7;14320:96;14359:15;14320:96;;;;;;;;;;;;;;;;;:11;:25;14332:12;:10;:12::i;:::-;-1:-1:-1;;;;;14320:25:0;;;;;;;;;;;;;;;;;-1:-1:-1;14320:25:0;;;:34;;;;;;;;;;;:96;;:38;:96;:::i;11634:158::-;11703:4;11720:42;11730:12;:10;:12::i;:::-;11744:9;11755:6;11720:9;:42::i;41197:20::-;;;-1:-1:-1;;;;;41197:20:0;;:::o;40954:32::-;;;-1:-1:-1;;;40954:32:0;;;;;:::o;40873:::-;;;;;;:::o;40448:::-;;;;;;;;:::o;59745:800::-;59801:12;:10;:12::i;:::-;59793:62;;;;-1:-1:-1;;;59793:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59874:20;59883:10;59874:8;:20::i;:::-;59866:53;;;;;-1:-1:-1;;;59866:53:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;59866:53:0;;;;;;;;;;;;;;;59999:10;59970:19;59992:18;;;:6;:18;;;;;60095:16;;60153;;;;;60182:20;;;-1:-1:-1;60213:19:0;;:23;;;60247:20;;;59992:18;;60095:16;;60153;60280:52;;60095:16;60280:18;:52::i;:::-;60343;60362:10;60374:20;60343:18;:52::i;:::-;60413:124;;;;;;;;;;;;60516:10;60413:124;;;;;;;;;;;;;;;59745:800;;;:::o;48110:361::-;37539:9;:7;:9::i;:::-;37531:54;;;;;-1:-1:-1;;;37531:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;37531:54:0;;;;;;;;;;;;;;;48225:12;;;;:4;;:12;;;;;:::i;:::-;-1:-1:-1;48248:16:0;;;;:6;;:16;;;;;:::i;:::-;-1:-1:-1;48297:27:0;;48275:8;:50;;-1:-1:-1;;48275:50:0;48297:27;;;;;;48292:32;48275:50;;;;;;;;48336:127;;79501:202;79621:28;79638:10;79621:16;:28::i;:::-;;79660:35;79673:11;79686:8;79660:12;:35::i;40240:56::-;;;;;;;;:::o;62149:1984::-;45666:12;:10;:12::i;:::-;45665:13;45657:50;;;;;-1:-1:-1;;;45657:50:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45657:50:0;;;;;;;;;;;;;;;62284:20;62293:10;62284:8;:20::i;:::-;62276:53;;;;;-1:-1:-1;;;62276:53:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;62276:53:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;62364:18:0;;62342:19;62364:18;;;:6;:18;;;;;62446:20;62371:10;62446:8;:20::i;:::-;62438:46;;;;;-1:-1:-1;;;62438:46:0;;;;;;;;;;;;-1:-1:-1;;;62438:46:0;;;;;;;;;;;;;;;62550:10;-1:-1:-1;;;;;62550:24:0;;;;62542:69;;;;;-1:-1:-1;;;62542:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62624:21;62648:95;62687:18;62720:12;;;;;;;;62727:1;62720:12;;;;62730:1;62720:12;;;;;62648:24;:95::i;:::-;62777:103;;;;;;;;;62849:20;62777:103;;;;;;;;;;;;;;;;;62624:119;;-1:-1:-1;62754:20:0;;62777:103;;62816:18;;62777:24;:103::i;:::-;62754:126;-1:-1:-1;62891:26:0;62920:31;:13;62754:126;62920:31;:17;:31;:::i;:::-;63113:17;:23;63078:16;;62891:60;;-1:-1:-1;63042:33:0;;63078:69;;;:20;:69;:::i;:::-;63164:26;;63042:105;;-1:-1:-1;63193:1:0;63164:26;;;;:30;;;;63160:361;;;63299:26;;63239:102;;:25;;63299:26;;;;63291:35;;63287:2;:39;63239:102;:29;:102;:::i;:::-;63211:130;;63160:361;;;63467:26;;63402:107;;:25;;63467:26;;;;;63462:31;63454:40;;63450:2;:44;63402:107;:29;:107;:::i;:::-;63374:135;;63160:361;63577:25;63555:18;:47;;63533:152;;;;-1:-1:-1;;;63533:152:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63769:16;;:40;;63790:18;63769:40;:20;:40;:::i;:::-;63750:59;;63842:19;;;;:43;;63866:18;63842:43;:23;:43;:::i;:::-;63820:19;;;:65;63956:37;63962:10;63974:18;63956:5;:37::i;:::-;64004:50;64023:10;64035:18;64004;:50::i;:::-;64072:53;;;;;;-1:-1:-1;;;;;64072:53:0;;;;;;64114:10;64072:53;;;;;;;;;;;;;;;45718:1;;;;;62149:1984;;:::o;40357:25::-;;;;;;;;:::o;82936:478::-;83104:11;:9;:11::i;:::-;;83126:67;83151:11;83164:13;83187:4;83126:24;:67::i;64321:241::-;64388:4;64405:16;64425:100;64446:25;64460:10;64446:13;:25::i;:::-;64486:28;64503:10;64486:16;:28::i;:::-;64425:6;:100::i;:::-;64424:101;;64321:241;-1:-1:-1;;;64321:241:0:o;80616:437::-;80753:28;80770:10;80753:16;:28::i;:::-;;80792:40;80805:11;80826:4;80792:12;:40::i;41024:24::-;;;-1:-1:-1;;;41024:24:0;;-1:-1:-1;;;;;41024:24:0;;:::o;11855:134::-;-1:-1:-1;;;;;11954:18:0;;;11927:7;11954:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;11855:134::o;60742:790::-;60850:7;60879:20;60888:10;60879:8;:20::i;:::-;60875:650;;;-1:-1:-1;;;;;60938:18:0;;60916:19;60938:18;;;:6;:18;;;;;61124:26;;:17;61064:23;61007:34;;60938:18;;60916:19;61007:145;;61124:26;;;;61123:27;;61115:36;;61111:2;:40;;61007:81;;:34;:81;:56;:81;:::i;:::-;:103;:145;:103;:145;:::i;:::-;61196:29;;60971:181;;-1:-1:-1;61196:29:0;;;;61169:11;61195:30;61187:39;;61183:2;:43;61241:26;;:::i;:::-;61270:123;;;;;;;;;61295:20;:26;61270:123;;61295:35;;61326:3;61295:35;:30;:35;:::i;:::-;61270:123;;61349:29;;;;;;61270:123;;;;;;;61241:152;-1:-1:-1;61415:57:0;61432:25;61241:152;61415:16;:57::i;:::-;61408:64;;;;;;;;60875:650;-1:-1:-1;61512:1:0;61505:8;;40803:21;;;;:::o;48652:219::-;37539:9;:7;:9::i;:::-;37531:54;;;;;-1:-1:-1;;;37531:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;37531:54:0;;;;;;;;;;;;;;;48742:8;;;48727:12;48761;;;48784:34;48803:8;48742;48784:18;:34::i;:::-;48836:27;;;-1:-1:-1;;;;;48836:27:0;;;;;;;;;;;;;;;;;;;;;;;37596:1;48652:219;:::o;58007:343::-;45666:12;:10;:12::i;:::-;45665:13;45657:50;;;;;-1:-1:-1;;;45657:50:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45657:50:0;;;;;;;;;;;;;;;58084:20;58093:10;58084:8;:20::i;:::-;58076:53;;;;;-1:-1:-1;;;58076:53:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;58076:53:0;;;;;;;;;;;;;;;58171:10;58142:19;58164:18;;;:6;:18;;;;;58217:19;;;;:34;;58241:9;58217:34;:23;:34;:::i;:::-;58195:19;;;:56;58262:28;58268:10;58280:9;58262:5;:28::i;:::-;58308:34;;;58320:10;58308:34;;;;;;;;;;;;;;;;;;;;;45718:1;58007:343;:::o;78799:200::-;78924:11;:9;:11::i;:::-;;78946:45;78969:11;78982:8;78946:22;:45::i;46759:1126::-;37539:9;:7;:9::i;:::-;37531:54;;;;;-1:-1:-1;;;37531:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;37531:54:0;;;;;;;;;;;;;;;47023:3;46998:21;:28;;46976:115;;;;-1:-1:-1;;;46976:115:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47146:4;47124:18;:26;;47102:119;;;;-1:-1:-1;;;47102:119:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47259:3;47240:15;:22;;47232:67;;;;;-1:-1:-1;;;47232:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47362:2;47332:26;:32;;47310:122;;;;-1:-1:-1;;;47310:122:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47445:20;:50;;;47506:17;:44;;;47561:14;:38;;;47610:25;:60;;;47688:189;47474:21;47532:18;47584:15;47644:26;47859:7;:5;:7::i;:::-;47688:189;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;47688:189:0;;;;;;;;;;;;;;46759:1126;;;;:::o;38433:109::-;37539:9;:7;:9::i;:::-;37531:54;;;;;-1:-1:-1;;;37531:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;37531:54:0;;;;;;;;;;;;;;;38506:28;38525:8;38506:18;:28::i;:::-;38433:109;:::o;57607:104::-;-1:-1:-1;;;;;57683:20:0;;;57607:104::o;55006:449::-;55060:20;55069:10;55060:8;:20::i;:::-;55052:53;;;;;-1:-1:-1;;;55052:53:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;55052:53:0;;;;;;;;;;;;;;;55145:10;55116:19;55138:18;;;:6;:18;;;;;55177:16;;;;55169:54;;;;;-1:-1:-1;;;55169:54:0;;;;;;;;;;;;-1:-1:-1;;;55169:54:0;;;;;;;;;;;;;;;55267:16;;;;;55236:28;55294:20;;;55327:52;55346:10;55267:16;55327:18;:52::i;:::-;55395:50;;;;;;55434:10;55395:50;;;;;;;;;;;;;;;;;55006:449;;:::o;69502:285::-;69623:7;45666:12;:10;:12::i;:::-;45665:13;45657:50;;;;;-1:-1:-1;;;45657:50:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;45657:50:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;69670:18:0;;69648:19;69670:18;;;:6;:18;;;;;69718:16;;:25;;69739:3;69718:25;:20;:25;:::i;:::-;69699:44;;;;;69502:285;-1:-1:-1;;;69502:285:0:o;858:98::-;938:10;858:98;:::o;17118:338::-;-1:-1:-1;;;;;17212:19:0;;17204:68;;;;-1:-1:-1;;;17204:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;17291:21:0;;17283:68;;;;-1:-1:-1;;;17283:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;17364:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;17416:32;;;;;;;;;;;;;;;;;17118:338;;;:::o;5445:136::-;5503:7;5530:43;5534:1;5537;5530:43;;;;;;;;;;;;;;;;;:3;:43::i;4989:181::-;5047:7;5079:5;;;5103:6;;;;5095:46;;;;;-1:-1:-1;;;5095:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;70113:1227;70225:4;70281:28;70312:29;70329:10;;;;;;;;;-1:-1:-1;;;;;70329:10:0;70312:8;:29::i;:::-;70396:6;;70281:60;;-1:-1:-1;70352:24:0;;70379:25;;-1:-1:-1;;;;;70396:6:0;70379:8;:25::i;:::-;70635:11;:17;70584:25;:31;70352:52;;-1:-1:-1;70530:19:0;;70552:101;;70635:17;70552:64;;:13;;:64;:31;:64;:::i;:::-;:82;:101;:82;:101;:::i;:::-;70734:20;;70684:34;;70530:123;;-1:-1:-1;70734:20:0;70684:34;;;70734:20;;70684:70;70664:17;70790:87;70850:16;70791:39;:13;70809:20;70791:39;:17;:39;:::i;70790:87::-;70909:13;;70767:110;;-1:-1:-1;70909:13:0;;;;;70888:18;;;;71000:26;;;;;;;;70996:308;;;71057:26;;;71049:35;;;-1:-1:-1;71139:12:0;71111:24;:11;71127:2;:7;;;71111:24;:15;:24;:::i;:::-;:40;;71099:52;;70996:308;;;71198:26;;;71190:35;;;-1:-1:-1;71267:25:0;:12;71284:2;:7;;;71267:25;:16;:25;:::i;:::-;71252:11;:40;;71240:52;;70996:308;71323:9;70113:1227;-1:-1:-1;;;;;;;;;;70113:1227:0:o;15689:308::-;-1:-1:-1;;;;;15765:21:0;;15757:65;;;;;-1:-1:-1;;;15757:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;15850:12;;:24;;15867:6;15850:24;:16;:24;:::i;:::-;15835:12;:39;-1:-1:-1;;;;;15906:18:0;;;;;;:9;:18;;;;;;:30;;15929:6;15906:30;:22;:30;:::i;:::-;-1:-1:-1;;;;;15885:18:0;;;;;;:9;:18;;;;;;;;:51;;;;15952:37;;;;;;;15885:18;;;;15952:37;;;;;;;;;;15689:308;;:::o;14937:471::-;-1:-1:-1;;;;;15035:20:0;;15027:70;;;;-1:-1:-1;;;15027:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;15116:23:0;;15108:71;;;;-1:-1:-1;;;15108:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15212;15234:6;15212:71;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;15212:17:0;;;;;;:9;:17;;;;;;;:71;;:21;:71;:::i;:::-;-1:-1:-1;;;;;15192:17:0;;;;;;;:9;:17;;;;;;:91;;;;15317:20;;;;;;;:32;;15342:6;15317:32;:24;:32;:::i;:::-;-1:-1:-1;;;;;15294:20:0;;;;;;;:9;:20;;;;;;;;;:55;;;;15365:35;;;;;;;15294:20;;15365:35;;;;;;;;;;;;;14937:471;;;:::o;5918:192::-;6004:7;6040:12;6032:6;;;;6024:29;;;;-1:-1:-1;;;6024:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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;6024:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;6076:5:0;;;5918:192::o;64896:208::-;-1:-1:-1;;;;;65044:18:0;64997:7;65044:18;;;:6;:18;;;;;65080:16;;64896:208::o;75352:227::-;75447:10;;75441:17;;-1:-1:-1;;;75447:10:0;;-1:-1:-1;;;;;75447:10:0;75441:5;:17::i;:::-;75437:135;;;75475:20;;-1:-1:-1;;;;;75475:14:0;;;:20;;;;;75490:4;;75475:20;;;;75490:4;75475:14;:20;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;75475:20:0;75437:135;;;75528:10;;:32;;;-1:-1:-1;;;75528:32:0;;-1:-1:-1;;;;;75528:32:0;;;;;;;;;;;;;;;-1:-1:-1;;;75528:10:0;;;;;;;:19;;:32;;;;;;;;;;;;;;;-1:-1:-1;75528:10:0;:32;;;5:2:-1;;;;30:1;27;20:12;5:2;75528:32:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;75528:32:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;75352:227:0;;:::o;66386:2894::-;66582:18;:16;:18::i;:::-;66560:113;;;;-1:-1:-1;;;66560:113:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66694:29;66703:19;66694:8;:29::i;:::-;66686:62;;;;;-1:-1:-1;;;66686:62:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;66686:62:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;66783:27:0;;66761:19;66783:27;;;:6;:27;;;;;66829:21;66821:58;;;;;-1:-1:-1;;;66821:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;66988:5;:19;;;66967:17;:40;;66945:136;;;;-1:-1:-1;;;66945:136:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67192:17;67167:21;67177:10;67167:9;:21::i;:::-;:42;;67145:110;;;;;-1:-1:-1;;;67145:110:0;;;;;;;;;;;;-1:-1:-1;;;67145:110:0;;;;;;;;;;;;;;;67354:26;67383:71;67426:17;67383:28;:71::i;:::-;67484:16;;;;67354:100;;-1:-1:-1;67484:40:0;;67354:100;67484:40;:20;:40;:::i;:::-;67465:16;;;:59;67773:12;;;;;;;;;67780:1;67773:12;;67673:26;67773:12;;;;;;67673:26;67702:94;;67741:17;;67702:24;:94::i;:::-;67877:96;;;;;;;;;67948:14;67877:96;;;;;;;;;;;;;;;;;67673:123;;-1:-1:-1;67860:14:0;;67877:96;;67916:17;;67877:24;:96::i;:::-;67995:8;;67860:113;;-1:-1:-1;67995:20:0;;67860:113;67995:20;:12;:20;:::i;:::-;67984:8;:31;68028:28;68059:30;:18;68082:6;68059:30;:22;:30;:::i;:::-;68146:16;;68028:61;;-1:-1:-1;68122:40:0;;;68100:122;;;;;-1:-1:-1;;;68100:122:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68305:16;;:42;;68326:20;68305:42;:20;:42;:::i;:::-;68286:61;;68380:19;;;;:42;;68404:17;68380:42;:23;:42;:::i;:::-;68358:19;;;:64;68557:10;;68551:17;;-1:-1:-1;;;;;68557:10:0;68551:5;:17::i;:::-;68547:388;;;68606:18;68593:9;:31;68585:63;;;;;-1:-1:-1;;;68585:63:0;;;;;;;;;;;;-1:-1:-1;;;68585:63:0;;;;;;;;;;;;;;;68547:388;;;68707:10;;:152;;;-1:-1:-1;;;68707:152:0;;68753:10;68707:152;;;;68794:4;68707:152;;;;;;;;;;;;-1:-1:-1;;;;;68707:10:0;;;;:23;;:152;;;;;;;;;;;;;;;:10;;:152;;;5:2:-1;;;;30:1;27;20:12;5:2;68707:152:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;68707:152:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;68707:152:0;68681:242;;;;;-1:-1:-1;;;68681:242:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;68974:36;68980:10;68992:17;68974:5;:36::i;:::-;69058:50;69077:10;69089:18;69058;:50::i;:::-;69126:144;;;;;;;;;;;;69215:10;69126:144;;;;-1:-1:-1;;;;;69126:144:0;;;;;;;;;;;;;;;;;66386:2894;;;;;;;:::o;72326:1085::-;72451:7;72476:28;72507:29;72524:10;;;;;;;;;-1:-1:-1;;;;;72524:10:0;72507:8;:29::i;:::-;72591:6;;72476:60;;-1:-1:-1;72547:24:0;;72574:25;;-1:-1:-1;;;;;72591:6:0;72574:8;:25::i;:::-;72745:11;:17;72724:16;;72547:52;;-1:-1:-1;72705:16:0;;72724:39;;;:20;:39;:::i;:::-;72813:20;;72791:19;;;;72705:58;;-1:-1:-1;72813:20:0;;72791:42;72774:14;72869:87;72929:16;72870:39;:13;72888:20;72870:39;:17;:39;:::i;72869:87::-;72988:13;;72846:110;;-1:-1:-1;72988:13:0;;;;;72967:18;;;;73079:23;;;;;;;;73075:299;;;73133:23;;;73125:32;;;-1:-1:-1;73185:39:0;73202:21;:8;73215:2;:7;;;73202:21;:12;:21;:::i;:::-;73185:12;;:39;:16;:39;:::i;:::-;73172:52;;73075:299;;;73271:23;;;73263:32;;;-1:-1:-1;73323:39:0;73353:8;73323:25;:12;73340:2;:7;;;73323:25;:16;:25;:::i;:39::-;73310:52;72326:1085;-1:-1:-1;;;;;;;;;;;72326:1085:0:o;6361:471::-;6419:7;6664:6;6660:47;;-1:-1:-1;6694:1:0;6687:8;;6660:47;6731:5;;;6735:1;6731;:5;:1;6755:5;;;;;:10;6747:56;;;;-1:-1:-1;;;6747:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75793:227;75888:10;;75882:17;;-1:-1:-1;;;;;75888:10:0;75882:5;:17::i;:::-;75878:135;;;75916:20;;-1:-1:-1;;;;;75916:14:0;;;:20;;;;;75931:4;;75916:20;;;;75931:4;75916:14;:20;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;75878:135:0;75969:10;;:32;;;-1:-1:-1;;;75969:32:0;;-1:-1:-1;;;;;75969:32:0;;;;;;;;;;;;;;;:10;;;;;:19;;:32;;;;;;;;;;;;;;:10;;:32;;;5:2:-1;;;;30:1;27;20:12;73946:1192:0;74072:7;74126:28;74157:29;74174:10;;;;;;;;;-1:-1:-1;;;;;74174:10:0;74157:8;:29::i;:::-;74241:6;;74126:60;;-1:-1:-1;74197:24:0;;74224:25;;-1:-1:-1;;;;;74241:6:0;74224:8;:25::i;:::-;74197:52;;74312:34;74349:117;74449:16;74349:81;74413:10;:16;;;74349:45;74376:11;:17;;;74349:8;:26;;:45;;;;:::i;:117::-;74578:13;;74543:19;;;;74507:20;;74312:154;;-1:-1:-1;74578:13:0;;;;74507:20;;;:55;:84;;;;;74477:27;;74647:25;;;;-1:-1:-1;74643:448:0;;;74709:21;74767:97;74829:20;74767:39;:26;74798:7;;;;:2;:7;74767:39;;;:30;:39;:::i;:97::-;74746:118;;74643:448;;;;74897:10;74917:26;;;74980:99;75044:20;74981:39;:26;75012:7;;;;:2;:7;74981:39;;;:30;:39;:::i;74980:99::-;74959:120;;74643:448;;75110:18;73946:1192;-1:-1:-1;;;;;;;73946:1192:0:o;7300:132::-;7358:7;7385:39;7389:1;7392;7385:39;;;;;;;;;;;;;;;;;:3;:39::i;16330:348::-;-1:-1:-1;;;;;16406:21:0;;16398:67;;;;-1:-1:-1;;;16398:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16499:68;16522:6;16499:68;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;16499:18:0;;;;;;:9;:18;;;;;;;:68;;:22;:68;:::i;:::-;-1:-1:-1;;;;;16478:18:0;;;;;;:9;:18;;;;;:89;16593:12;;:24;;16610:6;16593:24;:16;:24;:::i;:::-;16578:12;:39;16633:37;;;;;;;;16659:1;;-1:-1:-1;;;;;16633:37:0;;;;;;;;;;;;16330:348;;:::o;65221:214::-;-1:-1:-1;;;;;65372:18:0;65325:7;65372:18;;;:6;:18;;;;;65408:19;;;;65221:214::o;38648:229::-;-1:-1:-1;;;;;38722:22:0;;38714:73;;;;-1:-1:-1;;;38714:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38824:6;;;38803:38;;-1:-1:-1;;;;;38803:38:0;;;;38824:6;;;38803:38;;;38852:6;:17;;-1:-1:-1;;;;;;38852:17:0;-1:-1:-1;;;;;38852:17:0;;;;;;;;;;38648:229::o;76183:306::-;76294:6;;76271:10;;76239:7;;-1:-1:-1;;;;;76294:6:0;;;-1:-1:-1;;;76271:10:0;;;;76263:38;76259:223;;;-1:-1:-1;76325:1:0;76318:8;;76259:223;-1:-1:-1;;;;;76348:19:0;;76344:138;;-1:-1:-1;76392:6:0;76384:15;;76344:138;76439:15;;:31;;;-1:-1:-1;;;76439:31:0;;-1:-1:-1;;;;;76439:31:0;;;;;;;;;:15;;;;;:24;;:31;;;;;;;;;;;;;;:15;:31;;;5:2:-1;;;;30:1;27;20:12;5:2;76439:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;76439:31:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;76439:31:0;;-1:-1:-1;76432:38:0;;7962:345;8048:7;8150:12;8143:5;8135:28;;;;-1:-1:-1;;;8135:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27:10:-1;;8:100;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;8135:28:0;;8174:9;8190:1;8186;:5;;;;;;;7962:345;-1:-1:-1;;;;;7962:345:0:o;76622:7558::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;76622:7558:0;;;-1:-1:-1;76622:7558:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;-1:-1:-1;76622:7558:0;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;
Swarm Source
bzzr://24408987c6dcfcda4c0e73ff0354366a3d057faa494c86e0ef89208047b75fda
Loading...
Loading
Loading...
Loading
Net Worth in USD
$1.00
Net Worth in ETH
0.000505
Token Allocations
USDC
100.00%
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| ETH | 100.00% | $0.999985 | 1 | $0.9999 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.