# Vault and oracle keepers DoS in some situations due to `market.update(account,max,max,max,0,false)`

Perennial V2 keepers and vault call market.update to settle accounts, which reverts when an account is below margin, DoSing oracle settlement and bricking vault functions.

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

**Target:** Perennial Market.update / KeeperOracle._settle / Vault._updateUnderlying
**Root cause:** Market.update enforces the margin invariant even for empty orders with zero collateral change, so using it as a no-op 'settle' reverts whenever the account is below margin requirement.
**Steps:**
1. Call `market.update(account, UFixed6Lib.MAX, UFixed6Lib.MAX, UFixed6Lib.MAX, Fixed6Lib.ZERO, false)` on an account below margin.
2. Observe `InvariantLib.validate` reverts with `MarketInsufficientMarginError` because `PositionLib.margined` fails.
3. Note `KeeperOracle._settle` and `Vault._updateUnderlying` both use this call to settle accounts.
4. Push a user position to the edge of margin, then a small oracle price move puts it below margin.
5. All `KeeperFactory.settle` calls for that oracle version revert; vault `update`/`rebalance`/admin param changes revert too.
**How found:** Code reading of InvariantLib.validate revealed the margin check applies to all non-protected updates; tracing callers of market.update found KeeperOracle._settle and Vault._updateUnderlying rely on it as a non-reverting settle.
**Exploitation:** No direct theft; a user at the margin edge causes keeper settlement and vault operations to revert, blocking oracle fee collection and bricking vault functions until liquidation or price recovery.
**Escalation:** Setting a vault market weight to 0 while a residual position remains (minPosition) keeps the vault account at the margin edge, so repeated small price moves brick most vault functions.
**Insight:** When a protocol uses a state-changing call as a no-op 'settle', check whether invariants (margin, health) still gate it; any account near the threshold turns a keeper loop into a DoS.
