All vulnerabilities
CRITICALWeb3exploited in the wild

WEB3-CONIC-2023

Web3 · Ethereum · Conic Finance

Summary

On 21 July 2023 Conic Finance's ETH Omnipool on Ethereum lost roughly 1,700 ETH, about $3.6 million, to a read-only reentrancy attack. The attacker flash-loaned around $134 million, deposited into the Curve rETH pool, then called Curve's remove_liquidity(), which sends ETH to the recipient before the pool's totalSupply and balances are finalized, triggering the attacker contract's fallback during an inconsistent intermediate state. Inside that callback the attacker re-entered ConicEthPool.withdraw(), causing Conic's Curve LP oracle to value the LP token from Curve's virtual price and totalSupply while the pool was mid-operation, returning an inflated price. Conic's reentrancy guard was bypassed because its _isETH check assumed Curve v2 ETH pools list the native ETH placeholder address (0xEeee...EEeE) as a coin, whereas they actually use the WETH address, so the guard never fired. The inflated valuation let the attacker mint excess cncETH and withdraw more than deposited.

How to avoid it in your code

  • Never read Curve get_virtual_price() or totalSupply during a remove_liquidity / ETH-transfer window
  • Call Curve's reentrancy-lock check (e.g. via withdraw_admin_fees) before trusting any LP-token oracle read
  • Validate pool coin assumptions on-chain; do not hardcode ETH vs WETH placeholder addresses to select a guard
  • Treat view/oracle functions as reentrancy-sensitive when they derive prices from external pool state
  • Fuzz oracle reads against pools left in mid-operation inconsistent states

References

Related vulnerabilities

All Web3 →