§11–§12 · code
From browser math to Solidity.
What changes when the formulas on the method page move from double-precision TypeScript to a metered, fixed-point EVM, and the interface the resulting engine would expose.
§11
EVM implementation notes
Every formula on this page runs today in TypeScript, in a browser, in 64-bit floating point. Porting it to Solidity changes three things.
Fixed-point arithmetic
The EVM has no native floating point.[8] Every quantity in Table 1 and every intermediate in equations (4)–(9) would need to be represented as a scaled integer and carried through exp, ln, and the normal CDF using a fixed-point math library, at some cost in both gas and precision relative to the double-precision numbers computed client-side on this page.
The normal CDF, on-chain
This page’s Φ(x) uses the rational erfc approximation from Numerical Recipes[7], evaluated in double precision. The same rational-polynomial structure ports to fixed-point Solidity in principle; it has not been implemented or gas-profiled here.
View functions, not transactions
price() and greeks() in §12 are declared view: they read oracle state and return a number without writing anything.[10] That is what makes them callable, for free, by another contract in the middle of its own transaction — the composability property motivating §1.
Gas cost
Each of exp, ln, and Φ is a handful of arithmetic operations rather than a loop over paths — the entire appeal of §4 is that this cost does not scale with a path count N the way §2’s does. What that cost actually is, measured in gas, on a real deployment: measurement pending.
§12
Engine API
Proposed interface for the on-chain engine — not yet deployed. It exposes exactly the three outputs described in §1’s motivation (price, Greeks, margin) as view functions over the six inputs from Table 1, plus a position size for margin(). The long-term goal is for this to be consumable as a primitive: any protocol that needs a deterministic, reproducible price for this instrument calls the engine directly, on-chain, rather than running its own off-chain pricing service.
interface IPricingEngine {
struct MarketParams {
uint256 spot; // 1e18 fixed-point, from oracle
uint256 strike;
uint256 timeToExpiry; // seconds until expiry
uint256 volatility; // 1e18 fixed-point, annualized
int256 riskFreeRate; // 1e18 fixed-point
int256 carry; // 1e18 fixed-point, dividend / funding
}
struct Greeks {
int256 delta;
int256 vega;
}
/// Deterministic price of one unit of the instrument.
/// Same MarketParams in → same price out. Always.
function price(MarketParams calldata params) external view returns (uint256);
/// Numerical sensitivities, computed on-chain by finite difference
/// on price(). Documented as numerical, not closed-form.
function greeks(MarketParams calldata params) external view returns (Greeks memory);
/// Margin requirement for a given position size under this engine's
/// pricing model.
function margin(MarketParams calldata params, uint256 positionSize)
external
view
returns (uint256);
}notes
- [7]Bound on the erfc approximation: |error| < 1.2×10⁻⁷ over the full real line. See Press, Teukolsky, Vetterling & Flannery, Numerical Recipes in C, 2nd ed., §6.2. ↩
- [8]Solidity has no native floating point. Fixed-point libraries (e.g. PRBMath, ABDKMath64x64) represent a real number as an integer scaled by a fixed factor, commonly 10¹⁸ (“wei-scale”) or 2⁶⁴, and implement exp/ln as rational or binary-exponent approximations over that integer representation. ↩
- [10]A Solidity `view` function reads contract state but cannot modify it, so calling it from another contract requires no transaction, consumes no gas when called off-chain (e.g. from a wallet or another chain's light client via a static call), and cannot be front-run in the way a state-changing call can. ↩