Skip to content
Request an audit

Takers pay significantly higher fees than expected due to borrow amounts being split across segments

TitleTakers pay significantly higher fees than expected due to borrow amounts being split across segments
Reward$4432, Unique
ContestAmmplify - 2 Sep 2025 on Sherlock
Authorpanprog
ContextFee Logic

When takers pay their fees, the taker rate is applied to amounts of token0 and token1 derived from the geometric mean price of the interval, in Data.computeBorrows:

solidity
int24 gmTick = lowTick + (highTick - lowTick) / 2; // The tick of the geometric mean.

For example, if there is 1e18 taker liquidity in the [-122880..245760] range, the borrow amounts for this interval should be:

  • borrowX = 0.046e18
  • borrowY = 21.6e18

The issue is that taker liquidity is stored in a segment tree, so internally the range is broken into two segments. The amounts of token0 and token1 are then calculated from the geometric mean of each segment rather than the original price, which inflates the borrow amounts badly:

  • for [-122880..0]: borrowX = 20.6e18, borrowY = 0.044e18
  • for [0..245760]: borrowX = 0.00214e18, borrowY = 464.7e18

These sum to borrowX = 20.6e18 and borrowY = 464.8e18, at least 200x the expected borrow amount.

With a 10% taker rate, the taker expects to pay 0.0046e18 token0 and 2.16e18 token1. Because of how the liquidity is stored and calculated, they actually pay 2.06e18 token0 and 46.48e18 token1.

Alpha: the fee paid varies with the state — specifically the number of segments at that moment — which is inconsistent and always worth reporting. Check that fees are consistent for the same outcome.

Conclusion

This finding would earn you $4432. It requires knowing exactly how the fees work, and how much they can vary for the same outcome.

Full Report
Codebase

Message on Telegram All 62 posts