# Long trader's deposited margin can be wiped out

FlatcoinVault.settleFundingFees ternary zeroes marginDepositedTotal when positive funding fees exceed total margin, wiping long traders' collateral.

- Payout: Contest reward
- Severity: high
- Program: Flatmoney
- Credited: 0xrobsol
- Disclosed: 2023-12-11
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-12-flatmoney-judging/issues/195
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-12-flatmoney%3AH-7
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error

**Target:** FlatcoinVault.sol settleFundingFees funding-fee accounting
**Root cause:** The ternary compares marginDepositedTotal against _fundingFees before adding them, so a positive funding gain larger than total margin sets the total to 0 instead of X+Y; a large negative _fundingFees also passes the check and underflows on cast.
**Steps:**
1. Open long positions so _globalPositions.marginDepositedTotal = X.
2. Accrue positive funding fees Y to longs where X < Y.
3. Call `settleFundingFees()`; line 232 evaluates `int256(X) > Y` as false.
4. marginDepositedTotal is set to 0, erasing all long margin.
5. Alternatively with large negative _fundingFees, condition passes and `uint256(int256(X)+_fundingFees)` underflows/reverts.
**How found:** Code review of the ternary guard intended to prevent negative margin; noticed the comparison uses pre-addition values, so the branch logic is inverted for the positive-fee case and misses the negative-overflow case.
**Insight:** When a guard clamps a signed sum to zero, verify the comparison is done on the post-addition result, not the operands; ternary guards around int-to-uint casts are a recurring source of both silent zeroing and underflow.
