# Curve Read-only Reentrancy can increase the price of some CurveStableCollateral

Curve plain pools with raw ETH burn LP tokens before transferring ETH, so read-only reentrancy inflates CurveStableCollateral's LP price via stale totalSupply.

- Payout: Contest reward
- Severity: medium
- Program: Reserve
- Credited: ronnyx2017
- Disclosed: 2023-11-13
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2023-07-reserve-findings/issues/45
- Library page: https://bugbountylibrary.com/r/c4%3A2023-07-reserve%3AM-01
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:oracle-manipulation vuln:reentrancy

**Target:** CurveStableCollateral LP price oracle over Curve plain pools (eth/stETH)
**Root cause:** Curve remove_liquidity burns LP tokens before transferring out coins; during the raw ETH fallback, totalSupply is reduced while other coins remain in the pool, so aum/supply is inflated.
**Steps:**
1. Identify a CurveStableCollateral backed by a Curve Plain Pool containing raw ETH (e.g. eth/stETH 0xdc24...7022).
2. Call `remove_liquidity` on the pool; observe `burnFrom(msg.sender, _amount)` executes before coin transfers.
3. During the raw ETH `raw_call` fallback, reenter Reserve's `refresh()`/price path.
4. `totalBalancesValue()` still counts remaining coins while `lpToken.totalSupply()` is already reduced, inflating `aumLow/supply`.
5. Use inflated refPerTok to misprice collateral.
**How found:** Noticed Curve plain pools with native ETH burn LP before transferring coins, then checked Reserve's price formula dividing totalBalancesValue by lpToken.totalSupply, spotting the inconsistency window.
**Exploitation:** Attacker triggers remove_liquidity, and in the ETH fallback reenters the collateral's price refresh so the LP token is valued with reduced supply but full AUM, enabling overvaluation of collateral.
**Insight:** For read-only reentrancy, check whether the LP price oracle reads totalSupply and pool balances at points where Curve burns LP before paying out native ETH; raw-ETH plain pools (not just ERC777) create the window.
