put
Binary optionsComputes the price of a binary cash-or-nothing put option using the Black-Scholes model.
Avg. gas
1,918
Max abs. error
2e-12
Signature
function put(
uint128 spot,
uint128 strike,
uint32 timeToExp,
uint64 volatility,
uint64 rate
) internal pure returns (uint256 price)Parameters
| Name | Type | Description |
|---|---|---|
| spot | uint128 | Current spot price, 18-decimal fixed-point. |
| strike | uint128 | Strike price, 18-decimal fixed-point. Precision-tuned for the no-arbitrage band against spot — see Bounds. |
| timeToExp | uint32 | Time to expiration in seconds. timeToExp == 0 is allowed (handled as expired). |
| volatility | uint64 | Annualized implied volatility, 18-decimal fixed-point (e.g. 60% → 6e17). |
| rate | uint64 | Annualized risk-free rate, 18-decimal fixed-point. |
Returns
| Name | Type | Description |
|---|---|---|
| price | uint256 | Binary put price for unit payout in 18-decimal fixed-point — a discounted probability in [0, 1]. Scale externally for other payouts. |
Bounds
| Bound | Value |
|---|---|
| MIN_SPOT | 1e-6 smallest allowed spot price (1e12) |
| MAX_SPOT | 1e15 largest allowed spot price (1e33) |
| MAX_STSP_RATIO | 5× (strike must lie within [spot/5, spot·5]) |
| MAX_EXPIRATION | 32 years (1,009,152,000 seconds) |
| MAX_RATE | 400% annual (4e18) |
Behavior
- Validates all five inputs against module-wide constants and reverts with a typed error on any violation.
- Pays out 1 unit if the option finishes in-the-money (
strike > spot), 0 otherwise. The returned price is the discounted probability of that — multiply by your notional for any other payout. - Volatility has no explicit revert — it's bounded only by its
uint64type (max ≈1.84e19, i.e. ~1840% annualized). - Fast-path on expiration: when
timeToExp == 0, returns1if in-the-money (strike > spot), else0. - Composes four DeFiMath primitives — ln,
sqrtTime(specialized sqrt for years),expPositive(the discount factor), and stdNormCDF. - Symmetric counterpart of the binary call: same machinery with
Φ(−d₂)in place ofΦ(d₂). Pureinternalfunction; no external calls, no storage.
How it works
A binary (cash-or-nothing) put pays a fixed unit if strike > spot at expiry. Under Black-Scholes its price is the discounted risk-neutral probability of that event:
It reuses the same d₂ machinery as the binary call — Math.ln for ln(spot/strike), Math.sqrtTime for σ·√T, 1 / Math.expPositive(rT) for the discount factor — but evaluates Φ(−d₂) with Math.stdNormCDF. By put-call parity the two prices sum to the discount factor e^(−rT).
The price is a discounted probability, always in [0, 1], so the suite enforces an absolute error only — no relative bound. The 2e-12 max absolute error is enforced across a full sweep of strike, time, vol, and rate — head-to-head measurements against other libraries live in defimath-compare.
Errors
| Error | Trigger |
|---|---|
| SpotLowerBoundError | spot ≤ MIN_SPOT |
| SpotUpperBoundError | spot ≥ MAX_SPOT |
| StrikeLowerBoundError | strike · 5 < spot |
| StrikeUpperBoundError | spot · 5 < strike |
| TimeToExpiryUpperBoundError | timeToExp ≥ MAX_EXPIRATION |
| RateUpperBoundError | rate ≥ MAX_RATE |
Example
import "defimath-lib/contracts/derivatives/BinaryOptions.sol";
uint256 price = BinaryOptions.put(
1000e18, // spot = $1,000
950e18, // strike = $950
30 days, // 30 days to expiry
0.60e18, // 60% annualized vol
0.05e18 // 5% risk-free rate
);
// price ≈ 0.36e18 (~36% risk-neutral probability, discounted)