Math

Low-level fixed-point primitives in 18-decimal format (1e18 = 1.0). All pure, gas-efficient, and validated to sub-1e-12 absolute error against reference libraries.

Contract: Math.sol

Functions

FunctionGasDescription
exp333Exponential function e^x
expm1439e^x − 1 (precision-preserving for small x)
ln375Natural logarithm
log1p500ln(1 + x) (precision-preserving for small x)
log2391Base-2 logarithm
log10391Base-10 logarithm
pow750Power function x^a
sqrt245Square root
cbrt368Cube root
stdNormCDF731Standard normal CDF Φ(x)
erf685Error function

npm install defimath-lib

Conventions

  • All values use 18-decimal fixed-point (1e18 = 1.0).
  • Signedness mirrors the math: exp takes int256, returns uint256; ln takes uint256, returns int256.
  • All functions are internal pure — no storage access, no external calls.

Quick example

solidity
import "defimath-lib/contracts/math/Math.sol";

uint256 x    = 2e18;                     // x = 2.0
uint256 root = DeFiMath.sqrt(x);         // root ≈ 1.41421e18
int256  lnX  = DeFiMath.ln(x);           // lnX  ≈ 0.69315e18
uint256 ePow = DeFiMath.exp(int256(x));  // ePow ≈ 7.389e18

Important notes

  • Use expm1 for small x. Computing ex − 1 via exp(x) - 1e18 catastrophically cancels when |x| < 0.01. expm1 uses a Taylor series in that range and preserves full 18-digit precision.
  • Use log1p for small x. Same reason — log1p(x) preserves precision near zero where ln(1 + x) would lose ~15 digits to subtraction.
  • Negative exp underflows silently to 0. For x < −41.45e18, exp(x) returns 0 (not a revert) since the true value is below 1e-18 representational precision.
  • CLZ requires Solidity 0.8.31 + EVM "osaka". ln, sqrt, cbrt, and sqrtTime emit the new CLZ opcode introduced in Osaka.

Limits & errors

ErrorTrigger
ExpUpperBoundErrorexp(x) when x ≥ 135.305999e18
LnLowerBoundErrorln(0)
Log1pLowerBoundErrorlog1p(x) when x ≤ −1e18
SqrtUpperBoundErrorsqrt(x) when x ≥ 280 (~1.2e24)
CbrtUpperBoundErrorcbrt(x) when x ≥ 276 (~7.6e22)