# Users can get impact pool discounts while also increasing the virtual impact pool skew

GMX virtual inventory was updated even when skipped in price impact, letting users get discounts while skewing virtual pool negative for later traders.

- Payout: Contest reward
- Severity: medium
- Program: Gmx
- Credited: IllIllI
- Disclosed: 2023-04-20
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2023-04-gmx-judging/issues/246
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-04-gmx%3AM-8
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** GMX Synthetics MarketUtils/SwapPricingUtils
**Root cause:** applyDeltaToPoolAmount unconditionally updates virtual inventory for swaps, but getPriceImpactUsd skips virtual impact when a token lacks virtual inventory or when impact is positive, so virtual inventory drifts out of sync with what was actually charged.
**Steps:**
1. Set up 5 markets sharing a virtual market, each pairing ETH with a stablecoin.
2. Swap ETH into stablecoin in each market where swap imbalance gives a discount; virtual swap inventory for stables becomes increasingly negative.
3. When one market becomes flat, subsequent ETH->stable swaps hit the accumulated negative virtual impact, charging a large penalty.
4. Observe applyDeltaToVirtualInventoryForSwaps at MarketUtils.sol#L711-717 runs unconditionally while SwapPricingUtils.sol#L119-121 and #L96-105 skip virtual impact.
**How found:** Code reading: noticed applyDeltaToPoolAmount always calls applyDeltaToVirtualInventoryForSwaps, but getPriceImpactUsd early-returns before consulting virtual inventory when a token lacks it or impact is positive, implying state drift.
**Exploitation:** Users repeatedly swap in discounted directions, accumulating negative virtual inventory that later penalizes other users with large virtual swap impact; the discount is captured while the skew is externalized.
**Insight:** When a state-mutating accounting function runs unconditionally but the corresponding pricing read has early-return guards, the two diverge; audit pairs of write/read functions for matching guard conditions.
