lyapunov
market cap: · holders:
top: the price trajectory currently held in the program's 256-slot buffer, drawn against a faint second trace produced by perturbing the initial state by one part in ten thousand and re-integrating forward. in a chaotic regime the two paths separate exponentially; their log-distance grows linearly at a rate equal to the lyapunov exponent of the underlying dynamics. bottom: that exponent, estimated continuously across the same window via the rosenstein algorithm, plotted against the natural reference 0.9056 (white line). the shaded region between the two is the surcharge the hook would charge in expectation against the recent history.

on the name

aleksandr mikhailovich lyapunov was born in 1857 in yaroslavl and spent his working life in saint petersburg and kharkov, where he wrote a doctoral thesis on the stability of motion that was so far ahead of its time the academy did not know what to do with it. the central question of the thesis was simple and old: given a dynamical system, a set of differential equations that describe how some collection of variables evolves in time, can you tell whether a particular solution will stay close to where it starts, or whether it will run away. newton had asked this about planets. poincaré had asked it about three of them. lyapunov asked it about everything at once, and answered by inventing a number.

the number, now called the lyapunov exponent, is the rate at which two initial conditions that start arbitrarily close together separate over time. if the exponent is negative, they converge: the system is stable, perturbations die out, the future forgets the past. if the exponent is zero, they drift apart linearly: the system is conservative, neither stable nor chaotic. if the exponent is positive, they separate exponentially: the system is chaotic, the future is unknowable beyond a horizon that the exponent itself defines. lyapunov proved that this single number could be computed from the system's equations alone, without ever solving them, and that it told you everything you needed to know about long term behavior. the proof took him eight years. he was thirty five when he finished it. it would be sixty years before anyone outside russia read it.

he died by suicide in odessa in 1918, three days after his wife died of tuberculosis, during the russian civil war. he was sixty one. the funeral was small. the work was forgotten for a generation, recovered in the nineteen forties when the soviet academy reprinted it, and then exploded into mainstream mathematics in the nineteen sixties when edward lorenz, a meteorologist at mit, computed the first positive lyapunov exponent of a real physical system and discovered that the weather could not be predicted past two weeks for reasons that had nothing to do with measurement error and everything to do with the geometry lyapunov had described half a century earlier. the constant we use here, 0.9056, is the maximal lyapunov exponent of lorenz's atmospheric convection model under its canonical parameters. it is the number lyapunov spent his life learning how to compute and lorenz was the first to actually compute.

on chaos

what does an honest market look like? traders, economists, and protocol designers have spent a century trying to find a number that distinguishes real order flow from synthetic order flow, and the cleanest answer does not come from finance. it comes from dynamical systems. a price trajectory, plotted against time, is the output of a system whose inputs are every actor with a position, every order that arrives, every liquidation that fires, every block that gets produced. the system has an exponent. the exponent measures how fast two nearly identical configurations of that system diverge, and the value of the exponent is not arbitrary: it is what naturally happens when the system is driven by independent participants acting on independent information, and it sits, for any market deep enough to behave as a continuous process, at approximately λ₀ = 0.9056.

this is not a finance number. it is the maximal exponent of the lorenz attractor under the parameters lorenz used in his original 1963 paper, σ = 10, ρ = 28, β = 8/3, and it shows up in a market because a market under independent flow is, to a first approximation, a stochastically forced lorenz system. coordinated flow perturbs the exponent in two measurable directions. a whale walking the price in a straight line, or a coordinated group accumulating in a smooth ramp, drives the exponent toward zero, because the trajectory becomes locally non chaotic, locally predictable, locally a line. a wash trader bouncing a position between two wallets, or a sandwich attacker chopping every block, drives the exponent toward two, because the trajectory becomes locally indistinguishable from white noise, with no preferred direction at any scale. in both cases the deviation from 0.9056 is measurable in a few hundred slots, and in both cases what is being measured is not the price itself but the geometry of the price, which means it can be computed by anyone with access to the chain, which means it can be charged for.

on hooks

in november 2024, uniswap shipped its fourth major protocol revision and introduced a primitive the previous three versions had deliberately refused to expose. the primitive was the hook, a contract that pool deployers could attach to the moments immediately before and after a swap, immediately before and after a liquidity modification, and immediately before and after the pool's initialization. the hook ran inside the same transaction as the swap, with access to the swap's parameters, the pool's state, and the authority to modify both. it was the first time in the history of automated market makers that anyone other than the protocol itself could write logic that executed during a trade. dynamic fees, directional pricing, mev capture, limit orders, oracle integrations — an entire surface of mechanism design that had been theoretically describable for years but operationally unbuildable became, for the first time, something a single deployer could write into the pool itself.

solana arrived at the same primitive through a different door. the token-2022 program, deployed in 2023 as a successor to the original spl token program, introduced a feature called the transfer hook extension. the extension allows a mint creator to attach a program that is invoked on every transfer of the underlying token, regardless of which program initiated the transfer. where uniswap's hook fires when a specific pool's swap function is called, the transfer hook fires one layer lower, at the token movement itself. it runs when a dlmm pool executes a swap. it also runs when an arbitrage bot routes around the pool through a different venue, when a holder sends the token to a friend, when a market maker rebalances inventory between two accounts, when a liquidator seizes collateral. there is no path through which the token moves that does not pass through the hook, because the hook is part of what the token is.

this is a stricter guarantee than v4 provides. v4 hooks are pool scoped. a token that trades on a hooked v4 pool can also trade on a v3 pool, on a v2 pool, on a balancer pool, on a curve pool, on any of the hundreds of forks of any of those, and the hook on the v4 pool sees none of it. the transfer hook is the opposite. it is silent about which pool, which venue, which route, and instead commits to the only thing that matters, which is that no token can move without the hook running first. lyapunov exists because of this distinction. the protocol's correctness depends on observing every price discovery event on the asset, and on ethereum it would be possible for a sophisticated trader to route around the observation. on solana it is not possible.

