GMX engaged Guardian to review the security of their GMX Crosschain architecture. From the 9th of June to the 16th of June, a team of 6 auditors reviewed the source code in scope.
- Published
- Review window
- June 9 to 16, 2025
- Language
- Solidity
- Chains
- Arbitrum, Avalanche
- Sector
- Perpetuals
- 0 Critical
- 3 High
- 15 Medium
- 18 Low
- 0 Informational
Scope
Overview
GMX engaged Guardian to review the security of their GMX Crosschain architecture. From the 9th of June to the 16th of June, a team of 6 auditors reviewed the source code in scope.
Findings 36
-
H-01 High Users' Multichain Balance Can Be Consumed Logical Error Resolved
Description
deposit.receiveris assigned as the account inbridgeOutFromControllerduring theexecuteDepositflow. This account will be responsible for paying the Stargate fee from its multichain balance.Since anyone can deposit on behalf of another user, the
bridgeOutFromControllerfunction can be exploited to consume any account’swntbalance as Stargate fees by donating a minimal amount ofgmorglvtokens to them and invoking a bridge out.Recommendation
One option to consider is enforcing that
deposit.accountanddeposit.receiverare the same when callingbridgeOutFromController. Another option is to pass bothdeposit.accountanddeposit.receiverto the function.The
deposit.receivershould receive the tokens on the source chain, while the Stargate fees should be paid fromdeposit.account’s multichain balance.Resolution
GMX Team: Resolved.
-
H-02 High Positive Impact Becomes Unbacked Logical Error Partially resolved
Description
H-04 from the previous round has not been fully resolved. The positive impact is capped based on the impact pool amount using the
capPositiveImpactUsdByPositionImpactPoolfunction. This cap is applied under the assumption that the entire negativetotalPendingImpactAmountwill be paid without any cap.However, these pending negative impacts can be capped when decreasing a position. In such cases, the actual amount applied to the position impact pool differs from the delta amount recorded in
totalPendingImpactAmount.This means that the
totalImpactPoolAmountused in thecapPositiveImpactUsdByPositionImpactPoolfunction is overestimated until these positions with pending negative impact are closed and cap is applied to the pending negative impact. This can be used to gain an advantage by leveraging changes in price impact factors, which occur regularly depending on order book depth.While the
reduceLentAmountfunction can be used to cover unbacked positive impact by paying it from the treasury, overestimation of the positive cap limit persists as long as positions with large pending negative impacts (those that would be capped) remain open.Recommendation
Since it is not possible to know exactly how much of the negative
totalPendingImpactAmountwill be capped, consider excluding negative pending amounts from positive capping calculations for markets where the negative impact will be capped.This will result in users receiving less positive impact due to a lower cap, but it will prevent overestimated positive caps and ensure that positive impacts remain fully backed.
Resolution
GMX Team: Partially Resolved.
-
H-03 High Cross-Chain Nonce Handling And Execution Order Logical Error Resolved
Description
As a fix to previously reported issues, GMX now validates cross‑chain actions based on signatures. In the
lzComposeflow, each call to the GM or GLV multichain router (which increments a user’s nonce) is wrapped in a try/catch. When an action fails, its nonce is not updated, and since the failure is caught,LayerZerowill not retry it. Any later cross-chain action submitted with old nonce + n will therefore also fail.Previously this wasn’t the case since
_validateCallWithoutSignaturedidn't enforce order, it used to allow action t+1 to go through even if action t failed. While there’s no direct financial incentive, a malicious actor could trivially force one failure to deny‑of‑service all of Alice’s pending actions. Consider Alice submitting two cross‑chain deposits: Deposit 1 and Deposit 2.If Deposit 2 is processed before Deposit 1 completes, Deposit 2 will fail (due to a nonce mismatch), caught, and won't be retried and GMX’s UI will continue scheduling assuming the next nonce is 3—leading to a desync and permanent failure of future transactions.
LayerZero’s MessagingComposer.sol does not enforce per-user ordering insidelzCompose, so out-of-order actions are not automatically blocked: linkConsidering different chains have different bridging times, if user is scheduling actions from multiple chains, the chances of desync increase. If strict ordering of transactions is enforced, users will be required to wait for their previously triggered cross-chain transactions to fully complete before initiating any source-chain signature-based actions.
Depending on the latency of the source-to-destination chain path, this can block user interactions for a significant duration—potentially 30 minutes or more—resulting in a poor user experience and loss of reactivity during volatile conditions. (which could be considered crucial for perps exchange) For example, if there is incoming crosschain transaction from polygon, until that’s executed, user won’t be able to sign or use any of their multichain balance on arb/avax.
Recommendation
Consider:
- Option 1: Use a separate nonce queue for cross-chain actions, and validate that the incoming cross-chain nonce equals the
current expected nonce before executing any logic (i.e., prior to the try/catch block). This preserves strict ordering within cross-chain flows but decouples it from local nonce progression, allowing local source-chain actions to proceed independently, and since there is explicit reverts, a retry could be attempted.
- Option 2: If strict ordering is not necessary for crosschain actions, adopt a salted nonce model (e.g., combining user nonce with
a random salt or action ID). This allows actions to be processed independently without enforcing a sequential queue.
Resolution
GMX Team: Resolved.
-
M-01 Medium Max dataList Length Value Too Low Configuration Resolved
Description
The
dataListparameter will be used to decode GMX action data, like in thebridgeOutFromControllerflow. When creating requests in handler, this parameter is validated against theMAX_DATA_LENGTH.The GMX general config suggest the max length allowed is 10. However, the action data decoded from
dataListmust contain therelayParams, which involves multiple params like external calls, oracle params, signature, deadline, etc.According to our internal testing, even the simplest param encoding (empty external calls, oracle, fee params) will result in a
dataListlength of 41, way above the max configured length.Recommendation
Consider increasing the
maxDataLengthin the protocol's general config, to allow users to bridge out after deposit.Resolution
GMX Team: Resolved.
-
M-02 Medium Incorrect positionKey When Updating Logical Error Resolved
Description
The logic for updating
lastSrcChainIdhas been moved fromPositionUtilstoOrderUtilsafter the recent fixes.Previously, the position itself was used, but now the
positionKeyis derived from the order usingorder.initialCollateralToken.However, the derived
positionKeywill be incorrect if thecollateralTokenof the position differs fromorder.initialCollateralToken(Similar to issue M-05 from the GMX Crosschain-2 engagement).As a result, the
lastSrcChainIdof a different position will be incorrectly updated.Recommendation
To construct the
positionKeyaccurately, consider using the actual collateral token, which is the lasttokenOutin theswapPathoriginating from theinitialCollateralTokenResolution
GMX Team: Resolved.
-
M-03 Medium Positive Price Impact Is Not Guaranteed Logical Error Acknowledged
Description
This GMX update introduces pending impact a feature that moves the price impact settlement flow from increase to decrease.
Before this update, the positive price impact in the increase flow was always guaranteed as it was settled immediately.
This is no longer given now for multiple reasons, for example:
- The position impact pool is distributed to the LPs over time
- The amount available for the lending feature is capped
- Prices can change
- During insolvent liquidations the flow might early return before paying the impact pool
Recommendation
Consider acknowledging and documenting this risk for users or rethinking the pending impact implementation, by for example not distributing impact pool funds to the LPs if they are needed to pay out the pending impact.
Resolution
GMX Team: Acknowledged.
-
M-04 Medium TraderReferralCode Overwritten Logical Error Acknowledged
Description
Usually in the order flow the
TraderReferralCodeis not overwritten if the user already has one set. This check is performed in theReferralUtils.setTraderReferralCodefunction.However, in the multichain
setTraderReferralCodeflow theReferralStorage.setTraderReferralCodeis called directly instead of through theReferralUtilslibrary, therefore this check is missing.This means that the actual referrer who onboarded the user to GMX could be overwritten by another one here and fees are lost for the real referrer.
Recommendation
Consider calling
ReferralUtils.setTraderReferralCodeinstead ofReferralStorage.setTraderReferralCode.Resolution
GMX Team: Acknowledged.
-
M-05 Medium minPositionImpactPoolAmount Change Blocked Logical Error Resolved
Description
GMX has added a new check inside
setPositionImpactDistributionforminPositionImpactPoolAmount. It reverts ifminPositionImpactPoolAmountis less thantotalPendingImpactAmount: However, these two parameters are not inherently related in core logic.Consider the following case:
- Pending impact = $500
- Impact pool holds $10,000
- Current
minAmount= $200 - Admin wants to increase it to $300 or reduce it to $100 — both actions are not possible because of
this check.
- But the check isn't necessary in this context, as the impact pool already holds more than enough
funds.
Recommendation
Reconsider this check in terms of why it is needed at all.
Resolution
GMX Team: Resolved.
-
M-06 Medium Unset Configuration Keys Configuration Acknowledged
Description
Several critical configuration keys introduced in recent GMX updates remain unset, potentially leading to execution failures and undefined protocol behavior.
- Gas Limit Keys –
CREATE_DEPOSIT_GAS_LIMIT,CREATE_GLV_DEPOSIT_GAS_LIMIT
In the current setup, the
lzComposefunction can be called by any actor once DVNs validate the message. If an actor supplies insufficient gas, the subsequentcreateDepositorcreateGlvDepositactions may run out of gas and revert to thecatchblock.While a gas validation step was added in the new implementation, these keys default to
0unless configured—making the validation ineffective. This could force affected users to retry deposits manually via the routers, degrading UX and increasing vulnerability surface.- Lending Constraint Keys –
maxLendableImpactFactorKey,maxLendableImpactUsdKey
These keys are essential for defining safe boundaries for lending impact. Currently, they are not set during deployment. As a result, lending logic may behave unpredictably or allow unsafe exposures due to missing guardrails.
Recommendation
Set
CREATE_DEPOSIT_GAS_LIMITandCREATE_GLV_DEPOSIT_GAS_LIMITto appropriate values (e.g., ≥1.4M gas) considering downstream external calls.Similarly, ensure that
maxLendableImpactFactorKeyandmaxLendableImpactUsdKeyare explicitly configured for each market post-deployment to enforce proper lending constraints.Resolution
GMX Team: Acknowledged.
- Gas Limit Keys –
-
M-07 Medium lzCompose Can Still Be Exploited Censoring Acknowledged
Description
We previously raised issue M-04 regarding the potential censorship of composed deposits. Even if GMX ensures there is sufficient gas before invoking
try/catch, censorship remains possible due to the permissionless nature oflzCompose.Any actor can invoke
lzComposein a way that ensures the GMX core state causes a revert, effectively censoring the intended action.For example:
- All GMX actions are protected by a global reentrancy guard. A malicious actor could invoke
lzComposeduring a callback or while receiving ETH for any of their own actions. As a result, if a multichain provider attempts a deposit at this point, it would fail due to the reentrancy check and be caught silently.- Alternatively, the attacker could sandwich the transaction to trigger a price impact-related revert.
Recommendation
GMX could consider whitelisting specific executors. The
lzComposefunction exposes the executor (i.e., the address that calledlzComposeon the endpoint). Reference – LayerZero source codeRestricting execution to a trusted set of executors could:
- Mitigate censorship risks.
- Reduce exposure to potential exploits through
lzComposecalls for any other case.
That said, GMX would need to ensure this whitelist is dynamically managed, as
LayerZerokeepers may change over time. Alternatively, GMX could maintain and operate their own verified set of keepers.Resolution
GMX Team: Acknowledged.
-
M-08 Medium Some Timelock Actions Cannot Be Done Unexpected Behaviour Resolved
Description
In the
TimelockConfigcontract the signal functions are hardcoded to signal a predecessor and salt of 0. This means actions with the same payload will not be able to execute as the id is already used.Recommendation
For all of the signal functions in the
TimelockConfigcontract, consider allowing for a predecessor and salt to be specified to allow the same payload to be used again in the future and also allow for ordering specific actions.Otherwise be aware that actions with the same payload cannot be repeated through the
TimelockConfig.Resolution
GMX Team: Resolved.
-
M-09 Medium Max Lent Validation Misses Pool Amount Changes Validation Acknowledged
Description
The
capPositiveImpactUsdByPositionImpactPoolfunction validates that the amount that will become lent is not larger than a percentage of the backing pool amounts.However this validation is performed on the pool amount prior to the adjustments that are made in the execution of the
processCollateralfunction that follows.As a result the
maxLentvalidation can be easily bypassed and allow a malicious actor to lock withdrawals for the GM market or accrue a large index token exposure relative to the backing market token amounts.Recommendation
Ideally the max lent validation can account for the market balance updates that will occur, however this is non-trivial to implement. Be aware of this shortcoming in the
maxLentvalidation and carefully configure themaxLentthresholds with this in mind.Resolution
GMX Team: Acknowledged.
-
M-10 Medium Pending Impact Prioritized Over Current Impact Unexpected Behaviour Resolved
Description
During the decrease price impact flow, the pending price impact amount which has not been capped previously is prioritized over positive impact which is generated on decrease. This occurs with the following calculation in
capPositiveImpactUsdByPositionImpactPool:cache.totalImpactPoolAmount = cache.impactPoolAmount.toInt256() -cache.totalPendingImpactAmount;Over time the pending impact is likely to grow larger than the impact pool amount because:
- The positive impact is no longer capped on increase
- Negative impact will be capped on decrease, creating an excess of it's positive pending
counterpart
This means that over time it is likely that positive impact generated for decrease orders will be un-realizable due to an excess of positive pending impact. This will remove the impact incentive for decrease orders that balance the market.
Recommendation
Be aware of this behavior of the current
capPositiveImpactUsdByPositionImpactPooland consider if it is expected.Resolution
GMX Team: Resolved.
-
M-11 Medium reduceLentAmount Creates Arbitrage Unexpected Behaviour Resolved
Description
The
reduceLentAmountfunction adds thelongTokenAmountandshortTokenAmountratio of the backing tokens to the GM market in return for repaying some of thelentAmountvalue. ThelongTokenAmountandshortTokenAmountratio is paid at the existing ratio of the market token underlying balance.This however introduces more positive impact that can be realized for markets that are currently in an imbalanced state. Withdrawing tokens from an imbalanced market at the current market ratio is correct, because it reduces the net imbalance of USD values in the market.
However depositing tokens to an imbalanced market at the current market ratio is incorrect, because it increases the net imbalance of USD values in the market.
For example:
- GM A has 1,000 of token A and 10,000 of token B
- The USD imbalance is $9,000
- Withdrawing 50% of the gm supply brings this to $500 and$ 5,000, a USD imbalance of $4,500
- Depositing +50% to the GM supply worth of tokens brings this to $1,500 and$ 15,000, a USD
imbalance of $13,500
The USD imbalance is increased for deposits using this mechanism, and thus the pool is more severely off-balance by the price impact calculation measurement.
Recommendation
Keep the existing withdrawal ratio for GM withdrawals and the
withdrawFromPositionImpactPoolfunction. However thereduceLentAmountfunction should deposit new funds into the GM market at an even USD balance to bring the market closer to a balanced state rather than further away.Resolution
GMX Team: Resolved.
-
M-12 Medium Order Updates Do Not Update lastSrcChainId Unexpected Behaviour Acknowledged
Description
The
lastSrcChainIdis now updated on order creation, however when an order is updated it is not considered for alastSrcChainIdupdate.A user may create a limit order that is initially never executed due to the trigger price never being reached.
The
lastSrcChainIdof the position may be updated after the inception of the order but before the user updates the order to use a lower trigger price and become executable.This order update should set a new
lastSrcChainIdsince this is the most recent action with the order/position, however it is not considered.Recommendation
Include
_updatePositionLastSrcChainIdat the end ofupdateOrder.Resolution
GMX Team: Acknowledged.
-
M-13 Medium 63/64 Rule Is Not Considered In Validations Validation Acknowledged
Description
In the
LayerZeroProviderfor the composed actions the_validateGasLeftfunction is used to validate each of the corresponding gas limits.However the 63/64 rule is not taken into consideration given that each action is an external call that will only receive 63/64 of the current execution's available gas.
Recommendation
Account for the 63/64 rule in the
_validateGasLeftfunction similar to how it is accounted for in thevalidateGasLeftForCallbackfunction inCallbackUtils.sol.Resolution
GMX Team: Acknowledged.
-
M-14 Medium Composed Actions Gas Inaccurately Validated Censoring Acknowledged
Description
In the
LayerZeroProviderthe gas required for the execution of composed actions is validated against a static value, however depending on attributes of the composed action the action may require significantly more or less gas.For example, if an action has several associated permits or external calls then it will consume significantly more gas than the same action without those permits or external calls.
Validating all actions to have the highest expected expenditure would require users to overpay the lz executor, and requiring only the minimum opens these higher gas expenditure actions up to censoring.
Recommendation
Consider estimating the gas required for composed actions based upon additional factors such as the amount of token permits, and external calls associated with the action.
Resolution
GMX Team: Acknowledged.
-
M-15 Medium Inaccurate Liquidations Due To Incorrect Capping Logical Error Acknowledged
Description
GMX currently fails to correctly apply caps for negative price impact on
isPositionLiquidatable, which can incorrectly returnfalsewhen a position should be liquidated.- Due to the new deferred accounting of price impacts (i.e., unrealized/pending impact on position
increase), users can open positions with a large negative price impact that is not immediately realized.
- During liquidation checks,
isPositionLiquidatablecomputes the total price impact and applies the
maxNegativePriceImpactUsdcap to it.- However, this cap was originally meant to protect against sudden adverse price movements, not
unrealized negative impact from user’s own position open.
- By applying the cap to the total impact (including the user’s pending impact), the function can
understate the risk and allow a user to avoid liquidation.
Current market config for
maxPositionImpactFactorForLiquidationsis 0 by default for all markets. Therefore, negativepriceImpactUsdincluding pending price impact will be capped at 0.Recommendation
Only cap new negative price impact incurred from current price slippage during liquidation, not the previously accrued/pending impact from position opening.
Resolution
GMX Team: Acknowledged.
-
L-01 Low Misleading Comment In Constructor Best Practices Resolved
Description
The
MultichainTransferRouterconstructor was previously empty. This allowed users to callinitializeand set a multichain provider.This is now prevented be setting a
deployeraddress during contract deployment and only allowing this address to callinitialize.However the constructor has a comment that state:
leave empty, use initialize instead, but the function body is not empty. The is misleading and should be removed, as new logic was added.Recommendation
Remove the comment inside the constructor
Resolution
GMX Team: Resolved.
-
L-02 Low Redundant Logic In LastSrcChainId Update Best Practices Resolved
Description
During the create order flow
order.touchis called before_updatePositionLastSrcChainId. Therefore, theorder.updatedAtTime()will always equal the currentblock.timestamp.This makes the whole logic in the
_updatePositionLastSrcChainIdfunction redundant as at the end it will just update the chain id:dataStore.setUint(Keys.positionLastSrcChainId(positionKey),srcChainId).Recommendation
Update the
srcChainIdin every order creation by directly calling:dataStore.setUint(Keys.positionLastSrcChainId(positionKey), srcChainId);Resolution
GMX Team: Resolved.
-
L-03 Low Cross-chain Actions Cannot Use GMX Pool Liquidity Warning Resolved
Description
The
handleRelayFeefunction normally allows users to utilize GMX pool liquidity for performing swaps required to pay fees in the appropriate token.However, when actions are routed using multichain providers (such as via
lzCompose), the function returns early.As a result, users cannot access GMX liquidity and must instead depend on external calls through external swap handlers.
These external handlers cannot be granted the
SwapHandlercontroller role because they do not perform internal validations such asvalidateSwapPath, posing potential risks.Recommendation
Users interacting via cross-chain routing mechanisms like
lzComposeshould be made aware that they will not be able to leverage GMX's native pool liquidity for fee swaps.A potential enhancement would be to introduce controlled and validated swap paths for such externally routed flows or provide a fallback mechanism via the core contract to retain swap support.
Resolution
GMX Team: Resolved.
-
L-04 Low Enum Ordering Consistency Best Practices Acknowledged
Description
A new enum value,
SetTraderReferralCode, was recently added to theActionTypeenum used by multichain providers:enum ActionType { None, Deposit, GlvDeposit, BridgeOut, SetTraderReferralCode }Since Solidity enums are nothing but ordered
uint16s, placingSetTraderReferralCodeafterBridgeOutintroduces semantic inconsistency.Recommendation
Consider reordering the enum values for consistency.
0 to 3: BridgeIn Action4: BridgeOut Actionenum ActionType { None, //0 Deposit, //1 GlvDeposit, //2 SetTraderReferralCode, //3 BridgeOut //4 }Resolution
GMX Team: Acknowledged.
-
L-05 Low Newly Added Lending Config Keys Remain Unset Warning Acknowledged
Description
GMX has introduced several new configuration keys in the lending logic as part of recent changes. However, these remain unset in the current deployment process.
For instance, the following per-market keys:
maxLendableImpactFactorKeymaxLendableImpactUsdKey
These keys play a important role in determining the boundaries for lending-related impact calculations and risk mitigation, and leaving them unset could lead to undefined or unintended behavior post-deployment.
Recommendation
Be aware that these keys are currently unset and will need to be explicitly configured per market post-deployment to ensure lending behavior aligns with intended risk management.
Resolution
GMX Team: Acknowledged.
-
L-06 Low Theoretical Censorship Risk Via Stargate Reentrancy DoS Acknowledged
Description
The
bridgeOutFromControllerfunction allows users to bridge out atomically. However, similar to M-02, this action could theoretically be censored if a malicious actor chooses to interfere.In this case, censorship could occur through a
nonReentrant-basedrevert on the Stargate side. For reference, thenonReentrantmodifier is enforced here.A keeper could initiate the call trace from Stargate, invoke a GMX Core action that intentionally causes a revert (e.g., due to reentrancy), and thereby cause the bridgeOut to fail silently.
While there is no rational incentive for keepers to do this under normal assumptions, it remains a theoretical attack vector.
Recommendation
GMX should be aware of this possibility. While action may not be necessary due to the involvement of trusted roles (keepers) who lack any incentive to exploit this vector.
Resolution
GMX Team: Acknowledged.
-
L-07 Low Signatures Might Be Exposed Warning Resolved
Description
Users can provide additional data in the
dataListto invoke thebridgeOutFromControllerflow after deposit execution. This data includesrelayParams, which contains a signature field.Normally, a signature is not required for this specific action, as the function validates the call using
_validateCallWithoutSignature.Additionally, users cannot know the exact amount that will be bridged out following deposit execution, making it difficult to produce a valid signature.
However, if a user provides a signature thinking it is necessary, the signature will not be used but will still be valid and publicly exposed. Later, anyone could use the same signature to invoke the regular
bridgeOutflow.Recommendation
Either ensure that the signature field is empty when using the
bridgeOutFromControllerflow, or clearly document this behavior for users.Resolution
GMX Team: Resolved.
-
L-08 Low Documentation Regarding executionFee Documentation Resolved
Description
The
_handleRelayFeeand_handleRelayAfterActionfunctions will return early for calls made through theLayerZeroProvidercontract, with the addition of theisRelayFeeExcludedKey.Normally, the
_handleRelayFeefunction is responsible for handling both the relay fee and the execution fee associated with the deposit.With the exclusion of
LayerZeroProvider, the execution fee for cross-chain deposits can no longer be handled within_handleRelayFee.Instead, the execution fee must be transferred to the router contracts within
_handleExternalCallsduringwithRelay,before the early return in_handleRelayFee.Otherwise, cross-chain deposits will fail due to the router having an insufficient
wntbalance when attempting to transfer the execution fee to thedepositHandler.Recommendation
Document this behavior and inform users about the execution fee handling process.
Resolution
GMX Team: Resolved.
-
L-09 Low Bridged Deposit Might Fail Due To Oracle Warning Acknowledged
Description
The
_handleRelayBeforeActionfunction has thewithAtomicOraclePricesmodifier. These atomic prices are necessary to be able to perform swaps during the_handleRelayFeefunction. However,_handleRelayFeereturns early for bridged deposits, so swaps are not performed.Therefore, setting atomic prices in this case is not necessary. A bridged deposit that would normally succeed might fail during this unnecessary price setting due to issues such as sequencer downtime.
Recommendation
Consider not setting atomic oracle prices if
isRelayFeeExcludedKeyis true, or be aware of this situation.Resolution
GMX Team: Acknowledged.
-
L-10 Low reduceLentAmount DoS'd With Atomic Swap DoS Acknowledged
Description
The
reduceLentAmountfunction relies on thefundingAccounthaving sufficient approval and balance for the resultinglongTokenAmountandshortTokenAmount.However these amounts may change before the
reduceLentAmountfunction can be executed and cause the execution to fail.Furthermore a malicious actor may frontrun the
reduceLentAmountinvocation with an atomic swap that intentionally changes the backing ratios of the market such that thereduceLentAmountcall fails.In the worst case this could delay the reduction from occurring but can be fixed by ensuring that the
fundingAccounthas sufficient balances for both tokens and sufficient approvals.Recommendation
Be aware of this DoS vector and plan accordingly.
Resolution
GMX Team: Acknowledged.
-
L-11 Low reduceLentAmount Rounds Against The Protocol Rounding Resolved
Description
The
reduceLentAmountfunction uses thegetProportionalAmountsfunction to determine the amounts to be deposited to make up thereductionAmount.The
totalUsdis maximized using the max price for the index token, however thegetProportionalAmountsperforms round down truncation division on the resulting token amounts as well as the max prices for the total pool value calculation.Recommendation
Consider adding a boolean to the
getProportionalAmountsfunction to indicate that whether the result should be maximized or minimized.Resolution
GMX Team: Resolved.
-
L-12 Low Missing Residual Fee Refunds Warning Resolved
Description
In the
_handleRelayAfterActionfunction in the context of a composed action through the multichain provider the execution early returns.However this misses the
_transferResidualFeerefund which may be necessary if an external call refunded wnt amount to the router contract.Recommendation
Consider if the
_transferResidualFeeaction should still occur for multichain_handleRelayAfterActioninvocations. If not, be sure to clearly document this for any users or integrations so their wnt is not lost.Resolution
GMX Team: Resolved.
-
L-13 Low Nonexistent srcChainId Is Not Validated Validation Acknowledged
Description
In the
_decodeLzComposeMsgfunction theeidToSrcChainIdlookup is used to convert the LZ message'ssrcEidto achainId. However if the src chain is not supported thiseidToSrcChainIdwill return an unexpected 0 chain id.This will simply emit a misleading event and allow the deposit to occur from an unsupported chain. This may also lead to unexpected issues with composed actions.
Recommendation
Consider validating that the resulting
srcChainIdfrom theeidToSrcChainIdlookup is not 0 in the_decodeLzComposeMsgfunction.Resolution
GMX Team: Acknowledged.
-
L-14 Low Duplicated srcChainId Validations Superfluous Code Acknowledged
Description
Both
BridgeOutFromControllerUtils.bridgeOutFromControllerandMultichainTransferRouter.bridgeOutFromControllervalidate if thesrcChainId = 0and early return if so.This was added for a previous issue where native deposits (srcChainId = 0) where trying to bridge out GLV and GM tokens.
Recommendation
Remove one of the duplicated checks
Resolution
GMX Team: Acknowledged.
-
L-15 Low Price Impact Withdrawal Factor May DoS Users Configuration Acknowledged
Description
The
validateMaxLendableFactorfunction prevents users from withdrawing funds from the pool if thelentAmountis above a certain percentage of the pool amount. This is based on the market'smaxLendableImpactFactorForWithdrawalsKey.On the other side, decreasing positions allow users to realize positive price impact up to a percentage of the pool amount, based on the market's
maxLendableImpactFactorKey, which is different from the withdrawal flow.Two main issues arise from this logic:
validateMaxLendableFactoris checked on withdrawal execution, not on creation, so users might
create un-executable withdrawal orders.
- if
maxLendableImpactFactorForWithdrawalsKey > maxLendableImpactFactorKey, and a position
realized positive price impact using all lendable amount, subsequent withdrawal executions will fail.
In fact, after using the max lendable amount to pay positive price impact, the pool amount will decrease while the
lentAmountincreases. Therefore,validateMaxLendableFactorwill already fail for withdrawal executions aslentUsd > maxLendableUsdRecommendation
Consider checking for
validateMaxLendableFactorduring withdrawal order creation. Additionally, ensuremaxLendableImpactFactorForWithdrawalsKeyandmaxLendableImpactFactorKeyare correctly configured to avoid withdrawals DoS.Resolution
GMX Team: Acknowledged.
-
L-16 Low Positive Impact Cap Should Early Return Logical Error Resolved
Description
The
capPositiveImpactUsdByPositionImpactPoolapplies a cap on positivepriceImpactUsdamounts. However, if the amount is zero, the function will continue, even though it will eventually return zero.Recommendation
Early return if
priceImpactUsd < 0.Resolution
GMX Team: Resolved.
-
L-17 Low Forcing srcChainId To Equal dstEid Chain Logical Error Acknowledged
Description
The
bridgeOutflow ensures thesrcChainIdis equal to the chain mapped fordstEid. This solves the issue where users could bypass theisSrcChainIdEnabledKeyand bridge out to a different chain with thedstEidparam.However, this forces the user to bridge out to only one specific chain, especially in the following cases:
- bridge in + deposit +
bridgeOut(srcChainIdis the chain where funds are bridged from) - deposit +
bridgeOut(srcChainIdis the one user signed the gasless transaction from)
Recommendation
If this is the expected behavior, make sure to document it for users so they are aware of the limitations, and the importance of signing transactions from certain chains when the action will bridge out funds.
Resolution
GMX Team: Acknowledged.
- bridge in + deposit +
-
L-18 Low TargetIsNotAContract Error Not Used Superfluous Code Resolved
Description
The
TargetIsNotAContractis defined inErrors.solcontract, but it's never used.Recommendation
Remove the
TargetIsNotAContracterror.Resolution
GMX Team: Resolved.
No findings match.
More from GMX
All 44 reportsPut your code through the same review.
This review started with a conversation about scope. Tell us what you are building and we will plan yours with you.
