Skip to main content

GlvRouter

The GlvRouter contract is the main entry point for creating and cancelling GLV (GMX Liquidity Vault) deposits and withdrawals. It works similarly to the ExchangeRouter but targets GLV vaults instead of individual GM markets.

For an overview of the contract architecture and execution model, see Architecture.

Creating a GLV deposit

To create a GLV deposit, you must first transfer the required tokens to the GlvVault, then call GlvRouter.createGlvDeposit in the same transaction.

warning

The token transfer and the GlvRouter.createGlvDeposit call must occur in a single transaction. If they are separated, other users may withdraw the transferred tokens before your deposit is created.

You can deposit in two ways:

  • Underlying tokens -- Transfer long and short tokens to the GlvVault. The protocol mints GM tokens internally, then mints GLV tokens to the receiver.
  • GM market tokens -- Transfer GM tokens directly to the GlvVault by setting isMarketTokenDeposit to true. The protocol skips the GM minting step and mints GLV tokens to the receiver.

If this transaction reverts, the token transfer also reverts, so no funds remain in the GlvVault. If the deposit request is created successfully and is later cancelled, the initial deposit tokens are returned to the account that created the deposit, and any unused execution fee is refunded separately.

GlvRouter.createGlvDeposit

function createGlvDeposit(
IGlvDepositUtils.CreateGlvDepositParams calldata params
) external payable returns (bytes32)

Use this to add liquidity to a GLV vault. Transfer the execution fee and any long / short input tokens (or GM tokens) to the GlvVault in the same transaction, usually via multicall.

Example (TypeScript / ethers):

await usdc.approve(router.address, shortTokenAmount);

await glvRouter.multicall(
[
glvRouter.interface.encodeFunctionData("sendWnt", [glvVault.address, executionFee]),
glvRouter.interface.encodeFunctionData("sendTokens", [usdc.address, glvVault.address, shortTokenAmount]),
glvRouter.interface.encodeFunctionData("createGlvDeposit", [
{
addresses: {
glv: glvToken.address,
market: marketToken,
receiver: liquidityProvider.address,
callbackContract: ethers.constants.AddressZero,
uiFeeReceiver: ethers.constants.AddressZero,
initialLongToken: longToken,
initialShortToken: usdc.address,
longTokenSwapPath: [],
shortTokenSwapPath: [],
},
minGlvTokens,
executionFee,
callbackGasLimit: 0,
shouldUnwrapNativeToken: false,
isMarketTokenDeposit: false,
dataList: [],
},
]),
],
{ value: executionFee }
);

Parameters:

ParameterTypeDescription
paramsIGlvDepositUtils.CreateGlvDepositParamsStruct containing GLV deposit configuration

Returns: bytes32 -- the key that identifies this GLV deposit request.

CreateGlvDepositParams

The deposit struct is split into address fields and a set of numeric fields and flags.

FieldDescription
addressesGroup of address fields listed in CreateGlvDepositParamsAddresses.
minGlvTokensMinimum acceptable amount of GLV tokens to receive.
executionFeeAmount of native token (for example, ETH on Arbitrum) included as the execution fee. This is the maximum fee keepers can use to execute the deposit. Any excess is returned to the deposit account. See Execution Fee for details.
callbackGasLimitGas limit passed to the callback contract on deposit execution or cancellation.
shouldUnwrapNativeTokenWhether to unwrap the native token if the deposit is cancelled. For example, if initialLongToken is WETH and this is true, the contract converts WETH to ETH before refunding.
isMarketTokenDepositSet to true when depositing GM market tokens directly instead of underlying long/short tokens. When true, initialLongToken and initialShortToken must be the zero address, and both swap paths must be empty.
dataListArray of additional bytes32 data. Pass an empty array if no extra data is needed.

CreateGlvDepositParamsAddresses

FieldDescription
glvAddress of the GLV vault to deposit into.
marketGM market to deposit into. Must be a market that the GLV vault supports.
receiverAddress that receives the GLV tokens.
callbackContractContract to call on deposit execution or cancellation.
uiFeeReceiverAddress that receives the UI fee.
initialLongTokenLong token transferred into the contract. Set to the zero address for GM token deposits.
initialShortTokenShort token transferred into the contract. Set to the zero address for GM token deposits.
longTokenSwapPathArray of market addresses to swap initialLongToken through before depositing.
shortTokenSwapPathArray of market addresses to swap initialShortToken through before depositing.

Creating a GLV withdrawal

To create a GLV withdrawal, send the GLV tokens and execution fee to the GlvVault and call GlvRouter.createGlvWithdrawal in the same transaction, usually via multicall.

warning

The token transfer and the GlvRouter.createGlvWithdrawal call must occur in a single transaction. If they are separated, other users may withdraw the transferred tokens before your withdrawal is created.

GlvRouter.createGlvWithdrawal

function createGlvWithdrawal(
IGlvWithdrawalUtils.CreateGlvWithdrawalParams calldata params
) external payable returns (bytes32)

Use this to create an asynchronous GLV withdrawal request. Transfer the GLV tokens and execution fee to the GlvVault in the same transaction, usually via multicall. The withdrawal size is determined by the GLV token amount sent to the GlvVault with sendTokens.

Example (TypeScript / ethers):

