DeFiFoundry
50,000 USDC
View results
Submission Details
Severity: medium
Invalid

Wrong assumption in price safety mechanism

Summary

In Keeper Contract there is mechanism to compare the price with the chainlink price feed which is kind of safety feature. As per sponsor they can use any erc20 token pair of market for vault in GMX they are not just limited USDC pair. So while comparing with price we assuming the data feed of chainlink always return with 8 decimal, which is actually not true there are some price feed which return answer in the 18 decimal. Some example of these price feed are

Arbitrum:

  • BTC/ETH : 0xc5a90A6d7e4Af242dA238FFe279e9f2BA0c64B2e

  • Link/ETH: 0xb7c8Fb1dB45007F98A68Da0588e1AA524C317f27

  • PEPE/USD: 0x02DEd5a7EDDA750E3Eb240b54437a54d57b74dBE

  • SHIB/USD: 0x0E278D14B4bf6429dDB0a1B353e2Ae8A4e128C93

Vulnerability Details

So the team is assuming manually all chainlink price decimal to 8, but as some have 18 as well.

// KeeperProxy::_check
uint256 decimals = 30 - IERC20Meta(token).decimals();
price = price / 10 ** (decimals - 8); // Chainlink price decimals is always 8.
// https://github.com/CodeHawks-Contests/2025-02-gamma/blob/84b9da452fc84762378481fa39b4087b10bab5e0/contracts/KeeperProxy.sol#L192C1-L193C83

Impact

This could cause multiple issue,

  • Wrong comparison of price we are making up price as per chainlink 8 decimals.

  • big diff would cause the function to revert,

  • It make the safety feature ineffective

Tools Used

Manual Review

Recommendations

Instead of assuming it to 8, right way would be fetching the decimals from feed directly and working according it.

- price = price / 10 ** (decimals - 8); // Chainlink price decimals is always 8.
+ price = price / 10 ** (decimals - AggregatorV2V3Interface(dataFeed[token]).decimals());
Updates

Lead Judging Commences

n0kto Lead Judge 8 months ago
Submission Judgement Published
Invalidated
Reason: Out of scope

Support

FAQs

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