Steadefi

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

Calculation of `minMarketTokenAmt` in `AddLiquidityParams _alp` occur using wrong `depositValue`

Summary

Calculated minMarketTokenAmt is wrong, expose to slippage.

Vulnerability Details

In GMXDeposit.deposit() while calculating calcMinMarketSlippageAmt() i.e minimum GM Amount that will receive, while depositing to GMXv2 is using wrong parameter i.e _dc.depositValue

_dc.depositValue here is the USD price of tokens deposited by Caller

Which then in following code used to calculate borrowAmount(tokenA & tokenB) from the lendingVault with respect to corresponding leverage (3x or 5x)

Technically it should be _dc.depositValue + borrowedAmount value passed to GMXManager.calcMinMarketSlippageAmt() for calculating minmumMarketToken received from GMXv2

This particular method already implemented in other contracts like in GMXWithdraw.processWithdrawFailure()

_alp.minMarketTokenAmt = GMXManager.calcMinMarketSlippageAmt(
self,
_dc.depositValue,
dp.slippage
);
if (dp.token == address(self.lpToken)) {
// If LP token deposited
_dc.depositValue = self.gmxOracle.getLpTokenValue( // @audit
address(self.lpToken),
address(self.tokenA),
address(self.tokenA),
address(self.tokenB),
false, // @audit L :: i think it should be true
false
)
* dp.amt
/ SAFE_MULTIPLIER;
} else {
// If tokenA or tokenB deposited
_dc.depositValue = GMXReader.convertToUsdValue( // @audit
self,
address(dp.token),
dp.amt
);
}

Impact

As we passing less depositValue to function then calculated minMarketTokenAmt will be small, there could be a slippage in received Market Token.

Tools Used

Manual review

Recommendations

Code already have correct implementation in other contract, this instance was exception

Following method could applied here as well

// Borrow assets and create deposit in GMX
(
uint256 _borrowTokenAAmt,
uint256 _borrowTokenBAmt
) = GMXManager.calcBorrow(self, _dc.depositValue);
_dc.borrowParams.borrowTokenAAmt = _borrowTokenAAmt;
_dc.borrowParams.borrowTokenBAmt = _borrowTokenBAmt;
GMXManager.borrow(self, _borrowTokenAAmt, _borrowTokenBAmt);
GMXTypes.AddLiquidityParams memory _alp;
_alp.tokenAAmt = self.tokenA.balanceOf(address(this));
_alp.tokenBAmt = self.tokenB.balanceOf(address(this));
+ // Calculate slippage
+ uint256 _depositValue = GMXReader.convertToUsdValue(
+ self,
+ address(self.tokenA),
+ self.tokenA.balanceOf(address(this))
+ )
+ + GMXReader.convertToUsdValue(
+ self,
+ address(self.tokenB),
+ self.tokenB.balanceOf(address(this))
+ );
_alp.minMarketTokenAmt = GMXManager.calcMinMarketSlippageAmt(
self,
- _dc.depositValue, // @audit-issue PASSED LESS VALUE FOR CALCULATION
+ _depositValue,
dp.slippage
);
Updates

Lead Judging Commences

hans Lead Judge almost 2 years ago
Submission Judgement Published
Validated
Assigned finding tags:

Wrong calculation of minMarketTokenAmt

Impact: High Likelihood: High Logic error in the core functionality that can cause loss of user funds.

Support

FAQs

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