# In Cross Margin mode, the user’s profit calculation is incorrect.

Elfi cross-margin close uses initialMargin as decreaseMargin, zeroing recordPnlToken so profitable trades settle as ~zero profit, losing user funds.

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

**Target:** Perpetual futures DecreasePositionProcess (cross margin close)
**Root cause:** In _updateDecreasePosition, cache.decreaseMargin is set to position.initialMargin and subtracted from settledMargin to compute recordPnlToken; in cross margin the initial margin was never invested in the market, so this subtraction wrongly cancels the profit.
**Steps:**
1. Open a 1x long WETH-USDC position in cross margin mode with 1000 USDC collateral (no funds transferred to MarketVault).
2. Set oracle WETH price 1000 USD, then raise to 2000 USD.
3. Call closeCrossMarginLongPosition / decreasePosition for full qty.
4. Observe cache.recordPnlToken ≈ 0 and realizedPnl negative instead of +1000 USD profit.
**How found:** Compared isolated vs cross margin accounting: isolated transfers margin into MarketVault (borrowing 0), cross margin leaves collateral in PortfolioVault, so subtracting initialMargin from settledMargin in the shared close path is wrong; confirmed with a Foundry PoC logging recordPnlToken.
**Exploitation:** Any cross-margin trader closing a profitable position receives near-zero PnL; the protocol/user loses the profit amount on essentially every cross-margin trade.
**Insight:** When one code path serves both isolated and cross margin, check whether margin is actually escrowed in the market; any subtraction of initialMargin from settled value is only valid when that margin was invested.
