A rebuilt exp cascades across the library
v3.7.0 is a gas-and-precision release built on one change: exp was rebuilt. A two-stage range reduction feeding a [3,3] Padé approximant takes it from 327 to 289 gas while tightening its error bound. Because exp sits under Black-Scholes pricing, the Greeks, the implied-volatility solver, futures, and continuous-compounding rate math, that saving cascades through the whole library — callOptionPrice drops 126 gas, continuousToDiscrete 116, and every exp-dependent function gets cheaper.
expm1 was separately simplified: now that exp is precise enough, the non-Taylor branch is just exp(x) − 1, shedding 112 gas.
Gas changes
A representative slice — the savings reach every function that touches exp, directly or transitively (all six European Greeks, both binary prices and their Greeks, impliedVolatility ≈ −650, presentValue −42):
| Function | v3.6.0 gas | v3.7.0 gas | Saved |
|---|---|---|---|
exp |
327 | 289 | −38 (−12%) |
expm1 |
407 | 295 | −112 (−28%) |
pow |
803 | 761 | −42 (−5%) |
stdNormCDF |
660 | 618 | −42 (−6%) |
erf |
691 | 649 | −42 (−6%) |
futurePrice |
442 | 400 | −42 (−10%) |
compoundInterest |
467 | 425 | −42 (−9%) |
continuousToDiscrete |
491 | 375 | −116 (−24%) |
callOptionPrice |
2,708 | 2,582 | −126 (−5%) |
putOptionPrice |
2,718 | 2,592 | −126 (−5%) |
binaryCallPrice |
1,997 | 1,913 | −84 (−4%) |
Precision
Error bounds were tightened alongside the speedups, and every math primitive now carries an explicit, enforced bound (asserted in CI against the JS / decimal.js references over full-domain sweeps):
| Function | Max rel. error | Max abs. error |
|---|---|---|
exp |
2.2e-14 | 3.0e-16 |
expm1 |
2.2e-14 | 5.0e-16 |
pow |
1.0e-12 | 1.0e-14 (new — previously relative-only) |
cbrt |
2.0e-13 | 1.0e-16 |
erf |
— | 2.0e-15 |
stdNormCDF |
— | 3.0e-15 |
Testing & benchmarks
Error tolerances and gas benchmarks now live in a single source of truth — constants/Constants.mjs, holding the MAX_*_ERROR_* and AVG_GAS_* constants — so every published figure is asserted in CI. Gas is pinned to exact values (a test fails on both regression and improvement, so any change surfaces in the PR diff); behaviour tests sweep each function's full valid domain, and gas is measured over 1,000-sample sweeps balanced across the relative- and absolute-error regimes.
- Hardhat correctness layer: 623 → 640 tests
- Foundry property layer: unchanged — 92 properties × 32,000 runs = 2.94M executions per CI run
Behavior change
exp's upper bound is now a round 135e18 (previously 135.305999…e18) and typed int256. Inputs in the narrow (135e18, 135.306e18] window that used to succeed now revert with ExpUpperBoundError. Since e^135 ≈ 4×10⁵⁸ is far beyond any realistic financial exponent, this affects no practical caller. There are no other API changes — v3.7.0 is a drop-in upgrade.
Install
npm install defimath-lib- Docs: https://defimath.com/docs/
- Full changelog: v3.6.0...v3.7.0