Logo
·Blog

How a Pricing Bug in a Uniswap v4 Hook Drained $27K

Ngọc Kiệt

The VTSwapHook.sol exploit did not originate from Uniswap v4's core protocol. Instead, it stemmed from a custom hook - a piece of bespoke logic that the project itself wrote and attached to the pool. At its core, the incident combined two distinct bugs: a pricing error in a logarithmic price curve using ln(), and a reserve inflation flaw in the internal reserve update logic.

When layered on top of Uniswap v4's unlock() callback mechanism, the attacker executed repeated T → VT → T swap cycles — swapping from the base token into VT, then back — within a single flow. Consequently, small rounding errors compounded into real profit. According to Defimon Alerts, the attacker exploited exactly these two vulnerabilities to extract approximately $27,000, while Defimon's bot managed to rescue a portion of remaining assets.

The Protocol Nobody Was Watching

Zoo Finance is a DeFi project built around a "structured protocol" model — one designed to enhance liquidity efficiency and bring on-chain infrastructure assets into financial products. Publicly, the protocol develops a Liquid Node Token (LNT) model, which tokenizes and fractionalizes ownership of node or infrastructure operation licenses. This architecture allows broader user participation and improves tradability for assets that are otherwise highly illiquid.

Within the Reppo ecosystem, Zoo Finance serves as the liquidity and tokenization layer for the Liquid Node Sale model. Critically, the exploited component in this incident was not Uniswap core — it was the custom Uniswap v4 hook tied to Zoo Finance's trading logic.

Uniswap v4 enables each pool to attach a hook that customizes behavior during swaps, liquidity additions, or settlement — the final step where asset balances are reconciled after a chain of operations. This is a major leap in composability, but it also shifts the attack surface away from the core protocol and toward application-layer logic that individual projects write themselves. Research from Hacken – Auditing Uniswap v4 Hooks and CertiK – Uniswap V4 Hooks Security Considerations consistently highlights hooks as a high-risk area for economic bugs - particularly when projects introduce custom pricing, custom accounting, or complex callback flows.

In this case, the exploited hook was VTSwapHook.sol. As Defimon Alerts confirmed, this was a pricing error in a Uniswap v4 hook, not a flaw in Uniswap's core. Notably, the entire exploit moved extremely fast - compressing multiple dependent operations into a single callback flow, amplifying both the mathematical and accounting discrepancies before the market could respond.

Two Small Bugs. One Very Expensive Mistake.

This exploit was not a straightforward fund extraction. It was a form of iterative price manipulation built on arithmetic errors and accounting inconsistencies. The attack breaks down into three distinct layers.

The Math Looked Fine, Until It Wasn't

Rather than a standard constant product invariant - the model where an AMM keeps the product of two reserves nearly fixed - this hook implemented a nonlinear price curve based on ln(). Inside VTSwapHook.sol, the contract computes lnTerm from a logarithmic expression.

The core problem: the execution price was not derived from a precise integral of the curve. Instead, the contract approximated it by averaging the price before and after the swap - a classic midpoint approximation.

The lnTerm calculation inside VTSwapHook.sol
The lnTerm calculation inside VTSwapHook.sol
The code computing price_final = (price_before + price_after) / 2 — the midpoint approximation that Defimon identified as the root cause
The code computing price_final = (price_before + price_after) / 2 — the midpoint approximation that Defimon identified as the root cause

For any nonlinear function, midpoint approximation is not price-neutral. Each individual swap may introduce only a tiny error. However, as Defimon's analysis demonstrates, this error skews consistently in one direction, systematically favoring the swapper beyond fair value. Specifically, once that directional bias exists inside a loop, the pricing error stops being a harmless rounding artifact and becomes an extractable profit source.

The Pool Was Counting Money It Never Received

If the pricing error is the first layer, the accounting bug is the second, and it prevents the system from self-correcting. A properly designed pool should only record the net tokens received into its reserves after fees are deducted. In this hook, however, the internal reserve updates using specifiedAmount before fees, while the output calculation uses the reduced post-fee amount - the net input actually received by the pool.

Reserve updated against specifiedAmount, inflating virtual reserves even when the pool receives fewer real tokens.
Reserve updated against specifiedAmount, inflating virtual reserves even when the pool receives fewer real tokens.

