Skip to main content
Penalty-curve model enables dynamic fees in step 5. It is the part where MEV bots really receive what they deserve. The hook charges every swap a small baseline fee (0.1%), plus an extra penalty if the swap’s priority fee is unusually high compared to the recent reference median. The penalty only kicks in past a threshold, then grows smoothly up to a hard cap. To decide the penalty, the hook first computes the ratio of the swap’s priority fee to the reference median priority fee. If that ratio is above 2.7x, the penalty kicks in (see The formula below for the exact math). Check the table below to see what ratio will result in what total fee. So the penalty curve looks like this:
Frame 49
We can see it is 1.5 curve that has delayed start and has a strict 10% penalty cap.

Design questions

Why is the basic fee 0.1%?

2

Why does the penalty start only from 2.7x?

1

Why is the cap 10%?

3

The formula

The curve is computed on-chain with the formula below, using OpenZeppelin’s Math library.

Why frac^1.5 and not a “real” power function

Solidity has no cheap general pow for fractional exponents. But frac^1.5 can be rewritten as:
and sqrt is cheap on-chain via Math.sqrt. So the whole curve costs one multiplication and one integer square root, with no fixed-point ln / exp / pow library needed.

Constants

Formula → code mapping

How this looks in the code

All fixed-point math here uses two scales: PRECISION = 1000 for the ratio (so 2700 means “2.7x”), and WAD = 1e18 for the fractional-exponent part.

Notes

  • M (reference median) is a smoothed value, not the live running median directly — see [link] for how it’s derived.
  • Edge case: if referenceMedian <= 0 (no data yet), getDynamicFee_ returns BASIC_FEE directly, skipping the ratio/penalty calculation to avoid division by zero.

Key takeaway

  • Every swap pays a flat 0.1% baseline.
  • Nothing extra is charged until the priority fee is 2.7x the reference median.
  • Above that, a smooth frac^1.5 curve adds up to 10% more, saturating at 10x.
  • The whole thing is computed with one multiplication and one Math.sqrt, cheap enough to run on every swap.
Last modified on August 10, 2026