n0paths
n0paths — deterministic pricing primitives for onchain markets. Diagram: many random Monte Carlo paths fan out and are crossed out, replaced by a single deterministic line labeled '0 paths, same answer.'

working paper · v0.1 · experimental

Deterministic derivatives pricing, on-chain.

A pricing and risk engine computed entirely from public oracle inputs — deterministic by construction, with no off-chain computation.

abstract

Most on-chain options protocols either price off-chain and post the result, or fall back to Monte Carlo simulation when a payoff has no closed form — which an arithmetic-average Asian option does not. Off-chain pricing breaks composability: another contract cannot verify how a number was produced without re-running the whole pipeline. On-chain Monte Carlo breaks determinism: the same market state can price differently depending on path count and random seed, and that noise has to be paid for in gas on every call. This paper takes a third route. It computes the first two moments of the arithmetic average in closed form under geometric Brownian motion, matches them to a lognormal proxy, and prices the option against that proxy in a single deterministic evaluation — no paths, no seed, no sampling step. The tradeoff is stated plainly, not hidden: the estimator carries no sampling error, but it is not exact. §3 makes that distinction concrete; §9 measures it, live, against a Monte Carlo reference computed in the browser.

keywords — asian options, moment matching, turnbull–wakeman, deterministic pricing, on-chain derivatives, greeks

ORACLE
VOLATILITY
DETERMINISTIC PRICER
PRICE
GREEKS
MARGIN

fig. 1The four-stage pipeline. Each arrow is a deterministic function call, not a network request — the whole chain runs in one view call.

the average, and the problem with it

A(T) = (1/n) · Σ S(t_i), i = 1..n C = E[ e^(-rT) · max(A(T) − K, 0) ] — no known closed form

The arithmetic average of a lognormal process is not itself lognormal — there is no known closed-form price for this payoff. What follows is a moment-matched approximation, not an exact solution.


§1

Why derivatives need a pricing function

A derivative’s payoff is only known at expiry. Before then, anything that holds one, trades one, or lends against one needs an answer to a different question: what is this position worth right now? An automated market maker quoting the option needs a price to quote. A margin engine needs a mark-to-market value to decide whether a position is under-collateralized. A liquidation bot needs to know how much it is seizing. A structured-product vault rolling a position forward needs to know what it is rolling out of. All four are asking the same question at different moments — that answer is what a pricing function computes.

Off-chain, this is a solved problem: closed-form formulas where they exist, numerical PDE solvers or Monte Carlo where they don’t, and effectively unlimited compute to run them. On-chain, the same valuation has to run inside a metered, deterministic execution environment[2] — every step costs gas, every step must produce the same result for every caller, and there is no API to call out to a pricing service without reintroducing a trusted off-chain party. The arithmetic-average Asian call is a useful instrument to study this problem on precisely because it has no closed form: it forces the question of what a pricing engine looks like when the easy answer isn’t available.


§2

The conventional approach: Monte Carlo

When a payoff has no closed form, the standard off-chain answer is Monte Carlo: simulate a large number of independent price paths under the risk-neutral measure, evaluate the payoff on each one, discount, and average. It is general-purpose — the same method prices almost any payoff on almost any process — and its error is quantifiable.

Ĉ_N = e^(-rT) · (1/N) · Σ payoff(path_j), j = 1..N
(1)

The Monte Carlo price estimate: the discounted payoff, averaged over N independent simulated paths.

SE_N = s / √N
(2)

Standard error of that estimate, from the sample standard deviation s of the discounted payoffs across the N paths.

Equation (2) is the whole story of Monte Carlo’s cost structure[3]: error falls with more paths, but only with the square root of N, so halving the error means quadrupling the compute. Off-chain that trade is usually cheap to make — spin up more workers, run more paths. The next section asks what happens when each path is instead paid for, one unit of gas at a time, by whoever calls the contract.


§3

Why Monte Carlo is awkward on-chain

Nothing about §2 is wrong on-chain — it is just expensive in a specific way. Every simulated path is EVM computation, metered and paid for in gas by whoever calls the contract, on every call, forever. The randomness driving those paths needs a verifiable on-chain source, which is its own design problem. And because the estimate depends on how many paths were run and which random draws they used, two honest callers — or the same caller twice — can get two different prices for the identical market state. A pricing primitive other contracts are meant to build on should not have that property: composability wants a value that is a pure function of state, not a function of state and a private die roll.

fig. 2Fourteen simulated price paths fanning out from spot. In practice a pricer would run hundreds to thousands of these per call; each additional path buys a little less precision than the last.

Monte Carlo

  • 128 paths
  • sampling error
  • random seed
  • O(N × steps) compute
MOMENTSDISTRIBUTION APPROX.EXPECTED PAYOFF

M₁, M₂ → lognormal(μ, σₐ) → E[max(A−K, 0)]

fig. 3The same information — moments of the average — flows through one fixed sequence of closed-form steps. There is nothing to sample, so there is nothing to converge.

Deterministic

  • 0 sampling error
  • no seed
  • same inputs → same output

