# Position value can fall below the minimum acceptable quote value

PartyB could partially fill a close request after PartyA cancelled it, leaving an open position below minAcceptableQuoteValue, breaking liquidation economics.

- Payout: Contest reward
- Severity: medium
- Program: Symmetrical
- Credited: 0xcrunch
- Disclosed: 2023-06-05
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-06-symmetrical-judging/issues/248
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-06-symmetrical%3AM-18
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:business-logic vuln:liquidation

**Target:** symmio-core LibQuote.closeQuote / PartyB fillCloseRequest
**Root cause:** The CANCEL_CLOSE_PENDING branch of closeQuote resets quote state without enforcing the minAcceptableQuoteValue check that the else branch applies, so a partial fill can leave remaining locked value below the minimum.
**Steps:**
1. PartyA calls `requestToClosePosition` for 100% of position (passes minAcceptableQuoteValue check since remainder is 0)
2. PartyA calls `requestToCancelCloseRequest`, setting quoteStatus to CANCEL_CLOSE_PENDING
3. PartyB calls `fillCloseRequest` partially, ignoring the cancel
4. closeQuote hits the CANCEL_CLOSE_PENDING branch (line 196), skipping the minAcceptableQuoteValue require
5. Remaining open position value ends up below minAcceptableQuoteValue (e.g. 3 USD vs 5 USD minimum)
**How found:** Code-reading of closeQuote's if-else branches: noticed the minAcceptableQuoteValue require only exists in the final else branch, and reasoned that the CANCEL_CLOSE_PENDING path bypasses it; sponsor initially disputed, PoC by panprog confirmed the third sequence.
**Exploitation:** PartyB deliberately ignores PartyA's cancel request and partially fills the close, leaving a dust position below the minimum quote value; liquidation becomes uneconomical, delaying/blocking liquidation and exposing users to market risk.
**Insight:** When a state machine has multiple exit branches, check whether invariant validations are duplicated in every branch — a cancel/pending branch that resets state often skips checks the normal branch enforces.
