# treasuryShare is Overwritten in FeePoolV0._shareMochi()

FeePoolV0._shareMochi() zeroes treasuryShare when distributeMochi() runs, letting veCRV holders repeatedly re-split leftover usdm and drain treasury fees.

- Payout: Audit contest
- Severity: high
- Program: Mochi
- Found by: leastwood
- Disclosed: 2021-11-23
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2021-10-mochi-findings/issues/89
- Library page: https://bugbountylibrary.com/r/c4%3A2021-10-mochi%3AH-11
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** FeePoolV0.sol fee distribution contract
**Root cause:** _shareMochi() flushes both mochiShare and treasuryShare to zero after distributing mochi, even when usdm remains in the contract, so the treasury's accrued claim is discarded rather than preserved.
**Steps:**
1. Contract holds 100 usdm at 1:1 with mochi.
2. Call `updateReserve()` to set treasuryShare=20 usdm, mochiShare=80 usdm.
3. Call `distributeMochi()` before `sendToTreasury()`: 80 usdm converted to mochi and locked in curve rewards pool.
4. Observe mochiShare and treasuryShare both reset to 0 (flushed).
5. Call `updateReserve()` again to split remaining 20 usdm: mochiShare=16.
6. Repeat distributeMochi()/updateReserve() until all usdm intended for treasury is distributed to veCRV holders.
**How found:** Manual code review of FeePoolV0.sol L94, noticing that _shareMochi() zeroes treasuryShare alongside mochiShare while usdm still remains, then reasoning through the ordering of distributeMochi() vs sendToTreasury().
**Exploitation:** A veCRV holder calls distributeMochi() before sendToTreasury() to convert the mochiShare portion, which flushes treasuryShare to zero; they then re-invoke updateReserve() to re-split the leftover usdm, capturing the treasury's share as mochiShare, and repeat until the treasury's fees are fully drained to veCRV holders.
**Escalation:** Looping distributeMochi()/updateReserve() repeatedly compounds the drain until all treasury-intended usdm is redirected.
**Insight:** When a distribution function resets accounting state, check whether it zeroes counters for funds it did not actually move; ordering between distribute and settle functions can let a caller re-split and re-capture the un-settled portion.
