PropAMM Overview
Bombora implements the Flashbots priority update registry, so an integration built against BuilderNet works similarly here. Thanks goes also out to Titan for pushing PropAMMs forward on Ethereum. Check out their dashboard.
The problem
An ordinary onchain AMM only reprices when someone trades against it. Between trades its price drifts away from what the wider market is doing, so anyone routing through it executes against a price that is already old. Liquidity providers widen their spreads to cover that risk, and takers pay for it.
A propAMM (proprietary AMM) closes that gap. It is a normal onchain pool that anyone can trade against, but its price is refreshed by a market maker streaming signed quotes directly to the builder. The maker can quote as tightly as it would elsewhere, because it is no longer exposed to a price it set several blocks ago.
The guarantee
When multiple updates for the same state are available at the time a block is built, the builder prioritises the latest update.
In practice that means the maker's freshest quote is placed immediately before the transaction that reads it, with no staler update in between. The taker trades against a price set moments earlier rather than one set in a previous block.
A matched quote is submitted as part of the block. The proposer may still select a competing builder's block, so submission is the last step Bombora controls.
Roles
| Role | What they do |
|---|---|
| Maker | Streams signed quote updates for the pools it prices. |
| Taker | Submits ordinary bundles, some of which route through a propAMM pool. |
| Builder | Holds the latest quote per pool, pairs it with the trade that reads it, and orders the two together. |
How it works
Quote ingestion. Makers connect to Bombora over a WebSocket and authenticate per maker. Each quote is an ordinary signed transaction that writes to the Priority Update Registry, an onchain registry of price updates that are valid for a single block and that the pool reads back during execution.
Quote registry. The builder keeps at most one live quote per pool, newest wins. The registry is cleared when the chain advances, so a quote never carries over into a block it was not signed for.
Matching. A registry write touches a deterministic set of storage slots, so the builder derives a quote's write set from its calldata alone, with no simulation. A candidate bundle whose execution reads any of those slots is the trade that quote enables, and the two are paired. A quote that no trade matches is never applied, so the block spends no space on unused price updates.
Proof before commit. A paired quote and trade are simulated together on throwaway state before either enters the block, under the taker's own slippage protection. If the trade does not succeed, neither transaction is included. The builder never forces a fill.
Continuous re-evaluation. Candidates are re-evaluated against the freshest quote from every pool until the block is built, and whichever combination gives the best outcome is the one that is submitted.
For makers
A maker can opt in to a freshness buffer, so a trade is only eligible against a quote that arrived a set interval after that trade reached the builder. This gives the maker a window to react before its price can be traded against. See Maker Integration for the protocol, the buffer, and regional behaviour.
For takers
There is no separate submission path. Searchers, solvers and aggregators submit bundles exactly as they do today, and any route through a propAMM pool is matched automatically. Existing integrations need no changes to benefit.
Makers can also consent to publishing their next-block price updates on a public stream, so a route can be priced against the state the block will actually have rather than against what is currently onchain. See Takers & State Stream.