In the function processDepositFailure, the minimum fee is not checked. therefore fee can be 0
function processDepositFailure(
GMXTypes.Store storage self,
uint256 slippage,
uint256 executionFee
) external {
GMXChecks.beforeProcessAfterDepositFailureChecks(self);
GMXTypes.RemoveLiquidityParams memory _rlp;
// If current LP amount is somehow less or equal to amount before, we do not remove any liquidity
if (GMXReader.lpAmt(self) <= self.depositCache.healthParams.lpAmtBefore) {
processDepositFailureLiquidityWithdrawal(self);//@audit-info processDepositFailureLiquidityWithdrawal --
} else {
// Remove only the newly added LP amount
_rlp.lpAmt = GMXReader.lpAmt(self) - self.depositCache.healthParams.lpAmtBefore;
// If delta strategy is Long, remove all in tokenB to make it more
// efficent to repay tokenB debt as Long strategy only borrows tokenB
if (self.delta == GMXTypes.Delta.Long) {
address[] memory _tokenASwapPath = new address[](1);
_tokenASwapPath[0] = address(self.lpToken);
_rlp.tokenASwapPath = _tokenASwapPath;
(_rlp.minTokenAAmt, _rlp.minTokenBAmt) = GMXManager.calcMinTokensSlippageAmt(
self,
_rlp.lpAmt,
address(self.tokenB),
address(self.tokenB),
slippage
);
} else {
(_rlp.minTokenAAmt, _rlp.minTokenBAmt) = GMXManager.calcMinTokensSlippageAmt(
self,
_rlp.lpAmt,
address(self.tokenA),
address(self.tokenB),
slippage
);
}
_rlp.executionFee = executionFee;//@audit-issue dont check minimun fee
// Remove liqudity
self.depositCache.withdrawKey = GMXManager.removeLiquidity(
self,
_rlp
);
}
}
as can see never is checked if _rlp.executionFee < self.minExecutionFee
fee is loss
mnual review
add
if (_rlp.executionFee < self.minExecutionFee)
revert Errors.InsufficientExecutionFeeAmount();
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.