Reproduced Exploit

Ammplify — H-11: Segment-split geometric-mean borrow overstates taker fees

1. Full-range borrow at one GM tick is the economically intended base. 2. Segment tree stores liq in multiple nodes; each uses its own GM. 3. Sum of segment borrows ≫ full-range borrow (convexity of amounts vs tick). 4. Fee = rate × inflated base → takers overcharged.

Sep 2025Otheruntagged2 min read

Chain

Other

Category

untagged

Date

Sep 2025

Source

AuditVault

EVM Playground

Source-level debugger — step opcodes and Solidity in sync

evm-hack-analyzer

The attack is replayed in an in-browser EVM preloaded with the exact dumped fork state. The execution tree shows every call; step by Solidity line or by opcode across all depths — source, Stack, Memory, Storage, Balances (native / ERC-20 / NFT), Transient storage and Return value stay in sync. Click a tree node, opcode, or source line to jump. No backend, no live RPC.

Loading fork state…

Source & credit. Reproduction of a public audit finding curated by AuditVault — the original finding: 63177-h-11-takers-pay-significantly-higher-fees-than-expected-due. Standalone Foundry PoC and full write-up: 63177-h-11-takers-pay-significantly-higher-fees-than-expected-due_exp in the evm-hack-registry mirror.


Vulnerability classes: fee-calculation · wrong-state

Reproduction: self-contained Foundry PoC with only forge-std. Full trace: output.txt.

AuditVault taxonomy: severity/high · sector/dex · platform/sherlock · fee-calculation · wrong-state


Key info#

ImpactHIGH — takers overpay fees (segment sum ≫ full-range borrow)
ProtocolAmmplify
Vulnerable codecomputeBorrows uses per-segment geometric mean; tree split inflates sum
Finding#63177 / issue 452 · panprog
Compiler^0.8.24

TL;DR#

  1. Full-range borrow at one GM tick is the economically intended base.
  2. Segment tree stores liq in multiple nodes; each uses its own GM.
  3. Sum of segment borrows ≫ full-range borrow (convexity of amounts vs tick).
  4. Fee = rate × inflated base → takers overcharged.

The vulnerable code#

SOLIDITY
int24 gmTick = lowTick + (highTick - lowTick) / 2; // @> VULN: per-segment GM
// FIX: compute full-range borrows once, split by width

Diagrams#

flowchart TD A["Taker range spanning many nodes"] --> B["Each node computeBorrows at own GM"] B --> C["Sum segment borrows"] D["Full-range GM borrow"] --> E["Expected base"] C --> F["Inflated base"] E --> G["Fee expected"] F --> H["Fee charged much higher"]

Sources#


Sources & further analysis#

Reproductions & code

Alerts & third-party analyses

  • Web3Sec X hacked database: search.
  • Rekt leaderboard: search.
  • Solodit incident search: search.

These dashboards index community alerts tweets, post-mortems, and independent write-ups. Reach them through the protocol name above to cross-check this reproduction against other analyses.