# Code asymmetry of `globalPositions.marginDepositedTotal`

Inconsistent handling of marginDepositedTotal (allowed negative in settleFundingFees, clamped to zero in updateGlobalPositionData) inflates accounting and drains LP collateral.

- Payout: Contest reward
- Severity: medium
- Program: Flat Money Fix Review Contest
- Credited: xiaoming90
- Disclosed: 2024-03-29
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2024-03-flat-money-fix-review-contest-judging/issues/19
- Library page: https://bugbountylibrary.com/r/sherlock%3A2024-03-flat-money-fix-review-contest%3AM-2
- Tags: domain:web3 impact:funds-loss impact:integrity kind:contest platform:sherlock sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** FlatcoinVault.sol (settleFundingFees / updateGlobalPositionData)
**Root cause:** settleFundingFees lets globalPositions.marginDepositedTotal go negative expecting liquidation to restore it, but updateGlobalPositionData clamps any negative value to zero, wiping the debt before liquidation re-adds marginDelta.
**Steps:**
1. LP deposits 25 ETH, mints 25 UNIT; stableCollateralTotal=25 ETH.
2. Trader deposits 10 ETH margin, opens 100 ETH long; marginDepositedTotal=10 ETH.
3. Accrue 20 ETH funding owed by longs to LP; call `settleFundingFees()` -> marginDepositedTotal = 10 + (-20) = -10 ETH.
4. Before liquidation, trigger any order (open/adjust/close) calling `updateGlobalPositionData` with small marginDelta; line 190 clamps newMarginDepositedTotal to 0.
5. Liquidate the underwater position: marginDelta = -(10 + (-20)) = +10 ETH; updateGlobalPositionData sets marginDepositedTotal = 0 + 10 = 10 ETH.
6. Result: phantom 10 ETH margin credited, unbacked; LP collateral drained on subsequent funding settlements.
**How found:** Code-reading comparison of two functions handling the same state variable: noticed settleFundingFees intentionally permits negative values while updateGlobalPositionData clamps to zero, then constructed a numeric scenario showing the clamp destroys the debt before liquidation restores it.
**Exploitation:** Attacker (or any user) calls permissionless settleFundingFees to push marginDepositedTotal negative, then triggers a benign order to zero it out before liquidation, so liquidation re-credits margin that no longer exists, inflating accounting and letting LP collateral be paid out against phantom assets.
**Insight:** When one function deliberately allows a signed state variable to go negative with a comment promising a later function will restore it, check every other writer of that variable for clamping/abs()/zero-floor logic that silently discards the debt.
