Crypto exploits

PositionManager exploit analysis

The vault's deposit valued its existing USDT against the manipulable PancakeSwap V3 slot0 spot price (BTCB priced by a sound Chainlink feed), so crashing the spot made deposit() mint inflated shares that withdraw() redeemed in the same transaction for 32,080.60 USDT profit on BNB Chain.

David

Security ·

Reported loss
32,080.604282 USDT net to the attacker; USDT/BTCB pool lost 32,096.098596 USDT on its side, per DeFiHackLabs
Occurred
Logged
Chain
BNB Chain

Logged as “2026-09-30: Deposit Values The Vaults Existing Usdt At The Manipulable”.

Analysis2 min read

The PositionManager vault priced its own holdings with a hybrid that used a sound Chainlink feed for BTCB and the manipulable PancakeSwap V3 slot0 spot for USDT. deposit(uint256) is permissionless with no TWAP or deviation guard, and its share formula put the spot-priced USDT in the denominator. Crash the spot, denominator shrinks, and deposit mints too many shares. withdraw() is also permissionless and burns shares against the real pool position with no delay, so the inflated shares redeem more value than was deposited in the same transaction. On 30 September 2026, a single atomic transaction on BNB Chain crashed the USDT/BTCB spot price with an 8,000,000 USDT swap, ran 24 deposit/withdraw cycles, and walked away with 32,080.60 USDT net. The USDT/BTCB pool lost 32,096.10 USDT on its side.

The vulnerable contract is the verified PositionManager vault at 0x7cedB2e5d7791c7D46c5C9d35EaC4775bc887F00. Its deposit(uint256) values the vault's holdings to size the new shares it mints, with a formula of the form:

poolPrice = _processedPoolPrice() // slot0 sqrtPriceX96^2 (manipulable) token1Price = _getChainlinkPrice() * PRECISION // BTC/USD (sound) contractLiqInTok1 = amountToken0 * poolPrice / PRECISION + amountToken1 shares = depositAmount * totalSupply / contractLiqInBaseTok

The Chainlink leg is sound, but the USDT side of the vault is converted to BTCB-terms using the spot price. withdraw() then redeems shares pro-rata against the real pool position (PositionManager.sol:187-200) with no delay, no TWAP, and no deviation guard, which is what closes the loop.

The on-chain sequence

The exploit is one transaction (0x8725c09...63da3, block 124,829,770, BNB Chain). The attacker funded it with a 0-fee PancakeSwap Infinity Vault flash loan of 9,000,010 USDT, then:

  • Dumped 8,000,000 USDT into the V3 pool in a single zeroForOne swap, pushing sqrtPriceX96 from 274,452,124,608,361,913,298,767,630 down to 261,748,504,334,048,619,437,859,565. The USDT/BTCB spot now quotes USDT far too cheap.
  • Ran 24 cycles of PositionManager.deposit(1,000,000 USDT) followed immediately by PositionManager.withdraw(). Each deposit minted shares against the depressed spot (too many shares; the denominator is depressed), and each withdraw redeemed those shares pro-rata against the vault's real PancakeSwap V3 position - more USDT came back out than went in.
  • Sold the BTCB the attacker had accumulated back to USDT in the V3 pool, unwinding the manipulation and realizing the drained value.
  • Repaid the 9,000,010 USDT flash loan; net profit 32,080.60 USDT landed at the attacker EOA.

The PoC reproduces the sequence against a BNB Chain fork at block 124,829,769, runs the exact 24 deposit/withdraw cycles, and asserts an attacker net of 32,080.604282546 USDT to 1% tolerance. The deposit sum is 24,000,000 USDT; the attacker ends with 32,080 USDT more than they started (after flash repayment), a clean 8,080 USDT net of fees plus the cycle arbitrage captured across the manipulation window. The vault's own position is the loser: the pool's net USDT balance falls 32,096.10 USDT across the transaction.

What was missing

deposit() and withdraw() should price the vault's USDT against a Chainlink reference (or at least a TWAP with a meaningful window), not slot0. Even partial fixes help: a deviation check between the spot and the TWAP, a withdrawal delay between deposit and withdraw, or a deposit cooldown. The simplest single fix is to use the same Chainlink BTC/USD leg on the USDT side as well, treating USDT as the unit asset rather than re-denominating through a manipulable pool's spot price.

Sources read (3)

Other exploits

Query every incident yourself — free, no signup

Updated 11 Nov 2026. Figures are as reported by the sources listed above and are not independently verified.