low

GMXOracle.sol#L280: function `getLpTokenAmount` icorrectly assumes that the r...

Contest
Reward

Total

132.80 USDC

Selected
132.80 USDC
Selected Submission

GMXOracle.sol#L280: function getLpTokenAmount icorrectly assumes that the returned price is in 18 decimal places. But it is 30 decimal places.

Severity

High Risk

Relevant GitHub Links

https://github.com/Cyfrin/2023-10-SteadeFi/blob/0f909e2f0917cb9ad02986f631d622376510abec/contracts/oracles/GMXOracle.sol#L280

Summary

GMXOracle oracle has a function getLpTokenAmount which is in scope. This is Used in keeper script to calculate how much LP tokens for given USD value.

This function returns the lpTokenAmount with 30 decimal places instead of 18 as the function assumes.

Vulnerability Details

Lets look at the function getLpTokenAmount

  /**
    * @notice Get token A and token B's LP token amount required for a given value
    * @param givenValue Given value needed, expressed in 1e30 -------------------------->> refer this
    * @param marketToken LP token address
    * @param indexToken Index token address
    * @param longToken Long token address
    * @param shortToken Short token address
    * @param isDeposit Boolean for deposit or withdrawal
    * @param maximize Boolean for minimum or maximum price
    * @return lpTokenAmount Amount of LP tokens; expressed in 1e18 -------------->>> refer this
  */
  function getLpTokenAmount(
    uint256 givenValue,
    address marketToken,
    address indexToken,
    address longToken,
    address shortToken,
    bool isDeposit,
    bool maximize
  ) public view returns (uint256) {
    uint256 _lpTokenValue = getLpTokenValue(
      marketToken,
      indexToken,
      longToken,
      shortToken,
      isDeposit,
      maximize
    );


    return givenValue * SAFE_MULTIPLIER / _lpTokenValue;
  }

SAFE_MULTIPLIER is in 18 decimal places.

The values returned from the function _lpTokenValue is in 18 decimal places. Refer the line

So the final returned value from the function getLpTokenAmount is (1e30 * 1e18) / 1e18 = 1e30

Impact

Overestimating the lpToken amount for the given USD value.

Tools Used

Manual review.

Recommendations

Update the function getLpTokenAmount as shown below.

  function getLpTokenAmount(
    uint256 givenValue,
    address marketToken,
    address indexToken,
    address longToken,
    address shortToken,
    bool isDeposit,
    bool maximize
  ) public view returns (uint256) {
    uint256 _lpTokenValue = getLpTokenValue(
      marketToken,
      indexToken,
      longToken,
      shortToken,
      isDeposit,
      maximize
    );

    return givenValue * SAFE_MULTIPLIER / _lpTokenValue; ------>> remove

    return (givenValue * SAFE_MULTIPLIER) / (_lpTokenValue * 1e12); ---->> add
   
  }