The result: internal reserves grow faster than the real token flow entering the pool. This is precisely what Defimon described as "fee delta inflates virtual reserves without real tokens." Furthermore, once virtual reserves become inflated, the pricing error no longer stays isolated to a single transaction — it compounds with every subsequent swap iteration.

Rinse, Repeat, Drain

When these two flaws interact, the attacker gains access to a dangerous self-reinforcing cycle:

  • A T → VT swap overpays the attacker due to midpoint pricing.
  • The internal reserve updates against the gross input, becoming artificially inflated.
  • The price curve reads the inflated reserve and produces an even softer quote.
  • The attacker swaps back VT → T and repeats the cycle.

The table below compares a normal swap flow against the actual attack flow:

Normal flow vs. attack flow - illustrating how each layer of the exploit stacks.
Normal flow vs. attack flow - illustrating how each layer of the exploit stacks.

The most dangerous characteristic here is that each cycle does not need to generate large profit. As long as each round produces a net positive return and the loop runs fast enough, the attacker compounds small errors into a meaningful payout.

Why This Exploit Is Harder to Catch Than It Looks

This incident illustrates several structural patterns worth understanding clearly.

First, this is a textbook economic exploit - no reentrancy, no admin takeover, no broken cryptographic primitive. The attacker simply discovered that the system was mispricing outputs and misrecording state, then forced both errors to repeat enough times to matter.

Second, neither bug is visible in isolation. Reading only the ln() pricing function or only the reserve update function might lead an auditor to underestimate the severity. In contrast, placing them together inside a swap → reserve update → re-quote → swap loop makes the compounding effect immediately apparent. The vulnerability lives in the interaction between pricing, accounting, and callback execution - not in any single line of code.

Third, Uniswap v4's unlock() mechanism was the key accelerant. According to Uniswap's official documentation and the IUnlockCallback interface, a caller can batch multiple operations inside a single callback and settle at the end. The attacker exploited this to execute 20+ alternating swaps within one flow, exactly as Defimon described.

If You're Building or Auditing Hooks, Read This Carefully

For Builders

The most important takeaway: never underestimate arithmetic error in a custom curve. If a hook uses nonlinear pricing, the team must either derive the output from a mathematically exact integral or formally bound the approximation error and prove its directional neutrality. A small error with a consistent directional bias is already sufficient for exploitation if it can be repeated inside a callback.

Furthermore, reserve accounting must always reflect net tokens received — not nominal input. Any pool where internal reserves can diverge from actual token balances eventually turns its pricing state into a phantom. Specifically for Uniswap v4 hooks, all custom accounting logic must be stress-tested against round-trip swaps (T → VT → T), multi-step swaps, and extended callback chains.

For Auditors

This case is a direct reminder that auditing a hook cannot stop at access control or reentrancy checks. Auditors need to examine:

  • The error characteristics of any custom math
  • The directional bias of that error
  • The consistency between fee logic and reserve logic
  • The potential for error compounding inside unlockCallback
  • The attacker's net profit when alternating swaps run repeatedly in a single flow

Testing "does a single swap behave correctly" is insufficient. Auditors must test behavioral sequences — especially round-trip cycles that can expose anomalous positive profit.

Your Hook Security Checklist, Before the Next Exploit Happens

Based on this case, the following should be treated as mandatory checks for any future custom hook:

  • Verify economic invariants after every callback chain
  • Apply fuzzing to alternating swaps and round-trip swap sequences
  • Cross-validate internal reserves against actual on-chain token balances
  • Run stress simulations within a single unlock() flow
  • Clearly separate gross input, net input, and fee delta in all accounting logic

For ongoing monitoring of this incident, the three primary sources are: Defimon's original alert, the VTSwapHook.sol source code, and the referenced transaction on Arbiscan.

The Takeaway Nobody Wants to Hear

The VTSwapHook.sol incident is a defining case study for modern DeFi security. No flashy vulnerability was needed - just an imprecise price approximation and a misstated reserve update between gross and net values. Together, they were enough to construct a working exploit. When both flaws exist inside an environment with the callback composability of Uniswap v4, the attacker needs nothing more sophisticated than repeating what is already profitable.

The most critical insight from this case: in DeFi, a small error that repeats with directional bias is no longer just an error. It is alpha for the attacker.

Author: Ngoc Kiet, Security Research member of A-Star Group

Compiled by Dieu Anh

@ 2026 All rights reserved by A-star Group.

PRIVACY POLICY

TERM OF SERVICE