on the program

lyapunov is a solana mainnet program that does one thing. it is deployed as a token-2022 transfer hook on the lyapunov mint, registered as an extension on a meteora dlmm pool for the lyapunov/sol pair, and given no other responsibilities. on every swap routed through the dlmm pool, the pool's core program invokes the spl token-2022 transfer instruction, which in turn invokes lyapunov's execute instruction through cross program invocation before the transfer settles. the program is given the swap's amount, the input and output mints, the source and destination accounts, and a set of extra accounts declared in the mint's extra account metas list at deployment. it returns a single value, the surcharge to be withheld from the input amount before the transfer completes.

on each invocation the program reads the dlmm pool's currently active bin id and the bin's corresponding price, both stored in the pool's account data and fetched in a single account read. it appends the (slot, bin_id, price) tuple to a 256 entry circular buffer maintained in a program derived address with seed ["bins", mint_pubkey]. the buffer is a fixed layout struct that fits inside a single pda account well under the ten kilobyte limit, so the per swap account allocation is zero. every write reuses the same slot in the same account. the head pointer advances on each write, wrapping at 256, and the program maintains parallel arrays of nearest neighbor distances that are carried forward from the previous swap so the exponent estimate can be updated in constant time rather than recomputed from scratch.

with the buffer updated, the program reconstructs the trajectory's phase space via takens embedding at dimension three and unit delay, locates the nearest neighbor of the current point in that space, and tracks the average rate at which neighbor pairs separate over subsequent slots. the slope of the log separation versus slot is the lyapunov exponent. the procedure is the rosenstein algorithm, chosen because it can be expressed entirely in terms of summed squared differences and a single final logarithmic fit, with no exponentials and no matrix decompositions. the fit is performed in anchor's i128 fixed point arithmetic with a precomputed log table for the six lag values used in the regression, so the entire estimate completes in a deterministic and gas bounded sequence of integer operations that the program has measured at under two hundred thousand compute units in the steady state.

on the surcharge

the program compares the current exponent estimate to the natural reference of 0.9056, takes the absolute difference, and squares it. the result is multiplied by a fixed scaling constant baked into the program at deployment, and the product is the dynamic surcharge applied to the swap. the base swap fee is whatever the meteora dlmm pool's bin step defines for that pair, and the dynamic component sits on top of it. the surcharge is withheld from the swap's input amount through the token-2022 transfer hook's standard return value, which the token program respects atomically before the transfer balance is updated. a swap that arrives during a smoothly walked trend, with exponent near 0.1, pays roughly fifteen times the base fee. a swap that arrives during wash traded chop, with exponent near 1.8, pays roughly eighteen times. a swap that arrives during conditions near the natural exponent pays nothing beyond the base.

the surcharge is routed to a redistribution vault, a separate program derived address controlled by the hook program and holding a single immutable allocation function. the vault receives the surcharge tokens at the moment the swap settles and accumulates them across many swaps. when the vault's balance crosses a threshold set at deployment, the program distributes the accumulated balance in two parts. half is paid to the liquidity providers whose positions span the bins that were active during the surcharged swaps, weighted by the time and liquidity integrated exposure of each position to those bins. the other half is paid to holders of the underlying token, weighted by a holding time score computed from each wallet's first acquisition slot, which is stored in a per holder pda written on first receipt and never updated thereafter except to extend its tenure.

a holder who has held for a million slots receives a larger share than a holder who has held for ten thousand, and a holder who sells loses their score entirely, resetting to zero on next acquisition. the asymmetry is intentional. the protocol charges the wallets that drive the exponent away from its natural value, and pays the wallets that have done neither for the longest. the surcharge is not a tax. it is a transfer from one population to another, mediated by a measurement that neither population can directly observe but both populations affect.

on the substrate

solana is the right substrate for this because three of its properties combine to make the measurement legible. the slot time is roughly four hundred milliseconds, fast enough that a price trajectory's lyapunov exponent resolves in seconds rather than minutes, and a manipulation detected in slot n can be priced into the swap that occurs in slot n plus one. the token-2022 transfer hook extension is atomic with the transfer itself, so there is no window between the exponent computation and the surcharge application during which a sophisticated actor could front run the protocol's own measurement. and the program's storage model, with fixed layout accounts at deterministic addresses, means the entire trajectory state is visible to any client without traversing event logs or reconstructing history from chain replays. a wallet can read the buffer, run the rosenstein procedure itself, and confirm the exponent the hook is about to charge against. nothing about the protocol requires trust in the team, because there is no team to trust.

the program is deployed through the bpf upgradeable loader with its upgrade authority set to None at deployment, which seals the on chain bytecode against modification. there is no admin key, no migration function, no multisig controlling the vault, no proxy redirecting calls to a newer implementation, no governance contract that can be voted into existence later. the program's address is fixed. the bytecode at that address is fixed. the allocation function inside the vault is fixed. the only variable is the exponent, and the exponent is whatever the chain produces.

on the invariant

there is one constant inside the program, the natural exponent 0.9056, and one observable computed at every slot, the running exponent of the price trajectory. when the observable approaches the constant, the protocol does nothing. when the observable deviates from the constant, the protocol charges proportionally to the square of the deviation and pays the holders who walked the curve honestly. there is no team. there is no treasury. there is no governance forum, no token vote, no parameter that can be changed by anyone after deployment. the protocol is the measurement, and the measurement is the chain.