Skip to main content

The hook system

The core of the exchange stays minimal; behavior is extended through plugins. A plugin is a contract the pool calls at defined moments of its lifecycle through ten typed hooks — each hook has a specific signature for its specific event, and each pool opts into exactly the hooks its plugin uses via a per-pool bitmap. Hooks a pool has not opted into cost nothing. One deliberate boundary: a plugin is notified of everything but controls almost nothing. The one exception is the fee, and only for plugins explicitly granted the dynamic-fee capability.

The default plugin

Pools are born with the default plugin unless their listing names a different plugin factory. It composes six modules, and a pool is created and priced in a single listing call — it trades from then on with all of this active.

Dynamic Fees

The swap fee tracks market conditions instead of being fixed forever at creation. The module measures the standard deviation of the price over a rolling window: volatile markets pay a higher fee (compensating LPs for the harder inventory risk), calm markets pay less. The fee always stays within the floor and ceiling set for the pool, and the pool’s current fee is always readable directly — a UI never needs to interrogate the plugin.

Limit Orders

On-chain limit orders, filled inside the swap that crosses them. Covered in depth in Limit Orders.

TWAP Oracle

Time-weighted average price observations, as in Uniswap V3 — but as a plugin rather than baked into every pool. Pools that nobody uses as a price source don’t pay for an oracle; pools that are used as one carry the full observation ring.
Because the oracle is a plugin, the price feed is governance-replaceable: anything using a pool as a price source is trusting pool governance not to swap the oracle out. Integrators should factor this into their trust model.

Security Module

An emergency brake for incident response. Its defining constraint: it can pause new activity, but it never blocks the way out — liquidity providers can always withdraw. A safety switch that could trap funds would itself be a risk, so it is designed not to be able to.

Active Liquidity Management

Rebalancing a managed position without anybody watching. Elsewhere a vault’s range is moved by a keeper — a bot that has to stay up forever, and whose failure is silent: the vault keeps taking deposits and quietly stops being managed. Here the swap that moved the price is the trigger: when the pool’s own time-weighted price says the range should move, the module calls for a rebalance inside that swap. The module holds no funds and owns no position — it only decides when, and calls a target the pool has explicitly admitted to act. If that target fails, the failure is recorded on-chain and the trade goes through regardless: a rebalance can never block a swap.

Farming Proxy

Feeds price movements to the farming system so reward programmes track in-range liquidity correctly — and if the farming system ever misbehaves, the proxy drops it rather than letting it interfere with the pool. Trading never breaks because rewards did.

Writing new modules

The composition is not closed: a new module — compliance gating, MEV capture — is written against the same hook interfaces and composed the same way. Every module lives inside the swap path, which is why each carries its own containment rather than trusting its neighbors.
Hook-by-hook reference for plugin developers will be published in the Developers section.