Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
x5Repricer
Compiler Version
v0.7.6+commit.7338295f
Optimization Enabled:
Yes with 1000000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// "SPDX-License-Identifier: GNU General Public License v3.0" pragma solidity 0.7.6; import "@chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; import "./IRepricer.sol"; import "../Const.sol"; import "../Num.sol"; import "../NumExtra.sol"; //import "hardhat/console.sol"; contract x5Repricer is IRepricer, Const, Num, NumExtra { int public constant NEGATIVE_INFINITY = type(int256).min; function isRepricer() external override pure returns(bool) { return true; } function symbol() external override pure returns (string memory) { return "x5Repricer"; } function reprice( uint pMin, int volatility, IVault _vault, uint[2] memory primary, uint[2] memory complement, int _liveUnderlingValue ) external view override returns( uint newPrimaryLeverage, uint newComplementLeverage, int estPricePrimary, int estPriceComplement ) { require(address(_vault) != address(0), "Zero oracle"); (estPricePrimary, estPriceComplement) = calcEstPrice( calcDenomination(_vault), calcUnv( _liveUnderlingValue, getCurrentUnderlingValue(_vault) ), calcTtm(_vault.settleTime()), int(pMin), volatility ); uint estPrice = uint(estPriceComplement * iBONE / estPricePrimary); uint leveragesMultiplied = mul(primary[1], complement[1]); newPrimaryLeverage = uint(sqrt( int(div( mul(leveragesMultiplied, mul(complement[0], estPrice)), primary[0] ))) ); newComplementLeverage = div(leveragesMultiplied, newPrimaryLeverage); } function getCurrentUnderlingValue(IVault _vault) internal view returns(int currentUnderlingValue) { uint currentTimestamp; (,currentUnderlingValue,,currentTimestamp,) = AggregatorV3Interface(_vault.oracles(0)).latestRoundData(); require(currentTimestamp > 0, "EMPTY_ORACLE_LATEST_ROUND"); } function calcTtm(uint _settledTimestamp) internal view returns(int) { return (int(_settledTimestamp) - int(block.timestamp)) * iBONE / 31536000; // 365 * 24 * 3600 } function calcUnv(int _liveUnderlingValue, int _currentUnderlingValue) internal pure returns(int) { return 5 * iBONE + 5 * ((_currentUnderlingValue - _liveUnderlingValue) * iBONE / _liveUnderlingValue); } function calcDenomination(IVault _vault) internal view returns (int denomination) { denomination = int( _vault.derivativeSpecification().primaryNominalValue() + _vault.derivativeSpecification().complementNominalValue() ); } function calcEstPricePrimary( int _unvPrim, int _ttm, int _volatility ) internal pure returns(int256) { int volatilityBySqrtTtm = _volatility * sqrt(_ttm) / iBONE; int multiplier = (iBONE * iBONE) / volatilityBySqrtTtm; int volatilityByTtm = (_volatility * _volatility) * _ttm / (iBONE * iBONE * 2); int d1 = multiplier * (ln(_unvPrim/4) + volatilityByTtm) / iBONE; int option4 = ncdf(d1) * _unvPrim / iBONE - ncdf(d1 - volatilityBySqrtTtm) * 4; d1 = multiplier * (ln(_unvPrim/6) + volatilityByTtm) / iBONE; int option6 = ncdf(d1) * _unvPrim / iBONE - ncdf(d1 - volatilityBySqrtTtm) * 6; return option4 - option6; } function calcEstPrice( int _denomination, int _unvPrim, int _ttm, int _pMin, int _volatility ) internal pure returns(int estPricePrimary, int estPriceComplement) { estPricePrimary = calcEstPricePrimary(_unvPrim, _ttm, _volatility); if(estPricePrimary < _pMin) { estPricePrimary = _pMin; } int denominationTimesBone = _denomination * iBONE; if(estPricePrimary > denominationTimesBone - _pMin) { estPricePrimary = denominationTimesBone - _pMin; } estPriceComplement = denominationTimesBone - estPricePrimary; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0; interface AggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); // getRoundData and latestRoundData should both raise "No data present" // if they do not have data to report, instead of returning unset values // which could be misinterpreted as actual reported values. function getRoundData(uint80 _roundId) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.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, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } }
// "SPDX-License-Identifier: GNU General Public License v3.0" pragma solidity 0.7.6; import "../IVault.sol"; interface IRepricer { function isRepricer() external pure returns(bool); function symbol() external pure returns (string memory); function reprice( uint _pMin, int _volatility, IVault _vault, uint[2] memory _primary, uint[2] memory _complement, int _liveUnderlingValue ) external view returns( uint newPrimaryLeverage, uint newComplementLeverage, int estPricePrimary, int estPriceComplement ); }
// This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity 0.7.6; import "./Color.sol"; contract Const is Bronze { uint public constant BONE = 10**18; int public constant iBONE = int(BONE); uint public constant MIN_POW_BASE = 1 wei; uint public constant MAX_POW_BASE = (2 * BONE) - 1 wei; uint public constant POW_PRECISION = BONE / 10**10; uint public constant MAX_IN_RATIO = BONE / 2; uint public constant MAX_OUT_RATIO = (BONE / 3) + 1 wei; }
// This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity 0.7.6; import "./Const.sol"; contract Num is Const { function toi(uint a) internal pure returns (uint) { return a / BONE; } function floor(uint a) internal pure returns (uint) { return toi(a) * BONE; } function add(uint a, uint b) internal pure returns (uint c) { c = a + b; require(c >= a, "ADD_OVERFLOW"); } function sub(uint a, uint b) internal pure returns (uint c) { bool flag; (c, flag) = subSign(a, b); require(!flag, "SUB_UNDERFLOW"); } function subSign(uint a, uint b) internal pure returns (uint, bool) { if (a >= b) { return (a - b, false); } else { return (b - a, true); } } function mul(uint a, uint b) internal pure returns (uint c) { uint c0 = a * b; require(a == 0 || c0 / a == b, "MUL_OVERFLOW"); uint c1 = c0 + (BONE / 2); require(c1 >= c0, "MUL_OVERFLOW"); c = c1 / BONE; } function div(uint a, uint b) internal pure returns (uint c) { require(b != 0, "DIV_ZERO"); uint c0 = a * BONE; require(a == 0 || c0 / a == BONE, "DIV_INTERNAL"); // mul overflow uint c1 = c0 + (b / 2); require(c1 >= c0, "DIV_INTERNAL"); // add require c = c1 / b; } // DSMath.wpow function powi(uint a, uint n) internal pure returns (uint z) { z = n % 2 != 0 ? a : BONE; for (n /= 2; n != 0; n /= 2) { a = mul(a, a); if (n % 2 != 0) { z = mul(z, a); } } } // Compute b^(e.w) by splitting it into (b^e)*(b^0.w). // Use `powi` for `b^e` and `powK` for k iterations // of approximation of b^0.w function pow(uint base, uint exp) internal pure returns (uint) { require(base >= MIN_POW_BASE, "POW_BASE_TOO_LOW"); require(base <= MAX_POW_BASE, "POW_BASE_TOO_HIGH"); uint whole = floor(exp); uint remain = sub(exp, whole); uint wholePow = powi(base, toi(whole)); if (remain == 0) { return wholePow; } uint partialResult = powApprox(base, remain, POW_PRECISION); return mul(wholePow, partialResult); } function powApprox(uint base, uint exp, uint precision) internal pure returns (uint sum) { // term 0: uint a = exp; (uint x, bool xneg) = subSign(base, BONE); uint term = BONE; sum = term; bool negative = false; // term(k) = numer / denom // = (product(a - i - 1, i=1-->k) * x^k) / (k!) // each iteration, multiply previous term by (a-(k-1)) * x / k // continue until term is less than precision for (uint i = 1; term >= precision; i++) { uint bigK = i * BONE; (uint c, bool cneg) = subSign(a, sub(bigK, BONE)); term = mul(term, mul(c, x)); term = div(term, bigK); if (term == 0) break; if (xneg) negative = !negative; if (cneg) negative = !negative; if (negative) { sum = sub(sum, term); } else { sum = add(sum, term); } } } function min(uint first, uint second) internal pure returns (uint) { if(first < second) { return first; } return second; } }
// This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity 0.7.6; import "abdk-libraries-solidity/ABDKMathQuad.sol"; import "./Const.sol"; contract NumExtra is Const { function toIntMultiplied(bytes16 value, uint256 bone) internal pure returns(int256) { return ABDKMathQuad.toInt(ABDKMathQuad.mul(value, ABDKMathQuad.fromUInt(bone))); } function fromIntMultiplied(int256 value, uint256 bone) internal pure returns(bytes16) { return ABDKMathQuad.div(ABDKMathQuad.fromInt(value), ABDKMathQuad.fromUInt(bone)); } function ln(int256 x) public pure returns(int256) { return toIntMultiplied( ABDKMathQuad.ln(fromIntMultiplied(x, BONE)), BONE ); } function sqrt(int256 x) public pure returns(int256) { return toIntMultiplied( ABDKMathQuad.sqrt(fromIntMultiplied(x, BONE)), BONE ); } function powi(bytes16 a, uint n) internal pure returns (bytes16) { bytes16 z = n % 2 != 0 ? a : ABDKMathQuad.fromInt(1); for (n /= 2; n != 0; n /= 2) { a = ABDKMathQuad.mul(a, a); if (n % 2 != 0) { z = ABDKMathQuad.mul(z, a); } } return z; } // https://stackoverflow.com/questions/2328258/cumulative-normal-distribution-function-in-c-c/23119456#23119456 function ncdf(int x) public pure returns (int256) { bytes16 xq = fromIntMultiplied(x, BONE); bytes16 z = ABDKMathQuad.abs(xq); bytes16 c = 0x00000000000000000000000000000000; if(ABDKMathQuad.cmp(z, ABDKMathQuad.fromUInt(37)) == int8(-1) || ABDKMathQuad.eq(z, ABDKMathQuad.fromUInt(37)) ) { bytes16 e = ABDKMathQuad.exp( ABDKMathQuad.div( ABDKMathQuad.mul(ABDKMathQuad.neg(z), z), ABDKMathQuad.fromUInt(2) ) ); if(ABDKMathQuad.cmp(z, fromIntMultiplied(707106781186547, 10**14)) == int8(-1)) { c = one(z, e); } else { c = two(z, e); } } c = (ABDKMathQuad.sign(xq) == int8(-1) || ABDKMathQuad.eq(xq, 0)) ? c : ABDKMathQuad.sub(ABDKMathQuad.fromUInt(1), c); return toIntMultiplied(c, BONE); } function one(bytes16 z, bytes16 e) internal pure returns (bytes16) { bytes16 n = addm( addm( addm( addm( addm( addm(fromIntMultiplied(352624965998911, 10**16), z, fromIntMultiplied(700383064443688, 10**15)), z, fromIntMultiplied(637396220353165, 10**14)), z, fromIntMultiplied(33912866078383, 10**12)), z, fromIntMultiplied(112079291497871, 10**12)), z, fromIntMultiplied(221213596169931, 10**12)), z, fromIntMultiplied(220206867912376, 10**12) ); bytes16 d = addm( addm( addm( addm( addm( addm( addm(fromIntMultiplied(883883476483184, 10**16), z, fromIntMultiplied(175566716318264, 10**14)), z, fromIntMultiplied(16064177579207, 10**12)), z, fromIntMultiplied(867807322029461, 10**13)), z, fromIntMultiplied(296564248779674, 10**12)), z, fromIntMultiplied(637333633378831, 10**12)), z, fromIntMultiplied(793826512519948, 10**12)), z, fromIntMultiplied(440413735824752, 10**12)); return ABDKMathQuad.div(ABDKMathQuad.mul(e, n), d); } function two(bytes16 z, bytes16 e) internal pure returns (bytes16) { bytes16 f = addr(z, ABDKMathQuad.fromUInt(13), ABDKMathQuad.fromUInt(20)); f = addr(z, ABDKMathQuad.fromUInt(4), f); f = addr(z, ABDKMathQuad.fromUInt(3), f); f = addr(z, ABDKMathQuad.fromUInt(2), f); f = addr(z, ABDKMathQuad.fromUInt(1), f); return ABDKMathQuad.div(e, ABDKMathQuad.div(fromIntMultiplied(250662827463, 10**11), f)); // sqrt(4.0*acos(0.0)) } function addm(bytes16 a, bytes16 b, bytes16 c) internal pure returns (bytes16) { return ABDKMathQuad.add(ABDKMathQuad.mul(a, b), c); } function addr(bytes16 a, bytes16 b, bytes16 c) internal pure returns (bytes16) { return ABDKMathQuad.add(a, ABDKMathQuad.div(b, c)); } }
// This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity 0.7.6; import "./Token.sol"; import "./libs/complifi/IDerivativeSpecification.sol"; interface IVault { /// @notice vault initialization time function initializationTime() external view returns(uint256); /// @notice start of live period function liveTime() external view returns(uint256); /// @notice end of live period function settleTime() external view returns(uint256); /// @notice underlying value at the start of live period function underlyingStarts(uint index) external view returns(int256); /// @notice underlying value at the end of live period function underlyingEnds(uint index) external view returns(int256); /// @notice primary token conversion rate multiplied by 10 ^ 12 function primaryConversion() external view returns(uint256); /// @notice complement token conversion rate multiplied by 10 ^ 12 function complementConversion() external view returns(uint256); // @notice derivative specification address function derivativeSpecification() external view returns(IDerivativeSpecification); // @notice collateral token address function collateralToken() external view returns(IERC20); // @notice oracle address function oracles(uint index) external view returns(address); function oracleIterators(uint index) external view returns(address); // @notice primary token address function primaryToken() external view returns(IERC20); // @notice complement token address function complementToken() external view returns(IERC20); }
// This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity 0.7.6; import "./Num.sol"; // Highly opinionated token implementation interface IERC20 { function totalSupply() external view returns (uint); function balanceOf(address whom) external view returns (uint); function allowance(address src, address dst) external view returns (uint); function approve(address dst, uint amt) external returns (bool); function transfer(address dst, uint amt) external returns (bool); function transferFrom( address src, address dst, uint amt ) external returns (bool); } contract TokenBase is Num { mapping(address => uint) internal _balance; mapping(address => mapping(address=>uint)) internal _allowance; uint internal _totalSupply; event Approval(address indexed src, address indexed dst, uint amt); event Transfer(address indexed src, address indexed dst, uint amt); function _mint(uint amt) internal { _balance[address(this)] = add(_balance[address(this)], amt); _totalSupply = add(_totalSupply, amt); emit Transfer(address(0), address(this), amt); } function _burn(uint amt) internal { require(_balance[address(this)] >= amt, "INSUFFICIENT_BAL"); _balance[address(this)] = sub(_balance[address(this)], amt); _totalSupply = sub(_totalSupply, amt); emit Transfer(address(this), address(0), amt); } function _move(address src, address dst, uint amt) internal { require(_balance[src] >= amt, "INSUFFICIENT_BAL"); _balance[src] = sub(_balance[src], amt); _balance[dst] = add(_balance[dst], amt); emit Transfer(src, dst, amt); } function _push(address to, uint amt) internal { _move(address(this), to, amt); } function _pull(address from, uint amt) internal { _move(from, address(this), amt); } } contract Token is TokenBase, IERC20 { string private _name; string private _symbol; uint8 private constant _decimals = 18; function setName(string memory name) internal { _name = name; } function setSymbol(string memory symbol) internal { _symbol = symbol; } function name() public view returns (string memory) { return _name; } function symbol() public view returns (string memory) { return _symbol; } function decimals() public view returns(uint8) { return _decimals; } function allowance(address src, address dst) external view override returns (uint) { return _allowance[src][dst]; } function balanceOf(address whom) external view override returns (uint) { return _balance[whom]; } function totalSupply() public view override returns (uint) { return _totalSupply; } function approve(address dst, uint amt) external override returns (bool) { _allowance[msg.sender][dst] = amt; emit Approval(msg.sender, dst, amt); return true; } function increaseApproval(address dst, uint amt) external returns (bool) { _allowance[msg.sender][dst] = add(_allowance[msg.sender][dst], amt); emit Approval(msg.sender, dst, _allowance[msg.sender][dst]); return true; } function decreaseApproval(address dst, uint amt) external returns (bool) { uint oldValue = _allowance[msg.sender][dst]; if (amt > oldValue) { _allowance[msg.sender][dst] = 0; } else { _allowance[msg.sender][dst] = sub(oldValue, amt); } emit Approval(msg.sender, dst, _allowance[msg.sender][dst]); return true; } function transfer(address dst, uint amt) external override returns (bool) { _move(msg.sender, dst, amt); return true; } function transferFrom(address src, address dst, uint amt) external override returns (bool) { uint oldValue = _allowance[src][msg.sender]; require(msg.sender == src || amt <= oldValue, "TOKEN_BAD_CALLER"); _move(src, dst, amt); if (msg.sender != src && oldValue != uint256(-1)) { _allowance[src][msg.sender] = sub(oldValue, amt); emit Approval(msg.sender, dst, _allowance[src][msg.sender]); } return true; } }
// "SPDX-License-Identifier: GPL-3.0-or-later" pragma solidity 0.7.6; /// @title Derivative Specification interface /// @notice Immutable collection of derivative attributes /// @dev Created by the derivative's author and published to the DerivativeSpecificationRegistry interface IDerivativeSpecification { /// @notice Proof of a derivative specification /// @dev Verifies that contract is a derivative specification /// @return true if contract is a derivative specification function isDerivativeSpecification() external pure returns (bool); /// @notice Set of oracles that are relied upon to measure changes in the state of the world /// between the start and the end of the Live period /// @dev Should be resolved through OracleRegistry contract /// @return oracle symbols function oracleSymbols() external view returns (bytes32[] memory); /// @notice Algorithm that, for the type of oracle used by the derivative, /// finds the value closest to a given timestamp /// @dev Should be resolved through OracleIteratorRegistry contract /// @return oracle iterator symbols function oracleIteratorSymbols() external view returns (bytes32[] memory); /// @notice Type of collateral that users submit to mint the derivative /// @dev Should be resolved through CollateralTokenRegistry contract /// @return collateral token symbol function collateralTokenSymbol() external view returns (bytes32); /// @notice Mapping from the change in the underlying variable (as defined by the oracle) /// and the initial collateral split to the final collateral split /// @dev Should be resolved through CollateralSplitRegistry contract /// @return collateral split symbol function collateralSplitSymbol() external view returns (bytes32); /// @notice Lifecycle parameter that define the length of the derivative's Live period. /// @dev Set in seconds /// @return live period value function livePeriod() external view returns (uint256); /// @notice Parameter that determines starting nominal value of primary asset /// @dev Units of collateral theoretically swappable for 1 unit of primary asset /// @return primary nominal value function primaryNominalValue() external view returns (uint256); /// @notice Parameter that determines starting nominal value of complement asset /// @dev Units of collateral theoretically swappable for 1 unit of complement asset /// @return complement nominal value function complementNominalValue() external view returns (uint256); /// @notice Minting fee rate due to the author of the derivative specification. /// @dev Percentage fee multiplied by 10 ^ 12 /// @return author fee function authorFee() external view returns (uint256); /// @notice Symbol of the derivative /// @dev Should be resolved through DerivativeSpecificationRegistry contract /// @return derivative specification symbol function symbol() external view returns (string memory); /// @notice Return optional long name of the derivative /// @dev Isn't used directly in the protocol /// @return long name function name() external view returns (string memory); /// @notice Optional URI to the derivative specs /// @dev Isn't used directly in the protocol /// @return URI to the derivative specs function baseURI() external view returns (string memory); /// @notice Derivative spec author /// @dev Used to set and receive author's fee /// @return address of the author function author() external view returns (address); }
// This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity 0.7.6; abstract contract Color { function getColor() external view virtual returns (bytes32); } contract Bronze is Color { function getColor() external view override returns (bytes32) { return bytes32("BRONZE"); } }
// SPDX-License-Identifier: BSD-4-Clause /* * ABDK Math Quad Smart Contract Library. Copyright © 2019 by ABDK Consulting. * Author: Mikhail Vladimirov <[email protected]> */ pragma solidity ^0.5.0 || ^0.6.0 || ^0.7.0; /** * Smart contract library of mathematical functions operating with IEEE 754 * quadruple-precision binary floating-point numbers (quadruple precision * numbers). As long as quadruple precision numbers are 16-bytes long, they are * represented by bytes16 type. */ library ABDKMathQuad { /* * 0. */ bytes16 private constant POSITIVE_ZERO = 0x00000000000000000000000000000000; /* * -0. */ bytes16 private constant NEGATIVE_ZERO = 0x80000000000000000000000000000000; /* * +Infinity. */ bytes16 private constant POSITIVE_INFINITY = 0x7FFF0000000000000000000000000000; /* * -Infinity. */ bytes16 private constant NEGATIVE_INFINITY = 0xFFFF0000000000000000000000000000; /* * Canonical NaN value. */ bytes16 private constant NaN = 0x7FFF8000000000000000000000000000; /** * Convert signed 256-bit integer number into quadruple precision number. * * @param x signed 256-bit integer number * @return quadruple precision number */ function fromInt (int256 x) internal pure returns (bytes16) { if (x == 0) return bytes16 (0); else { // We rely on overflow behavior here uint256 result = uint256 (x > 0 ? x : -x); uint256 msb = msb (result); if (msb < 112) result <<= 112 - msb; else if (msb > 112) result >>= msb - 112; result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16383 + msb << 112; if (x < 0) result |= 0x80000000000000000000000000000000; return bytes16 (uint128 (result)); } } /** * Convert quadruple precision number into signed 256-bit integer number * rounding towards zero. Revert on overflow. * * @param x quadruple precision number * @return signed 256-bit integer number */ function toInt (bytes16 x) internal pure returns (int256) { uint256 exponent = uint128 (x) >> 112 & 0x7FFF; require (exponent <= 16638); // Overflow if (exponent < 16383) return 0; // Underflow uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 0x10000000000000000000000000000; if (exponent < 16495) result >>= 16495 - exponent; else if (exponent > 16495) result <<= exponent - 16495; if (uint128 (x) >= 0x80000000000000000000000000000000) { // Negative require (result <= 0x8000000000000000000000000000000000000000000000000000000000000000); return -int256 (result); // We rely on overflow behavior here } else { require (result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return int256 (result); } } /** * Convert unsigned 256-bit integer number into quadruple precision number. * * @param x unsigned 256-bit integer number * @return quadruple precision number */ function fromUInt (uint256 x) internal pure returns (bytes16) { if (x == 0) return bytes16 (0); else { uint256 result = x; uint256 msb = msb (result); if (msb < 112) result <<= 112 - msb; else if (msb > 112) result >>= msb - 112; result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16383 + msb << 112; return bytes16 (uint128 (result)); } } /** * Convert quadruple precision number into unsigned 256-bit integer number * rounding towards zero. Revert on underflow. Note, that negative floating * point numbers in range (-1.0 .. 0.0) may be converted to unsigned integer * without error, because they are rounded to zero. * * @param x quadruple precision number * @return unsigned 256-bit integer number */ function toUInt (bytes16 x) internal pure returns (uint256) { uint256 exponent = uint128 (x) >> 112 & 0x7FFF; if (exponent < 16383) return 0; // Underflow require (uint128 (x) < 0x80000000000000000000000000000000); // Negative require (exponent <= 16638); // Overflow uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 0x10000000000000000000000000000; if (exponent < 16495) result >>= 16495 - exponent; else if (exponent > 16495) result <<= exponent - 16495; return result; } /** * Convert signed 128.128 bit fixed point number into quadruple precision * number. * * @param x signed 128.128 bit fixed point number * @return quadruple precision number */ function from128x128 (int256 x) internal pure returns (bytes16) { if (x == 0) return bytes16 (0); else { // We rely on overflow behavior here uint256 result = uint256 (x > 0 ? x : -x); uint256 msb = msb (result); if (msb < 112) result <<= 112 - msb; else if (msb > 112) result >>= msb - 112; result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16255 + msb << 112; if (x < 0) result |= 0x80000000000000000000000000000000; return bytes16 (uint128 (result)); } } /** * Convert quadruple precision number into signed 128.128 bit fixed point * number. Revert on overflow. * * @param x quadruple precision number * @return signed 128.128 bit fixed point number */ function to128x128 (bytes16 x) internal pure returns (int256) { uint256 exponent = uint128 (x) >> 112 & 0x7FFF; require (exponent <= 16510); // Overflow if (exponent < 16255) return 0; // Underflow uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 0x10000000000000000000000000000; if (exponent < 16367) result >>= 16367 - exponent; else if (exponent > 16367) result <<= exponent - 16367; if (uint128 (x) >= 0x80000000000000000000000000000000) { // Negative require (result <= 0x8000000000000000000000000000000000000000000000000000000000000000); return -int256 (result); // We rely on overflow behavior here } else { require (result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return int256 (result); } } /** * Convert signed 64.64 bit fixed point number into quadruple precision * number. * * @param x signed 64.64 bit fixed point number * @return quadruple precision number */ function from64x64 (int128 x) internal pure returns (bytes16) { if (x == 0) return bytes16 (0); else { // We rely on overflow behavior here uint256 result = uint128 (x > 0 ? x : -x); uint256 msb = msb (result); if (msb < 112) result <<= 112 - msb; else if (msb > 112) result >>= msb - 112; result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16319 + msb << 112; if (x < 0) result |= 0x80000000000000000000000000000000; return bytes16 (uint128 (result)); } } /** * Convert quadruple precision number into signed 64.64 bit fixed point * number. Revert on overflow. * * @param x quadruple precision number * @return signed 64.64 bit fixed point number */ function to64x64 (bytes16 x) internal pure returns (int128) { uint256 exponent = uint128 (x) >> 112 & 0x7FFF; require (exponent <= 16446); // Overflow if (exponent < 16319) return 0; // Underflow uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 0x10000000000000000000000000000; if (exponent < 16431) result >>= 16431 - exponent; else if (exponent > 16431) result <<= exponent - 16431; if (uint128 (x) >= 0x80000000000000000000000000000000) { // Negative require (result <= 0x80000000000000000000000000000000); return -int128 (result); // We rely on overflow behavior here } else { require (result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); return int128 (result); } } /** * Convert octuple precision number into quadruple precision number. * * @param x octuple precision number * @return quadruple precision number */ function fromOctuple (bytes32 x) internal pure returns (bytes16) { bool negative = x & 0x8000000000000000000000000000000000000000000000000000000000000000 > 0; uint256 exponent = uint256 (x) >> 236 & 0x7FFFF; uint256 significand = uint256 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (exponent == 0x7FFFF) { if (significand > 0) return NaN; else return negative ? NEGATIVE_INFINITY : POSITIVE_INFINITY; } if (exponent > 278526) return negative ? NEGATIVE_INFINITY : POSITIVE_INFINITY; else if (exponent < 245649) return negative ? NEGATIVE_ZERO : POSITIVE_ZERO; else if (exponent < 245761) { significand = (significand | 0x100000000000000000000000000000000000000000000000000000000000) >> 245885 - exponent; exponent = 0; } else { significand >>= 124; exponent -= 245760; } uint128 result = uint128 (significand | exponent << 112); if (negative) result |= 0x80000000000000000000000000000000; return bytes16 (result); } /** * Convert quadruple precision number into octuple precision number. * * @param x quadruple precision number * @return octuple precision number */ function toOctuple (bytes16 x) internal pure returns (bytes32) { uint256 exponent = uint128 (x) >> 112 & 0x7FFF; uint256 result = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (exponent == 0x7FFF) exponent = 0x7FFFF; // Infinity or NaN else if (exponent == 0) { if (result > 0) { uint256 msb = msb (result); result = result << 236 - msb & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; exponent = 245649 + msb; } } else { result <<= 124; exponent += 245760; } result |= exponent << 236; if (uint128 (x) >= 0x80000000000000000000000000000000) result |= 0x8000000000000000000000000000000000000000000000000000000000000000; return bytes32 (result); } /** * Convert double precision number into quadruple precision number. * * @param x double precision number * @return quadruple precision number */ function fromDouble (bytes8 x) internal pure returns (bytes16) { uint256 exponent = uint64 (x) >> 52 & 0x7FF; uint256 result = uint64 (x) & 0xFFFFFFFFFFFFF; if (exponent == 0x7FF) exponent = 0x7FFF; // Infinity or NaN else if (exponent == 0) { if (result > 0) { uint256 msb = msb (result); result = result << 112 - msb & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; exponent = 15309 + msb; } } else { result <<= 60; exponent += 15360; } result |= exponent << 112; if (x & 0x8000000000000000 > 0) result |= 0x80000000000000000000000000000000; return bytes16 (uint128 (result)); } /** * Convert quadruple precision number into double precision number. * * @param x quadruple precision number * @return double precision number */ function toDouble (bytes16 x) internal pure returns (bytes8) { bool negative = uint128 (x) >= 0x80000000000000000000000000000000; uint256 exponent = uint128 (x) >> 112 & 0x7FFF; uint256 significand = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (exponent == 0x7FFF) { if (significand > 0) return 0x7FF8000000000000; // NaN else return negative ? bytes8 (0xFFF0000000000000) : // -Infinity bytes8 (0x7FF0000000000000); // Infinity } if (exponent > 17406) return negative ? bytes8 (0xFFF0000000000000) : // -Infinity bytes8 (0x7FF0000000000000); // Infinity else if (exponent < 15309) return negative ? bytes8 (0x8000000000000000) : // -0 bytes8 (0x0000000000000000); // 0 else if (exponent < 15361) { significand = (significand | 0x10000000000000000000000000000) >> 15421 - exponent; exponent = 0; } else { significand >>= 60; exponent -= 15360; } uint64 result = uint64 (significand | exponent << 52); if (negative) result |= 0x8000000000000000; return bytes8 (result); } /** * Test whether given quadruple precision number is NaN. * * @param x quadruple precision number * @return true if x is NaN, false otherwise */ function isNaN (bytes16 x) internal pure returns (bool) { return uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF > 0x7FFF0000000000000000000000000000; } /** * Test whether given quadruple precision number is positive or negative * infinity. * * @param x quadruple precision number * @return true if x is positive or negative infinity, false otherwise */ function isInfinity (bytes16 x) internal pure returns (bool) { return uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x7FFF0000000000000000000000000000; } /** * Calculate sign of x, i.e. -1 if x is negative, 0 if x if zero, and 1 if x * is positive. Note that sign (-0) is zero. Revert if x is NaN. * * @param x quadruple precision number * @return sign of x */ function sign (bytes16 x) internal pure returns (int8) { uint128 absoluteX = uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; require (absoluteX <= 0x7FFF0000000000000000000000000000); // Not NaN if (absoluteX == 0) return 0; else if (uint128 (x) >= 0x80000000000000000000000000000000) return -1; else return 1; } /** * Calculate sign (x - y). Revert if either argument is NaN, or both * arguments are infinities of the same sign. * * @param x quadruple precision number * @param y quadruple precision number * @return sign (x - y) */ function cmp (bytes16 x, bytes16 y) internal pure returns (int8) { uint128 absoluteX = uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; require (absoluteX <= 0x7FFF0000000000000000000000000000); // Not NaN uint128 absoluteY = uint128 (y) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; require (absoluteY <= 0x7FFF0000000000000000000000000000); // Not NaN // Not infinities of the same sign require (x != y || absoluteX < 0x7FFF0000000000000000000000000000); if (x == y) return 0; else { bool negativeX = uint128 (x) >= 0x80000000000000000000000000000000; bool negativeY = uint128 (y) >= 0x80000000000000000000000000000000; if (negativeX) { if (negativeY) return absoluteX > absoluteY ? -1 : int8 (1); else return -1; } else { if (negativeY) return 1; else return absoluteX > absoluteY ? int8 (1) : -1; } } } /** * Test whether x equals y. NaN, infinity, and -infinity are not equal to * anything. * * @param x quadruple precision number * @param y quadruple precision number * @return true if x equals to y, false otherwise */ function eq (bytes16 x, bytes16 y) internal pure returns (bool) { if (x == y) { return uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF < 0x7FFF0000000000000000000000000000; } else return false; } /** * Calculate x + y. Special values behave in the following way: * * NaN + x = NaN for any x. * Infinity + x = Infinity for any finite x. * -Infinity + x = -Infinity for any finite x. * Infinity + Infinity = Infinity. * -Infinity + -Infinity = -Infinity. * Infinity + -Infinity = -Infinity + Infinity = NaN. * * @param x quadruple precision number * @param y quadruple precision number * @return quadruple precision number */ function add (bytes16 x, bytes16 y) internal pure returns (bytes16) { uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; uint256 yExponent = uint128 (y) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) { if (yExponent == 0x7FFF) { if (x == y) return x; else return NaN; } else return x; } else if (yExponent == 0x7FFF) return y; else { bool xSign = uint128 (x) >= 0x80000000000000000000000000000000; uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; bool ySign = uint128 (y) >= 0x80000000000000000000000000000000; uint256 ySignifier = uint128 (y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (yExponent == 0) yExponent = 1; else ySignifier |= 0x10000000000000000000000000000; if (xSignifier == 0) return y == NEGATIVE_ZERO ? POSITIVE_ZERO : y; else if (ySignifier == 0) return x == NEGATIVE_ZERO ? POSITIVE_ZERO : x; else { int256 delta = int256 (xExponent) - int256 (yExponent); if (xSign == ySign) { if (delta > 112) return x; else if (delta > 0) ySignifier >>= uint256 (delta); else if (delta < -112) return y; else if (delta < 0) { xSignifier >>= uint256 (-delta); xExponent = yExponent; } xSignifier += ySignifier; if (xSignifier >= 0x20000000000000000000000000000) { xSignifier >>= 1; xExponent += 1; } if (xExponent == 0x7FFF) return xSign ? NEGATIVE_INFINITY : POSITIVE_INFINITY; else { if (xSignifier < 0x10000000000000000000000000000) xExponent = 0; else xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; return bytes16 (uint128 ( (xSign ? 0x80000000000000000000000000000000 : 0) | (xExponent << 112) | xSignifier)); } } else { if (delta > 0) { xSignifier <<= 1; xExponent -= 1; } else if (delta < 0) { ySignifier <<= 1; xExponent = yExponent - 1; } if (delta > 112) ySignifier = 1; else if (delta > 1) ySignifier = (ySignifier - 1 >> uint256 (delta - 1)) + 1; else if (delta < -112) xSignifier = 1; else if (delta < -1) xSignifier = (xSignifier - 1 >> uint256 (-delta - 1)) + 1; if (xSignifier >= ySignifier) xSignifier -= ySignifier; else { xSignifier = ySignifier - xSignifier; xSign = ySign; } if (xSignifier == 0) return POSITIVE_ZERO; uint256 msb = msb (xSignifier); if (msb == 113) { xSignifier = xSignifier >> 1 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; xExponent += 1; } else if (msb < 112) { uint256 shift = 112 - msb; if (xExponent > shift) { xSignifier = xSignifier << shift & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; xExponent -= shift; } else { xSignifier <<= xExponent - 1; xExponent = 0; } } else xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0x7FFF) return xSign ? NEGATIVE_INFINITY : POSITIVE_INFINITY; else return bytes16 (uint128 ( (xSign ? 0x80000000000000000000000000000000 : 0) | (xExponent << 112) | xSignifier)); } } } } /** * Calculate x - y. Special values behave in the following way: * * NaN - x = NaN for any x. * Infinity - x = Infinity for any finite x. * -Infinity - x = -Infinity for any finite x. * Infinity - -Infinity = Infinity. * -Infinity - Infinity = -Infinity. * Infinity - Infinity = -Infinity - -Infinity = NaN. * * @param x quadruple precision number * @param y quadruple precision number * @return quadruple precision number */ function sub (bytes16 x, bytes16 y) internal pure returns (bytes16) { return add (x, y ^ 0x80000000000000000000000000000000); } /** * Calculate x * y. Special values behave in the following way: * * NaN * x = NaN for any x. * Infinity * x = Infinity for any finite positive x. * Infinity * x = -Infinity for any finite negative x. * -Infinity * x = -Infinity for any finite positive x. * -Infinity * x = Infinity for any finite negative x. * Infinity * 0 = NaN. * -Infinity * 0 = NaN. * Infinity * Infinity = Infinity. * Infinity * -Infinity = -Infinity. * -Infinity * Infinity = -Infinity. * -Infinity * -Infinity = Infinity. * * @param x quadruple precision number * @param y quadruple precision number * @return quadruple precision number */ function mul (bytes16 x, bytes16 y) internal pure returns (bytes16) { uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; uint256 yExponent = uint128 (y) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) { if (yExponent == 0x7FFF) { if (x == y) return x ^ y & 0x80000000000000000000000000000000; else if (x ^ y == 0x80000000000000000000000000000000) return x | y; else return NaN; } else { if (y & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NaN; else return x ^ y & 0x80000000000000000000000000000000; } } else if (yExponent == 0x7FFF) { if (x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NaN; else return y ^ x & 0x80000000000000000000000000000000; } else { uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; uint256 ySignifier = uint128 (y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (yExponent == 0) yExponent = 1; else ySignifier |= 0x10000000000000000000000000000; xSignifier *= ySignifier; if (xSignifier == 0) return (x ^ y) & 0x80000000000000000000000000000000 > 0 ? NEGATIVE_ZERO : POSITIVE_ZERO; xExponent += yExponent; uint256 msb = xSignifier >= 0x200000000000000000000000000000000000000000000000000000000 ? 225 : xSignifier >= 0x100000000000000000000000000000000000000000000000000000000 ? 224 : msb (xSignifier); if (xExponent + msb < 16496) { // Underflow xExponent = 0; xSignifier = 0; } else if (xExponent + msb < 16608) { // Subnormal if (xExponent < 16496) xSignifier >>= 16496 - xExponent; else if (xExponent > 16496) xSignifier <<= xExponent - 16496; xExponent = 0; } else if (xExponent + msb > 49373) { xExponent = 0x7FFF; xSignifier = 0; } else { if (msb > 112) xSignifier >>= msb - 112; else if (msb < 112) xSignifier <<= 112 - msb; xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; xExponent = xExponent + msb - 16607; } return bytes16 (uint128 (uint128 ((x ^ y) & 0x80000000000000000000000000000000) | xExponent << 112 | xSignifier)); } } /** * Calculate x / y. Special values behave in the following way: * * NaN / x = NaN for any x. * x / NaN = NaN for any x. * Infinity / x = Infinity for any finite non-negative x. * Infinity / x = -Infinity for any finite negative x including -0. * -Infinity / x = -Infinity for any finite non-negative x. * -Infinity / x = Infinity for any finite negative x including -0. * x / Infinity = 0 for any finite non-negative x. * x / -Infinity = -0 for any finite non-negative x. * x / Infinity = -0 for any finite non-negative x including -0. * x / -Infinity = 0 for any finite non-negative x including -0. * * Infinity / Infinity = NaN. * Infinity / -Infinity = -NaN. * -Infinity / Infinity = -NaN. * -Infinity / -Infinity = NaN. * * Division by zero behaves in the following way: * * x / 0 = Infinity for any finite positive x. * x / -0 = -Infinity for any finite positive x. * x / 0 = -Infinity for any finite negative x. * x / -0 = Infinity for any finite negative x. * 0 / 0 = NaN. * 0 / -0 = NaN. * -0 / 0 = NaN. * -0 / -0 = NaN. * * @param x quadruple precision number * @param y quadruple precision number * @return quadruple precision number */ function div (bytes16 x, bytes16 y) internal pure returns (bytes16) { uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; uint256 yExponent = uint128 (y) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) { if (yExponent == 0x7FFF) return NaN; else return x ^ y & 0x80000000000000000000000000000000; } else if (yExponent == 0x7FFF) { if (y & 0x0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF != 0) return NaN; else return POSITIVE_ZERO | (x ^ y) & 0x80000000000000000000000000000000; } else if (y & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) { if (x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NaN; else return POSITIVE_INFINITY | (x ^ y) & 0x80000000000000000000000000000000; } else { uint256 ySignifier = uint128 (y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (yExponent == 0) yExponent = 1; else ySignifier |= 0x10000000000000000000000000000; uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) { if (xSignifier != 0) { uint shift = 226 - msb (xSignifier); xSignifier <<= shift; xExponent = 1; yExponent += shift - 114; } } else { xSignifier = (xSignifier | 0x10000000000000000000000000000) << 114; } xSignifier = xSignifier / ySignifier; if (xSignifier == 0) return (x ^ y) & 0x80000000000000000000000000000000 > 0 ? NEGATIVE_ZERO : POSITIVE_ZERO; assert (xSignifier >= 0x1000000000000000000000000000); uint256 msb = xSignifier >= 0x80000000000000000000000000000 ? msb (xSignifier) : xSignifier >= 0x40000000000000000000000000000 ? 114 : xSignifier >= 0x20000000000000000000000000000 ? 113 : 112; if (xExponent + msb > yExponent + 16497) { // Overflow xExponent = 0x7FFF; xSignifier = 0; } else if (xExponent + msb + 16380 < yExponent) { // Underflow xExponent = 0; xSignifier = 0; } else if (xExponent + msb + 16268 < yExponent) { // Subnormal if (xExponent + 16380 > yExponent) xSignifier <<= xExponent + 16380 - yExponent; else if (xExponent + 16380 < yExponent) xSignifier >>= yExponent - xExponent - 16380; xExponent = 0; } else { // Normal if (msb > 112) xSignifier >>= msb - 112; xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; xExponent = xExponent + msb + 16269 - yExponent; } return bytes16 (uint128 (uint128 ((x ^ y) & 0x80000000000000000000000000000000) | xExponent << 112 | xSignifier)); } } /** * Calculate -x. * * @param x quadruple precision number * @return quadruple precision number */ function neg (bytes16 x) internal pure returns (bytes16) { return x ^ 0x80000000000000000000000000000000; } /** * Calculate |x|. * * @param x quadruple precision number * @return quadruple precision number */ function abs (bytes16 x) internal pure returns (bytes16) { return x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; } /** * Calculate square root of x. Return NaN on negative x excluding -0. * * @param x quadruple precision number * @return quadruple precision number */ function sqrt (bytes16 x) internal pure returns (bytes16) { if (uint128 (x) > 0x80000000000000000000000000000000) return NaN; else { uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) return x; else { uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; if (xSignifier == 0) return POSITIVE_ZERO; bool oddExponent = xExponent & 0x1 == 0; xExponent = xExponent + 16383 >> 1; if (oddExponent) { if (xSignifier >= 0x10000000000000000000000000000) xSignifier <<= 113; else { uint256 msb = msb (xSignifier); uint256 shift = (226 - msb) & 0xFE; xSignifier <<= shift; xExponent -= shift - 112 >> 1; } } else { if (xSignifier >= 0x10000000000000000000000000000) xSignifier <<= 112; else { uint256 msb = msb (xSignifier); uint256 shift = (225 - msb) & 0xFE; xSignifier <<= shift; xExponent -= shift - 112 >> 1; } } uint256 r = 0x10000000000000000000000000000; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; r = (r + xSignifier / r) >> 1; // Seven iterations should be enough uint256 r1 = xSignifier / r; if (r1 < r) r = r1; return bytes16 (uint128 (xExponent << 112 | r & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF)); } } } /** * Calculate binary logarithm of x. Return NaN on negative x excluding -0. * * @param x quadruple precision number * @return quadruple precision number */ function log_2 (bytes16 x) internal pure returns (bytes16) { if (uint128 (x) > 0x80000000000000000000000000000000) return NaN; else if (x == 0x3FFF0000000000000000000000000000) return POSITIVE_ZERO; else { uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; if (xExponent == 0x7FFF) return x; else { uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; if (xSignifier == 0) return NEGATIVE_INFINITY; bool resultNegative; uint256 resultExponent = 16495; uint256 resultSignifier; if (xExponent >= 0x3FFF) { resultNegative = false; resultSignifier = xExponent - 0x3FFF; xSignifier <<= 15; } else { resultNegative = true; if (xSignifier >= 0x10000000000000000000000000000) { resultSignifier = 0x3FFE - xExponent; xSignifier <<= 15; } else { uint256 msb = msb (xSignifier); resultSignifier = 16493 - msb; xSignifier <<= 127 - msb; } } if (xSignifier == 0x80000000000000000000000000000000) { if (resultNegative) resultSignifier += 1; uint256 shift = 112 - msb (resultSignifier); resultSignifier <<= shift; resultExponent -= shift; } else { uint256 bb = resultNegative ? 1 : 0; while (resultSignifier < 0x10000000000000000000000000000) { resultSignifier <<= 1; resultExponent -= 1; xSignifier *= xSignifier; uint256 b = xSignifier >> 255; resultSignifier += b ^ bb; xSignifier >>= 127 + b; } } return bytes16 (uint128 ((resultNegative ? 0x80000000000000000000000000000000 : 0) | resultExponent << 112 | resultSignifier & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF)); } } } /** * Calculate natural logarithm of x. Return NaN on negative x excluding -0. * * @param x quadruple precision number * @return quadruple precision number */ function ln (bytes16 x) internal pure returns (bytes16) { return mul (log_2 (x), 0x3FFE62E42FEFA39EF35793C7673007E5); } /** * Calculate 2^x. * * @param x quadruple precision number * @return quadruple precision number */ function pow_2 (bytes16 x) internal pure returns (bytes16) { bool xNegative = uint128 (x) > 0x80000000000000000000000000000000; uint256 xExponent = uint128 (x) >> 112 & 0x7FFF; uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xExponent == 0x7FFF && xSignifier != 0) return NaN; else if (xExponent > 16397) return xNegative ? POSITIVE_ZERO : POSITIVE_INFINITY; else if (xExponent < 16255) return 0x3FFF0000000000000000000000000000; else { if (xExponent == 0) xExponent = 1; else xSignifier |= 0x10000000000000000000000000000; if (xExponent > 16367) xSignifier <<= xExponent - 16367; else if (xExponent < 16367) xSignifier >>= 16367 - xExponent; if (xNegative && xSignifier > 0x406E00000000000000000000000000000000) return POSITIVE_ZERO; if (!xNegative && xSignifier > 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) return POSITIVE_INFINITY; uint256 resultExponent = xSignifier >> 128; xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; if (xNegative && xSignifier != 0) { xSignifier = ~xSignifier; resultExponent += 1; } uint256 resultSignifier = 0x80000000000000000000000000000000; if (xSignifier & 0x80000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x16A09E667F3BCC908B2FB1366EA957D3E >> 128; if (xSignifier & 0x40000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1306FE0A31B7152DE8D5A46305C85EDEC >> 128; if (xSignifier & 0x20000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1172B83C7D517ADCDF7C8C50EB14A791F >> 128; if (xSignifier & 0x10000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10B5586CF9890F6298B92B71842A98363 >> 128; if (xSignifier & 0x8000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1059B0D31585743AE7C548EB68CA417FD >> 128; if (xSignifier & 0x4000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x102C9A3E778060EE6F7CACA4F7A29BDE8 >> 128; if (xSignifier & 0x2000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10163DA9FB33356D84A66AE336DCDFA3F >> 128; if (xSignifier & 0x1000000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100B1AFA5ABCBED6129AB13EC11DC9543 >> 128; if (xSignifier & 0x800000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10058C86DA1C09EA1FF19D294CF2F679B >> 128; if (xSignifier & 0x400000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1002C605E2E8CEC506D21BFC89A23A00F >> 128; if (xSignifier & 0x200000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100162F3904051FA128BCA9C55C31E5DF >> 128; if (xSignifier & 0x100000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000B175EFFDC76BA38E31671CA939725 >> 128; if (xSignifier & 0x80000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100058BA01FB9F96D6CACD4B180917C3D >> 128; if (xSignifier & 0x40000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10002C5CC37DA9491D0985C348C68E7B3 >> 128; if (xSignifier & 0x20000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000162E525EE054754457D5995292026 >> 128; if (xSignifier & 0x10000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000B17255775C040618BF4A4ADE83FC >> 128; if (xSignifier & 0x8000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000058B91B5BC9AE2EED81E9B7D4CFAB >> 128; if (xSignifier & 0x4000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100002C5C89D5EC6CA4D7C8ACC017B7C9 >> 128; if (xSignifier & 0x2000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000162E43F4F831060E02D839A9D16D >> 128; if (xSignifier & 0x1000000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000B1721BCFC99D9F890EA06911763 >> 128; if (xSignifier & 0x800000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000058B90CF1E6D97F9CA14DBCC1628 >> 128; if (xSignifier & 0x400000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000002C5C863B73F016468F6BAC5CA2B >> 128; if (xSignifier & 0x200000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000162E430E5A18F6119E3C02282A5 >> 128; if (xSignifier & 0x100000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000B1721835514B86E6D96EFD1BFE >> 128; if (xSignifier & 0x80000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000058B90C0B48C6BE5DF846C5B2EF >> 128; if (xSignifier & 0x40000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000002C5C8601CC6B9E94213C72737A >> 128; if (xSignifier & 0x20000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000162E42FFF037DF38AA2B219F06 >> 128; if (xSignifier & 0x10000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000B17217FBA9C739AA5819F44F9 >> 128; if (xSignifier & 0x8000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000058B90BFCDEE5ACD3C1CEDC823 >> 128; if (xSignifier & 0x4000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000002C5C85FE31F35A6A30DA1BE50 >> 128; if (xSignifier & 0x2000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000162E42FF0999CE3541B9FFFCF >> 128; if (xSignifier & 0x1000000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000B17217F80F4EF5AADDA45554 >> 128; if (xSignifier & 0x800000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000058B90BFBF8479BD5A81B51AD >> 128; if (xSignifier & 0x400000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000002C5C85FDF84BD62AE30A74CC >> 128; if (xSignifier & 0x200000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000162E42FEFB2FED257559BDAA >> 128; if (xSignifier & 0x100000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000B17217F7D5A7716BBA4A9AE >> 128; if (xSignifier & 0x80000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000058B90BFBE9DDBAC5E109CCE >> 128; if (xSignifier & 0x40000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000002C5C85FDF4B15DE6F17EB0D >> 128; if (xSignifier & 0x20000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000162E42FEFA494F1478FDE05 >> 128; if (xSignifier & 0x10000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000B17217F7D20CF927C8E94C >> 128; if (xSignifier & 0x8000000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000058B90BFBE8F71CB4E4B33D >> 128; if (xSignifier & 0x4000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000002C5C85FDF477B662B26945 >> 128; if (xSignifier & 0x2000000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000162E42FEFA3AE53369388C >> 128; if (xSignifier & 0x1000000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000B17217F7D1D351A389D40 >> 128; if (xSignifier & 0x800000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000058B90BFBE8E8B2D3D4EDE >> 128; if (xSignifier & 0x400000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000002C5C85FDF4741BEA6E77E >> 128; if (xSignifier & 0x200000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000162E42FEFA39FE95583C2 >> 128; if (xSignifier & 0x100000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000B17217F7D1CFB72B45E1 >> 128; if (xSignifier & 0x80000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000058B90BFBE8E7CC35C3F0 >> 128; if (xSignifier & 0x40000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000002C5C85FDF473E242EA38 >> 128; if (xSignifier & 0x20000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000162E42FEFA39F02B772C >> 128; if (xSignifier & 0x10000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000B17217F7D1CF7D83C1A >> 128; if (xSignifier & 0x8000000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000058B90BFBE8E7BDCBE2E >> 128; if (xSignifier & 0x4000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000002C5C85FDF473DEA871F >> 128; if (xSignifier & 0x2000000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000162E42FEFA39EF44D91 >> 128; if (xSignifier & 0x1000000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000B17217F7D1CF79E949 >> 128; if (xSignifier & 0x800000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000058B90BFBE8E7BCE544 >> 128; if (xSignifier & 0x400000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000002C5C85FDF473DE6ECA >> 128; if (xSignifier & 0x200000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000162E42FEFA39EF366F >> 128; if (xSignifier & 0x100000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000B17217F7D1CF79AFA >> 128; if (xSignifier & 0x80000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000058B90BFBE8E7BCD6D >> 128; if (xSignifier & 0x40000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000002C5C85FDF473DE6B2 >> 128; if (xSignifier & 0x20000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000162E42FEFA39EF358 >> 128; if (xSignifier & 0x10000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000B17217F7D1CF79AB >> 128; if (xSignifier & 0x8000000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000058B90BFBE8E7BCD5 >> 128; if (xSignifier & 0x4000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000002C5C85FDF473DE6A >> 128; if (xSignifier & 0x2000000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000162E42FEFA39EF34 >> 128; if (xSignifier & 0x1000000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000B17217F7D1CF799 >> 128; if (xSignifier & 0x800000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000058B90BFBE8E7BCC >> 128; if (xSignifier & 0x400000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000002C5C85FDF473DE5 >> 128; if (xSignifier & 0x200000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000162E42FEFA39EF2 >> 128; if (xSignifier & 0x100000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000B17217F7D1CF78 >> 128; if (xSignifier & 0x80000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000058B90BFBE8E7BB >> 128; if (xSignifier & 0x40000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000002C5C85FDF473DD >> 128; if (xSignifier & 0x20000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000162E42FEFA39EE >> 128; if (xSignifier & 0x10000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000B17217F7D1CF6 >> 128; if (xSignifier & 0x8000000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000058B90BFBE8E7A >> 128; if (xSignifier & 0x4000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000002C5C85FDF473C >> 128; if (xSignifier & 0x2000000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000162E42FEFA39D >> 128; if (xSignifier & 0x1000000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000B17217F7D1CE >> 128; if (xSignifier & 0x800000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000058B90BFBE8E6 >> 128; if (xSignifier & 0x400000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000002C5C85FDF472 >> 128; if (xSignifier & 0x200000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000162E42FEFA38 >> 128; if (xSignifier & 0x100000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000B17217F7D1B >> 128; if (xSignifier & 0x80000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000058B90BFBE8D >> 128; if (xSignifier & 0x40000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000002C5C85FDF46 >> 128; if (xSignifier & 0x20000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000162E42FEFA2 >> 128; if (xSignifier & 0x10000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000B17217F7D0 >> 128; if (xSignifier & 0x8000000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000058B90BFBE7 >> 128; if (xSignifier & 0x4000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000002C5C85FDF3 >> 128; if (xSignifier & 0x2000000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000162E42FEF9 >> 128; if (xSignifier & 0x1000000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000B17217F7C >> 128; if (xSignifier & 0x800000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000058B90BFBD >> 128; if (xSignifier & 0x400000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000002C5C85FDE >> 128; if (xSignifier & 0x200000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000162E42FEE >> 128; if (xSignifier & 0x100000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000B17217F6 >> 128; if (xSignifier & 0x80000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000058B90BFA >> 128; if (xSignifier & 0x40000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000002C5C85FC >> 128; if (xSignifier & 0x20000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000162E42FD >> 128; if (xSignifier & 0x10000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000B17217E >> 128; if (xSignifier & 0x8000000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000058B90BE >> 128; if (xSignifier & 0x4000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000002C5C85E >> 128; if (xSignifier & 0x2000000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000162E42E >> 128; if (xSignifier & 0x1000000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000B17216 >> 128; if (xSignifier & 0x800000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000058B90A >> 128; if (xSignifier & 0x400000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000002C5C84 >> 128; if (xSignifier & 0x200000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000162E41 >> 128; if (xSignifier & 0x100000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000B1720 >> 128; if (xSignifier & 0x80000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000058B8F >> 128; if (xSignifier & 0x40000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000002C5C7 >> 128; if (xSignifier & 0x20000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000162E3 >> 128; if (xSignifier & 0x10000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000B171 >> 128; if (xSignifier & 0x8000 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000058B8 >> 128; if (xSignifier & 0x4000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000002C5B >> 128; if (xSignifier & 0x2000 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000162D >> 128; if (xSignifier & 0x1000 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000B16 >> 128; if (xSignifier & 0x800 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000058A >> 128; if (xSignifier & 0x400 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000002C4 >> 128; if (xSignifier & 0x200 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000161 >> 128; if (xSignifier & 0x100 > 0) resultSignifier = resultSignifier * 0x1000000000000000000000000000000B0 >> 128; if (xSignifier & 0x80 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000057 >> 128; if (xSignifier & 0x40 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000002B >> 128; if (xSignifier & 0x20 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000015 >> 128; if (xSignifier & 0x10 > 0) resultSignifier = resultSignifier * 0x10000000000000000000000000000000A >> 128; if (xSignifier & 0x8 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000004 >> 128; if (xSignifier & 0x4 > 0) resultSignifier = resultSignifier * 0x100000000000000000000000000000001 >> 128; if (!xNegative) { resultSignifier = resultSignifier >> 15 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; resultExponent += 0x3FFF; } else if (resultExponent <= 0x3FFE) { resultSignifier = resultSignifier >> 15 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF; resultExponent = 0x3FFF - resultExponent; } else { resultSignifier = resultSignifier >> resultExponent - 16367; resultExponent = 0; } return bytes16 (uint128 (resultExponent << 112 | resultSignifier)); } } /** * Calculate e^x. * * @param x quadruple precision number * @return quadruple precision number */ function exp (bytes16 x) internal pure returns (bytes16) { return pow_2 (mul (x, 0x3FFF71547652B82FE1777D0FFDA0D23A)); } /** * Get index of the most significant non-zero bit in binary representation of * x. Reverts if x is zero. * * @return index of the most significant non-zero bit in binary representation * of x */ function msb (uint256 x) private pure returns (uint256) { require (x > 0); uint256 result = 0; if (x >= 0x100000000000000000000000000000000) { x >>= 128; result += 128; } if (x >= 0x10000000000000000) { x >>= 64; result += 64; } if (x >= 0x100000000) { x >>= 32; result += 32; } if (x >= 0x10000) { x >>= 16; result += 16; } if (x >= 0x100) { x >>= 8; result += 8; } if (x >= 0x10) { x >>= 4; result += 4; } if (x >= 0x4) { x >>= 2; result += 2; } if (x >= 0x2) result += 1; // No need to shift x anymore return result; } }
{ "optimizer": { "enabled": true, "runs": 1000000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"BONE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_IN_RATIO","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_OUT_RATIO","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_POW_BASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_POW_BASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NEGATIVE_INFINITY","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POW_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getColor","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"iBONE","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isRepricer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"int256","name":"x","type":"int256"}],"name":"ln","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"int256","name":"x","type":"int256"}],"name":"ncdf","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"pMin","type":"uint256"},{"internalType":"int256","name":"volatility","type":"int256"},{"internalType":"contract IVault","name":"_vault","type":"address"},{"internalType":"uint256[2]","name":"primary","type":"uint256[2]"},{"internalType":"uint256[2]","name":"complement","type":"uint256[2]"},{"internalType":"int256","name":"_liveUnderlingValue","type":"int256"}],"name":"reprice","outputs":[{"internalType":"uint256","name":"newPrimaryLeverage","type":"uint256"},{"internalType":"uint256","name":"newComplementLeverage","type":"uint256"},{"internalType":"int256","name":"estPricePrimary","type":"int256"},{"internalType":"int256","name":"estPriceComplement","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"int256","name":"x","type":"int256"}],"name":"sqrt","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b506141fb806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80638e6f235311610097578063a598cef811610066578063a598cef8146102d3578063c36596a6146101f4578063dd43eb57146102f0578063ec093021146102f8576100f5565b80638e6f23531461022957806395d89b4114610246578063992e2a92146102c35780639a86139b146102cb576100f5565b806340179d83116100d357806340179d83146101f45780634dcd7dee146101fc578063665df4601461020457806373d1747b14610221576100f5565b806301032adc146100fa5780631a1afbc5146101145780631f072062146101d8575b600080fd5b610102610300565b60408051918252519081900360200190f35b6101b2600480360361010081101561012b57600080fd5b60408051808201825283359360208101359373ffffffffffffffffffffffffffffffffffffffff8483013516939082019260a0830191606084019060029083908390808284376000920191909152505060408051808201825292959493818101939250906002908390839080828437600092019190915250919450509035915061030c9050565b604080519485526020850193909352838301919091526060830152519081900360800190f35b6101e06104b4565b604080519115158252519081900360200190f35b6101026104b9565b6101026104c5565b6101026004803603602081101561021a57600080fd5b50356104e9565b61010261051e565b6101026004803603602081101561023f57600080fd5b5035610532565b61024e610551565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610288578181015183820152602001610270565b50505050905090810190601f1680156102b55780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610102610588565b610102610594565b610102600480360360208110156102e957600080fd5b50356105b8565b610102610743565b610102610748565b671bc16d674ec7ffff81565b600080808073ffffffffffffffffffffffffffffffffffffffff881661039357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f206f7261636c65000000000000000000000000000000000000000000604482015290519081900360640190fd5b61043261039f89610758565b6103b1876103ac8c61098d565b610b23565b61042b8b73ffffffffffffffffffffffffffffffffffffffff166366101b646040518163ffffffff1660e01b815260040160206040518083038186803b1580156103fa57600080fd5b505afa15801561040e573d6000803e3d6000fd5b505050506040513d602081101561042457600080fd5b5051610b54565b8d8d610b6f565b9092509050600082670de0b6b3a764000083028161044c57fe5b059050600061046989600160200201518960016020020151610bb6565b905061049761049261048b836104868c6000602002015187610bb6565b610bb6565b8b51610cca565b6104e9565b95506104a38187610cca565b945050509650965096509692505050565b600190565b670de0b6b3a764000081565b7f800000000000000000000000000000000000000000000000000000000000000081565b600061051661050861050384670de0b6b3a7640000610e49565b610e67565b670de0b6b3a76400006110b1565b90505b919050565b6402540be400670de0b6b3a76400005b0481565b600061051661050861054c84670de0b6b3a7640000610e49565b6110cd565b60408051808201909152600a81527f7835526570726963657200000000000000000000000000000000000000000000602082015290565b6704a03ce68d21555681565b7f42524f4e5a45000000000000000000000000000000000000000000000000000090565b6000806105cd83670de0b6b3a7640000610e49565b905060006105da82611101565b905060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6106128361060d6025611126565b611192565b60000b148061062f575061062f8261062a6025611126565b611391565b156106c957600061066261065d61064e610648866113f7565b8661141c565b6106586002611126565b611860565b611c6d565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6106a08461060d6602831c2082c9f3655af3107a4000610e49565b60000b14156106ba576106b38382611ca1565b91506106c7565b6106c48382611e43565b91505b505b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6106f384611ed4565b60000b14806107085750610708836000611391565b6107245761071f6107196001611126565b82611f79565b610726565b805b905061073a81670de0b6b3a76400006110b1565b95945050505050565b600181565b6002670de0b6b3a764000061052e565b60008173ffffffffffffffffffffffffffffffffffffffff1663dbcb32bf6040518163ffffffff1660e01b815260040160206040518083038186803b1580156107a057600080fd5b505afa1580156107b4573d6000803e3d6000fd5b505050506040513d60208110156107ca57600080fd5b5051604080517fab56c592000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163ab56c59291600480820192602092909190829003018186803b15801561083457600080fd5b505afa158015610848573d6000803e3d6000fd5b505050506040513d602081101561085e57600080fd5b5051604080517fdbcb32bf000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff85169163dbcb32bf916004808301926020929190829003018186803b1580156108c657600080fd5b505afa1580156108da573d6000803e3d6000fd5b505050506040513d60208110156108f057600080fd5b5051604080517fc6bb30e2000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163c6bb30e291600480820192602092909190829003018186803b15801561095a57600080fd5b505afa15801561096e573d6000803e3d6000fd5b505050506040513d602081101561098457600080fd5b50510192915050565b6000808273ffffffffffffffffffffffffffffffffffffffff16635b69a7d860006040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156109e257600080fd5b505afa1580156109f6573d6000803e3d6000fd5b505050506040513d6020811015610a0c57600080fd5b5051604080517ffeaf968c000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163feaf968c9160048082019260a092909190829003018186803b158015610a7657600080fd5b505afa158015610a8a573d6000803e3d6000fd5b505050506040513d60a0811015610aa057600080fd5b506020810151606090910151909250905080610b1d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f454d5054595f4f5241434c455f4c41544553545f524f554e4400000000000000604482015290519081900360640190fd5b50919050565b600082670de0b6b3a76400008484030281610b3a57fe5b05600502670de0b6b3a76400006005020190505b92915050565b60006301e13380428303670de0b6b3a7640000020592915050565b600080610b7d868685611fa7565b915083821215610b8b578391505b670de0b6b3a76400008702848103831315610ba65784810392505b8281039150509550959350505050565b6000828202831580610bd0575082848281610bcd57fe5b04145b610c3b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4d554c5f4f564552464c4f570000000000000000000000000000000000000000604482015290519081900360640190fd5b6706f05b59d3b20000810181811015610cb557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4d554c5f4f564552464c4f570000000000000000000000000000000000000000604482015290519081900360640190fd5b670de0b6b3a7640000815b0495945050505050565b600081610d3857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f4449565f5a45524f000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b670de0b6b3a76400008302831580610d605750670de0b6b3a7640000848281610d5d57fe5b04145b610dcb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4449565f494e5445524e414c0000000000000000000000000000000000000000604482015290519081900360640190fd5b60028304810181811015610e4057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4449565f494e5445524e414c0000000000000000000000000000000000000000604482015290519081900360640190fd5b838181610cc057fe5b6000610e60610e57846120b0565b61065884611126565b9392505050565b60006f80000000000000000000000000000000608083901c1115610eac57507f7fff800000000000000000000000000000000000000000000000000000000000610519565b617fff60f083901c811690811415610ec75782915050610519565b6dffffffffffffffffffffffffffff608084901c1681610eea5760019150610efc565b6e010000000000000000000000000000175b80610f0d5750600091506105199050565b613fff8201600190811c9216158015610f89576e0100000000000000000000000000008210610f4257607182901b9150610f84565b6000610f4d83612152565b60e20360fe167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810160011c909403939290921b91505b610fed565b6e0100000000000000000000000000008210610fab57607082901b9150610fed565b6000610fb683612152565b60e10360fe167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810160011c909403939290921b91505b6e01000000000000000000000000000080830401600190811c9081848161101057fe5b048201901c9050600181848161102257fe5b048201901c9050600181848161103457fe5b048201901c9050600181848161104657fe5b048201901c9050600181848161105857fe5b048201901c9050600181848161106a57fe5b048201901c9050600081848161107c57fe5b0490508181101561108b578091505b816dffffffffffffffffffffffffffff16607086901b1760801b95505050505050610519565b6000610e606110c8846110c385611126565b61141c565b612202565b60006105166110db83612325565b7f3ffe62e42fefa39ef35793c7673007e50000000000000000000000000000000061141c565b7f7fffffffffffffffffffffffffffffff000000000000000000000000000000001690565b60008161113557506000610519565b81600061114182612152565b9050607081101561115a578060700382901b915061116d565b607081111561116d576070810382901c91505b613fff0160701b6dffffffffffffffffffffffffffff919091161760801b9050610519565b60006f7fffffffffffffffffffffffffffffff608084901c166f7fff00000000000000000000000000008111156111c857600080fd5b6f7fffffffffffffffffffffffffffffff608084901c166f7fff00000000000000000000000000008111156111fc57600080fd5b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000085811690851614158061125157506f7fff0000000000000000000000000000826fffffffffffffffffffffffffffffffff16105b61125a57600080fd5b7fffffffffffffffffffffffffffffffff00000000000000000000000000000000858116908516141561129257600092505050610b4e565b6f80000000000000000000000000000000608086811c82118015929187901c9190911015906113205780156112f357826fffffffffffffffffffffffffffffffff16846fffffffffffffffffffffffffffffffff16116112f3576001611315565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b945050505050610b4e565b8015611333576001945050505050610b4e565b826fffffffffffffffffffffffffffffffff16846fffffffffffffffffffffffffffffffff1611611384577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611315565b6001945050505050610b4e565b60007fffffffffffffffffffffffffffffffff0000000000000000000000000000000083811690831614156113ef57506f7fff00000000000000000000000000006f7fffffffffffffffffffffffffffffff608084901c1610610b4e565b506000610b4e565b7f80000000000000000000000000000000000000000000000000000000000000001890565b6000617fff60f084811c8216919084901c81169082141561159c5780617fff141561151d577fffffffffffffffffffffffffffffffff00000000000000000000000000000000858116908516141561149b575050507f800000000000000000000000000000000000000000000000000000000000000081168218610b4e565b7f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffff000000000000000000000000000000008686181614156114f257505050818117610b4e565b507f7fff8000000000000000000000000000000000000000000000000000000000009150610b4e9050565b7f7fffffffffffffffffffffffffffffff00000000000000000000000000000000841661156f57507f7fff8000000000000000000000000000000000000000000000000000000000009150610b4e9050565b5050507f800000000000000000000000000000000000000000000000000000000000000081168218610b4e565b80617fff1415611625577f7fffffffffffffffffffffffffffffff0000000000000000000000000000000085166115f857507f7fff8000000000000000000000000000000000000000000000000000000000009150610b4e9050565b5050507f800000000000000000000000000000000000000000000000000000000000000082168118610b4e565b6dffffffffffffffffffffffffffff608086901c1682611648576001925061165a565b6e010000000000000000000000000000175b6dffffffffffffffffffffffffffff608086901c168261167d576001925061168f565b6e010000000000000000000000000000175b90810290816116f4577f8000000000000000000000000000000000000000000000000000000000000000878718166116c8576000611315565b7f8000000000000000000000000000000000000000000000000000000000000000945050505050610b4e565b9282019260007c020000000000000000000000000000000000000000000000000000000083101561175a577c01000000000000000000000000000000000000000000000000000000008310156117525761174d83612152565b611755565b60e05b61175d565b60e15b9050614070818601101561177857600094506000925061181c565b6140e081860110156117bb5761407085101561179d57846140700383901c92506117b2565b6140708511156117b257614070850383901b92505b6000945061181c565b61c0dd81860111156117d557617fff94506000925061181c565b60708111156117ec576070810383901c92506117ff565b60708110156117ff578060700383901b92505b6dffffffffffffffffffffffffffff831692506140df8186010394505b82607086901b888a186f8000000000000000000000000000000060801b1660801c6fffffffffffffffffffffffffffffffff16171760801b95505050505050610b4e565b6000617fff60f084811c8216919084901c8116908214156118b05780617fff141561156f57507f7fff8000000000000000000000000000000000000000000000000000000000009150610b4e9050565b80617fff1415611938577dffffffffffffffffffffffffffff0000000000000000000000000000000084161561190b57507f7fff8000000000000000000000000000000000000000000000000000000000009150610b4e9050565b5050508082187f800000000000000000000000000000000000000000000000000000000000000016610b4e565b7f7fffffffffffffffffffffffffffffff000000000000000000000000000000008416611a00577f7fffffffffffffffffffffffffffffff0000000000000000000000000000000085166119b157507f7fff8000000000000000000000000000000000000000000000000000000000009150610b4e9050565b5050508082187f8000000000000000000000000000000000000000000000000000000000000000167f7fff00000000000000000000000000000000000000000000000000000000000017610b4e565b6dffffffffffffffffffffffffffff608085901c1681611a235760019150611a35565b6e010000000000000000000000000000175b6dffffffffffffffffffffffffffff608087901c1683611a99578015611a94576000611a6082612152565b6001955060e2039384017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8e01939190911b90505b611aae565b6e0100000000000000000000000000001760721b5b818181611ab757fe5b04905080611aef577f8000000000000000000000000000000000000000000000000000000000000000878718166116c8576000611315565b6d1000000000000000000000000000811015611b0757fe5b60006e080000000000000000000000000000821015611b68576e040000000000000000000000000000821015611b5d576e020000000000000000000000000000821015611b55576070611b58565b60715b611b60565b60725b60ff16611b71565b611b7182612152565b905083614071018186011115611b8f57617fff945060009150611c29565b83818601613ffc011015611baa576000945060009150611c29565b83818601613f8c011015611bf7578385613ffc011115611bd5578385613ffc010382901b9150611bee565b8385613ffc011015611bee57613ffc8585030382901c91505b60009450611c29565b6070811115611c0a576070810382901c91505b6dffffffffffffffffffffffffffff8216915083818601613f8d010394505b81607086901b888a186f8000000000000000000000000000000060801b1660801c6fffffffffffffffffffffffffffffffff16171760801b95505050505050610b4e565b6000610516611c9c837f3fff71547652b82fe1777d0ffda0d23a0000000000000000000000000000000061141c565b6125d7565b600080611d5c611d46611d30611d1a611d04611cec611cce660140b5e5d6593f662386f26fc10000610e49565b8a611ce766027cfea3c34b2866038d7ea4c68000610e49565b613bea565b89611ce7660243b55f4b9a8d655af3107a4000610e49565b88611ce7651ed7f455feaf64e8d4a51000610e49565b87611ce76565ef7e5b3d8f64e8d4a51000610e49565b86611ce765c9314dd1b6cb64e8d4a51000610e49565b85611ce765c846e82396b864e8d4a51000610e49565b90506000611e2e611e17611e00611de9611dd2611dba611da4611d8d660323e328a37c70662386f26fc10000610e49565b8c611ce7659fad4fc2b238655af3107a4000610e49565b8b611ce7650e9c3b9924c764e8d4a51000610e49565b8a611ce7660315442329bd956509184e72a000610e49565b89611ce766010db93eb39b9a64e8d4a51000610e49565b88611ce7660243a6ccd22a0f64e8d4a51000610e49565b87611ce76602d1fb234ac30c64e8d4a51000610e49565b86611ce76601908dd0472d7064e8d4a51000610e49565b905061073a611e3d858461141c565b82611860565b600080611e6384611e54600d611126565b611e5e6014611126565b613bff565b9050611e7984611e736004611126565b83613bff565b9050611e8984611e736003611126565b9050611e9984611e736002611126565b9050611ea984611e736001611126565b9050611ecc83610658611ec6643a5cab35c764174876e800610e49565b84611860565b949350505050565b60006f7fffffffffffffffffffffffffffffff608083901c166f7fff0000000000000000000000000000811115611f0a57600080fd5b6fffffffffffffffffffffffffffffffff8116611f2b576000915050610519565b6f80000000000000000000000000000000608084901c10611f6f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff915050610519565b6001915050610519565b6000610e60837f80000000000000000000000000000000000000000000000000000000000000008418613c0f565b600080670de0b6b3a7640000611fbc856104e9565b840281611fc557fe5b0590506000816ec097ce7bc90715b34b9f100000000081611fe257fe5b0590506f01812f9cf7920e2b66973e20000000008480028602056000670de0b6b3a76400008261201560048b5b05610532565b0184028161201f57fe5b059050600061202f8583036105b8565b600402670de0b6b3a76400008a612045856105b8565b028161204d57fe5b05039050670de0b6b3a76400008361206660068c61200f565b0185028161207057fe5b05915060006120808684036105b8565b600602670de0b6b3a76400008b612096866105b8565b028161209e57fe5b05039091039998505050505050505050565b6000816120bf57506000610519565b60008083136120d157826000036120d3565b825b905060006120e082612152565b905060708110156120f9578060700382901b915061210c565b607081111561210c576070810382901c91505b6dffffffffffffffffffffffffffff909116613fff820160701b17906000841215612147576f80000000000000000000000000000000821791505b5060801b9050610519565b600080821161216057600080fd5b6000700100000000000000000000000000000000831061218257608092831c92015b68010000000000000000831061219a57604092831c92015b64010000000083106121ae57602092831c92015b6201000083106121c057601092831c92015b61010083106121d157600892831c92015b601083106121e157600492831c92015b600483106121f157600292831c92015b600283106105165760010192915050565b6000617fff60f083901c166140fe81111561221c57600080fd5b613fff811015612230576000915050610519565b6e0100000000000000000000000000006dffffffffffffffffffffffffffff608085901c161761406f82101561226c5761406f8290031c61229b565b61406f82111561229b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf9182011b5b6f80000000000000000000000000000000608085901c106122ef577f80000000000000000000000000000000000000000000000000000000000000008111156122e357600080fd5b60000391506105199050565b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81111561231c57600080fd5b91506105199050565b60006f80000000000000000000000000000000608083901c111561236a57507f7fff800000000000000000000000000000000000000000000000000000000000610519565b7f3fff0000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffff00000000000000000000000000000000831614156123bc57506000610519565b617fff60f083901c8116908114156123d75782915050610519565b6dffffffffffffffffffffffffffff608084901c16816123fa576001915061240c565b6e010000000000000000000000000000175b8061243c57507fffff00000000000000000000000000000000000000000000000000000000000091506105199050565b600061406f81613fff851061247f5750600f9290921b91600091507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00184016124c9565b600192506e01000000000000000000000000000084106124ac5784613ffe039050600f84901b93506124c9565b60006124b785612152565b607f8190039590951b9461406d039150505b836f8000000000000000000000000000000014156125095782156124eb576001015b60006124f682612152565b60700392839003929190911b9050612580565b60008361251757600061251a565b60015b60ff1690505b6e01000000000000000000000000000082101561257e5793800260ff81901c607f81019190911c947fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff939093019260019290921b9082180190612520565b505b806dffffffffffffffffffffffffffff16607083901b846125a25760006125b4565b6f800000000000000000000000000000005b6fffffffffffffffffffffffffffffffff16171760801b95505050505050610519565b60006f80000000000000000000000000000000608083901c90811190617fff60f085901c8116916dffffffffffffffffffffffffffff16908214801561261c57508015155b1561264d57507f7fff8000000000000000000000000000000000000000000000000000000000009250610519915050565b61400d82111561268f5782612682577f7fff000000000000000000000000000000000000000000000000000000000000612685565b60005b9350505050610519565b613f7f8210156126c557507f3fff0000000000000000000000000000000000000000000000000000000000009250610519915050565b816126d357600191506126e5565b6e010000000000000000000000000000175b613fef821115612718577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc01182011b61272a565b613fef82101561272a57613fef8290031c5b828015612748575071406e0000000000000000000000000000000081115b1561275a575060009250610519915050565b821580156127795750713fffffffffffffffffffffffffffffffffff81115b156127aa57507f7fff0000000000000000000000000000000000000000000000000000000000009250610519915050565b6fffffffffffffffffffffffffffffffff81169060801c8380156127cd57508115155b156127d9579019906001015b6f80000000000000000000000000000000828116156128095770016a09e667f3bcc908b2fb1366ea957d3e0260801c5b6f40000000000000000000000000000000831615612838577001306fe0a31b7152de8d5a46305c85edec0260801c5b6f20000000000000000000000000000000831615612867577001172b83c7d517adcdf7c8c50eb14a791f0260801c5b6f100000000000000000000000000000008316156128965770010b5586cf9890f6298b92b71842a983630260801c5b6f080000000000000000000000000000008316156128c5577001059b0d31585743ae7c548eb68ca417fd0260801c5b6f040000000000000000000000000000008316156128f457700102c9a3e778060ee6f7caca4f7a29bde80260801c5b6f020000000000000000000000000000008316156129235770010163da9fb33356d84a66ae336dcdfa3f0260801c5b6f0100000000000000000000000000000083161561295257700100b1afa5abcbed6129ab13ec11dc95430260801c5b6e8000000000000000000000000000008316156129805770010058c86da1c09ea1ff19d294cf2f679b0260801c5b6e4000000000000000000000000000008316156129ae577001002c605e2e8cec506d21bfc89a23a00f0260801c5b6e2000000000000000000000000000008316156129dc57700100162f3904051fa128bca9c55c31e5df0260801c5b6e100000000000000000000000000000831615612a0a577001000b175effdc76ba38e31671ca9397250260801c5b6e080000000000000000000000000000831615612a3857700100058ba01fb9f96d6cacd4b180917c3d0260801c5b6e040000000000000000000000000000831615612a665770010002c5cc37da9491d0985c348c68e7b30260801c5b6e020000000000000000000000000000831615612a94577001000162e525ee054754457d59952920260260801c5b6e010000000000000000000000000000831615612ac25770010000b17255775c040618bf4a4ade83fc0260801c5b6d8000000000000000000000000000831615612aef577001000058b91b5bc9ae2eed81e9b7d4cfab0260801c5b6d4000000000000000000000000000831615612b1c57700100002c5c89d5ec6ca4d7c8acc017b7c90260801c5b6d2000000000000000000000000000831615612b495770010000162e43f4f831060e02d839a9d16d0260801c5b6d1000000000000000000000000000831615612b7657700100000b1721bcfc99d9f890ea069117630260801c5b6d0800000000000000000000000000831615612ba35770010000058b90cf1e6d97f9ca14dbcc16280260801c5b6d0400000000000000000000000000831615612bd0577001000002c5c863b73f016468f6bac5ca2b0260801c5b6d0200000000000000000000000000831615612bfd57700100000162e430e5a18f6119e3c02282a50260801c5b6d0100000000000000000000000000831615612c2a577001000000b1721835514b86e6d96efd1bfe0260801c5b6c80000000000000000000000000831615612c5657700100000058b90c0b48c6be5df846c5b2ef0260801c5b6c40000000000000000000000000831615612c825770010000002c5c8601cc6b9e94213c72737a0260801c5b6c20000000000000000000000000831615612cae577001000000162e42fff037df38aa2b219f060260801c5b6c10000000000000000000000000831615612cda5770010000000b17217fba9c739aa5819f44f90260801c5b6c08000000000000000000000000831615612d06577001000000058b90bfcdee5acd3c1cedc8230260801c5b6c04000000000000000000000000831615612d3257700100000002c5c85fe31f35a6a30da1be500260801c5b6c02000000000000000000000000831615612d5e5770010000000162e42ff0999ce3541b9fffcf0260801c5b6c01000000000000000000000000831615612d8a57700100000000b17217f80f4ef5aadda455540260801c5b6b800000000000000000000000831615612db55770010000000058b90bfbf8479bd5a81b51ad0260801c5b6b400000000000000000000000831615612de0577001000000002c5c85fdf84bd62ae30a74cc0260801c5b6b200000000000000000000000831615612e0b57700100000000162e42fefb2fed257559bdaa0260801c5b6b100000000000000000000000831615612e36577001000000000b17217f7d5a7716bba4a9ae0260801c5b6b080000000000000000000000831615612e6157700100000000058b90bfbe9ddbac5e109cce0260801c5b6b040000000000000000000000831615612e8c5770010000000002c5c85fdf4b15de6f17eb0d0260801c5b6b020000000000000000000000831615612eb7577001000000000162e42fefa494f1478fde050260801c5b6b010000000000000000000000831615612ee25770010000000000b17217f7d20cf927c8e94c0260801c5b6a8000000000000000000000831615612f0c577001000000000058b90bfbe8f71cb4e4b33d0260801c5b6a4000000000000000000000831615612f3657700100000000002c5c85fdf477b662b269450260801c5b6a2000000000000000000000831615612f605770010000000000162e42fefa3ae53369388c0260801c5b6a1000000000000000000000831615612f8a57700100000000000b17217f7d1d351a389d400260801c5b6a0800000000000000000000831615612fb45770010000000000058b90bfbe8e8b2d3d4ede0260801c5b6a0400000000000000000000831615612fde577001000000000002c5c85fdf4741bea6e77e0260801c5b6a020000000000000000000083161561300857700100000000000162e42fefa39fe95583c20260801c5b6a0100000000000000000000831615613032577001000000000000b17217f7d1cfb72b45e10260801c5b698000000000000000000083161561305b57700100000000000058b90bfbe8e7cc35c3f00260801c5b69400000000000000000008316156130845770010000000000002c5c85fdf473e242ea380260801c5b69200000000000000000008316156130ad577001000000000000162e42fefa39f02b772c0260801c5b69100000000000000000008316156130d65770010000000000000b17217f7d1cf7d83c1a0260801c5b69080000000000000000008316156130ff577001000000000000058b90bfbe8e7bdcbe2e0260801c5b690400000000000000000083161561312857700100000000000002c5c85fdf473dea871f0260801c5b69020000000000000000008316156131515770010000000000000162e42fefa39ef44d910260801c5b690100000000000000000083161561317a57700100000000000000b17217f7d1cf79e9490260801c5b688000000000000000008316156131a25770010000000000000058b90bfbe8e7bce5440260801c5b684000000000000000008316156131ca577001000000000000002c5c85fdf473de6eca0260801c5b682000000000000000008316156131f257700100000000000000162e42fefa39ef366f0260801c5b6810000000000000000083161561321a577001000000000000000b17217f7d1cf79afa0260801c5b6808000000000000000083161561324257700100000000000000058b90bfbe8e7bcd6d0260801c5b6804000000000000000083161561326a5770010000000000000002c5c85fdf473de6b20260801c5b68020000000000000000831615613292577001000000000000000162e42fefa39ef3580260801c5b680100000000000000008316156132ba5770010000000000000000b17217f7d1cf79ab0260801c5b6780000000000000008316156132e1577001000000000000000058b90bfbe8e7bcd50260801c5b67400000000000000083161561330857700100000000000000002c5c85fdf473de6a0260801c5b67200000000000000083161561332f5770010000000000000000162e42fefa39ef340260801c5b67100000000000000083161561335657700100000000000000000b17217f7d1cf7990260801c5b67080000000000000083161561337d5770010000000000000000058b90bfbe8e7bcc0260801c5b6704000000000000008316156133a4577001000000000000000002c5c85fdf473de50260801c5b6702000000000000008316156133cb57700100000000000000000162e42fefa39ef20260801c5b6701000000000000008316156133f2577001000000000000000000b17217f7d1cf780260801c5b668000000000000083161561341857700100000000000000000058b90bfbe8e7bb0260801c5b664000000000000083161561343e5770010000000000000000002c5c85fdf473dd0260801c5b6620000000000000831615613464577001000000000000000000162e42fefa39ee0260801c5b661000000000000083161561348a5770010000000000000000000b17217f7d1cf60260801c5b66080000000000008316156134b0577001000000000000000000058b90bfbe8e7a0260801c5b66040000000000008316156134d657700100000000000000000002c5c85fdf473c0260801c5b66020000000000008316156134fc5770010000000000000000000162e42fefa39d0260801c5b660100000000000083161561352257700100000000000000000000b17217f7d1ce0260801c5b658000000000008316156135475770010000000000000000000058b90bfbe8e60260801c5b6540000000000083161561356c577001000000000000000000002c5c85fdf4720260801c5b6520000000000083161561359157700100000000000000000000162e42fefa380260801c5b651000000000008316156135b6577001000000000000000000000b17217f7d1b0260801c5b650800000000008316156135db57700100000000000000000000058b90bfbe8d0260801c5b650400000000008316156136005770010000000000000000000002c5c85fdf460260801c5b65020000000000831615613625577001000000000000000000000162e42fefa20260801c5b6501000000000083161561364a5770010000000000000000000000b17217f7d00260801c5b64800000000083161561366e577001000000000000000000000058b90bfbe70260801c5b64400000000083161561369257700100000000000000000000002c5c85fdf30260801c5b6420000000008316156136b65770010000000000000000000000162e42fef90260801c5b6410000000008316156136da57700100000000000000000000000b17217f7c0260801c5b6408000000008316156136fe5770010000000000000000000000058b90bfbd0260801c5b640400000000831615613722577001000000000000000000000002c5c85fde0260801c5b64020000000083161561374657700100000000000000000000000162e42fee0260801c5b64010000000083161561376a577001000000000000000000000000b17217f60260801c5b638000000083161561378d57700100000000000000000000000058b90bfa0260801c5b63400000008316156137b05770010000000000000000000000002c5c85fc0260801c5b63200000008316156137d3577001000000000000000000000000162e42fd0260801c5b63100000008316156137f65770010000000000000000000000000b17217e0260801c5b6308000000831615613819577001000000000000000000000000058b90be0260801c5b630400000083161561383c57700100000000000000000000000002c5c85e0260801c5b630200000083161561385f5770010000000000000000000000000162e42e0260801c5b630100000083161561388257700100000000000000000000000000b172160260801c5b628000008316156138a45770010000000000000000000000000058b90a0260801c5b624000008316156138c6577001000000000000000000000000002c5c840260801c5b622000008316156138e857700100000000000000000000000000162e410260801c5b6210000083161561390a577001000000000000000000000000000b17200260801c5b6208000083161561392c57700100000000000000000000000000058b8f0260801c5b6204000083161561394e5770010000000000000000000000000002c5c70260801c5b62020000831615613970577001000000000000000000000000000162e30260801c5b620100008316156139925770010000000000000000000000000000b1710260801c5b6180008316156139b3577001000000000000000000000000000058b80260801c5b6140008316156139d457700100000000000000000000000000002c5b0260801c5b6120008316156139f55770010000000000000000000000000000162d0260801c5b611000831615613a1657700100000000000000000000000000000b160260801c5b610800831615613a375770010000000000000000000000000000058a0260801c5b610400831615613a58577001000000000000000000000000000002c40260801c5b610200831615613a79577001000000000000000000000000000001610260801c5b610100831615613a9a577001000000000000000000000000000000b00260801c5b6080831615613aba577001000000000000000000000000000000570260801c5b6040831615613ada5770010000000000000000000000000000002b0260801c5b6020831615613afa577001000000000000000000000000000000150260801c5b6010831615613b1a5770010000000000000000000000000000000a0260801c5b6008831615613b3a577001000000000000000000000000000000040260801c5b6004831615613b5a577001000000000000000000000000000000010260801c5b84613b8257600f81901c6dffffffffffffffffffffffffffff169050613fff82019150613bd5565b613ffe8211613bae57600f81901c6dffffffffffffffffffffffffffff16905081613fff039150613bd5565b6000917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc011011c5b60709190911b1760801b935061051992505050565b6000611ecc613bf9858561141c565b83613c0f565b6000611ecc84613c0f8585611860565b6000617fff60f084811c8216919084901c811690821415613c755780617fff1415613c6b577fffffffffffffffffffffffffffffffff0000000000000000000000000000000085811690851614156114f2578492505050610b4e565b8492505050610b4e565b80617fff1415613c89578392505050610b4e565b6f80000000000000000000000000000000608086901c90811015906dffffffffffffffffffffffffffff1683613cc25760019350613cd4565b6e010000000000000000000000000000175b6f80000000000000000000000000000000608087901c90811015906dffffffffffffffffffffffffffff1684613d0d5760019450613d1f565b6e010000000000000000000000000000175b82613d83577fffffffffffffffffffffffffffffffff0000000000000000000000000000000088167f800000000000000000000000000000000000000000000000000000000000000014613d735787613d76565b60005b9650505050505050610b4e565b80613dd7577fffffffffffffffffffffffffffffffff0000000000000000000000000000000089167f800000000000000000000000000000000000000000000000000000000000000014613d735788613d76565b8486038415158315151415613f65576070811315613dfe5789975050505050505050610b4e565b6000811315613e105790811c90613e5d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90811215613e475788975050505050505050610b4e565b6000811215613e5d578060000384901c93508596505b928101926e0200000000000000000000000000008410613e83576001968701969390931c925b86617fff1415613ee85784613eb8577f7fff000000000000000000000000000000000000000000000000000000000000613eda565b7fffff0000000000000000000000000000000000000000000000000000000000005b975050505050505050610b4e565b6e010000000000000000000000000000841015613f085760009650613f1c565b6dffffffffffffffffffffffffffff841693505b83607088901b86613f2e576000613f40565b6f800000000000000000000000000000005b6fffffffffffffffffffffffffffffffff16171760801b975050505050505050610b4e565b6000811315613f8057600184901b9350600187039650613f97565b6000811215613f9757600182901b91506001860396505b6070811315613fa95760019150614032565b6001811315613fc6576001810360018303901c6001019150614032565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90811215613ff75760019350614032565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811215614032576001816000030360018503901c60010193505b81841061404357818403935061404c565b83820393508294505b83614062575060009650610b4e95505050505050565b600061406d85612152565b9050806071141561409a57600185901c6dffffffffffffffffffffffffffff169450600188019750614115565b6070811015614101576070819003808911156140d0578086901b6dffffffffffffffffffffffffffff16955080890398506140fb565b6000987fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019590951b945b50614115565b6dffffffffffffffffffffffffffff851694505b87617fff141561417b578561414a577f7fff00000000000000000000000000000000000000000000000000000000000061416c565b7fffff0000000000000000000000000000000000000000000000000000000000005b98505050505050505050610b4e565b84607089901b8761418d57600061419f565b6f800000000000000000000000000000005b6fffffffffffffffffffffffffffffffff16171760801b98505050505050505050610b4e56fea264697066735822122079b7ba8f10037609d0ecda44b47c4c3264cf2fb12d0d65a7ab2c5c200e5929f464736f6c63430007060033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100f55760003560e01c80638e6f235311610097578063a598cef811610066578063a598cef8146102d3578063c36596a6146101f4578063dd43eb57146102f0578063ec093021146102f8576100f5565b80638e6f23531461022957806395d89b4114610246578063992e2a92146102c35780639a86139b146102cb576100f5565b806340179d83116100d357806340179d83146101f45780634dcd7dee146101fc578063665df4601461020457806373d1747b14610221576100f5565b806301032adc146100fa5780631a1afbc5146101145780631f072062146101d8575b600080fd5b610102610300565b60408051918252519081900360200190f35b6101b2600480360361010081101561012b57600080fd5b60408051808201825283359360208101359373ffffffffffffffffffffffffffffffffffffffff8483013516939082019260a0830191606084019060029083908390808284376000920191909152505060408051808201825292959493818101939250906002908390839080828437600092019190915250919450509035915061030c9050565b604080519485526020850193909352838301919091526060830152519081900360800190f35b6101e06104b4565b604080519115158252519081900360200190f35b6101026104b9565b6101026104c5565b6101026004803603602081101561021a57600080fd5b50356104e9565b61010261051e565b6101026004803603602081101561023f57600080fd5b5035610532565b61024e610551565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610288578181015183820152602001610270565b50505050905090810190601f1680156102b55780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610102610588565b610102610594565b610102600480360360208110156102e957600080fd5b50356105b8565b610102610743565b610102610748565b671bc16d674ec7ffff81565b600080808073ffffffffffffffffffffffffffffffffffffffff881661039357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f5a65726f206f7261636c65000000000000000000000000000000000000000000604482015290519081900360640190fd5b61043261039f89610758565b6103b1876103ac8c61098d565b610b23565b61042b8b73ffffffffffffffffffffffffffffffffffffffff166366101b646040518163ffffffff1660e01b815260040160206040518083038186803b1580156103fa57600080fd5b505afa15801561040e573d6000803e3d6000fd5b505050506040513d602081101561042457600080fd5b5051610b54565b8d8d610b6f565b9092509050600082670de0b6b3a764000083028161044c57fe5b059050600061046989600160200201518960016020020151610bb6565b905061049761049261048b836104868c6000602002015187610bb6565b610bb6565b8b51610cca565b6104e9565b95506104a38187610cca565b945050509650965096509692505050565b600190565b670de0b6b3a764000081565b7f800000000000000000000000000000000000000000000000000000000000000081565b600061051661050861050384670de0b6b3a7640000610e49565b610e67565b670de0b6b3a76400006110b1565b90505b919050565b6402540be400670de0b6b3a76400005b0481565b600061051661050861054c84670de0b6b3a7640000610e49565b6110cd565b60408051808201909152600a81527f7835526570726963657200000000000000000000000000000000000000000000602082015290565b6704a03ce68d21555681565b7f42524f4e5a45000000000000000000000000000000000000000000000000000090565b6000806105cd83670de0b6b3a7640000610e49565b905060006105da82611101565b905060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6106128361060d6025611126565b611192565b60000b148061062f575061062f8261062a6025611126565b611391565b156106c957600061066261065d61064e610648866113f7565b8661141c565b6106586002611126565b611860565b611c6d565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6106a08461060d6602831c2082c9f3655af3107a4000610e49565b60000b14156106ba576106b38382611ca1565b91506106c7565b6106c48382611e43565b91505b505b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6106f384611ed4565b60000b14806107085750610708836000611391565b6107245761071f6107196001611126565b82611f79565b610726565b805b905061073a81670de0b6b3a76400006110b1565b95945050505050565b600181565b6002670de0b6b3a764000061052e565b60008173ffffffffffffffffffffffffffffffffffffffff1663dbcb32bf6040518163ffffffff1660e01b815260040160206040518083038186803b1580156107a057600080fd5b505afa1580156107b4573d6000803e3d6000fd5b505050506040513d60208110156107ca57600080fd5b5051604080517fab56c592000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163ab56c59291600480820192602092909190829003018186803b15801561083457600080fd5b505afa158015610848573d6000803e3d6000fd5b505050506040513d602081101561085e57600080fd5b5051604080517fdbcb32bf000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff85169163dbcb32bf916004808301926020929190829003018186803b1580156108c657600080fd5b505afa1580156108da573d6000803e3d6000fd5b505050506040513d60208110156108f057600080fd5b5051604080517fc6bb30e2000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163c6bb30e291600480820192602092909190829003018186803b15801561095a57600080fd5b505afa15801561096e573d6000803e3d6000fd5b505050506040513d602081101561098457600080fd5b50510192915050565b6000808273ffffffffffffffffffffffffffffffffffffffff16635b69a7d860006040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b1580156109e257600080fd5b505afa1580156109f6573d6000803e3d6000fd5b505050506040513d6020811015610a0c57600080fd5b5051604080517ffeaf968c000000000000000000000000000000000000000000000000000000008152905173ffffffffffffffffffffffffffffffffffffffff9092169163feaf968c9160048082019260a092909190829003018186803b158015610a7657600080fd5b505afa158015610a8a573d6000803e3d6000fd5b505050506040513d60a0811015610aa057600080fd5b506020810151606090910151909250905080610b1d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f454d5054595f4f5241434c455f4c41544553545f524f554e4400000000000000604482015290519081900360640190fd5b50919050565b600082670de0b6b3a76400008484030281610b3a57fe5b05600502670de0b6b3a76400006005020190505b92915050565b60006301e13380428303670de0b6b3a7640000020592915050565b600080610b7d868685611fa7565b915083821215610b8b578391505b670de0b6b3a76400008702848103831315610ba65784810392505b8281039150509550959350505050565b6000828202831580610bd0575082848281610bcd57fe5b04145b610c3b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4d554c5f4f564552464c4f570000000000000000000000000000000000000000604482015290519081900360640190fd5b6706f05b59d3b20000810181811015610cb557604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4d554c5f4f564552464c4f570000000000000000000000000000000000000000604482015290519081900360640190fd5b670de0b6b3a7640000815b0495945050505050565b600081610d3857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f4449565f5a45524f000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b670de0b6b3a76400008302831580610d605750670de0b6b3a7640000848281610d5d57fe5b04145b610dcb57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4449565f494e5445524e414c0000000000000000000000000000000000000000604482015290519081900360640190fd5b60028304810181811015610e4057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4449565f494e5445524e414c0000000000000000000000000000000000000000604482015290519081900360640190fd5b838181610cc057fe5b6000610e60610e57846120b0565b61065884611126565b9392505050565b60006f80000000000000000000000000000000608083901c1115610eac57507f7fff800000000000000000000000000000000000000000000000000000000000610519565b617fff60f083901c811690811415610ec75782915050610519565b6dffffffffffffffffffffffffffff608084901c1681610eea5760019150610efc565b6e010000000000000000000000000000175b80610f0d5750600091506105199050565b613fff8201600190811c9216158015610f89576e0100000000000000000000000000008210610f4257607182901b9150610f84565b6000610f4d83612152565b60e20360fe167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810160011c909403939290921b91505b610fed565b6e0100000000000000000000000000008210610fab57607082901b9150610fed565b6000610fb683612152565b60e10360fe167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90810160011c909403939290921b91505b6e01000000000000000000000000000080830401600190811c9081848161101057fe5b048201901c9050600181848161102257fe5b048201901c9050600181848161103457fe5b048201901c9050600181848161104657fe5b048201901c9050600181848161105857fe5b048201901c9050600181848161106a57fe5b048201901c9050600081848161107c57fe5b0490508181101561108b578091505b816dffffffffffffffffffffffffffff16607086901b1760801b95505050505050610519565b6000610e606110c8846110c385611126565b61141c565b612202565b60006105166110db83612325565b7f3ffe62e42fefa39ef35793c7673007e50000000000000000000000000000000061141c565b7f7fffffffffffffffffffffffffffffff000000000000000000000000000000001690565b60008161113557506000610519565b81600061114182612152565b9050607081101561115a578060700382901b915061116d565b607081111561116d576070810382901c91505b613fff0160701b6dffffffffffffffffffffffffffff919091161760801b9050610519565b60006f7fffffffffffffffffffffffffffffff608084901c166f7fff00000000000000000000000000008111156111c857600080fd5b6f7fffffffffffffffffffffffffffffff608084901c166f7fff00000000000000000000000000008111156111fc57600080fd5b7fffffffffffffffffffffffffffffffff0000000000000000000000000000000085811690851614158061125157506f7fff0000000000000000000000000000826fffffffffffffffffffffffffffffffff16105b61125a57600080fd5b7fffffffffffffffffffffffffffffffff00000000000000000000000000000000858116908516141561129257600092505050610b4e565b6f80000000000000000000000000000000608086811c82118015929187901c9190911015906113205780156112f357826fffffffffffffffffffffffffffffffff16846fffffffffffffffffffffffffffffffff16116112f3576001611315565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b945050505050610b4e565b8015611333576001945050505050610b4e565b826fffffffffffffffffffffffffffffffff16846fffffffffffffffffffffffffffffffff1611611384577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff611315565b6001945050505050610b4e565b60007fffffffffffffffffffffffffffffffff0000000000000000000000000000000083811690831614156113ef57506f7fff00000000000000000000000000006f7fffffffffffffffffffffffffffffff608084901c1610610b4e565b506000610b4e565b7f80000000000000000000000000000000000000000000000000000000000000001890565b6000617fff60f084811c8216919084901c81169082141561159c5780617fff141561151d577fffffffffffffffffffffffffffffffff00000000000000000000000000000000858116908516141561149b575050507f800000000000000000000000000000000000000000000000000000000000000081168218610b4e565b7f80000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffff000000000000000000000000000000008686181614156114f257505050818117610b4e565b507f7fff8000000000000000000000000000000000000000000000000000000000009150610b4e9050565b7f7fffffffffffffffffffffffffffffff00000000000000000000000000000000841661156f57507f7fff8000000000000000000000000000000000000000000000000000000000009150610b4e9050565b5050507f800000000000000000000000000000000000000000000000000000000000000081168218610b4e565b80617fff1415611625577f7fffffffffffffffffffffffffffffff0000000000000000000000000000000085166115f857507f7fff8000000000000000000000000000000000000000000000000000000000009150610b4e9050565b5050507f800000000000000000000000000000000000000000000000000000000000000082168118610b4e565b6dffffffffffffffffffffffffffff608086901c1682611648576001925061165a565b6e010000000000000000000000000000175b6dffffffffffffffffffffffffffff608086901c168261167d576001925061168f565b6e010000000000000000000000000000175b90810290816116f4577f8000000000000000000000000000000000000000000000000000000000000000878718166116c8576000611315565b7f8000000000000000000000000000000000000000000000000000000000000000945050505050610b4e565b9282019260007c020000000000000000000000000000000000000000000000000000000083101561175a577c01000000000000000000000000000000000000000000000000000000008310156117525761174d83612152565b611755565b60e05b61175d565b60e15b9050614070818601101561177857600094506000925061181c565b6140e081860110156117bb5761407085101561179d57846140700383901c92506117b2565b6140708511156117b257614070850383901b92505b6000945061181c565b61c0dd81860111156117d557617fff94506000925061181c565b60708111156117ec576070810383901c92506117ff565b60708110156117ff578060700383901b92505b6dffffffffffffffffffffffffffff831692506140df8186010394505b82607086901b888a186f8000000000000000000000000000000060801b1660801c6fffffffffffffffffffffffffffffffff16171760801b95505050505050610b4e565b6000617fff60f084811c8216919084901c8116908214156118b05780617fff141561156f57507f7fff8000000000000000000000000000000000000000000000000000000000009150610b4e9050565b80617fff1415611938577dffffffffffffffffffffffffffff0000000000000000000000000000000084161561190b57507f7fff8000000000000000000000000000000000000000000000000000000000009150610b4e9050565b5050508082187f800000000000000000000000000000000000000000000000000000000000000016610b4e565b7f7fffffffffffffffffffffffffffffff000000000000000000000000000000008416611a00577f7fffffffffffffffffffffffffffffff0000000000000000000000000000000085166119b157507f7fff8000000000000000000000000000000000000000000000000000000000009150610b4e9050565b5050508082187f8000000000000000000000000000000000000000000000000000000000000000167f7fff00000000000000000000000000000000000000000000000000000000000017610b4e565b6dffffffffffffffffffffffffffff608085901c1681611a235760019150611a35565b6e010000000000000000000000000000175b6dffffffffffffffffffffffffffff608087901c1683611a99578015611a94576000611a6082612152565b6001955060e2039384017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8e01939190911b90505b611aae565b6e0100000000000000000000000000001760721b5b818181611ab757fe5b04905080611aef577f8000000000000000000000000000000000000000000000000000000000000000878718166116c8576000611315565b6d1000000000000000000000000000811015611b0757fe5b60006e080000000000000000000000000000821015611b68576e040000000000000000000000000000821015611b5d576e020000000000000000000000000000821015611b55576070611b58565b60715b611b60565b60725b60ff16611b71565b611b7182612152565b905083614071018186011115611b8f57617fff945060009150611c29565b83818601613ffc011015611baa576000945060009150611c29565b83818601613f8c011015611bf7578385613ffc011115611bd5578385613ffc010382901b9150611bee565b8385613ffc011015611bee57613ffc8585030382901c91505b60009450611c29565b6070811115611c0a576070810382901c91505b6dffffffffffffffffffffffffffff8216915083818601613f8d010394505b81607086901b888a186f8000000000000000000000000000000060801b1660801c6fffffffffffffffffffffffffffffffff16171760801b95505050505050610b4e565b6000610516611c9c837f3fff71547652b82fe1777d0ffda0d23a0000000000000000000000000000000061141c565b6125d7565b600080611d5c611d46611d30611d1a611d04611cec611cce660140b5e5d6593f662386f26fc10000610e49565b8a611ce766027cfea3c34b2866038d7ea4c68000610e49565b613bea565b89611ce7660243b55f4b9a8d655af3107a4000610e49565b88611ce7651ed7f455feaf64e8d4a51000610e49565b87611ce76565ef7e5b3d8f64e8d4a51000610e49565b86611ce765c9314dd1b6cb64e8d4a51000610e49565b85611ce765c846e82396b864e8d4a51000610e49565b90506000611e2e611e17611e00611de9611dd2611dba611da4611d8d660323e328a37c70662386f26fc10000610e49565b8c611ce7659fad4fc2b238655af3107a4000610e49565b8b611ce7650e9c3b9924c764e8d4a51000610e49565b8a611ce7660315442329bd956509184e72a000610e49565b89611ce766010db93eb39b9a64e8d4a51000610e49565b88611ce7660243a6ccd22a0f64e8d4a51000610e49565b87611ce76602d1fb234ac30c64e8d4a51000610e49565b86611ce76601908dd0472d7064e8d4a51000610e49565b905061073a611e3d858461141c565b82611860565b600080611e6384611e54600d611126565b611e5e6014611126565b613bff565b9050611e7984611e736004611126565b83613bff565b9050611e8984611e736003611126565b9050611e9984611e736002611126565b9050611ea984611e736001611126565b9050611ecc83610658611ec6643a5cab35c764174876e800610e49565b84611860565b949350505050565b60006f7fffffffffffffffffffffffffffffff608083901c166f7fff0000000000000000000000000000811115611f0a57600080fd5b6fffffffffffffffffffffffffffffffff8116611f2b576000915050610519565b6f80000000000000000000000000000000608084901c10611f6f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff915050610519565b6001915050610519565b6000610e60837f80000000000000000000000000000000000000000000000000000000000000008418613c0f565b600080670de0b6b3a7640000611fbc856104e9565b840281611fc557fe5b0590506000816ec097ce7bc90715b34b9f100000000081611fe257fe5b0590506f01812f9cf7920e2b66973e20000000008480028602056000670de0b6b3a76400008261201560048b5b05610532565b0184028161201f57fe5b059050600061202f8583036105b8565b600402670de0b6b3a76400008a612045856105b8565b028161204d57fe5b05039050670de0b6b3a76400008361206660068c61200f565b0185028161207057fe5b05915060006120808684036105b8565b600602670de0b6b3a76400008b612096866105b8565b028161209e57fe5b05039091039998505050505050505050565b6000816120bf57506000610519565b60008083136120d157826000036120d3565b825b905060006120e082612152565b905060708110156120f9578060700382901b915061210c565b607081111561210c576070810382901c91505b6dffffffffffffffffffffffffffff909116613fff820160701b17906000841215612147576f80000000000000000000000000000000821791505b5060801b9050610519565b600080821161216057600080fd5b6000700100000000000000000000000000000000831061218257608092831c92015b68010000000000000000831061219a57604092831c92015b64010000000083106121ae57602092831c92015b6201000083106121c057601092831c92015b61010083106121d157600892831c92015b601083106121e157600492831c92015b600483106121f157600292831c92015b600283106105165760010192915050565b6000617fff60f083901c166140fe81111561221c57600080fd5b613fff811015612230576000915050610519565b6e0100000000000000000000000000006dffffffffffffffffffffffffffff608085901c161761406f82101561226c5761406f8290031c61229b565b61406f82111561229b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbf9182011b5b6f80000000000000000000000000000000608085901c106122ef577f80000000000000000000000000000000000000000000000000000000000000008111156122e357600080fd5b60000391506105199050565b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81111561231c57600080fd5b91506105199050565b60006f80000000000000000000000000000000608083901c111561236a57507f7fff800000000000000000000000000000000000000000000000000000000000610519565b7f3fff0000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffff00000000000000000000000000000000831614156123bc57506000610519565b617fff60f083901c8116908114156123d75782915050610519565b6dffffffffffffffffffffffffffff608084901c16816123fa576001915061240c565b6e010000000000000000000000000000175b8061243c57507fffff00000000000000000000000000000000000000000000000000000000000091506105199050565b600061406f81613fff851061247f5750600f9290921b91600091507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00184016124c9565b600192506e01000000000000000000000000000084106124ac5784613ffe039050600f84901b93506124c9565b60006124b785612152565b607f8190039590951b9461406d039150505b836f8000000000000000000000000000000014156125095782156124eb576001015b60006124f682612152565b60700392839003929190911b9050612580565b60008361251757600061251a565b60015b60ff1690505b6e01000000000000000000000000000082101561257e5793800260ff81901c607f81019190911c947fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff939093019260019290921b9082180190612520565b505b806dffffffffffffffffffffffffffff16607083901b846125a25760006125b4565b6f800000000000000000000000000000005b6fffffffffffffffffffffffffffffffff16171760801b95505050505050610519565b60006f80000000000000000000000000000000608083901c90811190617fff60f085901c8116916dffffffffffffffffffffffffffff16908214801561261c57508015155b1561264d57507f7fff8000000000000000000000000000000000000000000000000000000000009250610519915050565b61400d82111561268f5782612682577f7fff000000000000000000000000000000000000000000000000000000000000612685565b60005b9350505050610519565b613f7f8210156126c557507f3fff0000000000000000000000000000000000000000000000000000000000009250610519915050565b816126d357600191506126e5565b6e010000000000000000000000000000175b613fef821115612718577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc01182011b61272a565b613fef82101561272a57613fef8290031c5b828015612748575071406e0000000000000000000000000000000081115b1561275a575060009250610519915050565b821580156127795750713fffffffffffffffffffffffffffffffffff81115b156127aa57507f7fff0000000000000000000000000000000000000000000000000000000000009250610519915050565b6fffffffffffffffffffffffffffffffff81169060801c8380156127cd57508115155b156127d9579019906001015b6f80000000000000000000000000000000828116156128095770016a09e667f3bcc908b2fb1366ea957d3e0260801c5b6f40000000000000000000000000000000831615612838577001306fe0a31b7152de8d5a46305c85edec0260801c5b6f20000000000000000000000000000000831615612867577001172b83c7d517adcdf7c8c50eb14a791f0260801c5b6f100000000000000000000000000000008316156128965770010b5586cf9890f6298b92b71842a983630260801c5b6f080000000000000000000000000000008316156128c5577001059b0d31585743ae7c548eb68ca417fd0260801c5b6f040000000000000000000000000000008316156128f457700102c9a3e778060ee6f7caca4f7a29bde80260801c5b6f020000000000000000000000000000008316156129235770010163da9fb33356d84a66ae336dcdfa3f0260801c5b6f0100000000000000000000000000000083161561295257700100b1afa5abcbed6129ab13ec11dc95430260801c5b6e8000000000000000000000000000008316156129805770010058c86da1c09ea1ff19d294cf2f679b0260801c5b6e4000000000000000000000000000008316156129ae577001002c605e2e8cec506d21bfc89a23a00f0260801c5b6e2000000000000000000000000000008316156129dc57700100162f3904051fa128bca9c55c31e5df0260801c5b6e100000000000000000000000000000831615612a0a577001000b175effdc76ba38e31671ca9397250260801c5b6e080000000000000000000000000000831615612a3857700100058ba01fb9f96d6cacd4b180917c3d0260801c5b6e040000000000000000000000000000831615612a665770010002c5cc37da9491d0985c348c68e7b30260801c5b6e020000000000000000000000000000831615612a94577001000162e525ee054754457d59952920260260801c5b6e010000000000000000000000000000831615612ac25770010000b17255775c040618bf4a4ade83fc0260801c5b6d8000000000000000000000000000831615612aef577001000058b91b5bc9ae2eed81e9b7d4cfab0260801c5b6d4000000000000000000000000000831615612b1c57700100002c5c89d5ec6ca4d7c8acc017b7c90260801c5b6d2000000000000000000000000000831615612b495770010000162e43f4f831060e02d839a9d16d0260801c5b6d1000000000000000000000000000831615612b7657700100000b1721bcfc99d9f890ea069117630260801c5b6d0800000000000000000000000000831615612ba35770010000058b90cf1e6d97f9ca14dbcc16280260801c5b6d0400000000000000000000000000831615612bd0577001000002c5c863b73f016468f6bac5ca2b0260801c5b6d0200000000000000000000000000831615612bfd57700100000162e430e5a18f6119e3c02282a50260801c5b6d0100000000000000000000000000831615612c2a577001000000b1721835514b86e6d96efd1bfe0260801c5b6c80000000000000000000000000831615612c5657700100000058b90c0b48c6be5df846c5b2ef0260801c5b6c40000000000000000000000000831615612c825770010000002c5c8601cc6b9e94213c72737a0260801c5b6c20000000000000000000000000831615612cae577001000000162e42fff037df38aa2b219f060260801c5b6c10000000000000000000000000831615612cda5770010000000b17217fba9c739aa5819f44f90260801c5b6c08000000000000000000000000831615612d06577001000000058b90bfcdee5acd3c1cedc8230260801c5b6c04000000000000000000000000831615612d3257700100000002c5c85fe31f35a6a30da1be500260801c5b6c02000000000000000000000000831615612d5e5770010000000162e42ff0999ce3541b9fffcf0260801c5b6c01000000000000000000000000831615612d8a57700100000000b17217f80f4ef5aadda455540260801c5b6b800000000000000000000000831615612db55770010000000058b90bfbf8479bd5a81b51ad0260801c5b6b400000000000000000000000831615612de0577001000000002c5c85fdf84bd62ae30a74cc0260801c5b6b200000000000000000000000831615612e0b57700100000000162e42fefb2fed257559bdaa0260801c5b6b100000000000000000000000831615612e36577001000000000b17217f7d5a7716bba4a9ae0260801c5b6b080000000000000000000000831615612e6157700100000000058b90bfbe9ddbac5e109cce0260801c5b6b040000000000000000000000831615612e8c5770010000000002c5c85fdf4b15de6f17eb0d0260801c5b6b020000000000000000000000831615612eb7577001000000000162e42fefa494f1478fde050260801c5b6b010000000000000000000000831615612ee25770010000000000b17217f7d20cf927c8e94c0260801c5b6a8000000000000000000000831615612f0c577001000000000058b90bfbe8f71cb4e4b33d0260801c5b6a4000000000000000000000831615612f3657700100000000002c5c85fdf477b662b269450260801c5b6a2000000000000000000000831615612f605770010000000000162e42fefa3ae53369388c0260801c5b6a1000000000000000000000831615612f8a57700100000000000b17217f7d1d351a389d400260801c5b6a0800000000000000000000831615612fb45770010000000000058b90bfbe8e8b2d3d4ede0260801c5b6a0400000000000000000000831615612fde577001000000000002c5c85fdf4741bea6e77e0260801c5b6a020000000000000000000083161561300857700100000000000162e42fefa39fe95583c20260801c5b6a0100000000000000000000831615613032577001000000000000b17217f7d1cfb72b45e10260801c5b698000000000000000000083161561305b57700100000000000058b90bfbe8e7cc35c3f00260801c5b69400000000000000000008316156130845770010000000000002c5c85fdf473e242ea380260801c5b69200000000000000000008316156130ad577001000000000000162e42fefa39f02b772c0260801c5b69100000000000000000008316156130d65770010000000000000b17217f7d1cf7d83c1a0260801c5b69080000000000000000008316156130ff577001000000000000058b90bfbe8e7bdcbe2e0260801c5b690400000000000000000083161561312857700100000000000002c5c85fdf473dea871f0260801c5b69020000000000000000008316156131515770010000000000000162e42fefa39ef44d910260801c5b690100000000000000000083161561317a57700100000000000000b17217f7d1cf79e9490260801c5b688000000000000000008316156131a25770010000000000000058b90bfbe8e7bce5440260801c5b684000000000000000008316156131ca577001000000000000002c5c85fdf473de6eca0260801c5b682000000000000000008316156131f257700100000000000000162e42fefa39ef366f0260801c5b6810000000000000000083161561321a577001000000000000000b17217f7d1cf79afa0260801c5b6808000000000000000083161561324257700100000000000000058b90bfbe8e7bcd6d0260801c5b6804000000000000000083161561326a5770010000000000000002c5c85fdf473de6b20260801c5b68020000000000000000831615613292577001000000000000000162e42fefa39ef3580260801c5b680100000000000000008316156132ba5770010000000000000000b17217f7d1cf79ab0260801c5b6780000000000000008316156132e1577001000000000000000058b90bfbe8e7bcd50260801c5b67400000000000000083161561330857700100000000000000002c5c85fdf473de6a0260801c5b67200000000000000083161561332f5770010000000000000000162e42fefa39ef340260801c5b67100000000000000083161561335657700100000000000000000b17217f7d1cf7990260801c5b67080000000000000083161561337d5770010000000000000000058b90bfbe8e7bcc0260801c5b6704000000000000008316156133a4577001000000000000000002c5c85fdf473de50260801c5b6702000000000000008316156133cb57700100000000000000000162e42fefa39ef20260801c5b6701000000000000008316156133f2577001000000000000000000b17217f7d1cf780260801c5b668000000000000083161561341857700100000000000000000058b90bfbe8e7bb0260801c5b664000000000000083161561343e5770010000000000000000002c5c85fdf473dd0260801c5b6620000000000000831615613464577001000000000000000000162e42fefa39ee0260801c5b661000000000000083161561348a5770010000000000000000000b17217f7d1cf60260801c5b66080000000000008316156134b0577001000000000000000000058b90bfbe8e7a0260801c5b66040000000000008316156134d657700100000000000000000002c5c85fdf473c0260801c5b66020000000000008316156134fc5770010000000000000000000162e42fefa39d0260801c5b660100000000000083161561352257700100000000000000000000b17217f7d1ce0260801c5b658000000000008316156135475770010000000000000000000058b90bfbe8e60260801c5b6540000000000083161561356c577001000000000000000000002c5c85fdf4720260801c5b6520000000000083161561359157700100000000000000000000162e42fefa380260801c5b651000000000008316156135b6577001000000000000000000000b17217f7d1b0260801c5b650800000000008316156135db57700100000000000000000000058b90bfbe8d0260801c5b650400000000008316156136005770010000000000000000000002c5c85fdf460260801c5b65020000000000831615613625577001000000000000000000000162e42fefa20260801c5b6501000000000083161561364a5770010000000000000000000000b17217f7d00260801c5b64800000000083161561366e577001000000000000000000000058b90bfbe70260801c5b64400000000083161561369257700100000000000000000000002c5c85fdf30260801c5b6420000000008316156136b65770010000000000000000000000162e42fef90260801c5b6410000000008316156136da57700100000000000000000000000b17217f7c0260801c5b6408000000008316156136fe5770010000000000000000000000058b90bfbd0260801c5b640400000000831615613722577001000000000000000000000002c5c85fde0260801c5b64020000000083161561374657700100000000000000000000000162e42fee0260801c5b64010000000083161561376a577001000000000000000000000000b17217f60260801c5b638000000083161561378d57700100000000000000000000000058b90bfa0260801c5b63400000008316156137b05770010000000000000000000000002c5c85fc0260801c5b63200000008316156137d3577001000000000000000000000000162e42fd0260801c5b63100000008316156137f65770010000000000000000000000000b17217e0260801c5b6308000000831615613819577001000000000000000000000000058b90be0260801c5b630400000083161561383c57700100000000000000000000000002c5c85e0260801c5b630200000083161561385f5770010000000000000000000000000162e42e0260801c5b630100000083161561388257700100000000000000000000000000b172160260801c5b628000008316156138a45770010000000000000000000000000058b90a0260801c5b624000008316156138c6577001000000000000000000000000002c5c840260801c5b622000008316156138e857700100000000000000000000000000162e410260801c5b6210000083161561390a577001000000000000000000000000000b17200260801c5b6208000083161561392c57700100000000000000000000000000058b8f0260801c5b6204000083161561394e5770010000000000000000000000000002c5c70260801c5b62020000831615613970577001000000000000000000000000000162e30260801c5b620100008316156139925770010000000000000000000000000000b1710260801c5b6180008316156139b3577001000000000000000000000000000058b80260801c5b6140008316156139d457700100000000000000000000000000002c5b0260801c5b6120008316156139f55770010000000000000000000000000000162d0260801c5b611000831615613a1657700100000000000000000000000000000b160260801c5b610800831615613a375770010000000000000000000000000000058a0260801c5b610400831615613a58577001000000000000000000000000000002c40260801c5b610200831615613a79577001000000000000000000000000000001610260801c5b610100831615613a9a577001000000000000000000000000000000b00260801c5b6080831615613aba577001000000000000000000000000000000570260801c5b6040831615613ada5770010000000000000000000000000000002b0260801c5b6020831615613afa577001000000000000000000000000000000150260801c5b6010831615613b1a5770010000000000000000000000000000000a0260801c5b6008831615613b3a577001000000000000000000000000000000040260801c5b6004831615613b5a577001000000000000000000000000000000010260801c5b84613b8257600f81901c6dffffffffffffffffffffffffffff169050613fff82019150613bd5565b613ffe8211613bae57600f81901c6dffffffffffffffffffffffffffff16905081613fff039150613bd5565b6000917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc011011c5b60709190911b1760801b935061051992505050565b6000611ecc613bf9858561141c565b83613c0f565b6000611ecc84613c0f8585611860565b6000617fff60f084811c8216919084901c811690821415613c755780617fff1415613c6b577fffffffffffffffffffffffffffffffff0000000000000000000000000000000085811690851614156114f2578492505050610b4e565b8492505050610b4e565b80617fff1415613c89578392505050610b4e565b6f80000000000000000000000000000000608086901c90811015906dffffffffffffffffffffffffffff1683613cc25760019350613cd4565b6e010000000000000000000000000000175b6f80000000000000000000000000000000608087901c90811015906dffffffffffffffffffffffffffff1684613d0d5760019450613d1f565b6e010000000000000000000000000000175b82613d83577fffffffffffffffffffffffffffffffff0000000000000000000000000000000088167f800000000000000000000000000000000000000000000000000000000000000014613d735787613d76565b60005b9650505050505050610b4e565b80613dd7577fffffffffffffffffffffffffffffffff0000000000000000000000000000000089167f800000000000000000000000000000000000000000000000000000000000000014613d735788613d76565b8486038415158315151415613f65576070811315613dfe5789975050505050505050610b4e565b6000811315613e105790811c90613e5d565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90811215613e475788975050505050505050610b4e565b6000811215613e5d578060000384901c93508596505b928101926e0200000000000000000000000000008410613e83576001968701969390931c925b86617fff1415613ee85784613eb8577f7fff000000000000000000000000000000000000000000000000000000000000613eda565b7fffff0000000000000000000000000000000000000000000000000000000000005b975050505050505050610b4e565b6e010000000000000000000000000000841015613f085760009650613f1c565b6dffffffffffffffffffffffffffff841693505b83607088901b86613f2e576000613f40565b6f800000000000000000000000000000005b6fffffffffffffffffffffffffffffffff16171760801b975050505050505050610b4e565b6000811315613f8057600184901b9350600187039650613f97565b6000811215613f9757600182901b91506001860396505b6070811315613fa95760019150614032565b6001811315613fc6576001810360018303901c6001019150614032565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90811215613ff75760019350614032565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811215614032576001816000030360018503901c60010193505b81841061404357818403935061404c565b83820393508294505b83614062575060009650610b4e95505050505050565b600061406d85612152565b9050806071141561409a57600185901c6dffffffffffffffffffffffffffff169450600188019750614115565b6070811015614101576070819003808911156140d0578086901b6dffffffffffffffffffffffffffff16955080890398506140fb565b6000987fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019590951b945b50614115565b6dffffffffffffffffffffffffffff851694505b87617fff141561417b578561414a577f7fff00000000000000000000000000000000000000000000000000000000000061416c565b7fffff0000000000000000000000000000000000000000000000000000000000005b98505050505050505050610b4e565b84607089901b8761418d57600061419f565b6f800000000000000000000000000000005b6fffffffffffffffffffffffffffffffff16171760801b98505050505050505050610b4e56fea264697066735822122079b7ba8f10037609d0ecda44b47c4c3264cf2fb12d0d65a7ab2c5c200e5929f464736f6c63430007060033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
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.