# `reduce_margin_by_amount` in `Vault.reduce_position` is wrongly calculated

Vault.reduce_position computed margin/debt ratio against debt only, so reducing a position repaid no debt and altered leverage.

- Payout: Contest reward
- Severity: high
- Program: Unstoppable
- Credited: GimelSec
- Disclosed: 2023-06-21
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-06-unstoppable-judging/issues/85
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-06-unstoppable%3AH-2
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** Vyper margin-dex Vault contract reduce_position
**Root cause:** margin_debt_ratio divides margin_amount by debt_amount alone instead of total position value (debt + margin), so reduce_margin_by_amount absorbs the entire amount_out_received and reduce_debt_by_amount becomes zero.
**Steps:**
1. Open a position with debt_amount=9000 USDC and margin_amount=9000 USDC via `open_position`.
2. Call `vault.reduce_position(uid, position_amount/3, 6000e6)`.
3. Observe `reduce_margin_by_amount = amount_out_received * PRECISION / PRECISION = amount_out_received` and `reduce_debt_by_amount = 0`.
4. Assert debt_amount_after remains 9000e6 instead of ~6000e6; margin drops fully, leverage changes.
**How found:** Code review of the leverage-preservation math in reduce_position; noticed ratio used debt only, then built a Foundry/Vyper test showing debt unchanged after reduction.
**Insight:** When a function claims to preserve a ratio (leverage) after partial unwind, verify the denominator includes every component of the position (debt + margin), not just one side; write a test asserting both debt and margin shrink proportionally.
