# Vault::takeFees can be front run to minimize accruedPerformanceFee

Vault highWaterMark updates on any deposit/mint/withdraw, so a dust withdrawal front-runs takeFees and zeroes accrued performance fees.

- Payout: Contest reward
- Severity: medium
- Program: Popcorn
- Credited: immeas
- Disclosed: 2023-09-07
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-01-popcorn-findings/issues/780
- Library page: https://bugbountylibrary.com/r/c4%3A2023-01-popcorn%3AM-03
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:business-logic vuln:fee-bypass

**Target:** ERC4626-style Vault fee accounting (takeFees/highWaterMark)
**Root cause:** highWaterMark is rewritten on every deposit/mint/withdraw interaction rather than only when fees are accrued, so any share-changing call resets the profit baseline used to compute accruedPerformanceFee.
**Steps:**
1. Set performanceFee to 10% via `_setFees(0,0,0,1e17)`.
2. Alice deposits 1e18; simulate yield by minting 1e18 to adapter.
3. Observe `vault.accruedPerformanceFee()` = 1e17.
4. Alice calls `vault.withdraw(1)` (dust) which triggers highWaterMark update.
5. `accruedPerformanceFee()` now returns 0, denying the fee.
**How found:** Reading fee logic: noticed performanceFee depends on highWaterMark, then traced that highWaterMark is written in deposit/mint/withdraw, making it manipulable by any user before fee collection.
**Exploitation:** Attacker monitors pending takeFees (or any fee collection) and submits a dust deposit/mint/withdraw just before it, resetting highWaterMark to current share value so the fee recipient collects nothing while the attacker keeps full yield.
**Insight:** When a fee/profit baseline (highWaterMark) is updated on ordinary user interactions rather than only at fee-accrual time, any dust deposit/withdraw becomes a griefing lever against the fee recipient; check every write site of the baseline variable.
