# If referral or liquidator is the same address as the account, then liquidation/referral fees will be lost due to local storage being overwritten after the `claimable` amount is credited to liquidator or referral

Self-liquidation or self-referral fees are credited to storage then overwritten by stale in-memory context during settle, losing user funds.

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

**Target:** Market.sol settle/_credit/_storeContext
**Root cause:** settle() loads _locals[account] into memory, then _credit() writes claimable directly to storage for the same account; _storeContext() later overwrites storage with the stale in-memory copy, discarding the credited fee.
**Steps:**
1. Open position for userB with collateral via `update(userB, 0, POSITION, 0, COLLATERAL, false)`.
2. Drop oracle price to 0.7 and call `update(userB, 0,0,0,0, true)` to self-liquidate.
3. Advance time and call `market.settle(userB.address)`.
4. Read `market.locals(userB.address).claimable` — returns 0 despite liquidation fee being subtracted from collateral.
**How found:** Code reading of settle() ordering: noticed _credit writes to _locals[account] storage while context.local is cached in memory and stored afterward, causing a lost-update when the credited account equals the settled account.
**Exploitation:** User self-liquidates (or self-refers); the liquidation/referral fee is deducted from their collateral but credited to their own claimable storage, which is then overwritten by the stale cached context, so the fee is stuck in the contract.
**Insight:** When a function caches struct state in memory and writes it back at the end, any helper that writes the same storage slot mid-execution creates a lost-update; check whether credited/beneficiary addresses can equal the account being settled.
