# Excess fromBalance removal not added to other positions fromBalance's when leveraging up

Leveraging up a cross-margin position caps fromBalance reduction at that position, leaving excess unused margin unallocated to other positions, inflating cross-available value.

- Payout: Contest reward
- Severity: high
- Program: Elfi Protocol
- Credited: mstpr-brainbot
- Disclosed: 2024-05-09
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2024-05-elfi-protocol-judging/issues/117
- Library page: https://bugbountylibrary.com/r/sherlock%3A2024-05-elfi-protocol%3AH-24
- Tags: domain:web3 impact:funds-loss impact:integrity kind:contest platform:sherlock sev:high tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** Perpetual futures cross-margin accounting (PositionMarginProcess/AssetsProcess)
**Root cause:** _executeReduceMargin only decrements the leveraged position's initialMarginInUsdFromBalance, capped at that position's fromBalance, and updatePositionLeverage calls unUseToken without redistributing the excess to other positions' fromBalance as withdraw/deposit flows do.
**Steps:**
1. Alice holds SHORT BTC (margin $100, fromBalance $100) and SHORT SOL (margin $100, fromBalance $40), both cross USDC.
2. Withdraw 10 USDC: withdraw() calls updateAllPositionFromBalanceMargin, reducing BTC fromBalance to $90.
3. Increase SOL leverage from 10x to 50x: reduceMargin = $100 - $1000/50 = $80.
4. _executeReduceMargin caps fromBalance reduction at $20 (SOL fromBalance), leaving $60 excess.
5. updatePositionLeverage calls accountProps.unUseToken($80) but never adds the $60 excess to BTC's fromBalance.
6. Result: total fromBalance understated by $60, cross-available value overstated.
**How found:** Code review comparing the leverage-up path against the deposit/withdraw path: noticed withdraw loops over all positions to exhaust the amount while _executeReduceMargin only touches the single position, then constructed a two-position numeric example.
**Exploitation:** No direct theft described; the accounting error inflates the account's cross-available value, letting a user carry more risk/withdraw more than entitled, potentially leaving bad debt to the protocol.
**Insight:** When a protocol has multiple code paths that consume a shared 'unused amount' pool, diff each path against the canonical loop-based implementation; leverage/margin-adjust paths are common places where the redistribution loop is forgotten.
