Résumé
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.
Comment l’éviter dans votre 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
Références
Vulnérabilités liées
Tout Web3 →- CRITICALWEB3-PENPIE-2024
On September 3, 2024, Penpie, a yield protocol built on Pendle, was drained of about $27.3 million (11,113.6 ETH in wstETH, sUSDe, egETH and rswETH) across Ethereum and Arbitrum. The root cause was a cross-function reentrancy enabled by permissionless market registration: registerPenpiePool trusted any market from Pendle's PendleMarketFactoryV3 without validating the Standardized Yield (SY) token, so the attacker registered a fake market whose SY was their own contract. PendleStakingBaseUpg.batchHarvestMarketRewards (and its internal _harvestBatchMarketRewards) snapshotted reward-token balances before and after calling the market's redeemRewards, but lacked a nonReentrant guard. The malicious SY's claimRewards callback re-entered PendleStakingBaseUpg.depositMarket with flash-loaned Pendle LP tokens mid-accounting, so the deposit was misattributed as harvested rewards, inflating the attacker's reward balance. Although depositMarket itself carried a nonReentrant modifier, the two functions did not share a lock, so the unguarded harvest path let the attacker re-enter the guarded deposit path and claim the inflated rewards via MasterPenpie.multiclaim.
- CRITICALWEB3-CURVE-VYPER-2023
On July 30, 2023 several Curve Finance native-ETH stable pools were exploited via a compiler/toolchain supply-chain bug in specific Vyper versions (0.2.15, 0.2.16, 0.3.0). The compiler's storage-slot allocator assigned every @nonreentrant(key) decorator its own unique storage slot instead of reusing one shared slot per key, so functions meant to share a single reentrancy lock each got an independent, separately-set lock. This left the guard effective against single-function reentrancy but defeated cross-function reentrancy, letting an attacker re-enter a different guarded function via the native-ETH transfer callback while balances were mid-update. WETH-paired pools were unaffected; the exploited native-ETH pools included CRV/ETH, pETH/ETH, msETH/ETH and alETH/ETH, impacting Alchemix, JPEG'd and Metronome. Gross losses were around $61M; white-hat actors and MEV bots such as c0ffeebabe.eth returned a significant portion, reducing net losses to roughly $52M.
- CRITICALWEB3-EULER-2023
On March 13, 2023 Euler Finance, an Ethereum DeFi lending protocol, was drained of roughly $197M across DAI, wBTC, stETH and USDC. The root cause was a missing health check in the donateToReserves function, which let a user transfer eTokens to the protocol's reserves without any solvency verification. Funded by a ~$30M Aave flash loan, the attacker used Euler's leveraged minting (up to ~19x) to build a position of roughly 410M eDAI against 390M dDAI, then called donateToReserves to push the account into bad debt (insolvency) on purpose. They then self-liquidated through a second address; Euler's soft-liquidation logic applied a steep discount that grew with account unhealthiness, paying the liquidator far more collateral than the outstanding debt, which produced the profit after the flash loan was repaid. The attacker, identifying as 'Jacob', subsequently returned essentially all of the stolen funds, with Euler confirming full recovery in early April 2023.
- CRITICALWEB3-RARI-FEI-2022
On 30 April 2022 the Rari Capital / Fei Protocol Fuse lending pools on Ethereum lost approximately $80 million (about $79.7 million across ETH, FEI, DAI, LUSD and USDC). Fuse pools were a fork of Compound's CToken, but the CEther contract sent ETH using low-level call.value() instead of Compound's gas-capped transfer(), forwarding all remaining gas to the recipient's fallback. The borrow() function called doTransferOut(), which performed that call.value() ETH transfer to the borrower before the borrow and collateral accounting was finalized, violating checks-effects-interactions. The attacker's fallback re-entered the Comptroller's exitMarket() while the deposited collateral was still counted as backing the loan, freeing the collateral while keeping the borrowed ETH; the Comptroller's reentrancy guard did not cover exitMarket on the affected pools. Funded by Balancer flash loans, this cross-contract reentrancy drained seven pools.
- CRITICALWEB3-BEANSTALK-2022
On April 17, 2022, the Beanstalk stablecoin protocol was drained of about $182 million in a governance attack amplified by a flash loan, netting the attacker roughly $80 million after repaying the loan. The attacker borrowed about $1 billion across Aave and other venues (350M DAI, 500M USDC, 150M USDT plus BEAN and LUSD), deposited it into Curve to mint roughly 795M BEAN3CRV-f and 59M BEANLUSD-f LP tokens, and supplied them to Beanstalk's Silo to instantly hold a supermajority (over 78%, above the two-thirds threshold) of STALK governance power. Beanstalk's emergencyCommit path let a proposal pass once 24 hours had elapsed and a two-thirds vote existed; the attacker had pre-submitted a malicious BIP (BIP-18) whose init contract transferred the protocol's funds, then executed emergencyCommit in a single transaction. The core flaw was that voting power could be acquired flash-loan-instantly with no time-lock against single-block voting. Funds were laundered through Tornado Cash and never recovered; the attacker remains anonymous.
- CRITICALWEB3-GRIM-2021
On 18 December 2021 Grim Finance, a yield-optimizer vault protocol on Fantom, lost approximately $30 million. The vulnerable depositFor() function in the GrimBoostVault contract let the caller pass an arbitrary token address, pulled it via safeTransferFrom(), and computed the deposited amount as the balanceOf difference before and after the transfer to mint vault shares. The function had no reentrancy guard and did not whitelist the token, so the attacker supplied a malicious contract whose safeTransferFrom handed control flow back mid-execution, functionally an ERC-777-style pre-transfer hook. The attacker re-entered depositFor() five times before any frame finalized its share accounting; because each nested frame observed overlapping cumulative balance snapshots, the outer call was credited roughly five times the collateral actually deposited, over-minting shares against a flash-loaned position that was then redeemed to drain the vaults. This was an arbitrary-token-callback cross-function reentrancy.