Skip to main content
Not every quote request is friendly flow. Arbitrageurs pick off stale quotes, and predatory flow can arrive through aggregator routers. Bebop exposes two entry points to your liquidity - RFQ and RFQA - and toxic-flow protection works differently on each. The difference changes how you price, so it is worth being explicit about up front.

How protection differs by path

On RFQ, you manage toxicity. Bebop gives you the address and source fields to identify where flow originates, plus the error types to reject it cleanly. You decide who to quote, who to widen against, and who to block. On RFQA, the protocol manages toxicity on-chain at execution time. The end user is not disclosed - the caller and receiver are the BebopRouter - so there is no per-counterparty signal to filter on.
RFQRFQA
Who manages toxicityYouThe protocol, on-chain
End-user visibilityorigin_address when the partner sets itNot disclosed - caller and receiver are the BebopRouter
Identifiersource per partner, or absent for open APIsource: rfqa
How you act on toxic flowDenylist or widen by source / address-
The rest of this page covers each path in turn.

RFQ: filter at the source

On the RFQ path you have the signals to identify flow and reject it without penalty.

Address fields

Every quote request carries:
  • taker_address - the on-chain caller. For aggregator requests this is usually the aggregator’s router contract, not the end user.
  • receiver - where your tokens land after execution.
Authenticated partners can also pass through origin fields. These are optional and present only when the partner sets them:
  • origin_address - the actual end user behind a partner router (the from address).
  • origin_target - the to address at the end of the partner’s flow.
  • origin_source - the upstream partner, when multi-hop partners are involved.
For toxic-flow tracking, key off origin_address when it is present and fall back to taker_address when it is not. Be aware that some sources never set origin_address, and others set it to the transaction origin rather than the true end user.

The source field

Bebop sends a source field when the request comes from an authenticated partner with a valid API key. Open-API requests carry no source and are subject to stricter rate limits and shorter expiries. RFQA requests carry source: rfqa, which tells you the request is protected flow and should be priced under the RFQA regime rather than filtered. source is your coarsest filter. You can denylist a source entirely, or widen spreads for sources you suspect of toxic flow.
Some source values correspond to pricing consumers that use your streamed levels directly. Widening their spreads silently degrades their pricing accuracy and leads to downstream complaints; prefer denylisting over widening when you can identify the source as a pricing consumer.

How to reject

Use the most specific error type that fits:
  • denylist - when the origin_address, taker_address, or source is on your block list. Does not count against your maker standing.
  • rejected - for any other refusal reason. Counts toward your error rate.
Avoid unavailable for policy rejections. It implies a transient outage and counts against you.

Practical patterns

  • Keep a per-source spread multiplier and widen quotes for sources with historically poor PnL.
  • Denylist an origin_address that has sniped you repeatedly.
  • If a specific source never sets origin_address and the flow is consistently toxic, denylist the source.
  • Bebop maintains an internal OFAC denylist; those addresses never reach you.

RFQA: protection at execution

RFQA requests settle through the BebopRouter, which applies maker protection on-chain at execution time. Because that protection operates at the contract level, RFQA does not expose the end user: taker_address and receiver are the BebopRouter, and the request carries source: rfqa.

Toxic-flow checker

The router runs an on-chain check on every swap. Using on-chain heuristics and known toxic-taker patterns, if a swap is predicted to be toxic - atomic arbitrage, for example - the checker attaches a fee large enough that the activity becomes unprofitable, and the swap does not execute.

Oracle slippage protection

The Bebop oracle combines the Binance mid price with on-chain pool prices into a fair reference price, pinned at quote time. At execution it re-checks the live on-chain price against that reference:
  • Price moved against you since signing. The oracle measures the gap as slippage, the router deducts it from the taker’s output and refunds it to you. This is what protects you when a taker sits on a quote and executes only once the market has moved in their favour.
  • Price moved in your favour, or did not move. No slippage is applied; you keep the full positive slippage.
The mechanism is asymmetric: it can only ever help the maker. It never reduces what you receive below your quote; it only returns value to you when the market turned against you between signing and execution.

Slippage split

Recovered slippage is split between the maker and the Bebop protocol treasury. The current split is 50% maker, 50% protocol.