Skip to content

Instantly share code, notes, and snippets.

@gititGoro
Last active December 31, 2020 03:33
Show Gist options
  • Save gititGoro/50173af6693b147da2eb5301c945d752 to your computer and use it in GitHub Desktop.
Save gititGoro/50173af6693b147da2eb5301c945d752 to your computer and use it in GitHub Desktop.
Rock3t eth fee buy pressure
pragma solidity 0.7.1;
abstract contract ERC20 {
function balanceOf(address holder) external virtual returns (uint);
}
/**
* Smart contract library of mathematical functions operating with IEEE 754
* quadruple-precision binary floating-point numbers (quadruple precision
* numbers). As long as quadruple precision numbers are 16-bytes long, they are
* represented by bytes16 type.
*/
library ABDKMathQuad {
/*
* 0.
*/
bytes16 private constant POSITIVE_ZERO = 0x00000000000000000000000000000000;
/*
* -0.
*/
bytes16 private constant NEGATIVE_ZERO = 0x80000000000000000000000000000000;
/*
* +Infinity.
*/
bytes16 private constant POSITIVE_INFINITY = 0x7FFF0000000000000000000000000000;
/*
* -Infinity.
*/
bytes16 private constant NEGATIVE_INFINITY = 0xFFFF0000000000000000000000000000;
/*
* Canonical NaN value.
*/
bytes16 private constant NaN = 0x7FFF8000000000000000000000000000;
/**
* Convert signed 256-bit integer number into quadruple precision number.
*
* @param x signed 256-bit integer number
* @return quadruple precision number
*/
function fromInt (int256 x) internal pure returns (bytes16) {
if (x == 0) return bytes16 (0);
else {
// We rely on overflow behavior here
uint256 result = uint256 (x > 0 ? x : -x);
uint256 msb = msb (result);
if (msb < 112) result <<= 112 - msb;
else if (msb > 112) result >>= msb - 112;
result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16383 + msb << 112;
if (x < 0) result |= 0x80000000000000000000000000000000;
return bytes16 (uint128 (result));
}
}
/**
* Convert quadruple precision number into signed 256-bit integer number
* rounding towards zero. Revert on overflow.
*
* @param x quadruple precision number
* @return signed 256-bit integer number
*/
function toInt (bytes16 x) internal pure returns (int256) {
uint256 exponent = uint128 (x) >> 112 & 0x7FFF;
require (exponent <= 16638); // Overflow
if (exponent < 16383) return 0; // Underflow
uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF |
0x10000000000000000000000000000;
if (exponent < 16495) result >>= 16495 - exponent;
else if (exponent > 16495) result <<= exponent - 16495;
if (uint128 (x) >= 0x80000000000000000000000000000000) { // Negative
require (result <= 0x8000000000000000000000000000000000000000000000000000000000000000);
return -int256 (result); // We rely on overflow behavior here
} else {
require (result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
return int256 (result);
}
}
/**
* Convert unsigned 256-bit integer number into quadruple precision number.
*
* @param x unsigned 256-bit integer number
* @return quadruple precision number
*/
function fromUInt (uint256 x) internal pure returns (bytes16) {
if (x == 0) return bytes16 (0);
else {
uint256 result = x;
uint256 msb = msb (result);
if (msb < 112) result <<= 112 - msb;
else if (msb > 112) result >>= msb - 112;
result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16383 + msb << 112;
return bytes16 (uint128 (result));
}
}
/**
* Convert quadruple precision number into unsigned 256-bit integer number
* rounding towards zero. Revert on underflow. Note, that negative floating
* point numbers in range (-1.0 .. 0.0) may be converted to unsigned integer
* without error, because they are rounded to zero.
*
* @param x quadruple precision number
* @return unsigned 256-bit integer number
*/
function toUInt (bytes16 x) internal pure returns (uint256) {
uint256 exponent = uint128 (x) >> 112 & 0x7FFF;
if (exponent < 16383) return 0; // Underflow
require (uint128 (x) < 0x80000000000000000000000000000000); // Negative
require (exponent <= 16638); // Overflow
uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF |
0x10000000000000000000000000000;
if (exponent < 16495) result >>= 16495 - exponent;
else if (exponent > 16495) result <<= exponent - 16495;
return result;
}
/**
* Convert signed 128.128 bit fixed point number into quadruple precision
* number.
*
* @param x signed 128.128 bit fixed point number
* @return quadruple precision number
*/
function from128x128 (int256 x) internal pure returns (bytes16) {
if (x == 0) return bytes16 (0);
else {
// We rely on overflow behavior here
uint256 result = uint256 (x > 0 ? x : -x);
uint256 msb = msb (result);
if (msb < 112) result <<= 112 - msb;
else if (msb > 112) result >>= msb - 112;
result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16255 + msb << 112;
if (x < 0) result |= 0x80000000000000000000000000000000;
return bytes16 (uint128 (result));
}
}
/**
* Convert quadruple precision number into signed 128.128 bit fixed point
* number. Revert on overflow.
*
* @param x quadruple precision number
* @return signed 128.128 bit fixed point number
*/
function to128x128 (bytes16 x) internal pure returns (int256) {
uint256 exponent = uint128 (x) >> 112 & 0x7FFF;
require (exponent <= 16510); // Overflow
if (exponent < 16255) return 0; // Underflow
uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF |
0x10000000000000000000000000000;
if (exponent < 16367) result >>= 16367 - exponent;
else if (exponent > 16367) result <<= exponent - 16367;
if (uint128 (x) >= 0x80000000000000000000000000000000) { // Negative
require (result <= 0x8000000000000000000000000000000000000000000000000000000000000000);
return -int256 (result); // We rely on overflow behavior here
} else {
require (result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
return int256 (result);
}
}
/**
* Convert signed 64.64 bit fixed point number into quadruple precision
* number.
*
* @param x signed 64.64 bit fixed point number
* @return quadruple precision number
*/
function from64x64 (int128 x) internal pure returns (bytes16) {
if (x == 0) return bytes16 (0);
else {
// We rely on overflow behavior here
uint256 result = uint128 (x > 0 ? x : -x);
uint256 msb = msb (result);
if (msb < 112) result <<= 112 - msb;
else if (msb > 112) result >>= msb - 112;
result = result & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF | 16319 + msb << 112;
if (x < 0) result |= 0x80000000000000000000000000000000;
return bytes16 (uint128 (result));
}
}
/**
* Convert quadruple precision number into signed 64.64 bit fixed point
* number. Revert on overflow.
*
* @param x quadruple precision number
* @return signed 64.64 bit fixed point number
*/
function to64x64 (bytes16 x) internal pure returns (int128) {
uint256 exponent = uint128 (x) >> 112 & 0x7FFF;
require (exponent <= 16446); // Overflow
if (exponent < 16319) return 0; // Underflow
uint256 result = uint256 (uint128 (x)) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF |
0x10000000000000000000000000000;
if (exponent < 16431) result >>= 16431 - exponent;
else if (exponent > 16431) result <<= exponent - 16431;
if (uint128 (x) >= 0x80000000000000000000000000000000) { // Negative
require (result <= 0x80000000000000000000000000000000);
return -int128 (result); // We rely on overflow behavior here
} else {
require (result <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
return int128 (result);
}
}
/**
* Convert octuple precision number into quadruple precision number.
*
* @param x octuple precision number
* @return quadruple precision number
*/
function fromOctuple (bytes32 x) internal pure returns (bytes16) {
bool negative = x & 0x8000000000000000000000000000000000000000000000000000000000000000 > 0;
uint256 exponent = uint256 (x) >> 236 & 0x7FFFF;
uint256 significand = uint256 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
if (exponent == 0x7FFFF) {
if (significand > 0) return NaN;
else return negative ? NEGATIVE_INFINITY : POSITIVE_INFINITY;
}
if (exponent > 278526)
return negative ? NEGATIVE_INFINITY : POSITIVE_INFINITY;
else if (exponent < 245649)
return negative ? NEGATIVE_ZERO : POSITIVE_ZERO;
else if (exponent < 245761) {
significand = (significand | 0x100000000000000000000000000000000000000000000000000000000000) >> 245885 - exponent;
exponent = 0;
} else {
significand >>= 124;
exponent -= 245760;
}
uint128 result = uint128 (significand | exponent << 112);
if (negative) result |= 0x80000000000000000000000000000000;
return bytes16 (result);
}
/**
* Convert quadruple precision number into octuple precision number.
*
* @param x quadruple precision number
* @return octuple precision number
*/
function toOctuple (bytes16 x) internal pure returns (bytes32) {
uint256 exponent = uint128 (x) >> 112 & 0x7FFF;
uint256 result = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
if (exponent == 0x7FFF) exponent = 0x7FFFF; // Infinity or NaN
else if (exponent == 0) {
if (result > 0) {
uint256 msb = msb (result);
result = result << 236 - msb & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
exponent = 245649 + msb;
}
} else {
result <<= 124;
exponent += 245760;
}
result |= exponent << 236;
if (uint128 (x) >= 0x80000000000000000000000000000000)
result |= 0x8000000000000000000000000000000000000000000000000000000000000000;
return bytes32 (result);
}
/**
* Convert double precision number into quadruple precision number.
*
* @param x double precision number
* @return quadruple precision number
*/
function fromDouble (bytes8 x) internal pure returns (bytes16) {
uint256 exponent = uint64 (x) >> 52 & 0x7FF;
uint256 result = uint64 (x) & 0xFFFFFFFFFFFFF;
if (exponent == 0x7FF) exponent = 0x7FFF; // Infinity or NaN
else if (exponent == 0) {
if (result > 0) {
uint256 msb = msb (result);
result = result << 112 - msb & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
exponent = 15309 + msb;
}
} else {
result <<= 60;
exponent += 15360;
}
result |= exponent << 112;
if (x & 0x8000000000000000 > 0)
result |= 0x80000000000000000000000000000000;
return bytes16 (uint128 (result));
}
/**
* Convert quadruple precision number into double precision number.
*
* @param x quadruple precision number
* @return double precision number
*/
function toDouble (bytes16 x) internal pure returns (bytes8) {
bool negative = uint128 (x) >= 0x80000000000000000000000000000000;
uint256 exponent = uint128 (x) >> 112 & 0x7FFF;
uint256 significand = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
if (exponent == 0x7FFF) {
if (significand > 0) return 0x7FF8000000000000; // NaN
else return negative ?
bytes8 (0xFFF0000000000000) : // -Infinity
bytes8 (0x7FF0000000000000); // Infinity
}
if (exponent > 17406)
return negative ?
bytes8 (0xFFF0000000000000) : // -Infinity
bytes8 (0x7FF0000000000000); // Infinity
else if (exponent < 15309)
return negative ?
bytes8 (0x8000000000000000) : // -0
bytes8 (0x0000000000000000); // 0
else if (exponent < 15361) {
significand = (significand | 0x10000000000000000000000000000) >> 15421 - exponent;
exponent = 0;
} else {
significand >>= 60;
exponent -= 15360;
}
uint64 result = uint64 (significand | exponent << 52);
if (negative) result |= 0x8000000000000000;
return bytes8 (result);
}
/**
* Test whether given quadruple precision number is NaN.
*
* @param x quadruple precision number
* @return true if x is NaN, false otherwise
*/
function isNaN (bytes16 x) internal pure returns (bool) {
return uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF >
0x7FFF0000000000000000000000000000;
}
/**
* Test whether given quadruple precision number is positive or negative
* infinity.
*
* @param x quadruple precision number
* @return true if x is positive or negative infinity, false otherwise
*/
function isInfinity (bytes16 x) internal pure returns (bool) {
return uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ==
0x7FFF0000000000000000000000000000;
}
/**
* Calculate sign of x, i.e. -1 if x is negative, 0 if x if zero, and 1 if x
* is positive. Note that sign (-0) is zero. Revert if x is NaN.
*
* @param x quadruple precision number
* @return sign of x
*/
function sign (bytes16 x) internal pure returns (int8) {
uint128 absoluteX = uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
require (absoluteX <= 0x7FFF0000000000000000000000000000); // Not NaN
if (absoluteX == 0) return 0;
else if (uint128 (x) >= 0x80000000000000000000000000000000) return -1;
else return 1;
}
/**
* Calculate sign (x - y). Revert if either argument is NaN, or both
* arguments are infinities of the same sign.
*
* @param x quadruple precision number
* @param y quadruple precision number
* @return sign (x - y)
*/
function cmp (bytes16 x, bytes16 y) internal pure returns (int8) {
uint128 absoluteX = uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
require (absoluteX <= 0x7FFF0000000000000000000000000000); // Not NaN
uint128 absoluteY = uint128 (y) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
require (absoluteY <= 0x7FFF0000000000000000000000000000); // Not NaN
// Not infinities of the same sign
require (x != y || absoluteX < 0x7FFF0000000000000000000000000000);
if (x == y) return 0;
else {
bool negativeX = uint128 (x) >= 0x80000000000000000000000000000000;
bool negativeY = uint128 (y) >= 0x80000000000000000000000000000000;
if (negativeX) {
if (negativeY) return absoluteX > absoluteY ? -1 : int8 (1);
else return -1;
} else {
if (negativeY) return 1;
else return absoluteX > absoluteY ? int8 (1) : -1;
}
}
}
/**
* Test whether x equals y. NaN, infinity, and -infinity are not equal to
* anything.
*
* @param x quadruple precision number
* @param y quadruple precision number
* @return true if x equals to y, false otherwise
*/
function eq (bytes16 x, bytes16 y) internal pure returns (bool) {
if (x == y) {
return uint128 (x) & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF <
0x7FFF0000000000000000000000000000;
} else return false;
}
/**
* Calculate x + y. Special values behave in the following way:
*
* NaN + x = NaN for any x.
* Infinity + x = Infinity for any finite x.
* -Infinity + x = -Infinity for any finite x.
* Infinity + Infinity = Infinity.
* -Infinity + -Infinity = -Infinity.
* Infinity + -Infinity = -Infinity + Infinity = NaN.
*
* @param x quadruple precision number
* @param y quadruple precision number
* @return quadruple precision number
*/
function add (bytes16 x, bytes16 y) internal pure returns (bytes16) {
uint256 xExponent = uint128 (x) >> 112 & 0x7FFF;
uint256 yExponent = uint128 (y) >> 112 & 0x7FFF;
if (xExponent == 0x7FFF) {
if (yExponent == 0x7FFF) {
if (x == y) return x;
else return NaN;
} else return x;
} else if (yExponent == 0x7FFF) return y;
else {
bool xSign = uint128 (x) >= 0x80000000000000000000000000000000;
uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
if (xExponent == 0) xExponent = 1;
else xSignifier |= 0x10000000000000000000000000000;
bool ySign = uint128 (y) >= 0x80000000000000000000000000000000;
uint256 ySignifier = uint128 (y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
if (yExponent == 0) yExponent = 1;
else ySignifier |= 0x10000000000000000000000000000;
if (xSignifier == 0) return y == NEGATIVE_ZERO ? POSITIVE_ZERO : y;
else if (ySignifier == 0) return x == NEGATIVE_ZERO ? POSITIVE_ZERO : x;
else {
int256 delta = int256 (xExponent) - int256 (yExponent);
if (xSign == ySign) {
if (delta > 112) return x;
else if (delta > 0) ySignifier >>= uint256 (delta);
else if (delta < -112) return y;
else if (delta < 0) {
xSignifier >>= uint256 (-delta);
xExponent = yExponent;
}
xSignifier += ySignifier;
if (xSignifier >= 0x20000000000000000000000000000) {
xSignifier >>= 1;
xExponent += 1;
}
if (xExponent == 0x7FFF)
return xSign ? NEGATIVE_INFINITY : POSITIVE_INFINITY;
else {
if (xSignifier < 0x10000000000000000000000000000) xExponent = 0;
else xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
return bytes16 (uint128 (
(xSign ? 0x80000000000000000000000000000000 : 0) |
(xExponent << 112) |
xSignifier));
}
} else {
if (delta > 0) {
xSignifier <<= 1;
xExponent -= 1;
} else if (delta < 0) {
ySignifier <<= 1;
xExponent = yExponent - 1;
}
if (delta > 112) ySignifier = 1;
else if (delta > 1) ySignifier = (ySignifier - 1 >> uint256 (delta - 1)) + 1;
else if (delta < -112) xSignifier = 1;
else if (delta < -1) xSignifier = (xSignifier - 1 >> uint256 (-delta - 1)) + 1;
if (xSignifier >= ySignifier) xSignifier -= ySignifier;
else {
xSignifier = ySignifier - xSignifier;
xSign = ySign;
}
if (xSignifier == 0)
return POSITIVE_ZERO;
uint256 msb = msb (xSignifier);
if (msb == 113) {
xSignifier = xSignifier >> 1 & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
xExponent += 1;
} else if (msb < 112) {
uint256 shift = 112 - msb;
if (xExponent > shift) {
xSignifier = xSignifier << shift & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
xExponent -= shift;
} else {
xSignifier <<= xExponent - 1;
xExponent = 0;
}
} else xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
if (xExponent == 0x7FFF)
return xSign ? NEGATIVE_INFINITY : POSITIVE_INFINITY;
else return bytes16 (uint128 (
(xSign ? 0x80000000000000000000000000000000 : 0) |
(xExponent << 112) |
xSignifier));
}
}
}
}
/**
* Calculate x - y. Special values behave in the following way:
*
* NaN - x = NaN for any x.
* Infinity - x = Infinity for any finite x.
* -Infinity - x = -Infinity for any finite x.
* Infinity - -Infinity = Infinity.
* -Infinity - Infinity = -Infinity.
* Infinity - Infinity = -Infinity - -Infinity = NaN.
*
* @param x quadruple precision number
* @param y quadruple precision number
* @return quadruple precision number
*/
function sub (bytes16 x, bytes16 y) internal pure returns (bytes16) {
return add (x, y ^ 0x80000000000000000000000000000000);
}
/**
* Calculate x * y. Special values behave in the following way:
*
* NaN * x = NaN for any x.
* Infinity * x = Infinity for any finite positive x.
* Infinity * x = -Infinity for any finite negative x.
* -Infinity * x = -Infinity for any finite positive x.
* -Infinity * x = Infinity for any finite negative x.
* Infinity * 0 = NaN.
* -Infinity * 0 = NaN.
* Infinity * Infinity = Infinity.
* Infinity * -Infinity = -Infinity.
* -Infinity * Infinity = -Infinity.
* -Infinity * -Infinity = Infinity.
*
* @param x quadruple precision number
* @param y quadruple precision number
* @return quadruple precision number
*/
function mul (bytes16 x, bytes16 y) internal pure returns (bytes16) {
uint256 xExponent = uint128 (x) >> 112 & 0x7FFF;
uint256 yExponent = uint128 (y) >> 112 & 0x7FFF;
if (xExponent == 0x7FFF) {
if (yExponent == 0x7FFF) {
if (x == y) return x ^ y & 0x80000000000000000000000000000000;
else if (x ^ y == 0x80000000000000000000000000000000) return x | y;
else return NaN;
} else {
if (y & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NaN;
else return x ^ y & 0x80000000000000000000000000000000;
}
} else if (yExponent == 0x7FFF) {
if (x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NaN;
else return y ^ x & 0x80000000000000000000000000000000;
} else {
uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
if (xExponent == 0) xExponent = 1;
else xSignifier |= 0x10000000000000000000000000000;
uint256 ySignifier = uint128 (y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
if (yExponent == 0) yExponent = 1;
else ySignifier |= 0x10000000000000000000000000000;
xSignifier *= ySignifier;
if (xSignifier == 0)
return (x ^ y) & 0x80000000000000000000000000000000 > 0 ?
NEGATIVE_ZERO : POSITIVE_ZERO;
xExponent += yExponent;
uint256 msb =
xSignifier >= 0x200000000000000000000000000000000000000000000000000000000 ? 225 :
xSignifier >= 0x100000000000000000000000000000000000000000000000000000000 ? 224 :
msb (xSignifier);
if (xExponent + msb < 16496) { // Underflow
xExponent = 0;
xSignifier = 0;
} else if (xExponent + msb < 16608) { // Subnormal
if (xExponent < 16496)
xSignifier >>= 16496 - xExponent;
else if (xExponent > 16496)
xSignifier <<= xExponent - 16496;
xExponent = 0;
} else if (xExponent + msb > 49373) {
xExponent = 0x7FFF;
xSignifier = 0;
} else {
if (msb > 112)
xSignifier >>= msb - 112;
else if (msb < 112)
xSignifier <<= 112 - msb;
xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
xExponent = xExponent + msb - 16607;
}
return bytes16 (uint128 (uint128 ((x ^ y) & 0x80000000000000000000000000000000) |
xExponent << 112 | xSignifier));
}
}
/**
* Calculate x / y. Special values behave in the following way:
*
* NaN / x = NaN for any x.
* x / NaN = NaN for any x.
* Infinity / x = Infinity for any finite non-negative x.
* Infinity / x = -Infinity for any finite negative x including -0.
* -Infinity / x = -Infinity for any finite non-negative x.
* -Infinity / x = Infinity for any finite negative x including -0.
* x / Infinity = 0 for any finite non-negative x.
* x / -Infinity = -0 for any finite non-negative x.
* x / Infinity = -0 for any finite non-negative x including -0.
* x / -Infinity = 0 for any finite non-negative x including -0.
*
* Infinity / Infinity = NaN.
* Infinity / -Infinity = -NaN.
* -Infinity / Infinity = -NaN.
* -Infinity / -Infinity = NaN.
*
* Division by zero behaves in the following way:
*
* x / 0 = Infinity for any finite positive x.
* x / -0 = -Infinity for any finite positive x.
* x / 0 = -Infinity for any finite negative x.
* x / -0 = Infinity for any finite negative x.
* 0 / 0 = NaN.
* 0 / -0 = NaN.
* -0 / 0 = NaN.
* -0 / -0 = NaN.
*
* @param x quadruple precision number
* @param y quadruple precision number
* @return quadruple precision number
*/
function div (bytes16 x, bytes16 y) internal pure returns (bytes16) {
uint256 xExponent = uint128 (x) >> 112 & 0x7FFF;
uint256 yExponent = uint128 (y) >> 112 & 0x7FFF;
if (xExponent == 0x7FFF) {
if (yExponent == 0x7FFF) return NaN;
else return x ^ y & 0x80000000000000000000000000000000;
} else if (yExponent == 0x7FFF) {
if (y & 0x0000FFFFFFFFFFFFFFFFFFFFFFFFFFFF != 0) return NaN;
else return POSITIVE_ZERO | (x ^ y) & 0x80000000000000000000000000000000;
} else if (y & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) {
if (x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0) return NaN;
else return POSITIVE_INFINITY | (x ^ y) & 0x80000000000000000000000000000000;
} else {
uint256 ySignifier = uint128 (y) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
if (yExponent == 0) yExponent = 1;
else ySignifier |= 0x10000000000000000000000000000;
uint256 xSignifier = uint128 (x) & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
if (xExponent == 0) {
if (xSignifier != 0) {
uint shift = 226 - msb (xSignifier);
xSignifier <<= shift;
xExponent = 1;
yExponent += shift - 114;
}
}
else {
xSignifier = (xSignifier | 0x10000000000000000000000000000) << 114;
}
xSignifier = xSignifier / ySignifier;
if (xSignifier == 0)
return (x ^ y) & 0x80000000000000000000000000000000 > 0 ?
NEGATIVE_ZERO : POSITIVE_ZERO;
assert (xSignifier >= 0x1000000000000000000000000000);
uint256 msb =
xSignifier >= 0x80000000000000000000000000000 ? msb (xSignifier) :
xSignifier >= 0x40000000000000000000000000000 ? 114 :
xSignifier >= 0x20000000000000000000000000000 ? 113 : 112;
if (xExponent + msb > yExponent + 16497) { // Overflow
xExponent = 0x7FFF;
xSignifier = 0;
} else if (xExponent + msb + 16380 < yExponent) { // Underflow
xExponent = 0;
xSignifier = 0;
} else if (xExponent + msb + 16268 < yExponent) { // Subnormal
if (xExponent + 16380 > yExponent)
xSignifier <<= xExponent + 16380 - yExponent;
else if (xExponent + 16380 < yExponent)
xSignifier >>= yExponent - xExponent - 16380;
xExponent = 0;
} else { // Normal
if (msb > 112)
xSignifier >>= msb - 112;
xSignifier &= 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
xExponent = xExponent + msb + 16269 - yExponent;
}
return bytes16 (uint128 (uint128 ((x ^ y) & 0x80000000000000000000000000000000) |
xExponent << 112 | xSignifier));
}
}
/**
* Calculate -x.
*
* @param x quadruple precision number
* @return quadruple precision number
*/
function neg (bytes16 x) internal pure returns (bytes16) {
return x ^ 0x80000000000000000000000000000000;
}
/**
* Calculate |x|.
*
* @param x quadruple precision number
* @return quadruple precision number
*/
function abs (bytes16 x) internal pure returns (bytes16) {
return x & 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;
}
/**
* Get index of the most significant non-zero bit in binary representation of
* x. Reverts if x is zero.
*
* @return index of the most significant non-zero bit in binary representation
* of x
*/
function msb (uint256 x) private pure returns (uint256) {
require (x > 0);
uint256 result = 0;
if (x >= 0x100000000000000000000000000000000) { x >>= 128; result += 128; }
if (x >= 0x10000000000000000) { x >>= 64; result += 64; }
if (x >= 0x100000000) { x >>= 32; result += 32; }
if (x >= 0x10000) { x >>= 16; result += 16; }
if (x >= 0x100) { x >>= 8; result += 8; }
if (x >= 0x10) { x >>= 4; result += 4; }
if (x >= 0x4) { x >>= 2; result += 2; }
if (x >= 0x2) result += 1; // No need to shift x anymore
return result;
}
}
/*
USAGE NOTE: feeUINT will return a uint fee. However, due to ABDK conversion, the number might appear
arbitrary. You might need to multiply it by a constant, K, to get it to look right. Feed in values to get the minimum
and maximum and then, if needs be, figure out K.
EG. your desired range is between 1000 and 4000. The algorithm produces a range of 500 to 2000. So K must be 2.
*/
contract BuyPressurePolynomial{
using ABDKMathQuad for bytes16;
using ABDKMathQuad for uint;
struct ParameterSet{
bytes16 a;
bytes16 b;
bytes16 c;
bytes16 d;
}
ParameterSet calibration;
address tokenPair;
ERC20 Rock3t;
constructor (address _tokenPair, address _rock3t) {
tokenPair = _tokenPair;
Rock3t = ERC20(_rock3t);
}
//onlyOwner modifier required
function calibrate(uint a,uint b,uint c, uint d) public {
calibration.a = a.fromUInt();
calibration.b = b.fromUInt();
calibration.c = c.fromUInt();
calibration.d = d.fromUInt();
}
function square(bytes16 number) internal pure returns (bytes16) {
return number.mul(number);
}
function cube(bytes16 number) internal pure returns (bytes16) {
return square(number).mul(number);
}
function fee () public returns (bytes16){
bytes16 tokensInUniswap = Rock3t.balanceOf(tokenPair).fromUInt();
bytes16 t_squared = square(tokensInUniswap);
bytes16 t_cubed = cube(tokensInUniswap);
bytes16 term1 = calibration.a.mul(t_cubed);
bytes16 term2 = calibration.b.mul(t_squared);
bytes16 term3 = calibration.c.mul(tokensInUniswap);
return term1.add(term2).add(term3).add(calibration.d);
}
function feeUINT() public returns (uint){
return fee().toUInt();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment