This repository was archived by the owner on Sep 24, 2023. It is now read-only.
This repository was archived by the owner on Sep 24, 2023. It is now read-only.
IllIllI - Positions cannot be liquidated once the oracle prices are zero #156
Open
Description
IllIllI
medium
Positions cannot be liquidated once the oracle prices are zero
Summary
In the unlikely event that the price of an asset reaches zero, there is no way to liquidate the position, because both usages of oracles will revert.
Vulnerability Detail
Zero is treated as an invalid value, for both index oracle prices, as well as position prices.
Impact
Positions won't be liquidatable, at an extremely critical moment that they should be liquidatable. Losses and fees will grow and the exchange will become insolvent.
Code Snippet
The Chainlink oracle rejects prices of zero:
// File: gmx-synthetics/contracts/oracle/Oracle.sol : Oracle._setPricesFromPriceFeeds() #1
571 (
572 /* uint80 roundID */,
573 int256 _price,
574 /* uint256 startedAt */,
575 /* uint256 timestamp */,
576 /* uint80 answeredInRound */
577 ) = priceFeed.latestRoundData();
578
579 uint256 price = SafeCast.toUint256(_price);
580 uint256 precision = getPriceFeedMultiplier(dataStore, token);
581
582 price = price * precision / Precision.FLOAT_PRECISION;
583
584 if (price == 0) {
585 @> revert EmptyFeedPrice(token);
586 }
587:
As does the usage of off-chain oracle prices:
// File: gmx-synthetics/contracts/oracle/Oracle.sol : Oracle.getLatestPrice() #2
346 if (!secondaryPrice.isEmpty()) {
347 return secondaryPrice;
348 }
349
350 Price.Props memory primaryPrice = primaryPrices[token];
351 if (!primaryPrice.isEmpty()) {
352 return primaryPrice;
353 }
354
355 @> revert OracleUtils.EmptyLatestPrice(token);
356: }
Tool used
Manual Review
Recommendation
Provide a mechanism for positions to be liquidated even if the price reaches zero