Contract 0x2b99e3d67dad973c1b9747da742b7e26c8bdd67b 1

 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x51de260861add1641bf9cd0afc945f1dd3adf369bd7b3dc54975cbac39a674ceUpdate Min Optio...1521085102023-11-19 23:19:1113 days 5 hrs ago0xde485812e28824e542b9c2270b6b8ed9232b7d0b IN  Dopex: Option Pricing0 ETH0.00004426 0.1
0x11422ea94fc94c836ef82e5055bc76aae2bdef69b4c534943cfc0209dfbc80e5Update Min Optio...1517991402023-11-19 0:02:1514 days 4 hrs ago0xde485812e28824e542b9c2270b6b8ed9232b7d0b IN  Dopex: Option Pricing0 ETH0.00003288 0.1
0x943a1bd40ccf778523ac44c45b2cb7e9a5622ff5a1409e19bb207c9ef729b008Update Min Optio...1501721352023-11-14 1:30:2319 days 3 hrs ago0xde485812e28824e542b9c2270b6b8ed9232b7d0b IN  Dopex: Option Pricing0 ETH0.00006512 0.1
0x771f46433b8f8cf0e051cf715204bc8c8dea1148604a5d0dfeece7f9b9950595Update Min Optio...1500840392023-11-13 18:45:2319 days 10 hrs ago0xde485812e28824e542b9c2270b6b8ed9232b7d0b IN  Dopex: Option Pricing0 ETH0.00009705 0.1
0xa9f3f14c58878b7e5b1bcde06fa1cca345df77d280b188945205af02eec80b690x6080604026355172021-10-27 23:25:04766 days 5 hrs ago0xde485812e28824e542b9c2270b6b8ed9232b7d0b IN  Create: OptionPricingSimple0 ETH0.117633997297 ETH1.311610685
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x6fcf4616918559abf93be0addf7d7c0910dd8918f0378a332b91ac5b83bedeff720532032023-03-21 8:01:28256 days 20 hrs ago 0xfca313e2be55957ac628a6193a60d38adc2da64e Dopex: Option Pricing0 ETH
0x1ce6b3c3a150567b6d105a760216a6980c2d1ea7ace9d19ca7d1ccb1ee4d2530720358492023-03-21 6:50:12256 days 22 hrs ago 0xb4ec6b4ec9e42a42b0b8cdd3d6df8867546cf11d Dopex: Option Pricing0 ETH
0x49db6457ba23d6691d5bb7f7417a529f31fd548cf3fb99a77fbe9ecc56820762720356512023-03-21 6:49:22256 days 22 hrs ago 0xf71b2b6fe3c1d94863e751d6b455f750e714163c Dopex: Option Pricing0 ETH
0xb25f3b970128a4062c4133e26acb7b87b56ef9fc3c2da8d14258bf1ef4dc526f720272112023-03-21 6:14:45256 days 22 hrs ago 0xc59836fec63cfb2e48b0aa00515056436d74dc03 Dopex: Option Pricing0 ETH
0xbdd365aca1aa5d49aa639880a658676e52b5b091e3d08b5fe8e08cff527edb52720267922023-03-21 6:13:00256 days 22 hrs ago 0xc59836fec63cfb2e48b0aa00515056436d74dc03 Dopex: Option Pricing0 ETH
0xd4b07a014ac40140ff5990c22a0951b60515056b404b58abfe9cef8abd16917c720172032023-03-21 5:33:30256 days 23 hrs ago 0xc59836fec63cfb2e48b0aa00515056436d74dc03 Dopex: Option Pricing0 ETH
0xeef6c0d0308516696d0cd1240d7c11ce9c77e13b06e72c675ad280245a8964ec719799612023-03-21 2:59:12257 days 1 hr ago 0x5847a350a388454a76f34ceb6eb386bf652dd0dd Dopex: Option Pricing0 ETH
0x3732364aae55896b378137924b4257340d3959bd280ddec40bc8e1315b1300c0719757602023-03-21 2:41:52257 days 2 hrs ago 0xfca313e2be55957ac628a6193a60d38adc2da64e Dopex: Option Pricing0 ETH
0x2e0b06d8fb74f448d3782d54410a38e38e4aea92ffc4bf11366e7cf08bf81253719619112023-03-21 1:43:51257 days 3 hrs ago 0xcdaacf37726bf1017821b5169e22eb34734b28a8 Dopex: Option Pricing0 ETH
0x8c72300149aa7834e8cb9acbdd952862b130b3e4daac5ed57eba5245bca4214d719617652023-03-21 1:43:14257 days 3 hrs ago 0xcdaacf37726bf1017821b5169e22eb34734b28a8 Dopex: Option Pricing0 ETH
0xa0d4a40003d86a779039943aef362b1d74c0a2b535652b59dd555f07d407f25d719609872023-03-21 1:39:55257 days 3 hrs ago 0xcdaacf37726bf1017821b5169e22eb34734b28a8 Dopex: Option Pricing0 ETH
0x92d0174771c36763f77314d321369256ce003ed5259a640f06846eacb5f5b494719608352023-03-21 1:39:23257 days 3 hrs ago 0xcdaacf37726bf1017821b5169e22eb34734b28a8 Dopex: Option Pricing0 ETH
0xe276a5cf6f7b0b543718304d68f6f054105b002a9c5507b59fb4cf23c071afea719309242023-03-20 23:31:49257 days 5 hrs ago 0xfca313e2be55957ac628a6193a60d38adc2da64e Dopex: Option Pricing0 ETH
0x92042856d51042a23557ec6c724bee8df160962c698edb1066938a2b037af16c719048722023-03-20 21:39:34257 days 7 hrs ago 0x10fd85ec522c245a63239b9fc64434f58520bd1f Dopex: Option Pricing0 ETH
0xc9ad176d146c860a529f43629f1cb8c0c3113adee38d67a2e9dbdcbbf2dd14c4718906252023-03-20 20:38:39257 days 8 hrs ago 0xcdaacf37726bf1017821b5169e22eb34734b28a8 Dopex: Option Pricing0 ETH
0x0f34f3ee3e86a9ffe3cf9a6c73823881a3d2d6f3be7ca863b1ed77e6311ba78e718551402023-03-20 18:10:28257 days 10 hrs ago 0xd74c61ca8917be73377d74a007e6f002c25efb4e Dopex: Option Pricing0 ETH
0x0f34f3ee3e86a9ffe3cf9a6c73823881a3d2d6f3be7ca863b1ed77e6311ba78e718551402023-03-20 18:10:28257 days 10 hrs ago 0xd74c61ca8917be73377d74a007e6f002c25efb4e Dopex: Option Pricing0 ETH
0xdc4eb526d8fc1dc826164738eea67cb89e2cad6d49f44894df3c0eb06c90c67f718168992023-03-20 15:32:28257 days 13 hrs ago 0xb4ec6b4ec9e42a42b0b8cdd3d6df8867546cf11d Dopex: Option Pricing0 ETH
0xdc4eb526d8fc1dc826164738eea67cb89e2cad6d49f44894df3c0eb06c90c67f718168992023-03-20 15:32:28257 days 13 hrs ago 0xb4ec6b4ec9e42a42b0b8cdd3d6df8867546cf11d Dopex: Option Pricing0 ETH
0x9da1bc55333cc384c468469552ffd622e9b75367b81930911f2b9c22d9ac0366718033702023-03-20 14:36:48257 days 14 hrs ago 0xfca313e2be55957ac628a6193a60d38adc2da64e Dopex: Option Pricing0 ETH
0x4e746362891ac3cb01d5573d0de888d6cee4c447e8f890903c7baf2803caf4a6717450842023-03-20 10:37:51257 days 18 hrs ago 0xfca313e2be55957ac628a6193a60d38adc2da64e Dopex: Option Pricing0 ETH
0x8b1a141c30281136b3731c13a239a55776682729af128d15be4d6e55706bb048717217132023-03-20 9:01:44257 days 19 hrs ago 0x10fd85ec522c245a63239b9fc64434f58520bd1f Dopex: Option Pricing0 ETH
0xedbee5490cc04f570f0a1c99bc70a444e7572ee4e0755358ad0f77cf6ff28677717141892023-03-20 8:30:45257 days 20 hrs ago 0x5847a350a388454a76f34ceb6eb386bf652dd0dd Dopex: Option Pricing0 ETH
0x14276cc8aa9d12bc8a404979d4e313aa4829d5c34ef74e149d85342382bf2aa9717124002023-03-20 8:23:22257 days 20 hrs ago 0x5847a350a388454a76f34ceb6eb386bf652dd0dd Dopex: Option Pricing0 ETH
0xbff76f42fe9e65c055bd11788247cc6455165cee25bfb4aca187a2752f23d050716994522023-03-20 7:29:46257 days 21 hrs ago 0x10fd85ec522c245a63239b9fc64434f58520bd1f Dopex: Option Pricing0 ETH
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
OptionPricingSimple

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, Unlicense license
File 1 of 7 : Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "../utils/Context.sol";
/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

