# Vault global shares and assets change will mismatch local shares and assets change during settlement due to incorrect `_withoutSettlementFeeGlobal` formula

Perennial V2 vault charged settlementFee twice in global accounting vs once locally, inflating user shares/assets and causing underflow on redeem/claim.

- Payout: Contest reward
- Severity: high
- Program: Perennial V2 3
- Credited: panprog
- Disclosed: 2024-02-28
- Write-up quality: 8/10
- Original: https://github.com/sherlock-audit/2024-02-perennial-v2-3-judging/issues/26
- Library page: https://bugbountylibrary.com/r/sherlock%3A2024-02-perennial-v2-3%3AH-3
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:sherlock sev:high tech:solidity technique:source-review vuln:accounting-error vuln:business-logic vuln:precision-loss

**Target:** Perennial V2 vault Checkpoint/Account settlement fee accounting
**Root cause:** _withoutSettlementFeeGlobal subtracts the full settlementFee for both deposits and redeems, while _withoutSettlementFeeLocal subtracts it proportionally across orders, so global shares/assets shrink twice as much as local.
**Steps:**
1. Set settlementFee=$10, User1 deposits $10 and User2 redeems 10 shares for same oracle version t=100 (checkpoint.orders=2).
2. On settlement, global deposit $10 -> 0 shares via `_withoutSettlementFeeGlobal(10)` returning 10-10=0.
3. Global redeem $10 -> 0 assets via same full-fee subtraction.
4. Local User1 deposit -> 5 shares via `_withoutSettlementFeeLocal(10)` returning 10-5=5.
5. Local User2 redeem -> $5 assets.
6. Observe sum(local shares) > global shares and sum(local assets) > global assets; later `Vault._update` underflows on `self.assets.sub(assets)`/`self.shares.sub(shares)`.
**How found:** Code review of Checkpoint._withoutSettlementFeeGlobal vs Account._withoutSettlementFeeLocal, noticing global subtracts full fee twice (deposit+redeem) while local weights by orders, then constructing a two-user same-version scenario.
**Exploitation:** Any oracle version with both deposits and redeems accrues a growing gap between local and global shares/assets equal to settlementFee per version; users redeeming or claiming later hit underflow in Vault._update and cannot withdraw/claim, effectively locking funds.
**Escalation:** Gap accumulates each settlement with mixed deposits/redeems ($100-$1000/day at $1 fee), eventually causing bank-run-style lockout for last redeemers.
**Insight:** When a fee is shared across orders, verify global aggregation subtracts it once total, not once per operation type; compare global vs local fee-weighting formulas for double-counting.
