Reproduced Exploit

Ammplify — H-8: Uninitialized Uniswap ticks inflate `getInsideFees` (funds stuck)

1. Open maker while ticks uninitialized and price inside range. 2. Snapshot stores feeGrowthInside = feeGrowthGlobal (inflated). 3. Settle initializes ticks; later getInsideFees returns ~0. 4. compound does new - stored → underflow; funds stuck forever.

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: 63174-h-8-incorrect-inside-fees-calculation-for-uninitialized-unis. Standalone Foundry PoC and full write-up: 63174-h-8-incorrect-inside-fees-calculation-for-uninitialized-unis_exp in the evm-hack-registry mirror.


Vulnerability classes: fee-calculation · locked-funds · data/uninitialized

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

AuditVault taxonomy: severity/high · sector/dex · platform/sherlock · fee-calculation · locked-funds · data/uninitialized


Key info#

ImpactHIGH — position permanently stuck (underflow); also enables fee inflation theft
ProtocolAmmplify
Vulnerable codePoolLib.getInsideFees treats uninitialized tick outsides as 0 → inside = global
Finding#63174 / issue 422 · panprog
StatusFixed PR #32
Compiler^0.8.24

TL;DR#

  1. Open maker while ticks uninitialized and price inside range.
  2. Snapshot stores feeGrowthInside = feeGrowthGlobal (inflated).
  3. Settle initializes ticks; later getInsideFees returns ~0.
  4. compound does new - stored → underflow; funds stuck forever.

The vulnerable code#

SOLIDITY
feeGrowthInside0X128 = feeGrowthGlobal0X128 - lowerFeeGrowthOutside0X128 - upperFeeGrowthOutside0X128;
// @> VULN: uninitialized outside=0 → inside = global
// FIX: if tick not initialized, return 0

Diagrams#

flowchart TD A["Open on uninit ticks"] --> B["Snapshot inside = feeGrowthGlobal"] B --> C["Mint initializes ticks"] C --> D["Later getInsideFees ~ 0"] D --> E["0 - global underflows"] E --> F["Position permanently stuck"]

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.