# `updateAllPositionFromBalanceMargin` function mistakenly increments positions "fromBalance"

Elfi cross-margin close loop passes full settle amount to each position instead of remaining reduceAmount, over-incrementing fromBalance and corrupting cross-account borrowing power.

- Payout: Contest reward
- Severity: high
- Program: Elfi Protocol
- Credited: KrisRenZo
- Disclosed: 2024-05-09
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2024-05-elfi-protocol-judging/issues/35
- Library page: https://bugbountylibrary.com/r/sherlock%3A2024-05-elfi-protocol%3AH-4
- 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 vuln:precision-loss

**Target:** Perp DEX cross-margin position accounting (PositionMarginProcess/DecreasePositionProcess)
**Root cause:** updateAllPositionFromBalanceMargin passes the original `amount` to updatePositionFromBalanceMargin for every position instead of the running `reduceAmount`, so each position's fromBalance is incremented by min(amount, borrowMargin) independently, exceeding the total changeToken.
**Steps:**
1. Deposit 1000 USDC + 1 WBTC; open WBTC short $1000 5x with USDC margin (consumes all USDC, initialMarginFromBalance = full).
2. Open WETH short $500 and SOL short $1000 5x; their initialMarginFromBalance = 0.
3. Move BTC price 25k->23k; close WBTC short fully, settledMargin ~1381 USDC, changeToken = 1381.
4. updateAllPositionFromBalanceMargin loops WETH then SOL, each receiving amount=1381; WETH fromBalance += 500, SOL fromBalance += 1000, reduceAmount goes negative.
5. Observe WETH/SOL initialMarginInUsdFromBalance inflated beyond actual, cross available value wrong.
**How found:** Code review of DecreasePosition::_settleCrossAccount and PositionMarginProcess loop; noticed `amount` (not `reduceAmount`) passed into per-position update, then traced multi-position example to confirm over-increment.
**Exploitation:** Not an external attack; accounting corruption triggered by normal open/close flow. Over-incrementing fromBalance lowers reported cross available value (or in opposite scenario raises borrowing power), enabling under-collateralized positions or DoS of legitimate withdrawals.
**Escalation:** Opposite sign scenario grants excess borrowing power, allowing positions beyond intended collateral limits.
**Insight:** In loops that distribute a delta across multiple positions, verify the running remainder is what's forwarded to each iteration, not the original total; test with multiple same-marginToken cross positions where only the first has fromBalance.
