# price() in AfEth.sol doesn't take afEth held for pending withdrawals into account

AfEth.price() divides TVL by totalSupply() without excluding afEth escrowed for pending withdrawals, inflating mint amounts and enabling a first-depositor division-by-zero DOS.

- Payout: Contest reward
- Severity: high
- Program: Asymmetry Finance
- Credited: MiloTruck
- Disclosed: 2024-02-06
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2023-09-asymmetry-findings/issues/25
- Library page: https://bugbountylibrary.com/r/c4%3A2023-09-asymmetry%3AH-04
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:business-logic vuln:dos vuln:share-inflation

**Target:** AfEth.sol price()/deposit()/requestWithdraw() share accounting
**Root cause:** requestWithdraw() transfers afEth to the contract instead of burning it, so totalSupply() overstates circulating supply while safEth/vAfEth balances are reduced, making price() too low.
**Steps:**
1. Alice is sole depositor; her afEth balance == totalSupply().
2. Alice calls `requestWithdraw(_amount = totalSupply())`: withdrawRatio = 1e18, all vAfEth burned, pendingSafEthWithdraws set to full safEth balance, afEth transferred to contract.
3. Bob calls `deposit()`; price() computes safEthValueInEth=0 and vEthValueInEth=0, totalSupply()>0, so price() returns 0.
4. `amountToMint = totalValue / priceBeforeDeposit` reverts with division by zero, bricking deposit().
**How found:** Code reading of price() vs requestWithdraw(): noticed afEth is transferred not burned, so totalSupply() diverges from circulating supply while TVL components decrease.
**Exploitation:** Attacker (first depositor) stakes then immediately requests full withdrawal, leaving escrowed afEth in the contract so price() returns 0; every subsequent deposit() reverts, permanently DOSing core protocol functionality. In partial-withdrawal scenarios, depositors mint more afEth than deserved, diluting prior holders.
**Escalation:** Permanent protocol-wide DOS from a single first depositor; also value dilution of existing holders via over-minting.
**Insight:** When a share price divides TVL by totalSupply(), check whether any shares are escrowed/locked in the contract itself (pending withdrawals, vesting, staking) and whether they should be excluded from supply; also test the zero-TVL/nonzero-supply edge for division-by-zero DOS.
