Contributing a Pool Factory and its Maths

Bush pools are only deployed through approved factories, and every approved factory lives in one place: the bush-pool-factoriesopen in new window repository. The repo holds each factory's contracts and tests, the exact off-chain maths for its pools in TypeScript, Python and Rust, and the tooling that proves the maths matches the deployed contracts. A pool type is not integrable by aggregators until its maths is in that package, so a factory and its maths are contributed together.

The full walkthrough is the repo's CONTRIBUTING.mdopen in new window; the review process is in GOVERNANCE.mdopen in new window, and the submission checklist is the pull request templateopen in new window. This page is the overview.

The idea in one paragraph

A factory is the contract that deploys pools of one type and registers them with the Bush Vault. Integrators (aggregators, routers, front-ends) need to price those pools off-chain, so every factory in the repo comes with exact maths - code in TypeScript, Python and Rust that returns the same wei the contract would. To make sure of that, the repo can deploy your factory on a local chain, create a pool through it, ask the real Router for quotes, and replay those quotes through your maths (npm run maths:check). The maths lives directly in maths/open in new window, the library integrators install, so once everything matches there is nothing left to merge.

What you will write

contracts/<family>/                          the factory, the pool, and anything they need
test/foundry/<family>/                       Foundry tests (and test/hardhat/<family>/ for Hardhat ones)
maths/check/adapters/<name>-pool-factory.ts  ~50 lines: how to create your pool, and which numbers the maths needs
maths/typescript/src/<pool>/                 your pool's maths, in at least one language ...
maths/python/src/pools/<pool>/
maths/rust/src/pools/<pool>/
maths/check/runners/ts/pools.ts              ... registered by pool type in that language's check registry
maths/check/runners/python/pools.py
maths/rust/src/pools/mod.rs
docs/<name>-pool-factory/PARAMETERS.md       every creation parameter, its range and default
docs/<name>-pool-factory/GAS_CHARACTERISTICS.md
docs/<name>-pool-factory/README.md

plus a row in the table in the root README. A working template to copy is included: contracts/_templateopen in new window (a ConstantSumPool and its factory), matching Foundry tests, a check adapter, the ConstantSum maths in each language, and docs/_template-pool-factoryopen in new window.

The steps

  1. Set up. npm install && npm run compile. You need Node >= 20, Foundry, Python >= 3.10 and a Rust toolchain.
  2. Copy the template into contracts/<family>, test/foundry/<family>, a new check adapter and a new docs folder, then replace ConstantSumPool with your contracts.
  3. Write the contracts. The pool implements IBasePool (onSwap, computeInvariant, computeBalance, and the fee / invariant-ratio bounds) and inherits BushPoolToken, PoolInfo and Version. Every rounding choice must favour the Vault. The factory extends BasePoolFactory: create(...) encodes constructor args, calls _create (CREATE2) and _registerPoolWithVault. If your pool needs a hook, it lives next to the factory and its maths is part of the contribution. The Build an AMM section covers the contract side in depth.
  4. Test. Extend BaseVaultTest from @bush.fi/v3-vault and cover swaps, adds, removes and every revert.
  5. Write the check adapter. It declares a few parameter variants (token decimals, token counts, every pool parameter that changes a code path) and a createPool that deploys your factory and returns poolType plus the pool-specific numbers your maths needs, read back from the chain.
  6. Write the maths. A pool class in maths/typescript/src/<pool>/ (and Python / Rust) implementing the same swap / invariant / balance functions as the contract on top of the shared fixed-point primitives, plus its state type, registered in each language's check registry.
  7. Prove it. npm run maths:generate writes test data from your real pool; npm run maths:check replays it through your maths. Every value must match exactly. Then add your poolType to each Vault so the packages' own test suites cover it too.
  8. Document. README.md, PARAMETERS.md and GAS_CHARACTERISTICS.md in docs/<name>-pool-factory/, and a row in the root README table.

Licensing

The maths packages are MIT. Contracts carry the license in their SPDX-License-Identifier header: code derived from the existing pools or inheriting the GPL @bush.fi/v3-* packages is GPL-3.0-or-later; independent code may use a license of your choice, stated in its headers and its factory README.