TopazTOPAZDocs

Liquidity

Pool Fees

Every swap on Topaz pays a fee. This page is the complete map: how the fee is set, who collects it, and how the three fee modules (default, custom, dynamic) layer together.

Where fees go

Topaz routes 100% of trading fees to veTOPAZ voters who voted for the pool that earned them — not to a protocol treasury. The voter share for a given epoch is proportional to how much you voted for that gauge, and the fees you can claim today are the fees collected during the prior epoch (synchronized with bribes).

LPs don't collect swap fees on staked v2 LP tokens — those fees are forwarded to the FeesVotingReward contract for voters. LPs earn TOPAZ emissions instead. For Slipstream, the same swap-fees-go-to-voters rule applies to staked positions; an unstaked Slipstream position continues to collect its share of swap fees in-NFT.

The trade-off
v2 LPs and staked Slipstream LPs swap variable swap-fee yield for TOPAZ-denominated emission yield. Unstaked Slipstream LPs keep fees but earn no emissions (and pay an extra unstaked-fee surcharge — see below).

v2 pool fees

v2 pools have a single fee value set per-pool, taken from the input token on each swap. Defaults:

ParameterValueDescription
Stable pool default0.05% (5 bps)Set by PoolFactory.stableFee.
Volatile pool default0.30% (30 bps)Set by PoolFactory.volatileFee.
Maximum allowed3.00% (300 bps)PoolFactory.MAX_FEE — the hard cap for any custom override.

The fee manager (a privileged role on PoolFactory) can change the global default for stable/volatile pools or set a custom fee per pool. There is also a ZERO_FEE_INDICATOR sentinel that lets a specific pool be set to 0% fee — distinguishing it from unset/default behavior.

Slipstream default fees

Slipstream pools use tick spacing as their pool-identity discriminator. Each tick spacing has a recommended default fee at the factory:

ParameterValueDescription
Tick spacing 10.01% (100 pips)Highly correlated pairs (USDT/USDC).
Tick spacing 500.05% (500 pips)Tight-correlated pairs (ETH/stETH, BTC/WBTC) and low-vol blue chips.
Tick spacing 2000.30% (3,000 pips)Volatile blue chips (TOPAZ/BNB, ETH/USDT).
Tick spacing 20001.00% (10,000 pips)Long-tail pairs.

These are the defaults at pool creation; every fee on every pool can be customized by the protocol fee manager via the CustomSwapFeeModule (0%–3% range), and dynamic fees can layer on top.

Note the precision: Slipstream fees are denominated in pips (1 / 1,000,000), so 500 pips = 5 bps = 0.05%. v2 pool fees are denominated in basis points out of 10,000 — a different scale. The frontend always displays percent.

Custom fee module (Slipstream)

The protocol fee manager can override the default fee on any Slipstream pool via the CustomSwapFeeModule:

  • Per-pool overrides — any pool can have any fee between 0% and 3%.
  • Special sentinel: setting fee = 420 (pips) means a true zero-fee pool, distinguishing it from 'unset' (which falls back to the tick-spacing default).
  • Hard cap: 3% (30,000 pips). The fee manager cannot exceed this.

Dynamic fee module (Slipstream)

Some Slipstream pools opt into a volatility-based dynamic fee. The module reads the pool's TWAP and adds a surcharge when the current tick has moved far from the time-weighted average:

totalFee   = min(baseFee + dynamicFee, feeCap)
dynamicFee = |currentTick − twapTick| × scalingFactor / 1e6
twapTick   = TWAP over secondsAgo (default 600s)
  • Stable conditions (tick ≈ TWAP): you pay only the base fee.
  • Volatile conditions: fee rises with the divergence, compensating LPs for elevated IL risk.
  • Capped: every pool that opts in has a feeCap (default 1%); the module never charges more than that.
  • Graceful fallback: if the pool lacks oracle data (low cardinality or fresh pool), the module returns 0 dynamic fee, so users still pay only the base fee.

Dynamic fees are disabled by default (defaultScalingFactor = 0). The fee manager opts a pool in by setting a feeCap and scalingFactor. For more on how TWAP works and BNB Chain cardinality requirements, see Oracles & TWAP.

Unstaked position fee (Slipstream)

To encourage LPs to stake their Slipstream NFTs in gauges (which makes their liquidity vote-weighted), the protocol applies an additional fee to unstaked positions when an alive gauge exists for the pool. The fee is taken at the swap level — unstaked LPs effectively pay a higher share of their fee to the gauge (which then flows to voters).

ParameterValueDescription
Default unstaked fee10% (100,000 / 1,000,000)Of the swap fee paid to unstaked LPs.
Maximum unstaked fee50%The fee manager can set a higher value up to 50% via the CustomUnstakedFeeModule.
Applies whenGauge exists & is aliveNo gauge or killed gauge → no unstaked fee.

Fee resolution order

When a Slipstream swap fires, the pool computes its fee in this order:

1. Read baseFee from dynamicFeeConfig[pool]
   - 420 → zero fee
   - 0   → fall back to factory.tickSpacingToFee(tickSpacing)
   - other → use it

2. Read dynamic fee config:
   - Pool has scalingFactor > 0  → use per-pool config
   - Otherwise                    → use defaultScalingFactor + defaultFeeCap

3. totalFee = min(baseFee + dynamicFee, feeCap)

4. If tx.origin is in the discounts map, apply discount

5. Charge totalFee on the swap input

Aggregator and partner discounts

The dynamic fee module supports per-address discounts, set by the fee manager. Useful for whitelisting aggregators or partner contracts that route significant volume through Topaz. Discount is applied at swap time based on tx.origin, so it benefits the end user even when an aggregator is the msg.sender.

  • Discount precision: 1,000,000 (so 200,000 = 20% off).
  • Maximum discount: 50% (MAX_DISCOUNT = 500,000).
  • Discounts apply to the totalFee after caps. They cannot make a swap unprofitable for LPs by going negative.

Continue reading