More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 47 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
Redeem Vault Bal... | 10338578 | 1470 days ago | IN | 0 ETH | 0.0008463 | ||||
Redeem Vault Bal... | 9795552 | 1554 days ago | IN | 0 ETH | 0.00023696 | ||||
Redeem Vault Bal... | 9781800 | 1556 days ago | IN | 0 ETH | 0.00026163 | ||||
Redeem Vault Bal... | 9774923 | 1557 days ago | IN | 0 ETH | 0.00023696 | ||||
Remove Underlyin... | 9754157 | 1560 days ago | IN | 0 ETH | 0.00016654 | ||||
Exercise | 9747361 | 1561 days ago | IN | 0.001 ETH | 0.00079263 | ||||
Add And Sell ERC... | 9747354 | 1561 days ago | IN | 0 ETH | 0.00115162 | ||||
Approve | 9747341 | 1561 days ago | IN | 0 ETH | 0.00030856 | ||||
Remove Collatera... | 9735799 | 1563 days ago | IN | 0 ETH | 0.00020218 | ||||
Burn O Tokens | 9735754 | 1563 days ago | IN | 0 ETH | 0.00006552 | ||||
Approve | 9732775 | 1564 days ago | IN | 0 ETH | 0.00020356 | ||||
Create And Sell ... | 9732775 | 1564 days ago | IN | 0 ETH | 0.00069786 | ||||
Approve | 9732727 | 1564 days ago | IN | 0 ETH | 0.00030856 | ||||
Exercise | 9728685 | 1564 days ago | IN | 0.00001 ETH | 0.00064298 | ||||
Remove Underlyin... | 9725612 | 1565 days ago | IN | 0 ETH | 0.00016654 | ||||
Remove Underlyin... | 9725207 | 1565 days ago | IN | 0 ETH | 0.00016654 | ||||
Exercise | 9718486 | 1566 days ago | IN | 0.001 ETH | 0.00056617 | ||||
Approve | 9718474 | 1566 days ago | IN | 0 ETH | 0.00017455 | ||||
Add ERC20Collate... | 9711923 | 1567 days ago | IN | 0 ETH | 0.0007958 | ||||
Create ERC20Coll... | 9710647 | 1567 days ago | IN | 0 ETH | 0.00137755 | ||||
Create And Sell ... | 9710298 | 1567 days ago | IN | 0 ETH | 0.00173319 | ||||
Remove Collatera... | 9707244 | 1568 days ago | IN | 0 ETH | 0.00054081 | ||||
Burn O Tokens | 9707192 | 1568 days ago | IN | 0 ETH | 0.00010129 | ||||
Exercise | 9706808 | 1568 days ago | IN | 0.01 ETH | 0.00069811 | ||||
Approve | 9706804 | 1568 days ago | IN | 0 ETH | 0.00030856 |
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
[{"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
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $1 | 1 | $1 |
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.