Steadefi

Steadefi
DeFiHardhatFoundryOracle
35,000 USDC
View results
Submission Details
Severity: high
Invalid

Bad calculation for 1e30 normalization

Summary

When GMX Oracle uses Chainlink, the received values (usually 8 decimal) from Chainlink have to be normalized to 30 decimal . Since GMX works with 30 decimal, but when _getTokenPriceMinMaxFormatted() is called the result is not as expected.

Vulnerability Details

_getTokenPriceMinMaxFormatted() successfully calls Chainlink and when it tries to nromalize the value to from 30 decimal can result some unexpected results, as you can see below:

function _getTokenPriceMinMaxFormatted(address token) internal view returns (uint256) {
(int256 _price, uint8 _priceDecimals) = chainlinkOracle.consult(token);
return uint256(_price) * 10 ** (30 - IERC20Metadata(token).decimals() - _priceDecimals); // @audit check this operation
}

For example:

Call WBTC price feed Chainlink
WBTC = 8 decimal e.g. 35.000,00000000
_price = 3500000000000
_priceDecimals = 8
result = uint256(_price) * 10 ** (30 - IERC20Metadata(token).decimals() - _priceDecimals);
result = 3500000000000 * 10 ** (30 - 8 - 8)
result = 35 * 10 ** 8 * 10 ** 14
result = 35 * 10 ** 22

The result has to be 35 * 10 ** 30.

Call WETH price feed Chainlink
WETH = 8 decimal e.g. 35.000,00000000
_price = 200000000000
_priceDecimals = 8
result = uint256(_price) * 10 ** (30 - IERC20Metadata(token).decimals() - _priceDecimals);
result = 200000000000 * 10 ** (30 - 18 - 8)
result = 35 * 10 ** 8 * 10 ** 6
result = 35 * 10 ** 14

For different pairs, it returns different decimals

Impact

High, every request in GMX Oracle returns a wrong value.

Tools Used

Manual code review

Recommendations

Set the correct equation for normalizable to 1e30 as:

function _getTokenPriceMinMaxFormatted(address token) internal view returns (uint256) {
(int256 _price, uint8 _priceDecimals) = chainlinkOracle.consult(token);
- return uint256(_price) * 10 ** (30 - IERC20Metadata(token).decimals() - _priceDecimals);
+ return uint256(_price) * 10 ** (30 - _priceDecimals);
}
Updates

Lead Judging Commences

hans Lead Judge almost 2 years ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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