# Incorrect price used when updating the global position data

LiquidationModule.liquidate passes position.lastPrice instead of currentPrice to updateGlobalPositionData, inflating long PnL and draining LP assets.

- Payout: Contest reward
- Severity: high
- Program: Flatmoney
- Credited: 0xLogos
- Disclosed: 2023-12-11
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-12-flatmoney-judging/issues/188
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-12-flatmoney%3AH-5
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:oracle-manipulation

**Target:** FlatcoinVault / LiquidationModule liquidation flow
**Root cause:** liquidate() calls updateGlobalPositionData with position.lastPrice rather than the oracle currentPrice; _profitLossTotal then computes PnL from a stale entry price instead of the live price.
**Steps:**
1. Open a leveraged long at price P0 (position.lastPrice = P0).
2. Price drops to P1 < P0 so the position becomes liquidatable.
3. Call `liquidate(tokenId)`; code fetches currentPrice=P1 but passes `price: position.lastPrice` (P0) to `vault.updateGlobalPositionData`.
4. Observe `PerpMath._profitLossTotal` computes price shift P0 vs global lastPrice, inflating long-side PnL.
5. newMarginDepositedTotal is reduced by the inflated profit, transferring value from LPs to long traders.
**How found:** Code review of the liquidation path: noticed updateGlobalPositionData expects the current oracle price (per its NatSpec and _profitLossTotal usage) but liquidate passes position.lastPrice.
**Exploitation:** Attacker opens a long at a high price, waits for price to fall until liquidatable, then triggers liquidation; the stale lastPrice inflates the global long PnL credited against LP margin, extracting LP value.
**Insight:** When a function's NatSpec says it takes 'the current price', grep every call site for stale per-position prices (lastPrice/entryPrice) — liquidation/close paths are prime spots where a stale price silently misprices global PnL.
