Routers

Routers

TL;DR – Why AEGIS DFM Is the Least‑Surprise Dynamic‑Fee Hook for Aggregators

  • Deterministic pricing. Every fee component is a pure, on‑chain function.

  • “Never‑higher” guarantee. Your user pays ≤ the fee you simulated 99.75 % of the time …

  • Edge‑case bounded & predictable. That surge fee hits exactly one follower trade, then linearly decays to zero over the next few hours.

  • No exotic math. Pool invariant stays constant‑product; keep your usual Uniswap‑V3/V4 price‑impact logic.

  • Gas‑friendly. The only extra storage write burdening swaps is the oracle observation, similar to Uniswap V3.


1 — How the Fee Works

Base fee

File & line: DynamicFeeManager.sol 180‑222 Logic: Clamps between per‑pool min / max using on‑chain volatility (maxTicksPerBlock).

Surge fee (only after a cap event)

Step
What happens

Trigger

If a single block’s tick‑move exceeds maxTicksPerBlock, TruncGeoOracleMulti (150‑169) sets capStart

Cap trade

Pays no surge (fee = base)

First follower trade

Pays base + surge

Subsequent trades

Surge decays linearly to 0 over decaySecs (228‑252)

Public view for routers

function getFeeState(bytes32 poolId)
        external view returns (uint24 base, uint24 surge);

Returns the exact numbers the next swap will use—no hidden maths.

No invariant changes

Permission bitmap excludes beforeModifyPosition; only swap callbacks enabled (Spot.sol 90‑111). Constant‑product forever.

2 — Why This Beats Other Dynamic‑Fee Hooks

Usual pain‑point

Typical dynamic hooks

AEGIS DFM

Hidden admin fee changes

Upgradeable proxies, opaque owner calls

On‑chain fee logic

Fee can spike after simulation

No public pre‑swap view

getFeeState() = what you will pay (unless rare cap)

Multiple paths to fee inflation

Policy gates, beforeModifyPosition

Single path (cap event) + bounded surge

Complicated invariants

Logistic/TWAMM curves

Same xy = k maths you already implement

3 — Optional “Extra” Steps

  1. Whitelist byte‑code hash (one‑time).

  2. Display live fee to users via the same getFeeState() call.

Last updated