note —“0 sampling error” does not mean “0 model error.” Removing the Monte Carlo estimator removes the noise that comes from sampling a finite number of paths. It does not remove the error that comes from approximating the arithmetic average’s true distribution with a moment-matched lognormal.

sampling uncertainty ≠ model uncertainty


§4

A deterministic alternative: moment matching

The arithmetic average of a set of lognormal prices has no known closed-form distribution — but its first two moments (mean and variance) can be computed exactly, in closed form, from the model’s parameters alone. Moment matching’s move is to stop trying to find the true distribution and instead borrow one with a known formula — here, lognormal — whose mean and variance are set equal to the real ones. Pricing the option is then one evaluation of a closed-form integral against that borrowed distribution, not a search or a simulation.[4] This is exact in the two moments matched, and approximate everywhere else — the borrowed shape does not have to match the true distribution’s skew or tail thickness, and in general it won’t exactly.

fig. 4Schematic, not computed from data: the true density of the arithmetic average has some unknown shape (dashed); the matched lognormal proxy (solid) shares its mean and variance but not necessarily its higher moments.


§10

Limitations

Stated plainly, in the same spirit as §3’s note: removing sampling error is not the same as removing all error, and a deterministic wrong answer is not better than a probabilistic right one. The following are the specific places this approach is known to be weakest.

Model risk grows with volatility and maturity

Moment matching is exact in the mean and variance of the average and silent about everything else — skew, kurtosis, tail shape. The gap between the true distribution and the lognormal proxy widens as σ√T grows, because higher-moment effects that are small at low volatility or short maturity compound over a longer, noisier path. §9’s live comparison is one data point on this curve, at one scenario, not a characterization of it.

Continuous averaging vs. a discrete oracle

Equations (4)–(5) assume the average is monitored continuously. A real oracle publishes at discrete intervals, so the quantity actually being priced is a discrete average — close to the continuous one for frequent publication, but not identical to it. This engine does not yet apply a discrete-monitoring correction.

Volatility is an input, not a forecast

σ in Table 1 is treated as a given constant for the life of the option. It says nothing about how that number should be produced — a running realized-volatility estimator, a GARCH-style update, or something else entirely — only that whatever produces it must do so deterministically, on-chain, for the engine downstream to stay deterministic.

A correct price is not a manipulation-resistant price

Determinism means the engine returns the same output for the same input, not that the input is trustworthy. Oracle manipulation[9] is a distinct risk that lives upstream of everything on this page.

Numerical Greeks inherit the pricer's approximation error, plus their own

§8’s finite differences are computed on an already-approximate price function, so delta and vega carry both the model error from §5 and a separate, smaller finite-difference error from the bump size h.

Nothing here is audited or deployed

The pricing math is implemented and unit-tested in TypeScript (§6’s numbers come from that implementation). The Solidity interface in §12 is a proposal, not a contract. There is no audit, no mainnet deployment, and no operating oracle integration to point to yet.


§14

Potential protocol use cases

None of the following are built or integrated. They are the reasons §1 gave for wanting a deterministic pricing primitive in the first place, made concrete.

Margin engines for average-price positions

A perpetual or structured position that settles against a session or funding-window average needs a live mark, not just a settlement-time payoff, to decide whether it's under-collateralized. A deterministic engine gives every liquidation bot and every position holder the same mark, from the same on-chain state, without a race over whose Monte Carlo run is authoritative.

On-chain AMMs for average-price options

A liquidity pool quoting Asian options needs to reprice its inventory on every trade. Doing that with on-chain Monte Carlo means paying simulation gas on every quote; a closed-form evaluation is a candidate for that hot path specifically because it doesn't scale with a path count.

Structured products that roll average-price exposure

A vault that sells a session-average call every epoch and rolls the position needs a fair mid-price to strike the next epoch's terms against. A composable price() call lets that roll happen inside a single transaction rather than waiting on an off-chain keeper.

Parametric payouts on a window average

Any product that pays out based on a price averaged over a defined window — not just an options desk — needs the same building block this page implements: a deterministic function from (spot history, window) to (expected value, sensitivity).


notes

  1. [2]Gas is the EVM's unit of metered computation — every opcode a transaction executes costs a fixed amount of gas, paid by the caller. A view call (see §11) is not a transaction and costs no gas when called off-chain, but does cost gas when called by another contract on-chain.
  2. [3]The 1/√N error bound for Monte Carlo estimators follows from the Central Limit Theorem applied to the sample mean of i.i.d. discounted payoffs — it is a property of the estimator, not of options pricing specifically, and holds for any Monte Carlo integration problem.
  3. [4]Moment matching is a general technique, not specific to Asian options: it is also used to price basket options, best-of/worst-of options, and other payoffs on a weighted sum of correlated lognormals that lack a closed form.
  4. [9]Oracle manipulation — e.g. a flash-loan-funded trade distorting a spot price or a short-window TWAP within one block — is a known DeFi risk class that is orthogonal to the pricing approximation discussed here. A deterministic pricer is exactly as vulnerable as its price input; it does not, by itself, make the input trustworthy.