Steadefi

Steadefi
DeFiHardhatFoundryOracle
35,000 USDC
View results
Submission Details
Severity: low
Valid

`GMXOracle._getTokenPriceMinMaxFormatted` will not work if `tokenDecimals + _priceDecimals` > 30

Summary

GMXOracle._getTokenPriceMinMaxFormatted will not work if tokenDecimals+ _priceDecimals > 30

Vulnerability Details

  • GMXOracle._getTokenPriceMinMaxFormatted function extracts the token price from chainlink oracle and normalizes it to 1e30:

    function _getTokenPriceMinMaxFormatted(address token) internal view returns (uint256) {
    (int256 _price, uint8 _priceDecimals) = chainlinkOracle.consult(token);
    return uint256(_price) * 10 ** (30 - IERC20Metadata(token).decimals() - _priceDecimals);
    }
  • Assuming that the used tokens in the protocol are of a maximum decimal of 18; then if the returned _priceDecimals is > 12; this will make _getTokenPriceMinMaxFormatted revert.

  • And since this function is used in GMXOracle.getAmountsOut & GMXOracle.getMarketTokenInfo functions; this will result in disabling these functions too.

Impact

Since most of the calculations in the GMXReader library are heavily dependent on these functions; this will disable the protocol from functioning if the IERC20Metadata(token).decimals() + _priceDecimals is > 30.

Proof of Concept

GMXOracle._getTokenPriceMinMaxFormatted function

/**
* @notice Get token price formatted for GMX mix/max decimals for 1e30 normalization
* @dev E.g. if token decimals is 18, to normalize to 1e30, we need to return 30-18 = 1e12
* consult() usually returns asset price in 8 decimals, so 30 - tokenDecimals - priceDecimals
* should format the decimals correctly for 1e30
* @param token Token address
* @return tokenPriceMinMaxFormatted
*/
function _getTokenPriceMinMaxFormatted(address token) internal view returns (uint256) {
(int256 _price, uint8 _priceDecimals) = chainlinkOracle.consult(token);
return uint256(_price) * 10 ** (30 - IERC20Metadata(token).decimals() - _priceDecimals);
}

Tools Used

Manual Review.

Recommendations

Update GMXOracle._getTokenPriceMinMaxFormatted function to handle the aforementioned scenario.

Updates

Lead Judging Commences

hans Auditor
over 1 year ago
hans Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Tokens with more than 18 decimals are not supported

Underflow in convertToUsdValue

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.