Contract 0x2b99e3d67dad973c1b9747da742b7e26c8bdd67b

 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0xa9f3f14c58878b7e5b1bcde06fa1cca345df77d280b188945205af02eec80b690x6080604026355172021-10-27 23:25:0431 days 50 mins ago0xde485812e28824e542b9c2270b6b8ed9232b7d0b IN  Contract Creation0 ETH0.117633997297 ETH
[ Download CSV Export 
Parent Txn Hash Block From To Value
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

Contract Source Code (Solidity Standard Json-Input format)

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
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.