# Increasing leverage can make the position have "0" `initialMargin`

Increasing leverage recomputes reduced margin at current price, zeroing position.initialMargin and bypassing borrowing fees or escaping losses.

- 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/49
- Library page: https://bugbountylibrary.com/r/sherlock%3A2024-05-elfi-protocol%3AH-10
- Tags: domain:web3 impact:funds-loss impact:integrity kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:source-review vuln:business-logic vuln:fee-bypass vuln:oracle-manipulation

**Target:** Perp DEX PositionMarginProcess leverage update
**Root cause:** updatePositionLeverage computes reduceMargin in USD but converts to token amount using current oracle price, then subtracts from initialMargin stored at entry price; price drop makes reduceMarginAmount exceed stored margin, flooring initialMargin to 0.
**Steps:**
1. Open 2x cross LONG position with marginToken wbtc at price 25000, initialMargin ~0.997 wbtc, initialMarginInUsd 24925.
2. Call `positionFacet.createUpdateLeverageRequest` with leverage 10x, same marginToken, addMarginAmount 10.
3. Execute `executeUpdateLeverageRequest` with oracle price dropped to 20000.
4. reduceMargin = initialMarginInUsd - qty/leverage; reduceMarginAmount = usdToToken(reduceMargin, price=20000) exceeds stored initialMargin.
5. Observe position.initialMargin == 0 while qty unchanged; borrowing fee = initialMargin * rate becomes 0.
**How found:** Code reading of updatePositionLeverage/_executeReduceMargin noticed reduceMargin is USD-denominated but converted to tokens at current oracle price, while initialMargin was recorded at entry price; hypothesized a price drop makes the subtraction underflow to zero.
**Exploitation:** Attacker opens a cross position, then raises leverage while price has dropped so the USD-denominated margin reduction converts to more tokens than the stored initialMargin, zeroing it. Position then pays no borrowing fees to the pool indefinitely. Isolated accounts can similarly close losing LONGs to reclaim initial margin, socializing losses.
**Escalation:** Same root cause extends to isolated-margin accounts escaping losses by closing underwater positions and securing initial margin back.
**Insight:** When a contract stores margin/balance in token units but computes deltas in USD, check whether the conversion uses a different price than the one used at deposit; a price move between the two can make the subtraction saturate to zero and silently disable fee accrual.
