Calculated from recorded token losses using historical USD prices at the incident time.
0x06d7e7436414c658a33452d28400799f3637e83930dcec39b3bd065dabc6ef040x9700204d77a67a18ea8f1b47275897b21e5efa97EthereumOn Ethereum mainnet block 19291250, transaction 0x06d7e7436414c658a33452d28400799f3637e83930dcec39b3bd065dabc6ef04 exploited ETH loan contract 0x9700204d77a67a18ea8f1b47275897b21e5efa97 by manipulating the on-chain spot price of ZoomerCoin collateral. The attacker used a 200 WETH Balancer flashloan, bought ZoomerCoin on the public ZoomerCoin/WETH Uniswap V2 pair 0xc2c701110de2b9503e98619d9c9e3017877b0f72, opened five loans through fresh borrower contracts while the spot price was inflated, sold the remaining tokens back into the pair, repaid the flashloan, and kept 13.935089217255456609 ETH in net profit.
The root cause is that victim selector 0x72c4cff6 priced collateral directly from same-transaction Uniswap V2 reserves and transferred ETH immediately. That design let the attacker control the collateral valuation at the exact moment the victim computed loan proceeds, producing five undercollateralized loans and draining almost all ETH liquidity from the contract.
The victim contract functioned as an ETH lender against ERC-20 collateral. Fork-based inspection of the deployed contract at block 19291249 shows FEE() = 0.02 ETH, INTEREST_RATE() = 6, LOAN_DURATION() = 864000, and an ETH balance of 17.300097602045297868 ETH before the exploit. The same inspection shows the contract resolves collateral prices through the canonical Uniswap V2 factory at .
0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6fZoomerCoin traded against WETH on pair 0xc2c701110de2b9503e98619d9c9e3017877b0f72. Pair-verification evidence confirms that address is a verified UniswapV2Pair, and the codehash matches the canonical Uniswap V2 pair implementation. ZoomerCoin's verified source also shows state variables that govern sell-tax reduction, and the exploit pre-state had _buyCount > _reduceSellTaxAt, so dumping the purchased ZoomerCoin back into the pool was not blocked by a punitive sell tax.
The attacker did not need privileged access. The entire sequence relied on public components: Balancer Vault 0xBA12222222228d8Ba445958a75a0704d566BF2C8, Uniswap V2 router 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D, the verified ZoomerCoin token 0x0d505c03d30e65f6e9b4Ef88855a47a89e4b7676, and the victim loan contract.
The vulnerability class is a flashloan-amplified price-manipulation attack against collateral valuation. The victim accepted a manipulable Uniswap V2 spot reserve reading as the source of truth for collateral value. It performed that price read after receiving borrower-supplied collateral and before transferring ETH to the borrower. Because the attacker could first move the Uniswap pool with borrowed capital inside the same transaction, the pool state that the victim observed was attacker-controlled rather than market-stable.
The relevant safety invariant is straightforward: newly originated debt must be bounded by a manipulation-resistant value of the posted collateral. The victim violated that invariant by reading live same-transaction reserves and immediately sending ETH. The per-address single-loan rule did not mitigate the issue because the attacker instantiated five fresh borrower contracts in the same transaction, bypassing storage keyed only by borrower address.
The critical breakpoint is inside selector 0x72c4cff6, where the victim transfers collateral in, looks up the token/WETH pair, reads getReserves(), branches on token0(), computes the payout using those live reserves and the stored 6% parameter, then transfers ETH to the caller and records the loan.
Fork inspection of the victim contract at the pre-state block produced the following evidence-backed execution outline:
- msg.value must equal slot 0x05, which matches FEE() = 0.02 ETH
- token.transferFrom(msg.sender, address(this), amount)
- factory.getPair(token, WETH)
- pair.getReserves()
- pair.token0() and token-order branch
- payout computation using slot 0x07, which matches INTEREST_RATE() = 6
- ETH transfer to CALLER
- loan record write keyed by CALLER
That structure is sufficient to explain the exploit. The victim performs no TWAP lookup, oracle sanity check, delayed settlement, or anti-flashloan guard before disbursing ETH. The attacker therefore used Balancer flash liquidity to buy ZoomerCoin first, causing the ZoomerCoin/WETH pool to reflect an artificially high WETH-denominated token price. While that inflated state was live, newly created borrower contracts called the victim with the exact 0.02 ETH fee and pledged ZoomerCoin quantities selected from the observed exploit sequence.
The post-state loan records confirm that the exploit created five active debts:
loans(0x86f6...aa8dc) = [ZOOMER, 30265400e18, 3.785511883118999207 ETH debt, active]
loans(0x06ba...bc40a) = [ZOOMER, 30265400e18, 3.785962093155396659 ETH debt, active]
loans(0x2e03...c4db2) = [ZOOMER, 30265400e18, 3.786665982721161494 ETH debt, active]
loans(0xc362...89407) = [ZOOMER, 30265400e18, 3.787627152121759302 ETH debt, active]
loans(0x2ec6...3697c) = [ZOOMER, 24047236e18, 3.010413007427848033 ETH debt, active]
After each manipulated loan opening, the attacker transferred leftover ZoomerCoin back to the helper contract and sold it into the same Uniswap pair, recovering enough ETH/WETH-equivalent value to continue the loop. The attacker repeated this process five times in one transaction, then wrapped ETH back into WETH and repaid the 200 WETH Balancer flashloan principal in full.
The balance-diff evidence shows the measurable effect of the root cause. The victim's ETH balance fell from 17300097602045297868 wei to 151726489427391410 wei, a loss of 17148371112617906458 wei (17.148371112617906458 ETH). The attacker's EOA rose from 1.575011944239229928 ETH to 15.510101161494686537 ETH, a net gain of 13.935089217255456609 ETH after gas.
The exploit flow is a single adversary-crafted transaction initiated by EOA 0xb0380b6d7a63e7cbf274c3b3c8838abbd6bd4abe and routed through helper contract 0xa4854022f4c16f0abc3fdec300427f6179a3043b.
First, the helper receives 200 WETH from Balancer Vault via flashloan. Second, it unwraps the WETH and funds a series of five freshly deployed borrower contracts. Each borrower contract spends 199.9 ETH to buy ZoomerCoin from the Uniswap V2 router, approves the victim to take a chosen collateral amount, and calls the victim selector 0x72c4cff6 with the required 0.02 ETH fee.
The core borrower-side behavior is reproduced by the following observed PoC structure, which mirrors the real transaction shape:
IUniswapV2Router02(ROUTER).swapExactETHForTokensSupportingFeeOnTransferTokens{value: BUY_ETH}(
0,
path,
address(this),
block.timestamp
);
IERC20(ZOOMER).approve(VICTIM, collateralAmount);
(bool ok,) = VICTIM.call{value: LOAN_FEE}(
abi.encodeWithSelector(bytes4(0x72c4cff6), ZOOMER, collateralAmount)
);
require(ok, "loan open failed");
Once the victim disburses ETH to a borrower contract, that borrower transfers its leftover ZoomerCoin and ETH back to the helper. The helper immediately sells the remaining tokens back through the router:
IUniswapV2Router02(ROUTER).swapExactTokensForETHSupportingFeeOnTransferTokens(
tokenBalance,
0,
path,
address(this),
block.timestamp
);
The attacker repeats the buy-borrow-sell cycle five times, creating five active loans and draining the victim to roughly 0.1517 ETH. The helper then wraps 200 ETH back into WETH and repays Balancer, leaving the residual ETH profit economically attributable to the attacker cluster and, in the real incident, realized at the originating EOA.
The direct victim is ETH loan contract 0x9700204d77a67a18ea8f1b47275897b21e5efa97. It lost 17148371112617906458 wei, encoded as 17.148371112617906458 ETH, in a single transaction. The contract was left with five active loans backed by ZoomerCoin collateral that only supported those debt amounts under the attacker-manipulated spot price.
The attacker EOA realized 13.935089217255456609 ETH of net profit after gas, as measured directly from the seed balance diff. The difference between victim loss and attacker profit is explained by price-impact effects, round-trip swap friction, and gas expenditure already reflected in the attacker's ending ETH balance.
The report is supported by the following concrete artifacts and identifiers:
0x06d7e7436414c658a33452d28400799f3637e83930dcec39b3bd065dabc6ef040x9700204d77a67a18ea8f1b47275897b21e5efa970x0d505c03d30e65f6e9b4Ef88855a47a89e4b76760xc2c701110de2b9503e98619d9c9e3017877b0f720xBA12222222228d8Ba445958a75a0704d566BF2C8