# UniV3Vault.sol#collectEarnings() can be front run

UniV3Vault's tvl() excluded unharvested LP fees, letting an attacker deposit before collectEarnings() and withdraw after to steal half the pending yield.

- Payout: Audit contest
- Severity: high
- Program: Mellow Protocol
- Found by: WatchPug
- Disclosed: 2022-02-09
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2021-12-mellow-findings/issues/98
- Library page: https://bugbountylibrary.com/r/c4%3A2021-12-mellow%3AH-03
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:race-window technique:source-review vuln:accounting-error vuln:business-logic

**Target:** UniV3Vault.sol (Uniswap V3 vault strategy contract)
**Root cause:** tvl() computed share price from pool balances only, excluding unclaimed trading fees (tokensOwed), so shares were underpriced relative to pending yield until collectEarnings() reinvested them.
**Steps:**
1. Observe strategy is about to call `collectEarnings()` (mempool) with pending fees of 1 ETH + 4000 USDC against tvl 10 ETH + 40000 USDC.
2. Front-run with higher gas: `deposit(10 ETH, 40000 USDC)` to acquire 50% of shares at pre-harvest price.
3. collectEarnings() executes, reinvesting fees into tvl.
4. Call `withdraw()` to redeem 10.5 ETH + 42000 USDC, capturing half the pending yield.
**How found:** Code review of tvl() vs collectEarnings(): noticed unharvested fees are not reflected in tvl(), so share price jumps at harvest — a classic sandwichable value accrual.
**Exploitation:** Attacker watches mempool for collectEarnings(), deposits an amount equal to current tvl at higher gas to take ~50% share, lets harvest land, then withdraws to pocket half the newly-included fees in ~1 block.
**Insight:** When a vault's share price only updates at an explicit harvest/rebalance call, check whether accrued-but-unclaimed yield is in the pricing function; if not, deposit-before/withdraw-after harvest is a reliable sandwich.
