gamma

Black-Scholes

Computes Gamma of the option using the Black-Scholes model (sensitivity to delta change).

Avg. gas

1,433

Max abs. error

3.2e-15

when γ < 1

Max rel. error

5e-12

when γ ≥ 1

Signature

solidity
function gamma(
    uint128 spot,
    uint128 strike,
    uint32  timeToExp,
    uint64  volatility,
    uint64  rate
) internal pure returns (uint256 gammaOut)

Parameters

NameTypeDescription
spotuint128Current spot price, 18-decimal fixed-point.
strikeuint128Strike price, 18-decimal fixed-point. Precision-tuned for the no-arbitrage band against spot — see Bounds.
timeToExpuint32Time to expiration in seconds. timeToExp == 0 is allowed (handled as expired).
volatilityuint64Annualized implied volatility, 18-decimal fixed-point (e.g. 60% → 6e17).
rateuint64Annualized risk-free rate, 18-decimal fixed-point.

Returns

NameTypeDescription
gammaOutuint256Gamma in 18-decimal fixed-point. Γ ≥ 0; identical for call and put under put-call parity.

Bounds

BoundValue
MIN_SPOT1e-6 smallest allowed spot price (1e12)
MAX_SPOT1e15 largest allowed spot price (1e33)
MAX_STSP_RATIO5× (strike must lie within [spot/5, spot·5])
MAX_EXPIRATION32 years (1,009,152,000 seconds)
MAX_RATE400% annual (4e18)

Behavior

  • Validates all five inputs against module-wide constants and reverts with a typed error on any violation.
  • Returns a single value — call and put gamma are identical under put-call parity, so there is no tuple.
  • Volatility has no explicit revert — it's bounded only by its uint64 type (max ≈ 1.84e19, i.e. ~1840% annualized). The MIN_VOL_IV / MAX_VOL_IV constants apply only to the impliedVolatility solver, not the greeks.
  • Fast-path on expiration: when timeToExp == 0, returns 0.
  • Composes three DeFiMath primitives — ln, sqrtTime (specialized sqrt for years), and exp (for the density φ(d₁)). Gamma needs no CDF and no discount factor.
  • Pure internal function; no external calls, no storage. Inlined into the caller's bytecode at compile time.

How it works

gamma is the second derivative of option value with respect to spot — the rate at which delta changes. Under Black-Scholes it is the standard normal density at d₁ scaled by 1 / (S·σ·√T):

Γ=φ(d1)SσT,φ(d1)=ed12/22π\Gamma = \frac{\varphi(d_1)}{S \, \sigma \sqrt{T}}, \qquad \varphi(d_1) = \frac{e^{-d_1^2 / 2}}{\sqrt{2\pi}}
d1=ln(S/K)+(r+σ22)TσTd_1 = \frac{\ln(S/K) + \left(r + \tfrac{\sigma^2}{2}\right) T}{\sigma \sqrt{T}}

The density φ(d₁) is evaluated as Math.exp(−d₁²/2) / √(2π) using the precomputed SQRT_2PI constant, then divided by spot · σ√T. √T comes from Math.sqrtTime and ln(spot/strike) from Math.ln. Gamma is symmetric across the call/put boundary, so only one value is returned.

Precision follows the dual-metric rule: a relative bound of 5e-12 where γ ≥ 1 (low vol / short time, where gamma spikes) and an absolute bound of 3.2e-15 where γ < 1. Both are enforced at spot = $1,000 across a full sweep of strike, time, vol, and rate — head-to-head measurements live in defimath-compare.

Errors

ErrorTrigger
SpotLowerBoundErrorspot ≤ MIN_SPOT
SpotUpperBoundErrorspot ≥ MAX_SPOT
StrikeLowerBoundErrorstrike · 5 < spot
StrikeUpperBoundErrorspot · 5 < strike
TimeToExpiryUpperBoundErrortimeToExp ≥ MAX_EXPIRATION
RateUpperBoundErrorrate ≥ MAX_RATE

Example

solidity
import "defimath-lib/contracts/derivatives/BlackScholes.sol";

uint256 g = BlackScholes.gamma(
    1000e18,         // spot = $1,000
    980e18,          // strike = $980
    60 days,         // 60 days to expiry
    0.60e18,         // 60% annualized vol
    0.05e18          // 5% risk-free rate
);
// g ≈ 0.0026e18 (per $1 move in spot)