Steadefi

Steadefi
DeFiHardhatFoundryOracle
35,000 USDC
View results
Submission Details
Severity: medium
Valid

`lpTokenValue` will always calculate for withdrawals even if the action is deposits because `isDeposit` is always passed false

Summary

lpTokenValue will be always calculated with the factor type WITHDRAWALS even if the action is deposit, due to the hardcoded false value passed in the function parameter.

Vulnerability Details

lpTokeValue function defined is GMXOracle.sol is responsible for returning the price of the GM token and it calculates this price based on the _pnlFactorType of either withdraw or deposit actions. To determine the type of action, isDeposit param is passed to the function.

function getLpTokenValue(
address marketToken,
address indexToken,
address longToken,
address shortToken,
bool isDeposit,//@audit this should be true or false based on action
bool maximize
) public view returns (uint256) {
bytes32 _pnlFactorType;

But wherever this function is called the isDeposit is passed always as false which will lead to the incorrect lpTokenValue.

Proof of concept

https://github.com/Cyfrin/2023-10-SteadeFi/blob/0f909e2f0917cb9ad02986f631d622376510abec/contracts/strategy/gmx/GMXDeposit.sol#L92

if (dp.token == address(self.lpToken)) {
// If LP token deposited
_dc.depositValue = self.gmxOracle.getLpTokenValue(
address(self.lpToken),
address(self.tokenA),
address(self.tokenA),
address(self.tokenB),
false,//@audit this should be true
false
) * dp.amt / SAFE_MULTIPLIER;

When user deposit lpToken to GMXVault the isDeposit is passed as false which will always lead to the incorrect price calculations.

Even in the calMinMarketSlippage this value is always hardcoded to false. This can result in the loss of user funds if the slippage is calculated on the wrong lpTokenPrice.

function calcMinMarketSlippageAmt(GMXTypes.Store storage self, uint256 depositValue, uint256 slippage)
external
view
returns (uint256)
{
uint256 _lpTokenValue = self.gmxOracle.getLpTokenValue(
address(self.lpToken),
address(self.tokenA),
address(self.tokenA),
address(self.tokenB),
false, //@audit-issue when depositing this should be true otherwise it will calculte for withdraw
false
);
return depositValue * SAFE_MULTIPLIER / _lpTokenValue * (10000 - slippage) / 10000;
}

Impact

The function is used to calculate the value of user GM Deposit or slippage, so if the price based on MAX_PNL_FACTOR_FOR_WITHDRAWALS is low this could lead to the loss of user deposits. For example if user deposit GM token and value of it is calcualted low for withdraw but it is actually high for deposits, the user will end up with the less gvTokens(vault token).

Tools Used

manual review

Recommendations

Always passed appropriate boolean when calculating the lpTokenValue, i.e true for deposit and false for withdraw.

Updates

Lead Judging Commences

hans Lead Judge almost 2 years ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
0xanmol Submitter
almost 2 years ago
hans Auditor
almost 2 years ago
0xanmol Submitter
almost 2 years ago
hans Auditor
almost 2 years ago
Steadefi Lead Judge
almost 2 years ago
hans Lead Judge almost 2 years ago
Submission Judgement Published
Validated
Assigned finding tags:

Wrong PNL Factor in GMXDeposit for for lpToken

Impact: Medium Likelihood: High The impact of using a wrong price (conservative vs optimistic) is limited, especially given the users specify the slippage.

Support

FAQs

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