# reinvestReward() generates dust totalPoolClaim causing vault abnormal

reinvestReward() increments totalPoolClaim without minting vault shares; if vault is emptied first, totalVaultSharesGlobal stays 0 and all future deposits mint 0 shares.

- Payout: Contest reward
- Severity: medium
- Program: Notional
- Credited: bin2chen
- Disclosed: 2023-10-09
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-10-notional-judging/issues/17
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-10-notional%3AM-2
- Tags: domain:web3 impact:dos kind:contest platform:sherlock sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic vuln:share-inflation

**Target:** SingleSidedLPVaultBase reinvestReward / _mintVaultShares
**Root cause:** reinvestReward() adds poolClaimAmount to totalPoolClaim without increasing totalVaultSharesGlobal; if totalVaultSharesGlobal is 0, _mintVaultShares divides by totalPoolClaim and yields 0 shares for every subsequent depositor.
**Steps:**
1. Deposit into vault, then withdraw all so totalPoolClaim=0 and totalVaultSharesGlobal=0.
2. REWARD_REINVESTMENT_ROLE (or bot) calls `reinvestReward(trades, minPoolClaim)` after rewards accrued; state.totalPoolClaim += poolClaimAmount while totalVaultSharesGlobal remains 0.
3. New depositor calls deposit; `_mintVaultShares` takes else branch: `vaultShares = (lpTokens * 0) / totalPoolClaim = 0`.
4. All future deposits mint 0 shares, vault unusable.
**How found:** Code reading of _mintVaultShares rounding-to-zero path; noted Notional's min borrow size / min leverage ratio guards normal deposits but reinvestReward() lacks the same guard and mutates totalPoolClaim without shares.
**Exploitation:** Precondition: vault emptied to zero state before a pending reinvestReward() executes. A malicious REWARD_REINVESTMENT_ROLE can donate reward tokens and trigger reinvestReward() before the first depositor to force totalPoolClaim>0 with totalVaultSharesGlobal=0, bricking deposits.
**Insight:** When a share-price formula divides by totalPoolClaim, audit every state mutation that touches totalPoolClaim (reward reinvestment, donations, fee accrual) for the missing totalVaultSharesGlobal>0 guard — first-depositor/empty-vault edge cases recur across vault designs.
