Skip to content
This repository was archived by the owner on Sep 24, 2023. It is now read-only.
This repository was archived by the owner on Sep 24, 2023. It is now read-only.

IllIllI - Missing checks for whether a position is still an ADL candidate #153

Open
@sherlock-admin

Description

@sherlock-admin

IllIllI

medium

Missing checks for whether a position is still an ADL candidate

Summary

There are no checks for whether a position is still an ADL candidate or not

Vulnerability Detail

All checks during AdlHandler.executeAdl() are global checks about exchange-wide PnL levels, and there are no checks for whether the specific position is a valid ADL candidate or not.

Impact

Between the time when the ADL keeper chooses its list of ADL candidates and when the transaction gets confirmed (e.g. if the keeper has a sudden CPU spike, or the connection to the sequencer has to be retried), the user may have already reduced their position, and it would be incorrect to further reduce their position.

Code Snippet

All checks are global:

// File: gmx-synthetics/contracts/exchange/AdlHandler.sol : AdlHandler.executeAdl()   #1

119 @>         (cache.shouldAllowAdl, cache.pnlToPoolFactor, cache.maxPnlFactorForAdl) = MarketUtils.isPnlFactorExceeded(
120                dataStore,
121                oracle,
122                market,
123                isLong,
124                Keys.MAX_PNL_FACTOR_FOR_ADL
125            );
126    
127            if (!cache.shouldAllowAdl) {
128                revert AdlNotRequired(cache.pnlToPoolFactor, cache.maxPnlFactorForAdl);
129:           }

https://github.com/sherlock-audit/2023-02-gmx/blob/main/gmx-synthetics/contracts/exchange/AdlHandler.sol#L119-L129

// File: gmx-synthetics/contracts/exchange/AdlHandler.sol : AdlHandler.executeAdl()   #2

150            // validate that the ratio of pending pnl to pool value was decreased
151 @>         cache.nextPnlToPoolFactor = MarketUtils.getPnlToPoolFactor(dataStore, oracle, market, isLong, true);
152            if (cache.nextPnlToPoolFactor >= cache.pnlToPoolFactor) {
153                revert InvalidAdl(cache.nextPnlToPoolFactor, cache.pnlToPoolFactor);
154            }
155    
156            cache.minPnlFactorForAdl = MarketUtils.getMinPnlFactorAfterAdl(dataStore, market, isLong);
157    
158            if (cache.nextPnlToPoolFactor < cache.minPnlFactorForAdl.toInt256()) {
159                revert PnlOvercorrected(cache.nextPnlToPoolFactor, cache.minPnlFactorForAdl);
160            }
161:       }

https://github.com/sherlock-audit/2023-02-gmx/blob/main/gmx-synthetics/contracts/exchange/AdlHandler.sol#L150-161

The order only gets canceled if the order would cause the position size to go negative

Tool used

Manual Review

Recommendation

Create a view function for whether the position is eligible for ADL, and revert if the user is not eligible when the order executes

Metadata

Metadata

Assignees

No one assigned

    Labels

    MediumRewardA payout will be made for this issueSponsor DisputedWon't FixThe sponsor confirmed this issue will not be fixed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions