← Back to news
v4.0.0Aug 06, 2026

DeFiMath v4.0.0: Black-76 options on futures, and a cleaner API

v4.0.0 is the first major release since v3.0.0, and it earns the version bump two ways: a new Black-76 module for pricing European options on a future, and a library reorganization that gives every module a name that reads like its math. The reorg changes import paths and call sites, so upgrading is not drop-in — a short migration guide is at the bottom.

Black-76: European options on a future

Black-76 prices dated European options whose underlying is a future, not a spot price — the standard model for options on commodity, rate, and crypto futures. It ships the same surface as Black-Scholes: call, put, the four Greeks (delta, gamma, theta, vega), and a Newton-Raphson impliedVolatility solver.

Function Gas Returns
call2,552call price
put2,565put price
delta1,915(Δcall, Δput)
gamma1,704Γ (call = put)
theta3,255(Θcall, Θput), per day
vega1,659ν (call = put), per 1% vol
impliedVolatility11,760 / 11,802IV from call / put price

Under the hood Black-76 is Black-Scholes with the underlying set to the future F and the rate zeroed inside d₁, with the whole payoff discounted by e^(−rT):

price = e^(−rT) · [ F·Φ(d₁) − K·Φ(d₂) ]        (call)
d₁ = [ ln(F/K) + σ²T/2 ] / (σ√T),   d₂ = d₁ − σ√T

That structure is reused verbatim from the Black-Scholes kernel — the same stdNormCDF, exp, and ln primitives — so it inherits the same precision and the same gas discipline. Prices hold to 5e-12 relative error (1.3e-10 absolute deep out-of-the-money), verified in CI against a black-scholes/greeks reference driven through the discounting identity.

A cleaner API — and why this is v4.0.0

Every library dropped its DeFiMath* prefix, and the two derivative modules got names that say what they are. The library namespace now carries the context, so functions shed their redundant prefixes too — DeFiMathOptions.callOptionPrice is just BlackScholes.call. The old contracts/finance/ folder split into contracts/rates/ and contracts/statistics/.

v3.x v4.0.0
DeFiMath · math/Math.solMath · math/Math.sol
DeFiMathOptions · derivatives/Options.solBlackScholes · derivatives/BlackScholes.sol
DeFiMathBinary · derivatives/Binary.solBinaryOptions · derivatives/BinaryOptions.sol
DeFiMathFutures · derivatives/Futures.solFutures · derivatives/Futures.sol
DeFiMathRates · finance/Rates.solRates · rates/Rates.sol
DeFiMathStats · finance/Stats.solStatistics · statistics/Statistics.sol
Black76 · derivatives/Black76.sol (new)

Two function families were also renamed now that the library name carries the context:

  • Black-ScholescallOptionPrice → call, putOptionPrice → put. The Greeks (delta, gamma, theta, vega, impliedVolatility) keep their names.
  • Binary options — the binary prefix is gone: binaryCallPrice → call, binaryPutPrice → put, binaryDelta → delta, binaryGamma → gamma, binaryTheta → theta, binaryVega → vega.

No formula, precision, or gas number changed in the rename — only the names and import paths.

Bugfix: expired put delta

BlackScholes.delta returned +1 for the put leg of an in-the-money option at expiry (timeToExp == 0); the correct value is −1. Fixed, with a regression test that fuzzes moneyness at expiry and asserts the delta bounds and put-call delta parity. The call leg and every non-expiry case were already correct. The new Black-76 module handles this case correctly from the start.

Precision & docs

Every derivative function now carries full NatSpec — parameter semantics, the error metric, and the enforced bound — matching the format already on the math primitives. Where a function has both a relative and an absolute guarantee (price-like outputs near zero), both are documented and published: relative error where |result| ≥ 1, absolute where |result| < 1.

Testing

Black-76 ships with the same two-layer coverage as the rest of the library — 100 Hardhat correctness tests (validated against the discounting identity) and 16 Foundry properties (put-call parity, delta parity δcall − δput = e^(−rT), discounted bounds, monotonicity, IV round-trips). The suite totals grow to 740 Hardhat tests and 114 Foundry properties × 32,000 runs = 3,648,000 random executions per CI run.

Migrating from v3.x

Update imports and call sites per the table above. A minimal example:

// v3.x
import "defimath-lib/contracts/derivatives/Options.sol";
import "defimath-lib/contracts/finance/Stats.sol";

uint256 px = DeFiMathOptions.callOptionPrice(spot, strike, timeToExp, vol, rate);
uint256 sd = DeFiMathStats.stdDev(data);

// v4.0.0
import "defimath-lib/contracts/derivatives/BlackScholes.sol";
import "defimath-lib/contracts/statistics/Statistics.sol";

uint256 px = BlackScholes.call(spot, strike, timeToExp, vol, rate);
uint256 sd = Statistics.stdDev(data);

Signatures, return types, and every numeric result are unchanged — the upgrade is a find-and-replace on names and paths, nothing more.

Get it

npm install defimath-lib