sherlock-audit/2023-02-gmx-judging

berndartmueller - Depositing in a market with the same long and short tokens will revert

Closed this issue · 0 comments

berndartmueller

high

Depositing in a market with the same long and short tokens will revert

Summary

Depositing in a market with identical long and short tokens reverts due to an underflow error in the ExecuteDepositUtils.getAdjustedLongAndShortTokenAmounts function caused by incorrectly comparing the pooled long (poolLongTokenAmount) and short token (poolShortTokenAmount) amounts when adjusting the long and short token amounts.

Vulnerability Detail

Executing a deposit in a market with the same long and short tokens requires adjusting the long and short token amounts. This is done within the ExecuteDepositUtils.getAdjustedLongAndShortTokenAmounts function.

However, this function incorrectly implements the adjustment logic. Specifically, the if (line 392) and else (line 401) branches incorrectly compare the long and short token pool amounts. This leads to an underflow error when calculating the diff amount in both lines 393 and 402.

Impact

Adjusting the long and short token amounts when depositing in a market with identical long and short tokens will revert and effectively halt liquidity providers' ability to deposit in such markets.

Code Snippet

contracts/deposit/ExecuteDepositUtils.sol#L393

381: function getAdjustedLongAndShortTokenAmounts(
382:     DataStore dataStore,
383:     Market.Props memory market,
384:     uint256 longTokenAmount
385: ) internal view returns (uint256, uint256) {
386:     uint256 poolLongTokenAmount = MarketUtils.getPoolAmount(dataStore, market.marketToken, market.longToken);
387:     uint256 poolShortTokenAmount = MarketUtils.getPoolAmount(dataStore, market.marketToken, market.shortToken);
388:
389:     uint256 adjustedLongTokenAmount;
390:     uint256 adjustedShortTokenAmount;
391:
392:     if (poolLongTokenAmount < poolShortTokenAmount) {
393:         uint256 diff = poolLongTokenAmount - poolShortTokenAmount; // @audit-info reverts due to underflow error
394:
395:         if (diff < poolLongTokenAmount) {
396:             adjustedLongTokenAmount = diff + (longTokenAmount - diff) / 2;
397:             adjustedShortTokenAmount = longTokenAmount - adjustedLongTokenAmount;
398:         } else {
399:             adjustedLongTokenAmount = longTokenAmount;
400:         }
401:     } else {
402:         uint256 diff = poolShortTokenAmount - poolLongTokenAmount; // @audit-info reverts due to underflow error
403:
404:         if (diff < poolShortTokenAmount) {
405:             adjustedShortTokenAmount = diff + (longTokenAmount - diff) / 2;
406:             adjustedLongTokenAmount - longTokenAmount - adjustedShortTokenAmount;
407:         } else {
408:             adjustedLongTokenAmount = 0;
409:             adjustedShortTokenAmount = longTokenAmount;
410:         }
411:     }
412:
413:     return (adjustedLongTokenAmount, adjustedShortTokenAmount);
414: }

Tool used

Manual Review

Recommendation

Consider adapting the calculation of diff by reversing the order of the operands.

Duplicate of #165