{
  "errors": {
    "Overflow()": "0x35278d12",
    "DivisionByZero()": "0x23d359a3",
    "OutOfRange()": "0x7db3aba7"
  },
  "ops": [
    {
      "object": "BL127",
      "name": "fromFixed18",
      "signature": "fromFixed18(int256)",
      "selector": "0x9aea0a13",
      "inputs": [
        "x"
      ],
      "notice": "Convert an 18-decimal fixed-point value to 127.128.",
      "domain": "|x| < 2^127",
      "reverts": "OutOfRange() if |x| >= 2^127"
    },
    {
      "object": "BL127",
      "name": "toFixed18",
      "signature": "toFixed18(int256)",
      "selector": "0xa2745c74",
      "inputs": [
        "x"
      ],
      "notice": "Convert a 127.128 value to 18-decimal fixed-point.",
      "domain": "any x",
      "reverts": "never"
    },
    {
      "object": "BL127",
      "name": "toFixed18Down",
      "signature": "toFixed18Down(int256)",
      "selector": "0x32154abe",
      "inputs": [
        "x"
      ],
      "notice": "Convert a 127.128 value to 18-decimal fixed-point, rounding toward negative infinity: toFixed18 under the name that says its direction. For an amount a protocol pays out.",
      "domain": "any x",
      "reverts": "never"
    },
    {
      "object": "BL127",
      "name": "toFixed18Up",
      "signature": "toFixed18Up(int256)",
      "selector": "0x27066ea4",
      "inputs": [
        "x"
      ],
      "notice": "Convert a 127.128 value to 18-decimal fixed-point, rounding toward positive infinity: ceil(x * 1e18 / 2^128). For an amount a protocol charges.",
      "domain": "any x",
      "reverts": "never"
    },
    {
      "object": "BL127",
      "name": "add",
      "signature": "add(int256,int256)",
      "selector": "0xa5f3c23b",
      "inputs": [
        "a",
        "b"
      ],
      "notice": "a + b. Reverts with Overflow on signed overflow.",
      "domain": "any a, b",
      "reverts": "Overflow() on signed overflow"
    },
    {
      "object": "BL127",
      "name": "sub",
      "signature": "sub(int256,int256)",
      "selector": "0xadefc37b",
      "inputs": [
        "a",
        "b"
      ],
      "notice": "a - b. Reverts with Overflow on signed overflow.",
      "domain": "any a, b",
      "reverts": "Overflow() on signed overflow"
    },
    {
      "object": "BL127",
      "name": "mul",
      "signature": "mul(int256,int256)",
      "selector": "0xbbe93d91",
      "inputs": [
        "a",
        "b"
      ],
      "notice": "floor(a * b / 2^128), the 127.128 product.",
      "domain": "any a, b",
      "reverts": "Overflow() when a·b / 2^128 does not fit in int256"
    },
    {
      "object": "BL127",
      "name": "div",
      "signature": "div(int256,int256)",
      "selector": "0x43509138",
      "inputs": [
        "a",
        "b"
      ],
      "notice": "a / b in 127.128, truncated toward zero.",
      "domain": "b != 0",
      "reverts": "DivisionByZero() when b == 0; Overflow() when the quotient does not fit"
    },
    {
      "object": "BL127",
      "name": "mulDown",
      "signature": "mulDown(int256,int256)",
      "selector": "0x4b8d10e0",
      "inputs": [
        "a",
        "b"
      ],
      "notice": "floor(a * b / 2^128), toward negative infinity: mul under the name that says its direction.",
      "domain": "any a, b",
      "reverts": "Overflow() when a·b / 2^128 does not fit"
    },
    {
      "object": "BL127",
      "name": "mulUp",
      "signature": "mulUp(int256,int256)",
      "selector": "0x1aabb2f7",
      "inputs": [
        "a",
        "b"
      ],
      "notice": "ceil(a * b / 2^128), toward positive infinity.",
      "domain": "any a, b",
      "reverts": "Overflow() when the rounded product does not fit"
    },
    {
      "object": "BL127",
      "name": "divDown",
      "signature": "divDown(int256,int256)",
      "selector": "0xddb29e92",
      "inputs": [
        "a",
        "b"
      ],
      "notice": "a / b in 127.128, rounded toward negative infinity. div truncates toward zero, which rounds a negative quotient up; this does not.",
      "domain": "b != 0",
      "reverts": "DivisionByZero() when b == 0; Overflow() when the quotient does not fit"
    },
    {
      "object": "BL127",
      "name": "divUp",
      "signature": "divUp(int256,int256)",
      "selector": "0xe2bec1fe",
      "inputs": [
        "a",
        "b"
      ],
      "notice": "a / b in 127.128, rounded toward positive infinity.",
      "domain": "b != 0",
      "reverts": "DivisionByZero() when b == 0; Overflow() when the quotient does not fit"
    },
    {
      "object": "BL127E",
      "name": "exp2",
      "signature": "exp2(int256)",
      "selector": "0xdbbb06d2",
      "inputs": [
        "x"
      ],
      "notice": "2^x, rounded to nearest.",
      "domain": "x < 127; returns 0 below -129",
      "reverts": "Overflow() for x >= 127"
    },
    {
      "object": "BL127E",
      "name": "exp",
      "signature": "exp(int256)",
      "selector": "0xe46751e3",
      "inputs": [
        "x"
      ],
      "notice": "e^x, rounded to nearest.",
      "domain": "x <= 88; returns 0 below -90",
      "reverts": "Overflow() for x > 88"
    },
    {
      "object": "BL127E",
      "name": "exp10",
      "signature": "exp10(int256)",
      "selector": "0x4c0dafa2",
      "inputs": [
        "x"
      ],
      "notice": "10^x, rounded to nearest.",
      "domain": "10^x < 2^127 (x below about 38.23)",
      "reverts": "Overflow() above that"
    },
    {
      "object": "BL127E",
      "name": "log2",
      "signature": "log2(int256)",
      "selector": "0xe0d68737",
      "inputs": [
        "x"
      ],
      "notice": "log2(x) for x > 0, rounded to nearest.",
      "domain": "x > 0",
      "reverts": "OutOfRange() for x <= 0"
    },
    {
      "object": "BL127E",
      "name": "ln",
      "signature": "ln(int256)",
      "selector": "0x8e6f2353",
      "inputs": [
        "x"
      ],
      "notice": "ln(x) = log2(x) * ln(2) for x > 0, rounded to nearest. Reverts with OutOfRange otherwise.",
      "domain": "x > 0",
      "reverts": "OutOfRange() for x <= 0"
    },
    {
      "object": "BL127E",
      "name": "log10",
      "signature": "log10(int256)",
      "selector": "0xb47ca3c7",
      "inputs": [
        "x"
      ],
      "notice": "log10(x) = log2(x) / log2(10) for x > 0, rounded to nearest. Reverts with OutOfRange otherwise.",
      "domain": "x > 0",
      "reverts": "OutOfRange() for x <= 0"
    },
    {
      "object": "BL127E",
      "name": "log2Up",
      "signature": "log2Up(int256)",
      "selector": "0xa1985bb6",
      "inputs": [
        "x"
      ],
      "notice": "ceil(log2(x)) for x > 0: msb(x) - 128, plus one unless x is a power of two. Exact.",
      "domain": "x > 0",
      "reverts": "OutOfRange() for x <= 0"
    },
    {
      "object": "BL127",
      "name": "sqrt",
      "signature": "sqrt(int256)",
      "selector": "0x665df460",
      "inputs": [
        "x"
      ],
      "notice": "sqrt(x) for x >= 0.",
      "domain": "x >= 0",
      "reverts": "OutOfRange() for x < 0"
    },
    {
      "object": "BL127E",
      "name": "pow",
      "signature": "pow(int256,int256)",
      "selector": "0x92b0c5b2",
      "inputs": [
        "x",
        "y"
      ],
      "notice": "x^y = 2^(y * log2(x)) for x >= 0, rounded to nearest.",
      "domain": "x >= 0",
      "reverts": "OutOfRange() for x < 0; Overflow() when the result does not fit"
    },
    {
      "object": "BL127E",
      "name": "powu",
      "signature": "powu(int256,int256)",
      "selector": "0xb8846d69",
      "inputs": [
        "x",
        "n"
      ],
      "notice": "x^floor(n) for an integer exponent, rounded to nearest: binary exponentiation on a 256-bit mantissa with a separate binary exponent, rounded once; when that mantissa's error bound (k + 5) 2^-255, k = |n|, straddles a rounding midpoint, the same product on a 512-bit mantissa decides (within (3k + 2) 2^-510 relative, under 2^-237 ULP below k = 2^16; exact at every tie). From k = 2^16, pow(|x|, n) with the sign restored. Correctly rounded, the magnitude's ties away from zero. Exact whenever the true value is representable. Negative n inverts the mantissa, so x^-n is as accurate as x^n.",
      "domain": "any x, any integer n = floor(n); the result must fit",
      "reverts": "Overflow() when x^n does not fit; DivisionByZero() for 0^n with n < 0"
    },
    {
      "object": "BL127E",
      "name": "compound",
      "signature": "compound(int256,int256)",
      "selector": "0xa31e7db8",
      "inputs": [
        "rate",
        "n"
      ],
      "notice": "(1 + rate)^floor(n): n periods of compounding at rate, rounded to nearest, so a per-second rate over years keeps every bit the format holds. 1 + rate is exact in 127.128 (the sum of two grid values), so nothing is lost before the exponentiation; on an 18-decimal grid the rate itself would have been the first loss.",
      "domain": "rate > -1 and 1 + rate fits; any integer n = floor(n)",
      "reverts": "Overflow() when 1 + rate or the result does not fit; DivisionByZero() for rate == -1 with n < 0"
    },
    {
      "object": "BL127",
      "name": "cbrt",
      "signature": "cbrt(int256)",
      "selector": "0xd4b6188c",
      "inputs": [
        "x"
      ],
      "notice": "Cube root, defined for all x: cbrt(-x) = -cbrt(x). Rounded to nearest (decided exactly); exact for perfect cubes.",
      "domain": "any x",
      "reverts": "Overflow() only at -2^255"
    },
    {
      "object": "BL127",
      "name": "gavg",
      "signature": "gavg(int256,int256)",
      "selector": "0xa13ed853",
      "inputs": [
        "a",
        "b"
      ],
      "notice": "The geometric mean sqrt(a b), rounded once to nearest from the exact 512-bit product; two negatives give the positive root.",
      "domain": "a·b >= 0",
      "reverts": "OutOfRange() if a and b have opposite signs (both nonzero); Overflow() only for a = b = -2^255"
    },
    {
      "object": "BL127",
      "name": "hypot",
      "signature": "hypot(int256,int256)",
      "selector": "0xc479210c",
      "inputs": [
        "a",
        "b"
      ],
      "notice": "sqrt(a^2 + b^2), rounded once to nearest from the exact sum of squares (two words); no intermediate overflows.",
      "domain": "any a, b; the result must fit",
      "reverts": "Overflow() when sqrt(a^2 + b^2) rounds past the largest word"
    },
    {
      "object": "BL127",
      "name": "inv",
      "signature": "inv(int256)",
      "selector": "0x3a02c983",
      "inputs": [
        "x"
      ],
      "notice": "1 / x. Reverts with DivisionByZero for x == 0.",
      "domain": "x != 0",
      "reverts": "DivisionByZero() for x == 0; Overflow() when 1/x does not fit"
    },
    {
      "object": "BL127",
      "name": "abs",
      "signature": "abs(int256)",
      "selector": "0x1b5ac4b5",
      "inputs": [
        "x"
      ],
      "notice": "|x|. Reverts with Overflow for x == -2^255, which has no positive.",
      "domain": "any x",
      "reverts": "Overflow() at -2^255"
    },
    {
      "object": "BL127",
      "name": "neg",
      "signature": "neg(int256)",
      "selector": "0x54a53dc1",
      "inputs": [
        "x"
      ],
      "notice": "-x. Reverts with Overflow for x == -2^255.",
      "domain": "any x",
      "reverts": "Overflow() at -2^255"
    },
    {
      "object": "BL127",
      "name": "sign",
      "signature": "sign(int256)",
      "selector": "0xae610b48",
      "inputs": [
        "x"
      ],
      "notice": "-1, 0 or 1 in 127.128.",
      "domain": "any x",
      "reverts": "never"
    },
    {
      "object": "BL127",
      "name": "min",
      "signature": "min(int256,int256)",
      "selector": "0x29aa9cbe",
      "inputs": [
        "a",
        "b"
      ],
      "notice": "Signed minimum.",
      "domain": "any a, b",
      "reverts": "never"
    },
    {
      "object": "BL127",
      "name": "max",
      "signature": "max(int256,int256)",
      "selector": "0x81fe5786",
      "inputs": [
        "a",
        "b"
      ],
      "notice": "Signed maximum.",
      "domain": "any a, b",
      "reverts": "never"
    },
    {
      "object": "BL127",
      "name": "clamp",
      "signature": "clamp(int256,int256,int256)",
      "selector": "0x7b8d0f0c",
      "inputs": [
        "x",
        "lo",
        "hi"
      ],
      "notice": "min(hi, max(lo, x)). If lo > hi the result is hi, as in the Huff.",
      "domain": "any x, lo, hi",
      "reverts": "never"
    },
    {
      "object": "BL127",
      "name": "avg",
      "signature": "avg(int256,int256)",
      "selector": "0xebf274be",
      "inputs": [
        "a",
        "b"
      ],
      "notice": "floor((a + b) / 2) without intermediate overflow.",
      "domain": "any a, b",
      "reverts": "never"
    },
    {
      "object": "BL127",
      "name": "zeroFloorSub",
      "signature": "zeroFloorSub(int256,int256)",
      "selector": "0xff78cf2d",
      "inputs": [
        "a",
        "b"
      ],
      "notice": "max(0, a - b), with the subtraction checked.",
      "domain": "any a, b",
      "reverts": "Overflow() if a - b does not fit"
    },
    {
      "object": "BL127",
      "name": "dist",
      "signature": "dist(int256,int256)",
      "selector": "0x2110b689",
      "inputs": [
        "a",
        "b"
      ],
      "notice": "|a - b|, checked.",
      "domain": "any a, b",
      "reverts": "Overflow() if a - b does not fit"
    },
    {
      "object": "BL127",
      "name": "lerp",
      "signature": "lerp(int256,int256,int256)",
      "selector": "0x84e13b60",
      "inputs": [
        "a",
        "b",
        "t"
      ],
      "notice": "a + t * (b - a), checked. t is not clamped to [0, 1].",
      "domain": "any a, b, t",
      "reverts": "Overflow() on any intermediate that does not fit"
    },
    {
      "object": "BL127",
      "name": "floor",
      "signature": "floor(int256)",
      "selector": "0xda3ff648",
      "inputs": [
        "x"
      ],
      "notice": "Largest integer <= x. Clearing the fraction bits of a two's complement word is a floor for both signs.",
      "domain": "any x",
      "reverts": "never"
    },
    {
      "object": "BL127",
      "name": "ceil",
      "signature": "ceil(int256)",
      "selector": "0x42fba7ae",
      "inputs": [
        "x"
      ],
      "notice": "Smallest integer >= x, as -floor(-x). Reverts with Overflow when that integer is 2^127, which does not fit.",
      "domain": "any x",
      "reverts": "Overflow() when the result is 2^127"
    },
    {
      "object": "BL127",
      "name": "frac",
      "signature": "frac(int256)",
      "selector": "0xae2785ac",
      "inputs": [
        "x"
      ],
      "notice": "x - floor(x), always in [0, 1).",
      "domain": "any x",
      "reverts": "never"
    },
    {
      "object": "BL127",
      "name": "round",
      "signature": "round(int256)",
      "selector": "0x58b4370b",
      "inputs": [
        "x"
      ],
      "notice": "Nearest integer, halves rounded up: floor(x + 1/2). Checked.",
      "domain": "any x",
      "reverts": "Overflow() when the result is 2^127"
    },
    {
      "object": "BL127",
      "name": "factorial",
      "signature": "factorial(int256)",
      "selector": "0x5ad78e8a",
      "inputs": [
        "n"
      ],
      "notice": "floor(n)! for 0 <= n < 34. 33! is the largest that fits.",
      "domain": "0 <= n < 34",
      "reverts": "OutOfRange() outside that"
    },
    {
      "object": "BL127S",
      "name": "lambertW0",
      "signature": "lambertW0(int256)",
      "selector": "0x6de23d34",
      "inputs": [
        "x"
      ],
      "notice": "Principal branch of the Lambert W function, W(x) e^W(x) = x, for x >= -1/e, rounded to nearest.",
      "domain": "x >= -1/e",
      "reverts": "OutOfRange() below -1/e"
    },
    {
      "object": "BL127S",
      "name": "lambertWm1",
      "signature": "lambertWm1(int256)",
      "selector": "0xae94abc8",
      "inputs": [
        "x"
      ],
      "notice": "Secondary real branch of the Lambert W function, W(x) e^W(x) = x with W(x) <= -1, for -1/e <= x < 0, rounded to nearest.",
      "domain": "-1/e <= x < 0",
      "reverts": "OutOfRange() outside that"
    },
    {
      "object": "BL127E",
      "name": "log1p",
      "signature": "log1p(int256)",
      "selector": "0x8552a5b0",
      "inputs": [
        "x"
      ],
      "notice": "ln(1 + x), rounded to nearest. The sum 1 + x is exact in 127.128, so this is ln of an exact argument, rounded once; it exists because on an 18-decimal grid the sum is where a small x loses its digits.",
      "domain": "x > -1",
      "reverts": "OutOfRange() at or below -1; Overflow() if 1 + x does not fit"
    },
    {
      "object": "BL127E",
      "name": "expm1",
      "signature": "expm1(int256)",
      "selector": "0x973fe005",
      "inputs": [
        "x"
      ],
      "notice": "e^x - 1, rounded to nearest: on the 2^-128 grid the one is exact, so this is exp(x) - 1 word for word, a small x by its own series for gas: 27 terms at 2^-192 for |x| <= 1/16.",
      "domain": "x <= 88; returns -1 below -90",
      "reverts": "Overflow() for x > 88"
    },
    {
      "object": "BL127H",
      "name": "sinh",
      "signature": "sinh(int256)",
      "selector": "0x17cdc976",
      "inputs": [
        "x"
      ],
      "notice": "sinh(x), correctly rounded (to nearest, ties away from zero): (u + u/(1+u)) / 2 with u = e^|x| - 1 from one double-word exp at 2^-192, u/(1+u) = 1 - e^-|x| by one division, the difference taken before the one rounding; when that value's bound reaches the rounding boundary, e^|x| and e^-|x| in two words.",
      "domain": "|x| <= 88",
      "reverts": "Overflow() beyond that"
    },
    {
      "object": "BL127H",
      "name": "cosh",
      "signature": "cosh(int256)",
      "selector": "0xaa13e96a",
      "inputs": [
        "x"
      ],
      "notice": "cosh(x), correctly rounded (to nearest, ties up): 1 + u (u/(1+u)) / 2 with u = e^|x| - 1 from one double-word exp at 2^-192 and u/(1+u) = 1 - e^-|x| by one division, which is (e^|x| + e^-|x|) / 2 summed before the one rounding; when that value's bound reaches the rounding boundary, e^|x| and e^-|x| in two words. cosh(0) is exactly one.",
      "domain": "|x| <= 88",
      "reverts": "Overflow() beyond that"
    },
    {
      "object": "BL127H",
      "name": "tanh",
      "signature": "tanh(int256)",
      "selector": "0x5e1f05c7",
      "inputs": [
        "x"
      ],
      "notice": "tanh(x), correctly rounded (to nearest, ties away from zero). For |x| < 1/4, u / (u + 2) with u = e^(2|x|) - 1 at 2^-192; up to |x| < 46, (1 - w) / (1 + w) with w = e^(-2|x|) at 2^-192; one division and one rounding, or, when the value's bound reaches the rounding boundary, (1 - w) / (1 + w) in two words. Beyond, exactly +-1, the nearest word.",
      "domain": "any x",
      "reverts": "never"
    },
    {
      "object": "BL127H",
      "name": "atanh",
      "signature": "atanh(int256)",
      "selector": "0xc6285a68",
      "inputs": [
        "x"
      ],
      "notice": "atanh(x) = log1p(2|x| / (1 - |x|)) / 2, correctly rounded (to nearest, ties away from zero): the quotient at 2^-192 by one division, one unrounded logarithm of 1 + it, scaled by ln2/2; when that value's bound reaches the rounding boundary, the double-word l2p of 1 + |x| and 1 - |x|, and when that one's does, their logarithms in two words.",
      "domain": "|x| < 1",
      "reverts": "OutOfRange() at or beyond +-1"
    },
    {
      "object": "BL127N",
      "name": "erf",
      "signature": "erf(int256)",
      "selector": "0x7a959e36",
      "inputs": [
        "x"
      ],
      "notice": "The error function. |x| <= 4 by the series, |x| > 4 as 1 - erfc(x) by the tail polynomial, both at 2^-192; one rounding when the value's bound (2^45.6 and 2^20 units of 2^-192, erf_model.py) clears the rounding boundary, else BL19's wide second stage (erfw127): correctly rounded. +-1 exactly from |x| >= 9.375, where 1 - erf is below 2^-130.8 and the subtraction rounds to one.",
      "domain": "any x",
      "reverts": "never"
    },
    {
      "object": "BL127N",
      "name": "erfc",
      "signature": "erfc(int256)",
      "selector": "0xa79456da",
      "inputs": [
        "x"
      ],
      "notice": "The complementary error function 1 - erf(x), computed directly for x > 4 so the tail keeps its digits down to the format's floor (erfc(9.3) is one ULP; zero from 9.375, where it is below 2^-130.8); 2 - erfc(-x) for x < 0. One rounding, or erf's second stage when the bound reaches the boundary: correctly rounded.",
      "domain": "any x",
      "reverts": "never"
    },
    {
      "object": "BL127N",
      "name": "normCdf",
      "signature": "normCdf(int256)",
      "selector": "0x7b9745a0",
      "inputs": [
        "x"
      ],
      "notice": "The standard normal distribution function Phi(x) = erfc(-x / sqrt2) / 2, the argument scaled at 2^-192. The tail keeps its digits to the format's floor: Phi(-13) is about two ULPs, Phi(-14) rounds to zero, and Phi(x) is exactly one from x = 14. One rounding, or erf's second stage at y = |x| / sqrt 2 (exact, as BL19's) when the bound reaches the boundary: correctly rounded. This is the N(d) of Black-Scholes; on an 18-decimal grid it is zero from about d = -8.3.",
      "domain": "any x",
      "reverts": "never"
    }
  ]
}
