blockulator
two formats

38 digits fixed, 71 floating

FP127 is fixed point with 128 bits after the point. FP19 is a 256-bit float that reaches 10±78,913. WAD gives the fraction 60 bits.

measured

Against 300-digit arithmetic

FP127, FP19 and 15 other libraries, run through 14 scenarios of up to 10,000 steps each.

two forms

Deploy it or inline it

Each format is one Yul source, built into a deployed contract and an inline library that are fuzzed equal on every int256.

trust

No owner, no upgrades

No contract has storage, a proxy or an admin key. A new version gets a new address, and the old ones stay.

Leave a market alone and its interest goes wrong

Put $10,000 in at 5% a year and accrue it in one step after N days. Aave and Morpho approximate ex with three terms, so the longer a market waits for an update, the fewer digits survive: after 10,000 days, one. FP127 and FP19 lose less than two digits over the whole range.

Correct digits against exact arithmetic, each capped at what the library's format holds. OpenZeppelin, Uniswap and Maker have no exponential, so they are not here. The input is the continuous-accrual scenario's; data: ladder.json.

Every library, every N
library · correct digits after1 day10 days100 days365 days1,000 days10,000 days
Floating point
FP1971.271.371.371.371.371.3
ABDKMathQuad33.833.634.033.633.633.3
Fixed point
FP12738.638.638.638.538.037.1
ABDK 64.6419.118.919.019.318.817.8
Solady18.318.718.218.118.117.9
Solmate18.318.718.218.118.117.9
PRBMath SD18.317.917.718.117.717.7
PRBMath UD18.317.917.718.117.717.7
snekmate18.318.718.218.118.117.9
Balancer18.318.718.218.118.117.9
Aave16.812.88.86.64.81.2
Morpho13.712.58.86.64.81.2

Twice the digits, and competitive on gas

FP127 carries twice the digits of every 18-decimal library and costs less than PRBMath's SD59x18 on add, mul, div, exp, ln, pow and sqrt. FP19 carries twice binary128's digits and costs less than ABDKMathQuad on add, mul, div, exp, ln and pow. Solady is cheaper than both, at 18 digits.

Each dot is a library: the digits its format holds at 1, against its gas as a multiple of FP127's over the ops both offer; hover for the range. Median of inline calls over random inputs that take no shortcut (t). Aave, Morpho and Maker are formulas inside protocols, so they have no gas. Every op: per op; data: gas.json, fp19/gas.json.

Gas per call, 24 ops
Floating pointFixed point
op · gas per callFP19QuadFP12764.64SoladySolmatePRB SDPRB UDsnekBalancerOZUniswap
digits at 1713438191818181818181818
add6627651281623—189150————
mul530688267171126131485237————
div8008184122219397509261————
expᵗ3,2785,8082,7163,3804304302,8162,7206041,040——
lnᵗ3,04316,3351,9447,0805566327,0836,4741,2261,091——
powᵗ5,90123,5973,317—1,2791,35510,0659,544—2,223——
sqrtᵗ1,205759469828393456978824—2,349766—
avg663—1143160—154105113—318—
abs1332114012018—121———18—
divDown987—475—87150——323—239179
divUp988—478—113176——386—621282
inv7471,25924220293—17794————
log2ᵗ2,82215,5531,7236,990——6,7246,402—1,908——
mulDown727—315—86150——323—239179
mulUp728—337—110176——386—621282
powuᵗ6,631—5,1893,1332,3182,5594,0063,881————
sub7451,2361401623—187150————
exp2ᵗ3,0965,0732,6683,225——2,6712,557————
gavg2,099—1,079833449—960949————
cbrtᵗ2,734—1,936—619———1,4242,311——
log10ᵗ3,038—1,934———8,6188,233—1,891——
log2Up679—209—247———505—513—
neg127911676——134—————
sign13918175———84—78———

Correct to the last wei

BlockulatorWad keeps Solady's function names and returns the exact answer, rounded the way each function promises, on all 108,000 results we tested across 27 functions and rounding directions. The libraries it replaces are a wei off on up to 98% of their results for some functions.

Seeded inputs over each function's domain, including those whose exact value sits next to a wei boundary. Every library here is 18-decimal fixed point. Every library that offers them is exact on divWad, divWadUp, mulWad, mulWadUp, sDivWad, sMulWad, sqrtWad, sqrtWadUp. Counts: wad.md.

Share wrong, per function
Fixed point
function · share wrongBWadSoladySolmatePRB SDPRB UDsnekOZUniswap
cbrtWad0 of 4,0000———23%——
expWad0 of 3,99548%48%72%93%48%——
lnWad0 of 3,99824%24%98%98%24%——
log2Wad0 of 3,998——93%90%———
log10Wad0 of 3,998——88%90%———
powWad0 of 3,46166%66%71%85%———
lambertW0Wad0 of 3,99928%——————
mulWad0 of 3,720000—000
mulWadUp0 of 3,72000——000
divWad0 of 3,966000—000
divWadUp0 of 3,96600——000
sMulWad0 of 3,715000————
sDivWad0 of 3,937000————
sqrtWad0 of 4,000000——0—
sqrtWadUp0 of 4,000—————0—

Everything else we measured