# Anyone can reset fees to 0 value when Vault is deployed 

Vault.changeFees lacks a check that proposedFeeTime is nonzero, so anyone can call it post-deployment to set fees to the default zero, halting fee collection.

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

**Target:** Vault.sol changeFees() fee-change timelock
**Root cause:** changeFees() only checks block.timestamp < proposedFeeTime + quitPeriod; with proposedFeeTime defaulting to 0, the check passes immediately after deployment, applying the default zero proposedFees.
**Steps:**
1. Deploy Vault (proposedFeeTime = 0, proposedFees = 0).
2. Wait quitPeriod (e.g. `vm.warp(block.timestamp + 3 days)`).
3. Call `vault.changeFees()` without any prior proposeFees().
4. Observe fees() returns all zeros; protocol fee collection disabled.
**How found:** Code reading of changeFees() revealed the timelock check omits a proposedFeeTime==0 guard, and the default state after deployment satisfies the time condition.
**Exploitation:** Any external actor calls changeFees() after quitPeriod elapses from deployment; no proposal needed, fees set to zero, protocol stops collecting deposit/withdrawal/management/performance fees.
**Insight:** When a timelock uses a timestamp variable as its gate, check the uninitialized default (0) — a zero timestamp makes any elapsed-time comparison pass, so guard against the never-proposed state explicitly.
