# The oracle price could be tampered

GMX Oracle._setPrices failed to reject duplicate price indexes, letting a malicious keeper re-point signatures to tampered prices and skew the median.

- Payout: Contest reward
- Severity: medium
- Program: Gmx
- Credited: KingNFT
- Disclosed: 2022-09-22
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2023-02-gmx-judging/issues/74
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-02-gmx%3AM-34
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:medium tech:evm tech:solidity technique:source-review vuln:oracle-manipulation vuln:signature-replay

**Target:** Oracle.sol _setPrices price compaction/index validation
**Root cause:** _setPrices validates signatures against minPrices[minPriceIndex]/maxPrices[maxPriceIndex] but never checks that compactedMinPricesIndexes/compactedMaxPricesIndexes are unique, so multiple signatures can be mapped to the same price slot.
**Steps:**
1. Set MIN_ORACLE_SIGNERS=2; two signers sign minPrices=[1000,1000], maxPrices=[1010,1010] for WNT.
2. Attacker rewrites minPrices=[1000,2000], maxPrices=[1010,2020] and sets compactedMinPricesIndexes=compactedMaxPricesIndexes=[0,0].
3. Call `oracle.setPrices(...)` with the original signatures; both signature checks validate against index 0 (1000/1010).
4. Median of [1000,2000] yields 1500 min / 1515 max, tampering the stored primary price.
**How found:** Code review of _setPrices: noticed signatures are validated against prices selected by index but indexes are never checked for duplicates, then wrote a hardhat PoC.
**Exploitation:** A malicious order keeper submits setPrices with duplicated indexes so valid signatures are re-used against attacker-chosen price array entries, shifting the median oracle price used by vaults/markets.
**Escalation:** Tampered oracle price feeds into vault/market pricing, enabling fund theft from vaults and markets.
**Insight:** When signatures commit to array elements via caller-supplied indexes, verify index uniqueness/permutation—otherwise one signed value can be reused to validate a different element.