File 2 of 7 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

File 3 of 7 : SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler
 * now has built in overflow checking.
 */
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) {
        unchecked {
            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) {
        unchecked {
            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) {
        unchecked {
            // 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) {
        unchecked {
            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) {
        unchecked {
            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) {
        return a + b;
    }

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

    /**
     * @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.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        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) {
        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) {
        unchecked {
            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.
     *
     * 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).
     *
     * 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) {
        unchecked {
            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) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

File 4 of 7 : ABDKMathQuad.sol
// 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.8.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) {
    unchecked {
      if (x == 0) return bytes16(0);
      else {
        // We rely on overflow behavior here
        uint256 result = uint256(x > 0 ? x : -x);

        uint256 msb = mostSignificantBit(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) {
    unchecked {
      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) {
    unchecked {
      if (x == 0) return bytes16(0);
      else {
        uint256 result = x;

        uint256 msb = mostSignificantBit(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) {
    unchecked {
      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) {
    unchecked {
      if (x == 0) return bytes16(0);
      else {
        // We rely on overflow behavior here
        uint256 result = uint256(x > 0 ? x : -x);

        uint256 msb = mostSignificantBit(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) {
    unchecked {
      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) {
    unchecked {
      if (x == 0) return bytes16(0);
      else {
        // We rely on overflow behavior here
        uint256 result = uint128(x > 0 ? x : -x);

        uint256 msb = mostSignificantBit(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) {
    unchecked {
      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(int256(result)); // We rely on overflow behavior here
      } else {
        require(result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
        return int128(int256(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) {
    unchecked {
      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) {
    unchecked {
      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 = mostSignificantBit(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) {
    unchecked {
      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 = mostSignificantBit(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) {
    unchecked {
      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) {
    unchecked {
      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) {
    unchecked {
      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) {
    unchecked {
      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) {
    unchecked {
      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) {
    unchecked {
      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) {
    unchecked {
      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 = mostSignificantBit(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) {
    unchecked {
      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) {
    unchecked {
      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
          : mostSignificantBit(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) {
    unchecked {
      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) {
            uint256 shift = 226 - mostSignificantBit(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
          ? mostSignificantBit(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) {
    unchecked {
      return x ^ 0x80000000000000000000000000000000;
    }
  }

  /**
   * Calculate |x|.
   *
   * @param x quadruple precision number
   * @return quadruple precision number
   */
  function abs(bytes16 x) internal pure returns (bytes16) {
    unchecked {
      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) {
    unchecked {
      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 = mostSignificantBit(xSignifier);
              uint256 shift = (226 - msb) & 0xFE;
              xSignifier <<= shift;
              xExponent -= (shift - 112) >> 1;
            }
          } else {
            if (xSignifier >= 0x10000000000000000000000000000)
              xSignifier <<= 112;
            else {
              uint256 msb = mostSignificantBit(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) {
    unchecked {
      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 = mostSignificantBit(xSignifier);
              resultSignifier = 16493 - msb;
              xSignifier <<= 127 - msb;
            }
          }

          if (xSignifier == 0x80000000000000000000000000000000) {
            if (resultNegative) resultSignifier += 1;
            uint256 shift = 112 - mostSignificantBit(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) {
    unchecked {
      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) {
    unchecked {
      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) {
    unchecked {
      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 mostSignificantBit(uint256 x) private pure returns (uint256) {
    unchecked {
      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;
    }
  }
}

File 5 of 7 : IOptionPricing.sol
//SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

interface IOptionPricing {
  function getOptionPrice(
    bool isPut,
    uint256 expiry,
    uint256 strike,
    uint256 lastPrice,
    uint256 baseIv
  ) external view returns (uint256);
}

File 6 of 7 : BlackScholes.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

// Libraries
import {ABDKMathQuad} from '../external/libraries/ABDKMathQuad.sol';

/// @title Black-Scholes option pricing formula and supporting statistical functions
/// @author Dopex
/// @notice This library implements the Black-Scholes model to price options.
/// See - https://en.wikipedia.org/wiki/Black%E2%80%93Scholes_model
/// @dev Implements the following implementation - https://cseweb.ucsd.edu/~goguen/courses/130/SayBlackScholes.html
/// Uses the ABDKMathQuad(https://github.com/abdk-consulting/abdk-libraries-solidity/blob/master/ABDKMathQuad.md)
/// library to make precise calculations. It uses a DIVISOR (1e16) for maintaining precision in constants.
library BlackScholes {
    uint8 internal constant OPTION_TYPE_CALL = 0;
    uint8 internal constant OPTION_TYPE_PUT = 1;

    uint256 internal constant DIVISOR = 10**16;

    /**
     * @notice The function that uses the Black-Scholes equation to calculate the option price
     * See http://en.wikipedia.org/wiki/Black%E2%80%93Scholes_model#Black-Scholes_formula
     * NOTE: The different parts of the equation are broken down to separate functions as using
     * ABDKMathQuad makes small equations verbose.
     * @param optionType Type of option - 0 = call, 1 = put
     * @param price Stock price
     * @param strike Strike price
     * @param timeToExpiry Time to expiry in days
     * @param riskFreeRate Risk-free rate
     * @param volatility Volatility on the asset
     * @return Option price based on the Black-Scholes model
     */
    function calculate(
        uint8 optionType,
        uint256 price,
        uint256 strike,
        uint256 timeToExpiry,
        uint256 riskFreeRate,
        uint256 volatility
    ) internal pure returns (uint256) {
        bytes16 S = ABDKMathQuad.fromUInt(price);
        bytes16 X = ABDKMathQuad.fromUInt(strike);
        bytes16 T = ABDKMathQuad.div(
            ABDKMathQuad.fromUInt(timeToExpiry),
            ABDKMathQuad.fromUInt(36500) // 365 * 10 ^ DAYS_PRECISION
        );
        bytes16 r = ABDKMathQuad.div(
            ABDKMathQuad.fromUInt(riskFreeRate),
            ABDKMathQuad.fromUInt(10000)
        );
        bytes16 v = ABDKMathQuad.div(
            ABDKMathQuad.fromUInt(volatility),
            ABDKMathQuad.fromUInt(100)
        );
        bytes16 d1 = ABDKMathQuad.div(
            ABDKMathQuad.add(
                ABDKMathQuad.ln(ABDKMathQuad.div(S, X)),
                ABDKMathQuad.mul(
                    ABDKMathQuad.add(
                        r,
                        ABDKMathQuad.mul(
                            v,
                            ABDKMathQuad.div(v, ABDKMathQuad.fromUInt(2))
                        )
                    ),
                    T
                )
            ),
            ABDKMathQuad.mul(v, ABDKMathQuad.sqrt(T))
        );
        bytes16 d2 = ABDKMathQuad.sub(
            d1,
            ABDKMathQuad.mul(v, ABDKMathQuad.sqrt(T))
        );
        if (optionType == OPTION_TYPE_CALL) {
            return
                ABDKMathQuad.toUInt(
                    ABDKMathQuad.mul(
                        _calculateCallTimeDecay(S, d1, X, r, T, d2),
                        ABDKMathQuad.fromUInt(DIVISOR)
                    )
                );
        } else if (optionType == OPTION_TYPE_PUT) {
            return
                ABDKMathQuad.toUInt(
                    ABDKMathQuad.mul(
                        _calculatePutTimeDecay(X, r, T, d2, S, d1),
                        ABDKMathQuad.fromUInt(DIVISOR)
                    )
                );
        } else return 0;
    }

    /// @dev Function to caluclate the call time decay
    /// From the implementation page(https://cseweb.ucsd.edu/~goguen/courses/130/SayBlackScholes.html); part of the equation
    /// ( S * CND(d1)-X * Math.exp(-r * T) * CND(d2) );
    function _calculateCallTimeDecay(
        bytes16 S,
        bytes16 d1,
        bytes16 X,
        bytes16 r,
        bytes16 T,
        bytes16 d2
    ) internal pure returns (bytes16) {
        return
            ABDKMathQuad.sub(
                ABDKMathQuad.mul(S, CND(d1)),
                ABDKMathQuad.mul(
                    ABDKMathQuad.mul(
                        X,
                        ABDKMathQuad.exp(
                            ABDKMathQuad.mul(ABDKMathQuad.neg(r), T)
                        )
                    ),
                    CND(d2)
                )
            );
    }

    /// @dev Function to caluclate the put time decay
    /// From the implementation page(https://cseweb.ucsd.edu/~goguen/courses/130/SayBlackScholes.html); part of the equation -
    /// ( X * Math.exp(-r * T) * CND(-d2) - S * CND(-d1) );
    function _calculatePutTimeDecay(
        bytes16 X,
        bytes16 r,
        bytes16 T,
        bytes16 d2,
        bytes16 S,
        bytes16 d1
    ) internal pure returns (bytes16) {
        bytes16 price_part1 = ABDKMathQuad.mul(
            ABDKMathQuad.mul(
                X,
                ABDKMathQuad.exp(ABDKMathQuad.mul(ABDKMathQuad.neg(r), T))
            ),
            CND(ABDKMathQuad.neg(d2))
        );
        bytes16 price_part2 = ABDKMathQuad.mul(S, CND(ABDKMathQuad.neg(d1)));
        bytes16 price = ABDKMathQuad.sub(price_part1, price_part2);
        return price;
    }

    /**
     * @notice Normal cumulative distribution function.
     * See http://en.wikipedia.org/wiki/Normal_distribution#Cumulative_distribution_function
     * From the implementation page(https://cseweb.ucsd.edu/~goguen/courses/130/SayBlackScholes.html); part of the equation -
     * "k = 1 / (1 + .2316419 * x); return ( 1 - Math.exp(-x * x / 2)/ Math.sqrt(2*Math.PI) * k * (.31938153 + k * (-.356563782 + k * (1.781477937 + k * (-1.821255978 + k * 1.330274429)))) );"
     * NOTE: The different parts of the equation are broken down to separate functions as using
     * ABDKMathQuad makes small equations verbose.
     */
    function CND(bytes16 x) internal pure returns (bytes16) {
        if (ABDKMathQuad.toInt(x) < 0) {
            return (
                ABDKMathQuad.sub(
                    ABDKMathQuad.fromUInt(1),
                    CND(ABDKMathQuad.neg(x))
                )
            );
        } else {
            bytes16 k = ABDKMathQuad.div(
                ABDKMathQuad.fromUInt(1),
                ABDKMathQuad.add(
                    ABDKMathQuad.fromUInt(1),
                    ABDKMathQuad.mul(
                        ABDKMathQuad.div(
                            ABDKMathQuad.fromUInt(2316419000000000),
                            ABDKMathQuad.fromUInt(DIVISOR)
                        ),
                        x
                    )
                )
            );
            bytes16 CND_part2 = _getCNDPart2(k, x);
            return ABDKMathQuad.sub(ABDKMathQuad.fromUInt(1), CND_part2);
        }
    }

    function _getCNDPart2(bytes16 k, bytes16 x)
        internal
        pure
        returns (bytes16)
    {
        return ABDKMathQuad.mul(_getCNDPart2_1(x), _getCNDPart2_2(k));
    }

    function _getCNDPart2_1(bytes16 x) internal pure returns (bytes16) {
        return
            ABDKMathQuad.div(
                ABDKMathQuad.exp(
                    ABDKMathQuad.mul(
                        ABDKMathQuad.neg(x),
                        ABDKMathQuad.div(x, ABDKMathQuad.fromUInt(2))
                    )
                ),
                ABDKMathQuad.sqrt(
                    ABDKMathQuad.mul(
                        ABDKMathQuad.fromUInt(2),
                        ABDKMathQuad.div(
                            ABDKMathQuad.fromUInt(31415926530000000),
                            ABDKMathQuad.fromUInt(DIVISOR)
                        )
                    )
                )
            );
    }

    function _getCNDPart2_2(bytes16 k) internal pure returns (bytes16) {
        return
            ABDKMathQuad.mul(
                ABDKMathQuad.add(
                    ABDKMathQuad.div(
                        ABDKMathQuad.fromUInt(3193815300000000),
                        ABDKMathQuad.fromUInt(DIVISOR)
                    ),
                    ABDKMathQuad.mul(
                        k,
                        ABDKMathQuad.add(
                            ABDKMathQuad.neg(
                                ABDKMathQuad.div(
                                    ABDKMathQuad.fromUInt(3565637820000000),
                                    ABDKMathQuad.fromUInt(DIVISOR)
                                )
                            ),
                            ABDKMathQuad.mul(
                                k,
                                ABDKMathQuad.add(
                                    ABDKMathQuad.div(
                                        ABDKMathQuad.fromUInt(
                                            17814779370000000
                                        ),
                                        ABDKMathQuad.fromUInt(DIVISOR)
                                    ),
                                    _getCNDPart2_2_1(k)
                                )
                            )
                        )
                    )
                ),
                k
            );
    }

    function _getCNDPart2_2_1(bytes16 k) internal pure returns (bytes16) {
        return
            ABDKMathQuad.mul(
                k,
                ABDKMathQuad.add(
                    ABDKMathQuad.neg(
                        ABDKMathQuad.div(
                            ABDKMathQuad.fromUInt(18212559780000000),
                            ABDKMathQuad.fromUInt(DIVISOR)
                        )
                    ),
                    ABDKMathQuad.mul(
                        k,
                        ABDKMathQuad.div(
                            ABDKMathQuad.fromUInt(13302744290000000),
                            ABDKMathQuad.fromUInt(DIVISOR)
                        )
                    )
                )
            );
    }
}

File 7 of 7 : OptionPricingSimple.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

// Libraries
import {SafeMath} from '@openzeppelin/contracts/utils/math/SafeMath.sol';
import {BlackScholes} from '../libraries/BlackScholes.sol';
import {ABDKMathQuad} from '../external/libraries/ABDKMathQuad.sol';

// Contracts
import {Ownable} from '@openzeppelin/contracts/access/Ownable.sol';

// Interfaces
import {IOptionPricing} from '../interfaces/IOptionPricing.sol';

contract OptionPricingSimple is Ownable, IOptionPricing {
    using SafeMath for uint256;

    // The max volatility possible
    uint256 public volatilityCap;

    // The % of the price of asset which is the minimum option price possible in 1e8 precision
    uint256 public minOptionPricePercentage;

    constructor(uint256 _volatilityCap, uint256 _minOptionPricePercentage) {
        volatilityCap = _volatilityCap;
        minOptionPricePercentage = _minOptionPricePercentage;
    }

    /*---- GOVERNANCE FUNCTIONS ----*/

    /// @notice updates volatility cap for an option pool
    /// @param _volatilityCap the new volatility cap
    /// @return whether volatility cap was updated
    function updateVolatilityCap(uint256 _volatilityCap)
        external
        onlyOwner
        returns (bool)
    {
        volatilityCap = _volatilityCap;

        return true;
    }

    /// @notice updates % of the price of asset which is the minimum option price possible
    /// @param _minOptionPricePercentage the new %
    /// @return whether % was updated
    function updateMinOptionPricePercentage(uint256 _minOptionPricePercentage)
        external
        onlyOwner
        returns (bool)
    {
        minOptionPricePercentage = _minOptionPricePercentage;

        return true;
    }

    /*---- VIEWS ----*/

    /**
     * @notice computes the option price (with liquidity multiplier)
     * @param isPut is put option
     * @param expiry expiry timestamp
     * @param strike strike price
     * @param lastPrice current price
     * @param volatility volatility
     */
    function getOptionPrice(
        bool isPut,
        uint256 expiry,
        uint256 strike,
        uint256 lastPrice,
        uint256 volatility
    ) external view override returns (uint256) {
        uint256 timeToExpiry = expiry.sub(block.timestamp).div(864);

        uint256 optionPrice = BlackScholes
            .calculate(
                isPut ? 1 : 0, // 0 - Put, 1 - Call
                lastPrice,
                strike,
                timeToExpiry, // Number of days to expiry mul by 100
                0,
                volatility
            )
            .div(BlackScholes.DIVISOR);

        uint256 minOptionPrice = lastPrice.mul(minOptionPricePercentage).div(
            1e10
        );

        if (minOptionPrice > optionPrice) {
            return minOptionPrice;
        }

        return optionPrice;
    }
}

Settings
{
  "evmVersion": "istanbul",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"_volatilityCap","type":"uint256"},{"internalType":"uint256","name":"_minOptionPricePercentage","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"bool","name":"isPut","type":"bool"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"uint256","name":"strike","type":"uint256"},{"internalType":"uint256","name":"lastPrice","type":"uint256"},{"internalType":"uint256","name":"volatility","type":"uint256"}],"name":"getOptionPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minOptionPricePercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minOptionPricePercentage","type":"uint256"}],"name":"updateMinOptionPricePercentage","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_volatilityCap","type":"uint256"}],"name":"updateVolatilityCap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"volatilityCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b5060405162002c0a38038062002c0a833981016040819052620000349162000084565b600080546001600160a01b031916339081178255604051909182917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600191909155600255620000a8565b6000806040838503121562000097578182fd5b505080516020909101519092909150565b612b5280620000b86000396000f3fe608060405234801561001057600080fd5b50600436106100885760003560e01c8063715018a61161005b578063715018a6146100e85780638da5cb5b146100f2578063ad1ad5dc1461010d578063f2fde38b1461012057600080fd5b806305e927df1461008d57806325b2a93b146100a9578063326611f8146100b25780635b7b6d88146100d5575b600080fd5b61009660015481565b6040519081526020015b60405180910390f35b61009660025481565b6100c56100c0366004612a63565b610133565b60405190151581526020016100a0565b6100966100e3366004612a1c565b610170565b6100f06101f9565b005b6000546040516001600160a01b0390911681526020016100a0565b6100c561011b366004612a63565b61026d565b6100f061012e3660046129f5565b6102a1565b600080546001600160a01b031633146101675760405162461bcd60e51b815260040161015e90612a7b565b60405180910390fd5b50600255600190565b600080610189610360610183884261038b565b906103a0565b905060006101b5662386f26fc100006101838a6101a75760006101aa565b60015b888a8760008b6103ac565b905060006101d76402540be400610183600254896104fd90919063ffffffff16565b9050818111156101eb5792506101f0915050565b509150505b95945050505050565b6000546001600160a01b031633146102235760405162461bcd60e51b815260040161015e90612a7b565b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b600080546001600160a01b031633146102985760405162461bcd60e51b815260040161015e90612a7b565b50600190815590565b6000546001600160a01b031633146102cb5760405162461bcd60e51b815260040161015e90612a7b565b6001600160a01b0381166103305760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161015e565b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60006103978284612aef565b90505b92915050565b60006103978284612ab0565b6000806103b887610509565b905060006103c587610509565b905060006103e56103d588610509565b6103e0618e94610509565b61056d565b905060006104006103f588610509565b6103e0612710610509565b9050600061041a61041088610509565b6103e06064610509565b9050600061046c61045f610436610431898961056d565b610841565b610454610459876104548861044f8a6103e06002610509565b610864565b610abf565b88610864565b6103e08461044f88610e7f565b90506000610486826104818561044f89610e7f565b6110b3565b905060ff8e166104c7576104b96104b46104a489858a898b886110c5565b61044f662386f26fc10000610509565b61110a565b9750505050505050506104f3565b60ff8e16600114156104e7576104b96104b46104a4888789868d8961118e565b60009750505050505050505b9695505050505050565b60006103978284612ad0565b60008161051857506000919050565b816000610524826111ed565b9050607081101561053d578060700382901b9150610550565b6070811115610550576070810382901c91505b613fff0160701b6001600160701b03919091161760801b92915050565b6000617fff60f084811c8216919084901c8116908214156105b35780617fff14156105a2575061ffff60ef1b915061039a9050565b505050600160ff1b8116821861039a565b80617fff14156105f7576dffffffffffffffffffffffffffff60801b8416156105e6575061ffff60ef1b915061039a9050565b505050808218600160ff1b1661039a565b600160801b600160ff1b03841661064157600160801b600160ff1b038516610629575061ffff60ef1b915061039a9050565b505050808218600160ff1b16617fff60f01b1761039a565b6001600160701b03608085901c168161065d5760019150610664565b600160701b175b6001600160701b03608087901c16836106a357801561069e576000610688826111ed565b6001955060e20393840160711901939190911b90505b6106ad565b600160701b1760721b5b8181816106ca57634e487b7160e01b600052601260045260246000fd5b049050806106f757600160ff1b878718166106e65760006106ec565b600160ff1b5b94505050505061039a565b6001606c1b81101561071957634e487b7160e01b600052600160045260246000fd5b6000600160731b82101561075857600160721b82101561074d57600160711b821015610746576070610750565b6071610750565b60725b60ff16610761565b610761826111ed565b90508361407101818601111561077f57617fff945060009150610812565b83818601613ffc01101561079a576000945060009150610812565b83818601613f8c0110156107e7578385613ffc0111156107c5578385613ffc010382901b91506107de565b8385613ffc0110156107de57613ffc8585030382901c91505b60009450610812565b60708111156107fa576070810382901c91505b6001600160701b038216915083818601613f8d010394505b81607086901b888a186001607f1b60801b1660801c6001600160801b0316171760801b9550505050505061039a565b600061039a61084f8361128b565b6f3ffe62e42fefa39ef35793c7673007e560801b5b6000617fff60f084811c8216919084901c8116908214156109035780617fff14156108e2576001600160801b031985811690851614156108af57505050600160ff1b8116821861039a565b600160ff1b6001600160801b03198686181614156108d25750505081811761039a565b5061ffff60ef1b915061039a9050565b600160801b600160ff1b0384166105a2575061ffff60ef1b915061039a9050565b80617fff141561093f57600160801b600160ff1b03851661092e575061ffff60ef1b915061039a9050565b505050600160ff1b8216811861039a565b6001600160701b03608086901c168261095b5760019250610962565b600160701b175b6001600160701b03608086901c168261097e5760019250610985565b600160701b175b90810290816109a257600160ff1b878718166106e65760006106ec565b928201926000600160e11b8310156109d557600160e01b8310156109ce576109c9836111ed565b6109d8565b60e06109d8565b60e15b905061407081860110156109f3576000945060009250610a90565b6140e08186011015610a3657614070851015610a1857846140700383901c9250610a2d565b614070851115610a2d57614070850383901b92505b60009450610a90565b61c0dd8186011115610a5057617fff945060009250610a90565b6070811115610a67576070810383901c9250610a7a565b6070811015610a7a578060700383901b92505b6001600160701b03831692506140df8186010394505b82607086901b888a186001607f1b60801b1660801c6001600160801b0316171760801b9550505050505061039a565b6000617fff60f084811c8216919084901c811690821415610b0d5780617fff1415610b03576001600160801b031985811690851614156108d257849250505061039a565b849250505061039a565b80617fff1415610b2157839250505061039a565b6001607f1b608086901c90811015906001600160701b031683610b475760019350610b4e565b600160701b175b6001607f1b608087901c90811015906001600160701b031684610b745760019450610b7b565b600160701b175b82610bab576001600160801b03198816600160ff1b14610b9b5787610b9e565b60005b965050505050505061039a565b80610bcb576001600160801b03198916600160ff1b14610b9b5788610b9e565b8486038415158315151415610cd6576070811315610bf2578997505050505050505061039a565b6000811315610c045790811c90610c33565b606f19811215610c1d578897505050505050505061039a565b6000811215610c33578060000384901c93508596505b92810192600160711b8410610c4e576001968701969390931c925b86617fff1415610c805784610c6857617fff60f01b610c72565b6001600160f01b03195b97505050505050505061039a565b600160701b841015610c955760009650610ca2565b6001600160701b03841693505b83607088901b86610cb4576000610cba565b6001607f1b5b6001600160801b0316171760801b97505050505050505061039a565b6000811315610cf157600184901b9350600187039650610d08565b6000811215610d0857600182901b91506001860396505b6070811315610d1a5760019150610d67565b6001811315610d37576001810360018303901c6001019150610d67565b606f19811215610d4a5760019350610d67565b600019811215610d67576001816000030360018503901c60010193505b818410610d78578184039350610d81565b83820393508294505b83610d9757506000965061039a95505050505050565b6000610da2856111ed565b90508060711415610dc857600185901c6001600160701b03169450600188019750610e17565b6070811015610e0a57607081900380891115610df7578086901b6001600160701b031695508089039850610e04565b600098600019019590951b945b50610e17565b6001600160701b03851694505b87617fff1415610e4a5785610e3157617fff60f01b610e3b565b6001600160f01b03195b9850505050505050505061039a565b84607089901b87610e5c576000610e62565b6001607f1b5b6001600160801b0316171760801b9850505050505050505061039a565b60006001607f1b608083901c1115610e9d575061ffff60ef1b919050565b617fff60f083901c811690811415610eb6575090919050565b6001600160701b03608084901c1681610ed25760019150610ed9565b600160701b175b80610ee8575060009392505050565b613fff8201600190811c9216158015610f3a57600160701b8210610f1257607182901b9150610f75565b6000610f1d836111ed565b60e20360fe16606f19810160011c909403939290921b9150610f75565b600160701b8210610f5157607082901b9150610f75565b6000610f5c836111ed565b60e10360fe16606f19810160011c909403939290921b91505b600160701b80830401600190811c90818481610fa157634e487b7160e01b600052601260045260246000fd5b048201901c90506001818481610fc757634e487b7160e01b600052601260045260246000fd5b048201901c90506001818481610fed57634e487b7160e01b600052601260045260246000fd5b048201901c9050600181848161101357634e487b7160e01b600052601260045260246000fd5b048201901c9050600181848161103957634e487b7160e01b600052601260045260246000fd5b048201901c9050600181848161105f57634e487b7160e01b600052601260045260246000fd5b048201901c9050600081848161108557634e487b7160e01b600052601260045260246000fd5b04905081811015611094578091505b816001600160701b0316607086901b1760801b95505050505050919050565b600061039783600160ff1b8418610abf565b60006110ff6110d78861044f8961143b565b6104816110f68861044f6110f1600160ff1b8b188a610864565b6114d6565b61044f8661143b565b979650505050505050565b6000617fff60f083901c16613fff8110156111285750600092915050565b6001607f1b608084901c1061113c57600080fd5b6140fe81111561114b57600080fd5b600160701b6001600160701b03608085901c161761406f8210156111755761406f8290031c611187565b61406f8211156111875761406e1982011b5b9392505050565b6000806111ba6111ab8961044f6110f1600160ff1b8c188b610864565b61044f600160ff1b881861143b565b905060006111d18561044f600160ff1b871861143b565b905060006111df83836110b3565b9a9950505050505050505050565b60008082116111fb57600080fd5b6000600160801b831061121057608092831c92015b600160401b831061122357604092831c92015b640100000000831061123757602092831c92015b62010000831061124957601092831c92015b610100831061125a57600892831c92015b6010831061126a57600492831c92015b6004831061127a57600292831c92015b6002831061039a5760010192915050565b60006001607f1b608083901c11156112a9575061ffff60ef1b919050565b613fff60f01b6001600160801b0319831614156112c857506000919050565b617fff60f083901c8116908114156112e1575090919050565b6001600160701b03608084901c16816112fd5760019150611304565b600160701b175b8061131a57506001600160f01b03199392505050565b600061406f81613fff85106113405750600f9290921b9160009150613ffe19840161137f565b60019250600160701b84106113625784613ffe039050600f84901b935061137f565b600061136d856111ed565b607f8190039590951b9461406d039150505b836001607f1b14156113b3578215611395576001015b60006113a0826111ed565b60700392839003929190911b9050611401565b6000836113c15760006113c4565b60015b60ff1690505b600160701b8210156113ff5793800260ff81901c607f81019190911c94600019939093019260019290921b90821801906113ca565b505b806001600160701b0316607083901b8461141c576000611422565b6001607f1b5b6001600160801b0316171760801b979650505050505050565b600080611447836114fd565b12156114695761039a61145a6001610509565b610481600160ff1b851861143b565b60006114ab6114786001610509565b6103e06114856001610509565b61045461045961149b66083ac553a55e00610509565b6103e0662386f26fc10000610509565b905060006114b982856115a4565b90506114ce6114c86001610509565b826110b3565b949350505050565b600061039a6114f8836f1fffb8aa3b295c17f0bbbe87fed0691d60811b610864565b6115bb565b6000617fff60f083901c166140fe81111561151757600080fd5b613fff81101561152a5750600092915050565b600160701b6001600160701b03608085901c161761406f8210156115545761406f8290031c611566565b61406f8211156115665761406e1982011b5b6001607f1b608085901c1061159057600160ff1b81111561158657600080fd5b6000039392505050565b6001600160ff1b0381111561118757600080fd5b60006103976115b28361290d565b61044f85612955565b60006001607f1b608083901c90811190617fff60f085901c8116916001600160701b031690821480156115ed57508015155b15611601575061ffff60ef1b949350505050565b61400d821115611626578261161b57617fff60f01b6101f0565b600095945050505050565b613f7f82101561163f5750613fff60f01b949350505050565b8161164d5760019150611654565b600160701b175b613fef82111561166a57613fee1982011b61167c565b613fef82101561167c57613fef8290031c5b82801561168d575061203760811b81115b1561169d57506000949350505050565b821580156116bc5750713fffffffffffffffffffffffffffffffffff81115b156116d05750617fff60f01b949350505050565b6001600160801b0381169060801c8380156116ea57508115155b156116f6579019906001015b6001607f1b8281161561171a5770016a09e667f3bcc908b2fb1366ea957d3e0260801c5b6001607e1b83161561173d577001306fe0a31b7152de8d5a46305c85edec0260801c5b6001607d1b831615611760577001172b83c7d517adcdf7c8c50eb14a791f0260801c5b6001607c1b8316156117835770010b5586cf9890f6298b92b71842a983630260801c5b6001607b1b8316156117a6577001059b0d31585743ae7c548eb68ca417fd0260801c5b6001607a1b8316156117c957700102c9a3e778060ee6f7caca4f7a29bde80260801c5b600160791b8316156117ec5770010163da9fb33356d84a66ae336dcdfa3f0260801c5b600160781b83161561180f57700100b1afa5abcbed6129ab13ec11dc95430260801c5b600160771b8316156118325770010058c86da1c09ea1ff19d294cf2f679b0260801c5b600160761b831615611855577001002c605e2e8cec506d21bfc89a23a00f0260801c5b600160751b83161561187857700100162f3904051fa128bca9c55c31e5df0260801c5b600160741b83161561189b577001000b175effdc76ba38e31671ca9397250260801c5b600160731b8316156118be57700100058ba01fb9f96d6cacd4b180917c3d0260801c5b600160721b8316156118e15770010002c5cc37da9491d0985c348c68e7b30260801c5b600160711b831615611904577001000162e525ee054754457d59952920260260801c5b600160701b8316156119275770010000b17255775c040618bf4a4ade83fc0260801c5b6001606f1b83161561194a577001000058b91b5bc9ae2eed81e9b7d4cfab0260801c5b6001606e1b83161561196d57700100002c5c89d5ec6ca4d7c8acc017b7c90260801c5b6001606d1b8316156119905770010000162e43f4f831060e02d839a9d16d0260801c5b6001606c1b8316156119b357700100000b1721bcfc99d9f890ea069117630260801c5b6001606b1b8316156119d65770010000058b90cf1e6d97f9ca14dbcc16280260801c5b6001606a1b8316156119f9577001000002c5c863b73f016468f6bac5ca2b0260801c5b600160691b831615611a1c57700100000162e430e5a18f6119e3c02282a50260801c5b600160681b831615611a3f577001000000b1721835514b86e6d96efd1bfe0260801c5b600160671b831615611a6257700100000058b90c0b48c6be5df846c5b2ef0260801c5b600160661b831615611a855770010000002c5c8601cc6b9e94213c72737a0260801c5b600160651b831615611aa8577001000000162e42fff037df38aa2b219f060260801c5b600160641b831615611acb5770010000000b17217fba9c739aa5819f44f90260801c5b600160631b831615611aee577001000000058b90bfcdee5acd3c1cedc8230260801c5b600160621b831615611b1157700100000002c5c85fe31f35a6a30da1be500260801c5b600160611b831615611b345770010000000162e42ff0999ce3541b9fffcf0260801c5b600160601b831615611b5757700100000000b17217f80f4ef5aadda455540260801c5b6001605f1b831615611b7a5770010000000058b90bfbf8479bd5a81b51ad0260801c5b6001605e1b831615611b9d577001000000002c5c85fdf84bd62ae30a74cc0260801c5b6001605d1b831615611bc057700100000000162e42fefb2fed257559bdaa0260801c5b6001605c1b831615611be3577001000000000b17217f7d5a7716bba4a9ae0260801c5b6001605b1b831615611c0657700100000000058b90bfbe9ddbac5e109cce0260801c5b6001605a1b831615611c295770010000000002c5c85fdf4b15de6f17eb0d0260801c5b600160591b831615611c4c577001000000000162e42fefa494f1478fde050260801c5b600160581b831615611c6f5770010000000000b17217f7d20cf927c8e94c0260801c5b600160571b831615611c92577001000000000058b90bfbe8f71cb4e4b33d0260801c5b600160561b831615611cb557700100000000002c5c85fdf477b662b269450260801c5b600160551b831615611cd85770010000000000162e42fefa3ae53369388c0260801c5b600160541b831615611cfb57700100000000000b17217f7d1d351a389d400260801c5b600160531b831615611d1e5770010000000000058b90bfbe8e8b2d3d4ede0260801c5b600160521b831615611d41577001000000000002c5c85fdf4741bea6e77e0260801c5b600160511b831615611d6457700100000000000162e42fefa39fe95583c20260801c5b600160501b831615611d87577001000000000000b17217f7d1cfb72b45e10260801c5b6980000000000000000000831615611db057700100000000000058b90bfbe8e7cc35c3f00260801c5b6940000000000000000000831615611dd95770010000000000002c5c85fdf473e242ea380260801c5b6920000000000000000000831615611e02577001000000000000162e42fefa39f02b772c0260801c5b6910000000000000000000831615611e2b5770010000000000000b17217f7d1cf7d83c1a0260801c5b6908000000000000000000831615611e54577001000000000000058b90bfbe8e7bdcbe2e0260801c5b6904000000000000000000831615611e7d57700100000000000002c5c85fdf473dea871f0260801c5b6902000000000000000000831615611ea65770010000000000000162e42fefa39ef44d910260801c5b6901000000000000000000831615611ecf57700100000000000000b17217f7d1cf79e9490260801c5b68800000000000000000831615611ef75770010000000000000058b90bfbe8e7bce5440260801c5b68400000000000000000831615611f1f577001000000000000002c5c85fdf473de6eca0260801c5b68200000000000000000831615611f4757700100000000000000162e42fefa39ef366f0260801c5b68100000000000000000831615611f6f577001000000000000000b17217f7d1cf79afa0260801c5b68080000000000000000831615611f9757700100000000000000058b90bfbe8e7bcd6d0260801c5b68040000000000000000831615611fbf5770010000000000000002c5c85fdf473de6b20260801c5b68020000000000000000831615611fe7577001000000000000000162e42fefa39ef3580260801c5b600160401b83161561200a5770010000000000000000b17217f7d1cf79ab0260801c5b678000000000000000831615612031577001000000000000000058b90bfbe8e7bcd50260801c5b67400000000000000083161561205857700100000000000000002c5c85fdf473de6a0260801c5b67200000000000000083161561207f5770010000000000000000162e42fefa39ef340260801c5b6710000000000000008316156120a657700100000000000000000b17217f7d1cf7990260801c5b6708000000000000008316156120cd5770010000000000000000058b90bfbe8e7bcc0260801c5b6704000000000000008316156120f4577001000000000000000002c5c85fdf473de50260801c5b67020000000000000083161561211b57700100000000000000000162e42fefa39ef20260801c5b670100000000000000831615612142577001000000000000000000b17217f7d1cf780260801c5b668000000000000083161561216857700100000000000000000058b90bfbe8e7bb0260801c5b664000000000000083161561218e5770010000000000000000002c5c85fdf473dd0260801c5b66200000000000008316156121b4577001000000000000000000162e42fefa39ee0260801c5b66100000000000008316156121da5770010000000000000000000b17217f7d1cf60260801c5b6608000000000000831615612200577001000000000000000000058b90bfbe8e7a0260801c5b660400000000000083161561222657700100000000000000000002c5c85fdf473c0260801c5b660200000000000083161561224c5770010000000000000000000162e42fefa39d0260801c5b660100000000000083161561227257700100000000000000000000b17217f7d1ce0260801c5b658000000000008316156122975770010000000000000000000058b90bfbe8e60260801c5b654000000000008316156122bc577001000000000000000000002c5c85fdf4720260801c5b652000000000008316156122e157700100000000000000000000162e42fefa380260801c5b65100000000000831615612306577001000000000000000000000b17217f7d1b0260801c5b6508000000000083161561232b57700100000000000000000000058b90bfbe8d0260801c5b650400000000008316156123505770010000000000000000000002c5c85fdf460260801c5b65020000000000831615612375577001000000000000000000000162e42fefa20260801c5b6501000000000083161561239a5770010000000000000000000000b17217f7d00260801c5b6480000000008316156123be577001000000000000000000000058b90bfbe70260801c5b6440000000008316156123e257700100000000000000000000002c5c85fdf30260801c5b6420000000008316156124065770010000000000000000000000162e42fef90260801c5b64100000000083161561242a57700100000000000000000000000b17217f7c0260801c5b64080000000083161561244e5770010000000000000000000000058b90bfbd0260801c5b640400000000831615612472577001000000000000000000000002c5c85fde0260801c5b64020000000083161561249657700100000000000000000000000162e42fee0260801c5b6401000000008316156124ba577001000000000000000000000000b17217f60260801c5b63800000008316156124dd57700100000000000000000000000058b90bfa0260801c5b63400000008316156125005770010000000000000000000000002c5c85fc0260801c5b6320000000831615612523577001000000000000000000000000162e42fd0260801c5b63100000008316156125465770010000000000000000000000000b17217e0260801c5b6308000000831615612569577001000000000000000000000000058b90be0260801c5b630400000083161561258c57700100000000000000000000000002c5c85e0260801c5b63020000008316156125af5770010000000000000000000000000162e42e0260801c5b63010000008316156125d257700100000000000000000000000000b172160260801c5b628000008316156125f45770010000000000000000000000000058b90a0260801c5b62400000831615612616577001000000000000000000000000002c5c840260801c5b6220000083161561263857700100000000000000000000000000162e410260801c5b6210000083161561265a577001000000000000000000000000000b17200260801c5b6208000083161561267c57700100000000000000000000000000058b8f0260801c5b6204000083161561269e5770010000000000000000000000000002c5c70260801c5b620200008316156126c0577001000000000000000000000000000162e30260801c5b620100008316156126e25770010000000000000000000000000000b1710260801c5b618000831615612703577001000000000000000000000000000058b80260801c5b61400083161561272457700100000000000000000000000000002c5b0260801c5b6120008316156127455770010000000000000000000000000000162d0260801c5b61100083161561276657700100000000000000000000000000000b160260801c5b6108008316156127875770010000000000000000000000000000058a0260801c5b6104008316156127a8577001000000000000000000000000000002c40260801c5b6102008316156127c9577001000000000000000000000000000001610260801c5b6101008316156127ea577001000000000000000000000000000000b00260801c5b608083161561280a577001000000000000000000000000000000570260801c5b604083161561282a5770010000000000000000000000000000002b0260801c5b602083161561284a577001000000000000000000000000000000150260801c5b601083161561286a5770010000000000000000000000000000000a0260801c5b600883161561288a577001000000000000000000000000000000040260801c5b60048316156128aa577001000000000000000000000000000000010260801c5b846128cb57600f81901c6001600160701b03169050613fff820191506128fa565b613ffe82116128f057600f81901c6001600160701b0316905081613fff0391506128fa565b600091613fee19011c5b60709190911b1760801b95945050505050565b600061039a61292d6110f1600160ff1b851861044f866103e06002610509565b6103e061295061293d6002610509565b61044f61149b666f9c9e651c4480610509565b610e7f565b600061039a6129b961297061149b660b58c2126f4900610509565b6104548561044f61299661298d61149b660caaedbfa8a700610509565b600160ff1b1890565b6104548961044f6129b061149b663f4a728c19ce80610509565b6104548d6129bf565b83610864565b600061039a8261044f6129de61298d61149b6640b43a04233100610509565b6104548661044f61149b662f42c683f17c80610509565b600060208284031215612a06578081fd5b81356001600160a01b0381168114611187578182fd5b600080600080600060a08688031215612a33578081fd5b85358015158114612a42578182fd5b97602087013597506040870135966060810135965060800135945092505050565b600060208284031215612a74578081fd5b5035919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600082612acb57634e487b7160e01b81526012600452602481fd5b500490565b6000816000190483118215151615612aea57612aea612b06565b500290565b600082821015612b0157612b01612b06565b500390565b634e487b7160e01b600052601160045260246000fdfea26469706673582212201231c078f4e9ca7177d1e208bb6bf3581273fe0bc414e3b381ba057fdcd32ae864736f6c6343000804003300000000000000000000000000000000000000000000000000000000000003e80000000000000000000000000000000000000000000000000000000000000001

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

00000000000000000000000000000000000000000000000000000000000003e80000000000000000000000000000000000000000000000000000000000000001

-----Decoded View---------------
Arg [0] : _volatilityCap (uint256): 1000
Arg [1] : _minOptionPricePercentage (uint256): 1

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000003e8
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000001


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.