Our Commitment to Aggregators

Integrating an AMM used to mean reading one invariant and one router. It no longer does. Across the ecosystem, programmable pools have turned integration into a moving target: hooks that change a pool's fee or its output amounts with logic that lives nowhere an aggregator can see; pool types that ship to mainnet before anyone has published maths that reproduces them; reference implementations that lag the contracts by weeks and then quietly disagree with them; routers that multiply and get redeployed under new addresses; and pools that behave one way in a query and another way in the block that lands. Every one of these has cost aggregators failed transactions, bad quotes, or the decision to simply not route through a protocol at all.

Bush is built on this same programmable architecture, and we want your liquidity routing through it. So this page is a promise about how we run the thing that matters most to you: the bush-pool-factoriesopen in new window repository, where every approved pool type and its off-chain maths live together. Everything below is enforced in that repo's GOVERNANCE.mdopen in new window, CONTRIBUTING.mdopen in new window and pull request templateopen in new window, not just stated here.

1. No pool type without its maths

A factory is not approved until its pool's maths is in maths/open in new window. Not "coming soon", not "see the Solidity" - the package you install has the pool type, or the pool type does not exist for integrators. A PR that adds a factory must include the maths and the adapter that proves it; a PR that adds only contracts fails review.

This means you will never learn about a new Bush pool type from a failed swap. You will learn about it from a new poolType in a package release, with test data showing exactly what it returns.

2. The maths is proven against the contracts, to the wei

Every result in every maths package is checked bit-for-bit against a pool deployed through the real factory: the maths/checkopen in new window tool deploys the factory on a local chain, creates pools across parameter variants (token decimals, token counts, every parameter that changes a code path), queries swaps, adds and removes through the real Router, and replays them through the TypeScript, Python and Rust maths. Every value must match exactly. "Maths that disagree with the deployed pool" is a named reason for failing review, and npm run maths:all must be green before a PR is opened.

The recorded results are committed as testData/open in new window, so you can verify your own integration against the same numbers we do, without an RPC.

3. Tested behaviour, proven by the maths - not a PDF

We do not gate approval on an audit report, and we want to be honest about why. An audit is a snapshot of one version of the code by one firm; it does not tell you whether the pool you are quoting today returns what the maths says. So the review requires something you can verify yourself: every contract ships with a test suite that exercises every pool operation the factory deploys, and the maths check in promise #2 is the proof that the contracts do what they claim. Contracts whose behaviour is not covered by tests, or that were changed from an upstream source without tests covering the change, fail review. A linked audit covering the contracts as submitted is welcome and will be listed, but it is a bonus, not the gate.

Where a Bush pool differs from its upstream, the difference is small, tested, and documented so you are not surprised by it. Today the only substantive divergence in WeightedPool from Balancer's contract is the minimum static swap fee (0.05% on Bush, 0.001% upstream). Per-token minimum balances and the round-up of the token-in balance are upstream behaviour that older Balancer-derived maths packages do not model - which is exactly why the Bush maths exists and is checked against the deployed pool, not against another package.

4. Nothing changes silently

  • Any change to an approved contract requires a new PR and re-review. There is no quiet redeploy.
  • The maths package is published from a tagged release through CI with npm provenance; the tag must match package.json, and the full test suite runs first.
  • Deprecated or superseded factories are marked deprecated, never deleted, so your existing references keep resolving and you can see the history of what replaced what.
  • Every factory documents every creation parameter, its valid range and its default in PARAMETERS.md, so there is no undocumented validation rule that a pool can hit and you cannot predict.

5. Hooks you can see, or pools you can skip

Every hook attached by an approved factory ships with its maths in the same package as the pool - the Vault class applies it when you pass hookType and hookState, and the Hooks Reference lists exactly what state each one needs and which events change it. There is no approved hook whose fee logic you have to reverse-engineer.

We will not ask you to model a hook we have not shipped maths for. Because Bush pools can carry a hook contract set at creation, a pool may exist with a hook that is not in that reference; getHooksConfig(pool) on the Vault tells you so, and the correct response is to skip it. You lose nothing we have endorsed by doing so, and we would rather you skip a pool than quote it wrong.

6. Routing that stays put

The Router surface for aggregators is small and prepaid: the Aggregator Router and Aggregator Batch Router take no approvals and expose the same functions as the retail routers. Every deployed address is listed with its deployment task on the Deployment Addresses page and resolvable onchain through the Contract Registry, and the factories' PoolCreated and the Vault's Swap / LiquidityAdded / LiquidityRemoved events, not a hosted API, are the source of truth for pool discovery and state.

Time-dependent pools (LBPs, ReClamm) are documented as such, with the maths taking the landing block's timestamp as an explicit input, so "it queried fine and reverted in the block" is a class of failure we design out rather than apologise for.

What we ask in return

Tell us when something does not match. If the package returns a different amount than the Router for any pool created by an approved factory, that is a P0 for us, not a rounding quirk; open an issue on bush-pool-factoriesopen in new window or reach us on Discordopen in new window. And if you want a pool type Bush does not have, the path to getting it integrated is the same one we hold ourselves to: contribute the factory with its maths, and it will be checked, reviewed and published the same way.