GMX engaged Guardian to review the security of their GMX Crosschain architecture. From the 23rd of June to the 2nd of July, a team of 6 auditors reviewed the source code in scope.
- Published
- Review window
- June 23 to July 2, 2025
- Language
- Solidity
- Chains
- Arbitrum, Avalanche
- Sector
- Perpetuals
- 0 Critical
- 1 High
- 4 Medium
- 14 Low
- 0 Informational
Scope
Overview
GMX engaged Guardian to review the security of their GMX Crosschain architecture. From the 23rd of June to the 2nd of July, a team of 6 auditors reviewed the source code in scope.
Findings 19
-
H-01 High Bridged Withdrawals Fail Logical Error Resolved
Description
GM and GLV withdrawals result in two output tokens, and the
bridgeOutFromControllerfunction is called twice to bridge these tokens. Both calls tobridgeOutFromControlleruse the samewithdrawal.dataList.The
dataListcontains the Stargate provider address, and that provider can only bridge a single specific token, which isstargate.token(). Therefore, it is not possible to bridge bothoutputTokenandsecondaryOutputTokenusing the samedataList.Recommendation
One option to consider is including two different providers in the
dataListduring cross-chain withdrawals.However, this would require different
dataListdecoding logic for deposits and withdrawals, as deposits require bridging only a single token.Another option is to enforce
outputToken = secondaryOutputTokenwhen the user wants to withdraw and bridge out.Resolution
GMX Team: Resolved.
-
M-01 Medium Price Impact Factor Gaming Gaming Acknowledged
Description
Because the price impact is no longer capped to the amount available in the impact amalgam, but rather the maximum lent, it is possible that net positive impact is paid out to traders from the market up to the magnitude of the max lent.
This could arise and be potentially forced through a gaming of the price impact factors as they change based upon the market depth.
A sophisticated actor could observe that the market depth off-chain is now lower and open trades before the price impact factors are updated to bank a X amount of negative impact for creating an imbalance of A.
The sophisticated actor could then observe the price impact factors by GMX being updated and realize Y amount of positive impact for closing their position and removing the imbalance of A.
Recommendation
Be aware of this risk, to mitigate its probability the risk oracle price impact factor changes should not be large in magnitude compared to their previous factors. Furthermore be sure to keep the max lent usd values small so that the opportunity is limited.
Resolution
GMX Team: Acknowledged.
-
M-02 Medium Incorrect Position Key Used Logical Error Resolved
Description
In the
_updatePositionLastSrcChainIdfunction the swap path is evaluated to find the collateral token of the position.However for decrease orders this will produce an inaccurate result as the swap path has nothing to do with the collateral token of the position.
Recommendation
Only evaluate the resulting token from the order swap path for increase orders and use the
initialCollateralTokenfor decrease orders.Resolution
GMX Team: Resolved.
-
M-03 Medium Incorrect Gas Utils Function Logical Error Resolved
Description
The
_handleGlvWithdrawalinLayerZeroProvider.soluses_validateGasLeftto validate if the gas left is sufficient to cover the remaining GLV withdrawal creation flow.However, it uses the
GasUtilsfunctionestimateCreateGlvDepositGasLimitinstead of theestimateCreateGlvWithdrawalGasLimit.This can lead to incorrect gas validation and potentially causing the known compose censoring issue.
Recommendation
Use the correct
GasUtilsfunction for the_handleGlvWithdrawalflow:estimateCreateGlvWithdrawalGasLimitResolution
GMX Team: Resolved.
-
M-04 Medium Same Actions Cannot Be Done Validation Resolved
Description
The nonce was removed from the
relayParamsto fix a previous issue, and the replay check is now performed based on thedigest.However, since there is no unique identifier, the
structHashand thedigestwill be identical for the exact same actions.This will result in the same signature being generated, causing the action to fail even if the user legitimately intends to perform it a second time.
Users must change something in the signature if they want to perform the same action with the same parameters.
The easiest option appears to be the
deadline, allowing users to repeat the same action by signing with a different deadline value.Recommendation
Document this behavior for users and inform them about how digests are generated. Alternatively, consider adding a user-provided salt to the
relayParamsto allow differentiation of actions, even when all other parameters are identical.Resolution
GMX Team: Resolved.
-
L-01 Low Lent Payback Is Not Rounded Up Rounding Resolved
Description
In the
reduceLentAmountfunction thelongTokenAmountandshortTokenAmountcomputed to be paid by the caller is rounded down. Instead this amount should be rounded up to round in the favor of the GM market.Recommendation
Consider rounding the
longTokenAmountandshortTokenAmountvalues up to round in favor of the GM market.Resolution
GMX Team: Resolved.
-
L-02 Low Config Keeper May Init An Invalid Provider Unexpected Behavior Resolved
Description
In the
initOracleProviderForTokenfunction there is no validation that the provider is enabled with theisOracleProviderEnabledKey.Furthermore there is no validation that the token is not
address(0).Recommendation
Consider validating that the provider is enabled with the
isOracleProviderEnabledKeyand that the token is notaddress(0).Resolution
GMX Team: Resolved.
-
L-03 Low Provider May Be Immediately Updated Unexpected Behavior Acknowledged
Description
In the
initOracleProviderForTokenfunction theoracleProviderUpdatedAtvalue is not assigned, therefore the config keeper may immediately invoke thesetOracleProviderForTokenfunction to configure a new provider.Recommendation
Consider updating the
oracleProviderUpdatedAtvalue in theinitOracleProviderForTokenfunction.Resolution
GMX Team: Acknowledged.
-
L-04 Low Config Keeper Trusted To Set Providers Trust Assumptions Acknowledged
Description
In the
setOracleProviderForTokenfunction the config keeper is able to reset the oracle provider for a token that is currently configured.As a result a compromised Config Keeper may assign a supported provider that is incompatible with the specified token in order to DoS trades for a period of time and potentially carry out risk free trades or avoid liquidation.
It may also be possible to use a feed which reports an inaccurate price for the token in order to game the exchange.
Recommendation
Consider if the Config Keeper should be trusted to set the provider for an already configured token. If not, then consider only allowing the oracle provider for an already configured token to be configured through the time lock.
Resolution
GMX Team: Acknowledged.
-
L-05 Low Lacking Error Validation Validation Resolved
Description
In the
validateSignaturefunction, during the second attempt at signature verification the error returned by thetryRecoverfunction is not validated to be theECDSA.RecoverError.NoErrorresult.Recommendation
Out of an abundance of caution, consider validating that the error from the second
tryRecoverinvocation is theECDSA.RecoverError.NoErrorresult.Resolution
GMX Team: Resolved.
-
L-06 Low Bridging Fee Is Paid Twice Logical Error Resolved
Description
Two cross-chain bridging transactions occur during cross-chain withdrawals, regardless of the output tokens, and both transactions incur a bridging fee.
However, if
outputToken = secondaryOutputToken, there's no need to bridge twice. Instead, the total output amount can be bridged in a single transaction, avoiding double fees.Recommendation
Bridge
outputAmount + secondaryOutputAmountin a single transaction if the output tokens are the same.Resolution
GMX Team: Resolved.
-
L-07 Low Documentation Regarding Withdrawals Documentation Acknowledged
Description
Cross-chain withdrawals attempt to bridge both
outputTokenandsecondaryOutputToken. However, there is no guarantee that these tokens are supported by Stargate, as the Stargate currently supports only a limited set of major tokens.As a result, users attempting to bridge out the resulting output tokens may encounter unexpected failures.
Recommendation
Document which output tokens are supported by Stargate for bridging, and clearly inform users of these limitations.
Resolution
GMX Team: Acknowledged.
-
L-08 Low Increased Signature Protection Warning Acknowledged
Description
In the
validateSignaturefunction the minified digest is not marked as used, based on the idea that the original digest being marked as used is sufficient.However there is some nonzero chance that a malicious actor is able to find a collision with the minified digest that allows the same signature to be submitted and successfully authenticated on behalf of the victim.
Recommendation
While the likelihood of this being a viable attack vector is extremely small, out of an abundance of caution the
minifiedDigestwhich was signed should be marked as used as well.This way if a collision were to ever occur it would simply prevent a user from making a certain signature, versus allowing for an unexpected action to be carried out on behalf of the user.
Resolution
GMX Team: Acknowledged.
-
L-09 Low Execution Cost Greater Than Provided Fee Configuration Acknowledged
Description
During withdrawal creation, the handler verifies if the
wnttokens sent by the user are enough to cover the estimated gas spent during execution.For withdrawals, this estimation uses the an estimated gas limit of
1_500_000set in the config, plus some base amount and adjustments.However, the withdrawal execution now includes two optional bridge out flows, that will break the gas limit estimation. Therefore, keepers will need to spend more gas than the execution fee supplied by the user, so they will prefer not to execute these.
The same applies to the glv withdrawal flow. Additionally, this may pose a notable issue on chains with lower block gas limits such as avalanche, in some cases opening up opportunities for risk free trades.
Recommendation
During our internal testing, the gas spent to execute a withdrawal with bridge out flows is above
2_700_000. We advice to conduct some testing with different params and increase both thewithdrawalGasLimitandglvWithdrawalGasLimitto a more suitable value.Resolution
GMX Team: Acknowledged.
-
L-10 Low Missing Gas Limit Config Params Configuration Acknowledged
Description
The
LayerZeroProvidernow allows users to initiate a GM or GLV withdrawal order creation. These new flows also include the_validateGasLeftto prevent a previous issue regardinglzComposecensoring.However, neither
CREATE_WITHDRAWAL_GAS_LIMITorCREATE_GLV_DEPOSIT_GAS_LIMITare set in general config, so these values are 0 in thedataStore.This opens up the risk of an actor invoking the
lzComposefunction, providing insufficient amount of gas and forcing the withdrawal transaction to fail.Recommendation
Add the missing keys to the general config and be sure to include them in the
updateGeneralConfigUtilsscript.Resolution
GMX Team: Acknowledged.
-
L-11 Low Order Cancels Do Not Update lastSrcChainId Logical Error Acknowledged
Description
The
lastSrcChainIdis updated on order creation, however when an order is canceled it is not considered for alastSrcChainIdupdate.Recommendation
Include
_updatePositionLastSrcChainIdat the end of the cancel order flow.Resolution
GMX Team: Acknowledged.
-
L-12 Low Loss Of Signature Cancelability And Sequentiality Warning Acknowledged
Description
As a fix for using nonces in non-atomic actions (crosschain), GMX switched to using digests to protect against replays.
However, this approach is applied globally across all actions, not just cross-chain ones. This comes with two implications:
- Users can no longer cancel a signature by issuing a new one with the same nonce—unlike
standard EVM-style signature workflows. A signed message remains valid until its deadline.
- At time T=0, if a user signs multiple actions, they are no longer processed sequentially, which
could be important in some trade setups.
Recommendation
If these trade-offs are acceptable, consider enforcing short deadlines close to the current timestamp. Otherwise, consider separating cross-chain non-atomic logic from the rest of the gasless/multichain action set.
Resolution
GMX Team: Acknowledged.
-
L-13 Low Unnecessary Reordering Of Transfer Steps Best Practices Acknowledged
Description
To support multichain fee payments for atomic actions from
lzCompose, GMX reordered_processTransferRequeststo come before the WNT transfer.However, this is no longer necessary, as the early return for excluded addresses in
handleRelayFeewas removed. This allows users to send tokens directly to the router when needed.Recommendation
While there is no harm in the current order as well, we just want to make GMX aware that they can use
handleRelayFeeto transfer tokens to router similar to all gasless actions, and don’t have to use transfer requests specifically.Resolution
GMX Team: Acknowledged.
-
L-14 Low Bridging Out Tokens From GLV Vault Warning Resolved
Description
User may optionally bridge out tokens after withdrawing from GLV. However, the
executeGlvWithdrawaluses thesrcChainId,receiveranddataListfrom theglvWithdrawalstruct.If
receiver = glvWithdrawal.glv(),srcChainId = 0anddataListcontains the bridge action data, this will start a bridge out using theglvas the account.Although user will lose all of its funds plus a previous
wntdeposit to pay for the bridge fee, this is an unexpected scenario that might become significant if theglvaddress will eventually have non-zero multichain balance.Recommendation
Consider passing an empty
dataListarray andsrcChainId = 0, just like it's done in theexecuteGlvDepositflow.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.
