low

Unsafe Casting performed in the `GMXOracle::_getTokenPriceMinMaxFormatted`

Contest
Reward

Total

132.80 USDC

Selected
132.80 USDC
Selected Submission

Unsafe Casting performed in the GMXOracle::_getTokenPriceMinMaxFormatted

Severity

Medium Risk

Relevant GitHub Links

https://github.com/Cyfrin/2023-10-SteadeFi/blob/main/contracts/oracles/GMXOracle.sol#L311

Summary

The function GMXOracle::_getTokenPriceMinMaxFormatted in line#314 have converted the int256 result from Chainlink Oracle to uint256. Converting int256 to uint256 can have unexpected consequences when done unsafely.

Vulnerability Details

The function GMXOracle::_getTokenPriceMinMaxFormatted in line#314 have converted the int256 result from Chainlink Oracle to uint256. Converting int256 to uint256 can have unexpected consequences when done unsafely.

function _getTokenPriceMinMaxFormatted(address token) internal view returns (uint256) {
    (int256 _price, uint8 _priceDecimals) = chainlinkOracle.consult(token);

@>  return uint256(_price) * 10 ** (30 - IERC20Metadata(token).decimals() - _priceDecimals);
  }

We are providing a similar scenario that can be reproduced in Remix:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

contract TestUnsafeCasting {
    function testUpsafeCasting(int256 x) public pure returns (uint256) {
        return uint256(x);
    }
}

In this case, when we input -23 as input to the function testUnsafeCasting, it returns 115792089237316195423570985008687907853269984665640564039457584007913129639913 because of unsafe casting from int256 to uint256.

Impact

Protocol may experience unexpected output from the function GMXOracle::_getTokenPriceMinMaxFormatted

Tools Used

Manual Review, Remix

Recommendations

Use Openzeppelin SafeCast Library.