The KeeperProxy::_check function contains incorrect logic for decimal calculation and the price difference check.
The expression decimals = 30 - IERC20Meta(token).decimals(); subtracts the token's decimals from 30 and stores the result in decimals.
Then, decimals is further subtracted by 8 and raised to the power of 10.
then the price of token is divided by the 10 power of (decimals - 8),
The entire logic is incorrect and returns a price value that differs from the Chainlink price.
If the decimals of price and chainLinkPrice are not equal, the require statement will always revert.
Proof of code :-
first case [ Token has 18 decimals ]
second case [ Token with 12 decimals ]
Incorrect calculation of decimals will cause the require statement to revert unintentionally.
Incorrect decimal handling can cause unintended reverts in the require statement, leading to failures in price validation.
Manual Review
Implement the correct logic for decimal calculation to ensure accurate price checks.
GMX github documentation: “Prices stored within the Oracle contract represent the price of one unit of the token using a value with 30 decimals of precision. Representing the prices in this way allows for conversions between token amounts and fiat values to be simplified, e.g. to calculate the fiat value of a given number of tokens the calculation would just be: token amount * oracle price, to calculate the token amount for a fiat value it would be: fiat value / oracle price.” Sponsor confirmed the keeper does the same, so price decimals change in function of the token, to be sure the above rule is true. Example for USDC (6 decimals): Prices will have 24 decimals → 1e6 * 1e24 = 1e30. Just a reminder for some submissions: shortToken == collateralTokens, so the decimals is 1e24 for shortToken prices.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.