Overview

Patchbay is a constant-product AMM on Solana where every pool is a patch: an ordered chain of up to four hook modules that run before and after swaps and liquidity changes.

  1. Inuser pays
  2. Dynamic feebefore_swap
  3. Curvex · y = k
  4. Limit orderafter_swap
  5. Outuser is paid
One swap through an example patch. Modules with Before swap run before the curve, in patch order; modules with After swap run after it, before the user is paid.

The idea#

  • A pool is two mints, a static fee and a patch: an ordered list of up to four module accounts.
  • A module is a program plus a module account. The last byte of the module account’s address is its permission flags: eight bits, the eight jacks on its faceplate.
  • On every swap and liquidity change the AMM calls the modules whose bits are set, in patch order. They can raise the fee, refuse a withdrawal, record a price or fill orders.
  • The patch is part of the pool’s address, so it never changes. The same pair can have many pools, one per patch and fee.

Built-in modules#

Four modules ship in the patchbay-modules program. Anyone can create one with their own parameters and plug it into a new pool. Your own program can sit in the same slots.

ModuleJacksWhat it does
Dynamic fee 0x43Raises the fee after large price moves. The extra fee decays with a half-life.
TWAP oracle 0x01Records a time-weighted price before each swap. Any program can read it.
Limit order 0x82Fills resting orders after a swap moves the price across them.
Lockup 0x10Refuses liquidity removal until the pool’s unlock time.
Your moduleany valid byteAny program that implements the hook interface. See Write a module.

The same in every pool#

  • Constant product, x · y = k, on raw token atoms. Swaps are exact input. All math is checked u128 and rounds in the pool’s favour.
  • The static fee is set at creation, from 0 to 10%. A Dynamic fee module can override it, up to 50%. A share of the LP fee, at most 25%, can go to the protocol treasury.
  • min_amount_out always holds. Whatever the modules do, the user receives at least that much or the transaction reverts.
  • Modules cannot move vault funds, receive your signature or call back into the pool. See Security.

Clusters#

Program IDs are the same on every cluster. Devnet is the public test deployment, with test mints and seeded pools; mainnet-beta follows with the same IDs. The full list is on Addresses.

Not in v1#

  • Exact-output swaps.
  • Multi-hop routing inside the program. The app routes between pools; on mainnet it compares with Jupiter and falls back to it.
  • Concentrated liquidity.
  • On-chain token governance. The module registry is curated by an admin key, which can later be handed to a multisig or a DAO.