# Liquidatable long positions can be forced into short positions and vice versa

Liquidator can over-trade a liquidatable position past zero, flipping a long into a short (or vice versa) without owner consent.

- Payout: Contest reward
- Severity: medium
- Program: Starknet Perpetual
- Credited: alexxander
- Disclosed: 2025-06-18
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2025-03-starknet-perpetual#m-02
- Library page: https://bugbountylibrary.com/r/c4%3A2025-03-starknet-perpetual%3AM-02
- Tags: domain:web3 impact:integrity kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:business-logic vuln:liquidation

**Target:** Perpetuals core.liquidate() / value_risk_calculator
**Root cause:** Liquidation validation only checks that TR decreases and TV/TR ratio improves, not that the trade size is bounded by the liquidated position's synthetic balance, so a liquidator can trade through zero.
**Steps:**
1. Set up a liquidatable long position: collateral -20000, synthetic ETH 15, price 1500, riskfactor 0.25.
2. Liquidator signs an order to buy 25 ETH (more than the 15 held) from the liquidated position.
3. Call `core.liquidate(operator_nonce, liquidator_signature, liquidated_position_id, liquidator_order, actual_amount_base_liquidated=25, actual_amount_quote_liquidated=-10, ...)`.
4. Observe liquidated synthetic balance becomes -10 (short) and collateral 17500, passing both TR-decrease and ratio checks.
**How found:** Reading _validate_liquidated_position and liquidated_position_validations, noticed the checks only constrain TR decrease and TV/TR ratio, not trade size relative to synthetic balance; constructed numeric examples showing both a safe and an overshooting trade satisfy the conditions.
**Exploitation:** A liquidator (or colluding operator) submits an oversized liquidation order that exceeds the victim's synthetic balance, forcing the victim's position to flip sign and take on opposite market exposure without consent.
**Insight:** When a liquidation/health check validates only aggregate risk metrics (TR, TV/TR), test whether an arbitrarily large trade still satisfies them — bounds on trade size relative to the position's own balance are often missing.
