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.
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
GlvVaultby settingisMarketTokenDeposittotrue. 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:
| Parameter | Type | Description |
|---|---|---|
params | IGlvDepositUtils.CreateGlvDepositParams | Struct 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.
| Field | Description |
|---|---|
addresses | Group of address fields listed in CreateGlvDepositParamsAddresses. |
minGlvTokens | Minimum acceptable amount of GLV tokens to receive. |
executionFee | Amount 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. |
callbackGasLimit | Gas limit passed to the callback contract on deposit execution or cancellation. |
shouldUnwrapNativeToken | Whether 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. |
isMarketTokenDeposit | Set 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. |
dataList | Array of additional bytes32 data. Pass an empty array if no extra data is needed. |
CreateGlvDepositParamsAddresses
| Field | Description |
|---|---|
glv | Address of the GLV vault to deposit into. |
market | GM market to deposit into. Must be a market that the GLV vault supports. |
receiver | Address that receives the GLV tokens. |
callbackContract | Contract to call on deposit execution or cancellation. |
uiFeeReceiver | Address that receives the UI fee. |
initialLongToken | Long token transferred into the contract. Set to the zero address for GM token deposits. |
initialShortToken | Short token transferred into the contract. Set to the zero address for GM token deposits. |
longTokenSwapPath | Array of market addresses to swap initialLongToken through before depositing. |
shortTokenSwapPath | Array 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.
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:
| Parameter | Type | Description |
|---|---|---|
params | IGlvWithdrawalUtils.CreateGlvWithdrawalParams | Struct 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.
| Field | Description |
|---|---|
addresses | Group of address fields listed in CreateGlvWithdrawalParamsAddresses. |
minLongTokenAmount | Minimum output amount of long token after swapping through longTokenSwapPath. For example, if WETH is swapped to BTC, this specifies the minimum BTC amount. |
minShortTokenAmount | Minimum output amount of short token after swapping through shortTokenSwapPath. |
shouldUnwrapNativeToken | Whether 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. |
executionFee | Amount 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. |
callbackGasLimit | Gas limit passed to the callback contract on withdrawal execution or cancellation. |
dataList | Array of additional bytes32 data. Pass an empty array if no extra data is needed. |
CreateGlvWithdrawalParamsAddresses
| Field | Description |
|---|---|
receiver | Address that receives the withdrawn tokens. |
callbackContract | Contract to call on withdrawal execution or cancellation. |
uiFeeReceiver | Address that receives the UI fee. |
market | GM market to withdraw from. Must be a market that the GLV vault supports. |
glv | Address of the GLV vault to withdraw from. |
longTokenSwapPath | Array of market addresses to swap the withdrawn long token through. |
shortTokenSwapPath | Array 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:
| Parameter | Type | Description |
|---|---|---|
key | bytes32 | Key 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:
| Parameter | Type | Description |
|---|---|---|
key | bytes32 | Key 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
- GLV Reader -- Query GLV vault data and pricing
- Simulations -- Dry-run GLV actions
- Contract addresses -- GlvRouter and GlvVault addresses per chain
- ExchangeRouter -- GM market operations