await glvToken.approve(router.address, glvTokenAmount);

await glvRouter.multicall(
[
glvRouter.interface.encodeFunctionData("sendWnt", [glvVault.address, executionFee]),
glvRouter.interface.encodeFunctionData("sendTokens", [
glvToken.address,
glvVault.address,
glvTokenAmount,
]),
glvRouter.interface.encodeFunctionData("createGlvWithdrawal", [
{
addresses: {
receiver: trader.address,
callbackContract: ethers.constants.AddressZero,
uiFeeReceiver: ethers.constants.AddressZero,
market: marketToken.address,
glv: glvToken.address,
longTokenSwapPath: [],
shortTokenSwapPath: [],
},
minLongTokenAmount,
minShortTokenAmount,
shouldUnwrapNativeToken: false,
executionFee,
callbackGasLimit: 0,
dataList: [],
},
]),
],
{ value: executionFee }
);

Parameters:

ParameterTypeDescription
paramsIGlvWithdrawalUtils.CreateGlvWithdrawalParamsStruct containing GLV withdrawal configuration

Returns: bytes32 -- the key that identifies this GLV withdrawal request.

CreateGlvWithdrawalParams

The GLV token amount to withdraw is not part of CreateGlvWithdrawalParams. It is set by the amount sent to the GlvVault in the preceding sendTokens call.

FieldDescription
addressesGroup of address fields listed in CreateGlvWithdrawalParamsAddresses.
minLongTokenAmountMinimum output amount of long token after swapping through longTokenSwapPath. For example, if WETH is swapped to BTC, this specifies the minimum BTC amount.
minShortTokenAmountMinimum output amount of short token after swapping through shortTokenSwapPath.
shouldUnwrapNativeTokenWhether to unwrap the native token on output. For example, if the output token is WETH and this is true, the contract converts WETH to ETH before sending.
executionFeeAmount of native token (for example, ETH on Arbitrum) included as the execution fee. This is the maximum fee keepers can use to execute the withdrawal. Any excess is returned to the withdrawal account. See Execution Fee for details.
callbackGasLimitGas limit passed to the callback contract on withdrawal execution or cancellation.
dataListArray of additional bytes32 data. Pass an empty array if no extra data is needed.

CreateGlvWithdrawalParamsAddresses

FieldDescription
receiverAddress that receives the withdrawn tokens.
callbackContractContract to call on withdrawal execution or cancellation.
uiFeeReceiverAddress that receives the UI fee.
marketGM market to withdraw from. Must be a market that the GLV vault supports.
glvAddress of the GLV vault to withdraw from.
longTokenSwapPathArray of market addresses to swap the withdrawn long token through.
shortTokenSwapPathArray of market addresses to swap the withdrawn short token through.

Cancelling GLV requests

You can cancel a pending GLV deposit or withdrawal if it hasn't been executed yet. Only the account that created the request can cancel it.

GlvRouter.cancelGlvDeposit

function cancelGlvDeposit(bytes32 key) external

Cancels a pending GLV deposit. The deposited tokens and any unused execution fee are returned to the original account.

Parameters:

ParameterTypeDescription
keybytes32Key of the GLV deposit request to cancel

GlvRouter.cancelGlvWithdrawal

function cancelGlvWithdrawal(bytes32 key) external

Cancels a pending GLV withdrawal. The GLV tokens and any unused execution fee are returned to the original account.

Parameters:

ParameterTypeDescription
keybytes32Key of the GLV withdrawal request to cancel

Simulating GLV execution

You can dry-run GLV deposits and withdrawals before keeper execution. These simulation helpers are publicly callable on GlvRouter, but the real execution path remains keeper-only on GlvDepositHandler.executeGlvDeposit and GlvWithdrawalHandler.executeGlvWithdrawal. Like the simulation helpers on ExchangeRouter, these calls execute with supplied oracle prices and revert with EndOfOracleSimulation on success, so they are typically used through eth_call or callStatic-style preflight checks rather than as standalone state-changing transactions.

GlvRouter.simulateExecuteGlvDeposit

function simulateExecuteGlvDeposit(
bytes32 key,
OracleUtils.SimulatePricesParams memory simulatedOracleParams
)

Simulates execution for a specific GLV deposit request key.

GlvRouter.simulateExecuteLatestGlvDeposit

function simulateExecuteLatestGlvDeposit(
OracleUtils.SimulatePricesParams memory simulatedOracleParams
)

Simulates execution for the latest created GLV deposit request.

GlvRouter.simulateExecuteGlvWithdrawal

function simulateExecuteGlvWithdrawal(
bytes32 key,
OracleUtils.SimulatePricesParams memory simulatedOracleParams
)

Simulates execution for a specific GLV withdrawal request key.

GlvRouter.simulateExecuteLatestGlvWithdrawal

function simulateExecuteLatestGlvWithdrawal(
OracleUtils.SimulatePricesParams memory simulatedOracleParams
)

Simulates execution for the latest created GLV withdrawal request.

External swaps before GLV actions

GlvRouter also exposes makeExternalCalls(...) through its ExternalHandler integration. Use this when you need to perform an external swap or aggregator call before creating the GLV request, then refund any residual tokens back to the intended receivers.

Next steps