{"id":"bc94c53d-69fb-4903-8e8a-a57bfdcd5e9f","shortId":"Tywh8b","kind":"skill","title":"gmx-liquidity","tagline":"Provide liquidity on GMX V2 — deposit into GM pools and GLV vaults, withdraw, shift between pools, and query pool data across Arbitrum, Avalanche, and Botanix.","description":"# GMX Liquidity Skill\n\n## Overview\n\nGMX V2 has two liquidity layers that back perpetual and spot trading:\n\n- **GM Pools** — Single-market liquidity pools. Each GM pool backs one market (e.g., ETH/USD) and is composed of a long token and short token. Depositing mints GM tokens (LP tokens); withdrawing burns them.\n- **GLV Vaults** (GMX Liquidity Vaults) — Multi-market vaults that hold multiple GM tokens and auto-rebalance across constituent pools. Depositing mints GLV tokens; withdrawing burns them.\n\n**Supported chains:**\n| Chain | Chain ID | Native Token | GLV Vaults |\n|-------|----------|-------------|------------|\n| Arbitrum | 42161 | ETH | Yes |\n| Avalanche | 43114 | AVAX | Yes |\n| Botanix | 3637 | BTC | No (contracts deployed, no vaults configured) |\n\n**Execution model:** All write operations use a two-step async pattern:\n1. User creates a request (deposit/withdrawal/shift) via `ExchangeRouter` or `GlvRouter` multicall\n2. Keeper executes the request with oracle prices (typically 1–30 seconds later)\n\nThe user pays an execution fee (in native token) upfront to cover keeper gas costs. Excess fee is refunded.\n\n**Integration paths:**\n- **SDK** (`@gmx-io/sdk`) — Read pool data, balances, and market info. Write operations (deposit/withdraw) are not yet in the SDK.\n- **Contract-level** (viem) — Full read + write via `ExchangeRouter.multicall()` and `GlvRouter.multicall()`.\n\nThis skill complements [gmx-trading](../gmx-trading/SKILL.md) which covers perpetual trading and swaps.\n\n## GM Pools\n\nEach GM pool is a pair of tokens backing a specific market:\n- **Long token** — The asset (e.g., WETH for ETH/USD)\n- **Short token** — The stablecoin (e.g., USDC)\n- **GM token** — The LP token representing a share of the pool\n\n**Deposits** can be:\n- **Balanced** — Deposit both long and short tokens proportionally. Lower fees (helps balance the pool).\n- **Single-sided** — Deposit only one token. The protocol swaps a portion internally. Higher fees if it imbalances the pool.\n\n**Withdrawals** burn GM tokens and return the underlying long and short tokens. A withdrawal can specify `minLongTokenAmount` and `minShortTokenAmount` for slippage protection.\n\n**Pricing:** GM token price = pool value / GM token supply. Pool value is the sum of long and short token values at oracle prices plus accrued PnL.\n\nGM pool addresses are dynamic — discover them via `sdk.markets.getMarkets()`.\n\n## GLV Vaults\n\nGLV vaults hold multiple GM tokens and auto-rebalance across markets:\n\n**Known GLV vaults** (source: [`sdk/src/configs/markets.ts`](https://github.com/gmx-io/gmx-interface/blob/release/sdk/src/configs/markets.ts)):\n| Chain | Vault | Long Token | Short Token | Address |\n|-------|-------|-----------|-------------|---------|\n| Arbitrum | GLV [WETH-USDC] | WETH | USDC | `0x528A5bac7E746C9A509A1f4F6dF58A03d44279F9` |\n| Arbitrum | GLV [WBTC-USDC] | WBTC | USDC | `0xdF03EEd325b82bC1d4Db8b49c30ecc9E05104b96` |\n| Avalanche | GLV [WAVAX-USDC] | WAVAX | USDC | `0x901eE57f7118A7be56ac079cbCDa7F22663A3874` |\n\n**Deposit modes:**\n- **Raw tokens** — Deposit long/short tokens. The vault creates a GM deposit into the selected constituent market, then deposits the resulting GM tokens into the GLV.\n- **GM tokens** — Deposit existing GM tokens directly (`isMarketTokenDeposit: true`). Skips the intermediate deposit step.\n\n**Withdrawals** burn GLV tokens. The vault withdraws from the specified constituent market and returns the underlying long/short tokens.\n\n## Reading Pool Data (SDK)\n\nUse `sdk.markets.getMarketsInfo()` to query all pool data:\n\n```typescript\nconst { GmxSdk } = require(\"@gmx-io/sdk\");\n\nconst sdk = new GmxSdk({\n  chainId: 42161,\n  rpcUrl: \"https://arb1.arbitrum.io/rpc\",\n  oracleUrl: \"https://arbitrum-api.gmxinfra.io\",\n  subsquidUrl: \"https://gmx.squids.live/gmx-synthetics-arbitrum:prod/api/graphql\",\n});\n\nconst { marketsInfoData, tokensData } = await sdk.markets.getMarketsInfo();\n\n// Find a specific pool\nconst ethPool = Object.values(marketsInfoData).find(\n  (m) => tokensData[m.indexTokenAddress]?.symbol === \"WETH\" && !m.isSpotOnly\n);\n\n// Pool liquidity data\nconsole.log(\"Long pool:\", ethPool.longPoolAmount);       // Long token amount in pool\nconsole.log(\"Short pool:\", ethPool.shortPoolAmount);      // Short token amount in pool\nconsole.log(\"Pool value (max):\", ethPool.poolValueMax);   // Total pool value USD\nconsole.log(\"Pool value (min):\", ethPool.poolValueMin);\n\n// Pool capacity\nconsole.log(\"Max long:\", ethPool.maxLongPoolAmount);      // Max long token capacity\nconsole.log(\"Max short:\", ethPool.maxShortPoolAmount);     // Max short token capacity\n\n// GM token address\nconsole.log(\"Market token:\", ethPool.marketTokenAddress);\n```\n\n**Check GM token balances:**\n\n```typescript\nconst { tokensData } = await sdk.tokens.getTokensBalances();\n// GM tokens appear as regular tokens — filter by market token addresses\n```\n\n**List all pools:**\n\n```typescript\nconst { marketsInfoData, tokensData } = await sdk.markets.getMarketsInfo();\n\nfor (const market of Object.values(marketsInfoData)) {\n  const indexSymbol = tokensData[market.indexTokenAddress]?.symbol ?? \"SPOT\";\n  const longSymbol = tokensData[market.longTokenAddress]?.symbol;\n  const shortSymbol = tokensData[market.shortTokenAddress]?.symbol;\n  console.log(`${indexSymbol}: ${longSymbol}/${shortSymbol} — Pool: ${market.poolValueMax}`);\n}\n```\n\n## Reading Pool Data (REST / GraphQL)\n\n**REST API** — Get market info including pool sizes:\n\n```\nGET https://arbitrum-api.gmxinfra.io/markets/info\n```\n\nReturns extended market data including pool sizes, utilization, open interest, and fee factors.\n\n**GraphQL (Subsquid)** — Query historical deposit/withdrawal events:\n\n| Chain | Endpoint |\n|-------|----------|\n| Arbitrum | `https://gmx.squids.live/gmx-synthetics-arbitrum:prod/api/graphql` |\n| Avalanche | `https://gmx.squids.live/gmx-synthetics-avalanche:prod/api/graphql` |\n| Botanix | `https://gmx.squids.live/gmx-synthetics-botanix:prod/api/graphql` |\n\n## Prerequisites for Write Operations\n\nBefore calling `ExchangeRouter.multicall()` or `GlvRouter.multicall()`:\n\n**1. Token approvals:**\n- For **all operations** (GM and GLV): approve tokens to `SyntheticsRouter`\n- This applies to GM deposits/withdrawals/shifts via `ExchangeRouter` and GLV deposits/withdrawals via `GlvRouter`\n\n```typescript\n// Approve USDC to SyntheticsRouter (works for both GM and GLV operations)\nawait usdcContract.write.approve([syntheticsRouterAddress, amount]);\n```\n\n**2. Default parameter values:**\n```typescript\ncallbackContract: zeroAddress,   // No callback\ncallbackGasLimit: 0n,            // No callback gas\ndataList: [],                     // Reserved for future use\nuiFeeReceiver: zeroAddress,      // No UI fee (set to your address if building a frontend)\n```\n\n**3. Native token handling:**\nWhen depositing the wrapped native token (WETH on Arbitrum, WAVAX on Avalanche, PBTC on Botanix) and `shouldUnwrapNativeToken` is true, add the deposit amount to the `sendWnt` call value instead of using `sendTokens`. The `sendWnt` call wraps native token automatically.\n\n```typescript\n// If depositing ETH (native) on Arbitrum:\nconst wntAmount = executionFee + longTokenAmount; // execution fee + deposit amount\n// Use sendWnt for the full amount, skip sendTokens for the long token\n```\n\n**4. Slippage:**\nApply slippage client-side before passing to the contract:\n```typescript\n// Apply 0.3% slippage to minimum output\nconst minMarketTokens = expectedMarketTokens * 997n / 1000n;\n```\n\n## Execution Fee Calculation\n\nAll operations require an execution fee in native token. The formula is the same for all operations:\n\n```\nestimatedGasLimit = (per-operation formula)\noraclePriceCount = (per-operation formula)\n\n// adjustGasLimitForEstimate (mirrors contract logic)\ngasLimit = estimatedGasFeeBaseAmount\n         + (estimatedGasFeePerOraclePrice × oraclePriceCount)\n         + applyFactor(estimatedGasLimit, estimatedFeeMultiplierFactor)\n\nexecutionFee = gasLimit × gasPrice\n```\n\n**Per-operation formulas:**\n\n| Operation | estimatedGasLimit | oraclePriceCount |\n|-----------|------------------|-----------------|\n| GM Deposit | `depositToken + swaps × singleSwap` | `3 + swapsCount` |\n| GM Withdrawal | `withdrawalMultiToken + swaps × singleSwap` | `3 + swapsCount` |\n| Shift | `shift` | `4` |\n| GLV Deposit (raw tokens) | `glvDepositGasLimit + markets × glvPerMarketGasLimit + depositToken + swaps × singleSwap` | `2 + marketsCount + swapsCount` |\n| GLV Deposit (GM tokens) | `glvDepositGasLimit + markets × glvPerMarketGasLimit` | `2 + marketsCount` |\n| GLV Withdrawal | `glvWithdrawalGasLimit + markets × glvPerMarketGasLimit + withdrawalMultiToken + swaps × singleSwap` | `2 + marketsCount + swapsCount` |\n\n**Important: `marketsCount` for GLV operations.**\nGLV vaults contain many constituent GM markets — GLV [WETH-USDC] on Arbitrum has **40+ markets**. The contract validates the execution fee against the actual constituent count, and reverts with `InsufficientExecutionFee` if too low. The SDK does not expose a method to query the GLV constituent market count. Use these values:\n\n| GLV Vault | Chain | Recommended `marketsCount` |\n|-----------|-------|---------------------------|\n| GLV [WETH-USDC] | Arbitrum | 53 |\n| GLV [WBTC-USDC] | Arbitrum | 53 |\n| GLV [WAVAX-USDC] | Avalanche | 20 |\n\nExcess execution fee is always refunded, so overestimating `marketsCount` is safe. GLV execution fees are typically ~0.001 ETH — roughly 10x higher than GM operations (~0.0001 ETH) due to the large number of constituent markets.\n\n**Using the SDK to get gas parameters:**\n\n```typescript\nconst gasLimits = await sdk.utils.getGasLimits();\nconst gasPrice = await sdk.utils.getGasPrice();\n\n// --- Per-operation gas limit field names from sdk.utils.getGasLimits() ---\n// GM Deposit:       gasLimits.depositToken\n// GM Withdrawal:    gasLimits.withdrawalMultiToken\n// Shift:            gasLimits.shift\n// GLV per-market:   gasLimits.glvPerMarketGasLimit\n// GLV Deposit:      gasLimits.glvDepositGasLimit\n// GLV Withdrawal:   gasLimits.glvWithdrawalGasLimit\n// Swap (per swap):  gasLimits.singleSwap\n// Base fee fields:  gasLimits.estimatedGasFeeBaseAmount,\n//                   gasLimits.estimatedGasFeePerOraclePrice,\n//                   gasLimits.estimatedFeeMultiplierFactor\n\nfunction calculateExecutionFee(estimatedGasLimit: bigint, oraclePriceCount: bigint): bigint {\n  let gasLimit = gasLimits.estimatedGasFeeBaseAmount;\n  gasLimit += gasLimits.estimatedGasFeePerOraclePrice * oraclePriceCount;\n  gasLimit += estimatedGasLimit * gasLimits.estimatedFeeMultiplierFactor / 10n ** 30n;\n  return gasLimit * gasPrice;\n}\n\n// Example: GM deposit (no swaps)\nconst gmDepositFee = calculateExecutionFee(gasLimits.depositToken, 3n);\n\n// Example: GLV deposit (raw tokens, 53 markets, no swaps)\nconst marketsCount = 53n;\nconst glvDepositGas = gasLimits.glvDepositGasLimit\n  + marketsCount * gasLimits.glvPerMarketGasLimit\n  + gasLimits.depositToken;\nconst glvDepositFee = calculateExecutionFee(glvDepositGas, 2n + marketsCount);\n```\n\n## Depositing into GM Pools\n\nUse `ExchangeRouter.multicall()` to batch send tokens + create deposit in one transaction:\n\n```typescript\nimport { encodeFunctionData, zeroAddress } from \"viem\";\n\nconst exchangeRouterAddress = \"0x1C3fa76e6E1088bCE750f23a5BFcffa1efEF6A41\"; // Arbitrum\nconst depositVaultAddress = \"0xF89e77e8Dc11691C9e8757e84aaFbCD8A67d7A55\";   // Arbitrum\n\n// Step 1: Approve tokens to SyntheticsRouter (one-time)\n// await longToken.write.approve([syntheticsRouterAddress, longTokenAmount]);\n// await shortToken.write.approve([syntheticsRouterAddress, shortTokenAmount]);\n\n// Step 2: Build multicall\nconst wntAmount = executionFee; // Add longTokenAmount if depositing native token\n\nconst multicall = [\n  encodeFunctionData({\n    abi: exchangeRouterAbi,\n    functionName: \"sendWnt\",\n    args: [depositVaultAddress, wntAmount],\n  }),\n  encodeFunctionData({\n    abi: exchangeRouterAbi,\n    functionName: \"sendTokens\",\n    args: [longTokenAddress, depositVaultAddress, longTokenAmount],\n  }),\n  encodeFunctionData({\n    abi: exchangeRouterAbi,\n    functionName: \"sendTokens\",\n    args: [shortTokenAddress, depositVaultAddress, shortTokenAmount],\n  }),\n  encodeFunctionData({\n    abi: exchangeRouterAbi,\n    functionName: \"createDeposit\",\n    args: [{\n      addresses: {\n        receiver: account.address,\n        callbackContract: zeroAddress,\n        uiFeeReceiver: zeroAddress,\n        market: marketTokenAddress,         // GM pool address\n        initialLongToken: longTokenAddress,\n        initialShortToken: shortTokenAddress,\n        longTokenSwapPath: [],\n        shortTokenSwapPath: [],\n      },\n      minMarketTokens: minGmTokensOut,      // Apply slippage\n      shouldUnwrapNativeToken: false,\n      executionFee: executionFee,\n      callbackGasLimit: 0n,\n      dataList: [],\n    }],\n  }),\n];\n\n// Step 3: Send transaction\nconst hash = await walletClient.writeContract({\n  address: exchangeRouterAddress,\n  abi: exchangeRouterAbi,\n  functionName: \"multicall\",\n  args: [multicall],\n  value: wntAmount,\n});\n```\n\n**Native token deposits:** If depositing WETH/WAVAX/PBTC with `shouldUnwrapNativeToken: true`, add the deposit amount to `wntAmount` (`executionFee + longTokenAmount`) and skip the `sendTokens` call for that token. The `sendWnt` call wraps native ETH/AVAX/BTC automatically.\n\n## Withdrawing from GM Pools\n\n```typescript\nconst withdrawalVaultAddress = \"0x0628D46b5D145f183AdB6Ef1f2c97eD1C4701C55\"; // Arbitrum\n\n// Approve GM tokens to SyntheticsRouter first\n// await gmToken.write.approve([syntheticsRouterAddress, marketTokenAmount]);\n\nconst multicall = [\n  encodeFunctionData({\n    abi: exchangeRouterAbi,\n    functionName: \"sendWnt\",\n    args: [withdrawalVaultAddress, executionFee], // Only execution fee, no deposit\n  }),\n  encodeFunctionData({\n    abi: exchangeRouterAbi,\n    functionName: \"sendTokens\",\n    args: [marketTokenAddress, withdrawalVaultAddress, marketTokenAmount], // GM tokens\n  }),\n  encodeFunctionData({\n    abi: exchangeRouterAbi,\n    functionName: \"createWithdrawal\",\n    args: [{\n      addresses: {\n        receiver: account.address,\n        callbackContract: zeroAddress,\n        uiFeeReceiver: zeroAddress,\n        market: marketTokenAddress,\n        longTokenSwapPath: [],\n        shortTokenSwapPath: [],\n      },\n      minLongTokenAmount: minLongOut,       // Apply slippage\n      minShortTokenAmount: minShortOut,     // Apply slippage\n      shouldUnwrapNativeToken: true,        // Unwrap WETH to ETH on receive\n      executionFee: executionFee,\n      callbackGasLimit: 0n,\n      dataList: [],\n    }],\n  }),\n];\n\nconst hash = await walletClient.writeContract({\n  address: exchangeRouterAddress,\n  abi: exchangeRouterAbi,\n  functionName: \"multicall\",\n  args: [multicall],\n  value: executionFee,\n});\n```\n\n## GLV Deposits\n\nUse `GlvRouter.multicall()` (not ExchangeRouter):\n\n```typescript\nconst glvRouterAddress = \"0x7EAdEE2ca1b4D06a0d82fDF03D715550c26AA12F\";  // Arbitrum\nconst glvVaultAddress = \"0x393053B58f9678C9c28c2cE941fF6cac49C3F8f9\";   // Arbitrum\n\n// Approve tokens to SyntheticsRouter (same as GM operations)\n\nconst multicall = [\n  encodeFunctionData({\n    abi: glvRouterAbi,\n    functionName: \"sendWnt\",\n    args: [glvVaultAddress, wntAmount],\n  }),\n  encodeFunctionData({\n    abi: glvRouterAbi,\n    functionName: \"sendTokens\",\n    args: [longTokenAddress, glvVaultAddress, longTokenAmount],\n  }),\n  encodeFunctionData({\n    abi: glvRouterAbi,\n    functionName: \"createGlvDeposit\",\n    args: [{\n      addresses: {\n        glv: glvTokenAddress,                // GLV vault address\n        market: constituentMarketAddress,    // Which GM market to deposit through\n        receiver: account.address,\n        callbackContract: zeroAddress,\n        uiFeeReceiver: zeroAddress,\n        initialLongToken: longTokenAddress,\n        initialShortToken: shortTokenAddress,\n        longTokenSwapPath: [],\n        shortTokenSwapPath: [],\n      },\n      minGlvTokens: minGlvTokensOut,        // Note: minGlvTokens, not minMarketTokens\n      executionFee: executionFee,\n      callbackGasLimit: 0n,\n      shouldUnwrapNativeToken: false,\n      isMarketTokenDeposit: false,           // true if depositing GM tokens directly\n      dataList: [],\n    }],\n  }),\n];\n\nconst hash = await walletClient.writeContract({\n  address: glvRouterAddress,\n  abi: glvRouterAbi,\n  functionName: \"multicall\",\n  args: [multicall],\n  value: wntAmount,\n});\n```\n\n**Depositing GM tokens directly:** Set `isMarketTokenDeposit: true` and send GM tokens to `GlvVault` instead of long/short tokens. This skips the intermediate GM deposit step and uses less gas.\n\n## GLV Withdrawals\n\n```typescript\n// Approve GLV tokens to SyntheticsRouter first\n\nconst multicall = [\n  encodeFunctionData({\n    abi: glvRouterAbi,\n    functionName: \"sendWnt\",\n    args: [glvVaultAddress, executionFee],\n  }),\n  encodeFunctionData({\n    abi: glvRouterAbi,\n    functionName: \"sendTokens\",\n    args: [glvTokenAddress, glvVaultAddress, glvTokenAmount], // GLV tokens\n  }),\n  encodeFunctionData({\n    abi: glvRouterAbi,\n    functionName: \"createGlvWithdrawal\",\n    args: [{\n      addresses: {\n        receiver: account.address,\n        callbackContract: zeroAddress,\n        uiFeeReceiver: zeroAddress,\n        market: constituentMarketAddress,    // Which GM market to withdraw from\n        glv: glvTokenAddress,\n        longTokenSwapPath: [],\n        shortTokenSwapPath: [],\n      },\n      minLongTokenAmount: minLongOut,\n      minShortTokenAmount: minShortOut,\n      shouldUnwrapNativeToken: true,\n      executionFee: executionFee,\n      callbackGasLimit: 0n,\n      dataList: [],\n    }],\n  }),\n];\n\nconst hash = await walletClient.writeContract({\n  address: glvRouterAddress,\n  abi: glvRouterAbi,\n  functionName: \"multicall\",\n  args: [multicall],\n  value: executionFee,\n});\n```\n\n## Shift Operations\n\nShifts move GM tokens from one pool to another atomically — without withdrawing first. Lower fees than manual withdraw + deposit.\n\n```typescript\nconst shiftVaultAddress = \"0xfe99609C4AA83ff6816b64563Bdffd7fa68753Ab\"; // Arbitrum\n\n// Approve from-market GM tokens to SyntheticsRouter first\n\nconst multicall = [\n  encodeFunctionData({\n    abi: exchangeRouterAbi,\n    functionName: \"sendWnt\",\n    args: [shiftVaultAddress, executionFee],\n  }),\n  encodeFunctionData({\n    abi: exchangeRouterAbi,\n    functionName: \"sendTokens\",\n    args: [fromMarketTokenAddress, shiftVaultAddress, fromMarketTokenAmount],\n  }),\n  encodeFunctionData({\n    abi: exchangeRouterAbi,\n    functionName: \"createShift\",\n    args: [{\n      addresses: {\n        receiver: account.address,\n        callbackContract: zeroAddress,\n        uiFeeReceiver: zeroAddress,\n        fromMarket: fromMarketTokenAddress,\n        toMarket: toMarketTokenAddress,\n      },\n      minMarketTokens: minToMarketTokens,  // Apply slippage\n      executionFee: executionFee,\n      callbackGasLimit: 0n,\n      dataList: [],\n    }],\n  }),\n];\n\nconst hash = await walletClient.writeContract({\n  address: exchangeRouterAddress,\n  abi: exchangeRouterAbi,\n  functionName: \"multicall\",\n  args: [multicall],\n  value: executionFee,\n});\n```\n\nNote: `CreateShiftParams` does not have a `shouldUnwrapNativeToken` field (unlike deposit/withdrawal).\n\n## Cancelling Pending Operations\n\nIf a request hasn't been executed by a keeper yet, the creator can cancel it using the request key (bytes32) returned by the create function:\n\n**Via ExchangeRouter:**\n```typescript\nawait walletClient.writeContract({\n  address: exchangeRouterAddress,\n  abi: exchangeRouterAbi,\n  functionName: \"cancelDeposit\",    // or cancelWithdrawal, cancelShift\n  args: [requestKey],\n});\n```\n\n**Via GlvRouter:**\n```typescript\nawait walletClient.writeContract({\n  address: glvRouterAddress,\n  abi: glvRouterAbi,\n  functionName: \"cancelGlvDeposit\",  // or cancelGlvWithdrawal\n  args: [requestKey],\n});\n```\n\nCancellation refunds tokens to the receiver address. Only the account that created the request can cancel it.\n\n## Fees\n\n**Deposit/withdrawal fees:** Same balancing incentive model as swap fees. Deposits that balance the pool (move it closer to 50/50) pay lower fees. Deposits that imbalance the pool pay higher fees. The fee is deducted from the minted GM/GLV tokens.\n\n**Execution fees:** Paid in native token upfront. Covers keeper gas costs. Calculated using the formula in the [Execution Fee Calculation](#execution-fee-calculation) section. Excess fee is refunded to the receiver.\n\n## Limitations\n\n- **SDK write operations:** `@gmx-io/sdk` does not yet expose convenience methods for deposit/withdraw/shift. Use contract-level multicall as shown above.\n- **APY:** Not directly exposed via API. Derived client-side from trading fees, borrowing rates, and funding rates flowing through each pool.\n- **GLV on Botanix:** GLV contracts are deployed on Botanix but no vaults are configured yet. GM pool operations work on all three chains.\n- **Multichain deposits:** Cross-chain deposits (from a different chain via LayerZero) are not covered in this skill.\n- **Atomic withdrawals:** `ExchangeRouter.executeAtomicWithdrawal()` exists but requires oracle price params — intended for advanced/keeper use.\n\n## References\n\n- [Liquidity Operations Reference](references/liquidity-operations.md) — Contract structs, flows, gas formulas, GLV addresses\n- [Contract Addresses](../gmx-trading/references/contract-addresses.md) — All deployed contracts per chain (shared with gmx-trading)\n- [SDK Reference](../gmx-trading/references/sdk-reference.md) — SDK module and method documentation (shared with gmx-trading)\n- [API Endpoints](../gmx-trading/references/api-endpoints.md) — Oracle, OpenAPI, and GraphQL endpoints (shared with gmx-trading)\n- [GMX Documentation](https://docs.gmx.io) — Official protocol documentation\n- [GMX App — Pools](https://app.gmx.io/#/pools) — GM pool interface\n- [GMX App — Vaults](https://app.gmx.io/#/vaults) — GLV vault interface\n- [`@gmx-io/sdk` on npm](https://www.npmjs.com/package/@gmx-io/sdk) — SDK package","tags":["gmx","liquidity","gmx-io","agent-skills","claude-code-skill","claude-skills","defi","trading"],"capabilities":["skill","source-gmx-io","skill-gmx-liquidity","topic-agent-skills","topic-claude-code-skill","topic-claude-skills","topic-defi","topic-gmx","topic-liquidity","topic-trading"],"categories":["gmx-ai"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/gmx-io/gmx-ai/gmx-liquidity","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add gmx-io/gmx-ai","source_repo":"https://github.com/gmx-io/gmx-ai","install_from":"skills.sh"}},"qualityScore":"0.454","qualityRationale":"deterministic score 0.45 from registry signals: · indexed on github topic:agent-skills · 8 github stars · SKILL.md body (21,922 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:13:29.978Z","embedding":null,"createdAt":"2026-05-18T13:20:37.379Z","updatedAt":"2026-05-18T19:13:29.978Z","lastSeenAt":"2026-05-18T19:13:29.978Z","tsv":"'/#/pools)':2102 '/#/vaults)':2111 '/gmx-io/gmx-interface/blob/release/sdk/src/configs/markets.ts)):':389 '/gmx-synthetics-arbitrum:prod/api/graphql':514,693 '/gmx-synthetics-avalanche:prod/api/graphql':697 '/gmx-synthetics-botanix:prod/api/graphql':701 '/gmx-trading/references/api-endpoints.md':2080 '/gmx-trading/references/contract-addresses.md':2054 '/gmx-trading/references/sdk-reference.md':2067 '/gmx-trading/skill.md':228 '/markets/info':668 '/package/@gmx-io/sdk)':2123 '/rpc':508 '/sdk':194,498,1947,2118 '0.0001':1082 '0.001':1074 '0.3':868 '0n':762,1321,1454,1553,1671,1765 '0x0628d46b5d145f183adb6ef1f2c97ed1c4701c55':1380 '0x1c3fa76e6e1088bce750f23a5bfcffa1efef6a41':1224 '0x393053b58f9678c9c28c2ce941ff6cac49c3f8f9':1483 '0x528a5bac7e746c9a509a1f4f6df58a03d44279f9':404 '0x7eadee2ca1b4d06a0d82fdf03d715550c26aa12f':1479 '0x901ee57f7118a7be56ac079cbcda7f22663a3874':420 '0xdf03eed325b82bc1d4db8b49c30ecc9e05104b96':412 '0xf89e77e8dc11691c9e8757e84aafbcd8a67d7a55':1228 '0xfe99609c4aa83ff6816b64563bdffd7fa68753ab':1711 '1':145,165,711,1231 '1000n':877 '10n':1162 '10x':1077 '2':156,752,956,966,976,1248 '20':1057 '2n':1199 '3':784,934,941,1324 '30':166 '30n':1163 '3637':125 '3n':1176 '4':854,945 '40':998 '42161':117,504 '43114':121 '50/50':1887 '53':1045,1051,1182 '53n':1188 '997n':876 'abi':1263,1271,1280,1289,1333,1395,1408,1419,1462,1496,1504,1513,1571,1619,1627,1638,1679,1725,1733,1742,1773,1827,1843 'account':1860 'account.address':1296,1426,1533,1645,1749 'accru':357 'across':24,97,380 'actual':1008 'add':807,1254,1350 'address':361,396,590,614,779,1294,1305,1331,1424,1460,1518,1523,1569,1643,1677,1747,1771,1825,1841,1857,2051,2053 'adjustgaslimitforestim':908 'advanced/keeper':2038 'alway':1062 'amount':544,553,751,810,841,847,1353 'anoth':1697 'api':658,1964,1969,2078 'app':2098,2107 'app.gmx.io':2101,2110 'app.gmx.io/#/pools)':2100 'app.gmx.io/#/vaults)':2109 'appear':606 'appli':725,856,867,1314,1437,1441,1760 'applyfactor':916 'approv':713,720,737,1232,1382,1485,1610,1713 'arb1.arbitrum.io':507 'arb1.arbitrum.io/rpc':506 'arbitrum':25,116,397,405,690,796,833,996,1044,1050,1225,1229,1381,1480,1484,1712 'arbitrum-api.gmxinfra.io':510,667 'arbitrum-api.gmxinfra.io/markets/info':666 'arg':1267,1275,1284,1293,1337,1399,1412,1423,1466,1500,1508,1517,1575,1623,1631,1642,1683,1729,1737,1746,1777,1834,1849 'asset':252 'async':143 'atom':1698,2027 'auto':95,378 'auto-rebal':94,377 'automat':826,1372 'avalanch':26,120,413,694,799,1056 'avax':122 'await':518,602,622,748,1102,1106,1239,1243,1329,1388,1458,1567,1675,1769,1823,1839 'back':40,55,245 'balanc':198,277,288,598,1872,1880 'base':1140 'batch':1208 'bigint':1149,1151,1152 'borrow':1977 'botanix':28,124,698,802,1988,1994 'btc':126 'build':781,1249 'burn':77,105,312,463 'bytes32':1814 'calcul':880,1919,1927,1931 'calculateexecutionfe':1147,1174,1197 'call':707,814,822,1362,1368 'callback':760,764 'callbackcontract':757,1297,1427,1534,1646,1750 'callbackgaslimit':761,1320,1453,1552,1670,1764 'cancel':1791,1808,1851,1866 'canceldeposit':1830 'cancelglvdeposit':1846 'cancelglvwithdraw':1848 'cancelshift':1833 'cancelwithdraw':1832 'capac':571,579,587 'chain':108,109,110,390,688,1037,2008,2013,2018,2059 'chainid':503 'check':595 'client':859,1972 'client-sid':858,1971 'closer':1885 'complement':224 'compos':62 'configur':132,1999 'console.log':538,547,556,565,572,580,591,646 'const':492,499,515,524,600,619,625,630,636,641,834,873,1100,1104,1172,1186,1189,1195,1222,1226,1251,1260,1327,1378,1392,1456,1477,1481,1493,1565,1616,1673,1709,1722,1767 'constitu':98,437,472,988,1009,1029,1090 'constituentmarketaddress':1525,1651 'contain':986 'contract':128,212,865,910,1001,1958,1990,2045,2052,2057 'contract-level':211,1957 'conveni':1952 'cost':183,1918 'count':1010,1031 'cover':180,230,1915,2023 'creat':147,430,1211,1818,1862 'createdeposit':1292 'createglvdeposit':1516 'createglvwithdraw':1641 'createshift':1745 'createshiftparam':1782 'createwithdraw':1422 'creator':1806 'cross':2012 'cross-chain':2011 'data':23,197,482,490,537,654,672 'datalist':766,1322,1455,1564,1672,1766 'deduct':1902 'default':753 'deploy':129,1992,2056 'deposit':9,70,100,274,278,294,421,425,433,440,450,460,789,809,829,840,930,947,960,1118,1131,1169,1179,1201,1212,1257,1343,1345,1352,1406,1471,1530,1560,1579,1601,1707,1878,1891,2010,2014 'deposit/withdraw':204 'deposit/withdraw/shift':1955 'deposit/withdrawal':686,1790,1869 'deposit/withdrawal/shift':150 'deposits/withdrawals':733 'deposits/withdrawals/shifts':728 'deposittoken':931,953 'depositvaultaddress':1227,1268,1277,1286 'deriv':1970 'differ':2017 'direct':454,1563,1582,1966 'discov':364 'docs.gmx.io':2093 'document':2072,2092,2096 'due':1084 'dynam':363 'e.g':58,253,261 'encodefunctiondata':1218,1262,1270,1279,1288,1394,1407,1418,1495,1503,1512,1618,1626,1637,1724,1732,1741 'endpoint':689,2079,2085 'estimatedfeemultiplierfactor':918 'estimatedgasfeebaseamount':913 'estimatedgasfeeperoraclepric':914 'estimatedgaslimit':898,917,927,1148,1160 'eth':118,830,1075,1083,1448 'eth/avax/btc':1371 'eth/usd':59,256 'ethpool':525 'ethpool.longpoolamount':541 'ethpool.markettokenaddress':594 'ethpool.maxlongpoolamount':575 'ethpool.maxshortpoolamount':583 'ethpool.poolvaluemax':560 'ethpool.poolvaluemin':569 'ethpool.shortpoolamount':550 'event':687 'exampl':1167,1177 'excess':184,1058,1933 'exchangerout':152,730,1475,1821 'exchangerouter.executeatomicwithdrawal':2029 'exchangerouter.multicall':219,708,1206 'exchangerouterabi':1264,1272,1281,1290,1334,1396,1409,1420,1463,1726,1734,1743,1774,1828 'exchangerouteraddress':1223,1332,1461,1772,1826 'execut':133,158,173,838,878,885,1004,1059,1070,1403,1800,1908,1925,1929 'execution-fee-calcul':1928 'executionfe':836,919,1253,1318,1319,1356,1401,1451,1452,1469,1550,1551,1625,1668,1669,1686,1731,1762,1763,1780 'exist':451,2030 'expectedmarkettoken':875 'expos':1022,1951,1967 'extend':670 'factor':681 'fals':1317,1555,1557 'fee':174,185,286,305,680,775,839,879,886,1005,1060,1071,1141,1404,1703,1868,1870,1877,1890,1898,1900,1909,1926,1930,1934,1976 'field':1113,1142,1788 'filter':610 'find':520,528 'first':1387,1615,1701,1721 'flow':1982,2047 'formula':891,902,907,925,1922,2049 'from-market':1714 'frommarket':1754 'frommarkettokenaddress':1738,1755 'frommarkettokenamount':1740 'frontend':783 'full':215,846 'function':1146,1819 'functionnam':1265,1273,1282,1291,1335,1397,1410,1421,1464,1498,1506,1515,1573,1621,1629,1640,1681,1727,1735,1744,1775,1829,1845 'fund':1980 'futur':769 'gas':182,765,1097,1111,1606,1917,2048 'gaslimit':912,920,1101,1154,1156,1159,1165 'gaslimits.deposittoken':1119,1175,1194 'gaslimits.estimatedfeemultiplierfactor':1145,1161 'gaslimits.estimatedgasfeebaseamount':1143,1155 'gaslimits.estimatedgasfeeperoracleprice':1144,1157 'gaslimits.glvdepositgaslimit':1132,1191 'gaslimits.glvpermarketgaslimit':1129,1193 'gaslimits.glvwithdrawalgaslimit':1135 'gaslimits.shift':1124 'gaslimits.singleswap':1139 'gaslimits.withdrawalmultitoken':1122 'gaspric':921,1105,1166 'get':659,665,1096 'github.com':388 'github.com/gmx-io/gmx-interface/blob/release/sdk/src/configs/markets.ts)):':387 'glv':14,79,102,114,368,370,383,398,406,414,447,464,719,732,746,946,959,968,982,984,991,1028,1035,1040,1046,1052,1069,1125,1130,1133,1178,1470,1519,1521,1607,1611,1635,1658,1986,1989,2050,2112 'glvdepositfe':1196 'glvdepositga':1190,1198 'glvdepositgaslimit':950,963 'glvpermarketgaslimit':952,965,972 'glvrouter':154,735,1837 'glvrouter.multicall':221,710,1473 'glvrouterabi':1497,1505,1514,1572,1620,1628,1639,1680,1844 'glvrouteraddress':1478,1570,1678,1842 'glvtokenaddress':1520,1632,1659 'glvtokenamount':1634 'glvvault':1591 'glvvaultaddress':1482,1501,1510,1624,1633 'glvwithdrawalgaslimit':970 'gm':11,45,53,72,91,235,238,263,313,334,339,359,374,432,443,448,452,588,596,604,717,727,744,929,936,961,989,1080,1117,1120,1168,1203,1303,1375,1383,1416,1491,1527,1561,1580,1588,1600,1653,1691,1717,2001,2103 'gm/glv':1906 'gmdepositfe':1173 'gmtoken.write.approve':1389 'gmx':2,7,29,33,81,192,226,496,1945,2063,2076,2089,2091,2097,2106,2116 'gmx-io':191,495,1944,2115 'gmx-liquid':1 'gmx-trade':225,2062,2075,2088 'gmx.squids.live':513,692,696,700 'gmx.squids.live/gmx-synthetics-arbitrum:prod/api/graphql':512,691 'gmx.squids.live/gmx-synthetics-avalanche:prod/api/graphql':695 'gmx.squids.live/gmx-synthetics-botanix:prod/api/graphql':699 'gmxsdk':493,502 'graphql':656,682,2084 'handl':787 'hash':1328,1457,1566,1674,1768 'hasn':1797 'help':287 'higher':304,1078,1897 'histor':685 'hold':89,372 'id':111 'imbal':308,1893 'import':979,1217 'incent':1873 'includ':662,673 'indexsymbol':631,647 'info':201,661 'initiallongtoken':1306,1538 'initialshorttoken':1308,1540 'instead':816,1592 'insufficientexecutionfe':1014 'integr':188 'intend':2036 'interest':678 'interfac':2105,2114 'intermedi':459,1599 'intern':303 'io':193,497,1946,2117 'ismarkettokendeposit':455,1556,1584 'keeper':157,181,1803,1916 'key':1813 'known':382 'larg':1087 'later':168 'layer':38 'layerzero':2020 'less':1605 'let':1153 'level':213,1959 'limit':1112,1940 'liquid':3,5,30,37,50,82,536,2041 'list':615 'logic':911 'long':65,249,280,319,348,392,539,542,574,577,852 'long/short':426,478,1594 'longsymbol':637,648 'longtoken.write.approve':1240 'longtokenaddress':1276,1307,1509,1539 'longtokenamount':837,1242,1255,1278,1357,1511 'longtokenswappath':1310,1433,1542,1660 'low':1017 'lower':285,1702,1889 'lp':74,266 'm':529 'm.indextokenaddress':531 'm.isspotonly':534 'mani':987 'manual':1705 'market':49,57,86,200,248,381,438,473,592,612,626,660,671,951,964,971,990,999,1030,1091,1128,1183,1301,1431,1524,1528,1650,1654,1716 'market.indextokenaddress':633 'market.longtokenaddress':639 'market.poolvaluemax':651 'market.shorttokenaddress':644 'marketscount':957,967,977,980,1039,1066,1187,1192,1200 'marketsinfodata':516,527,620,629 'markettokenaddress':1302,1413,1432 'markettokenamount':1391,1415 'max':559,573,576,581,584 'method':1024,1953,2071 'min':568 'minglvtoken':1544,1547 'minglvtokensout':1545 'mingmtokensout':1313 'minimum':871 'minlongout':1436,1663 'minlongtokenamount':327,1435,1662 'minmarkettoken':874,1312,1549,1758 'minshortout':1440,1665 'minshorttokenamount':329,1439,1664 'mint':71,101,1905 'mintomarkettoken':1759 'mirror':909 'mode':422 'model':134,1874 'modul':2069 'move':1690,1883 'multi':85 'multi-market':84 'multical':155,1250,1261,1336,1338,1393,1465,1467,1494,1574,1576,1617,1682,1684,1723,1776,1778,1960 'multichain':2009 'multipl':90,373 'name':1114 'nativ':112,176,785,792,824,831,888,1258,1341,1370,1912 'new':501 'note':1546,1781 'npm':2120 'number':1088 'object.values':526,628 'offici':2094 'one':56,296,1214,1237,1694 'one-tim':1236 'open':677 'openapi':2082 'oper':137,203,705,716,747,882,897,901,906,924,926,983,1081,1110,1492,1688,1793,1943,2003,2042 'oracl':162,354,2033,2081 'oraclepricecount':903,915,928,1150,1158 'oracleurl':509 'output':872 'overestim':1065 'overview':32 'packag':2125 'paid':1910 'pair':242 'param':2035 'paramet':754,1098 'pass':862 'path':189 'pattern':144 'pay':171,1888,1896 'pbtc':800 'pend':1792 'per':900,905,923,1109,1127,1137,2058 'per-market':1126 'per-oper':899,904,922,1108 'perpetu':41,231 'plus':356 'pnl':358 'pool':12,19,22,46,51,54,99,196,236,239,273,290,310,337,342,360,481,489,523,535,540,546,549,555,557,562,566,570,617,650,653,663,674,1204,1304,1376,1695,1882,1895,1985,2002,2099,2104 'portion':302 'prerequisit':702 'price':163,333,336,355,2034 'proport':284 'protect':332 'protocol':299,2095 'provid':4 'queri':21,487,684,1026 'rate':1978,1981 'raw':423,948,1180 'read':195,216,480,652 'rebal':96,379 'receiv':1295,1425,1450,1532,1644,1748,1856,1939 'recommend':1038 'refer':2040,2043,2066 'references/liquidity-operations.md':2044 'refund':187,1063,1852,1936 'regular':608 'repres':268 'request':149,160,1796,1812,1864 'requestkey':1835,1850 'requir':494,883,2032 'reserv':767 'rest':655,657 'result':442 'return':316,475,669,1164,1815 'revert':1012 'rough':1076 'rpcurl':505 'safe':1068 'sdk':190,210,483,500,1019,1094,1941,2065,2068,2124 'sdk.markets.getmarkets':367 'sdk.markets.getmarketsinfo':485,519,623 'sdk.tokens.gettokensbalances':603 'sdk.utils.getgaslimits':1103,1116 'sdk.utils.getgasprice':1107 'sdk/src/configs/markets.ts':386 'second':167 'section':1932 'select':436 'send':1209,1325,1587 'sendtoken':819,849,1274,1283,1361,1411,1507,1630,1736 'sendwnt':813,821,843,1266,1367,1398,1499,1622,1728 'set':776,1583 'share':270,2060,2073,2086 'shift':17,943,944,1123,1687,1689 'shiftvaultaddress':1710,1730,1739 'short':68,257,282,321,350,394,548,551,582,585 'shortsymbol':642,649 'shorttoken.write.approve':1244 'shorttokenaddress':1285,1309,1541 'shorttokenamount':1246,1287 'shorttokenswappath':1311,1434,1543,1661 'shouldunwrapnativetoken':804,1316,1348,1443,1554,1666,1787 'shown':1962 'side':293,860,1973 'singl':48,292 'single-market':47 'single-sid':291 'singleswap':933,940,955,975 'size':664,675 'skill':31,223,2026 'skill-gmx-liquidity' 'skip':457,848,1359,1597 'slippag':331,855,857,869,1315,1438,1442,1761 'sourc':385 'source-gmx-io' 'specif':247,522 'specifi':326,471 'spot':43,635 'stablecoin':260 'step':142,461,1230,1247,1323,1602 'struct':2046 'subsquid':683 'subsquidurl':511 'sum':346 'suppli':341 'support':107 'swap':234,300,932,939,954,974,1136,1138,1171,1185,1876 'swapscount':935,942,958,978 'symbol':532,634,640,645 'syntheticsrout':723,740,1235,1386,1488,1614,1720 'syntheticsrouteraddress':750,1241,1245,1390 'three':2007 'time':1238 'token':66,69,73,75,92,103,113,177,244,250,258,264,267,283,297,314,322,335,340,351,375,393,395,424,427,444,449,453,465,479,543,552,578,586,589,593,597,605,609,613,712,721,786,793,825,853,889,949,962,1181,1210,1233,1259,1342,1365,1384,1417,1486,1562,1581,1589,1595,1612,1636,1692,1718,1853,1907,1913 'tokensdata':517,530,601,621,632,638,643 'tomarket':1756 'tomarkettokenaddress':1757 'topic-agent-skills' 'topic-claude-code-skill' 'topic-claude-skills' 'topic-defi' 'topic-gmx' 'topic-liquidity' 'topic-trading' 'total':561 'trade':44,227,232,1975,2064,2077,2090 'transact':1215,1326 'true':456,806,1349,1444,1558,1585,1667 'two':36,141 'two-step':140 'typescript':491,599,618,736,756,827,866,1099,1216,1377,1476,1609,1708,1822,1838 'typic':164,1073 'ui':774 'uifeereceiv':771,1299,1429,1536,1648,1752 'under':318,477 'unlik':1789 'unwrap':1445 'upfront':178,1914 'usd':564 'usdc':262,401,403,409,411,417,419,738,994,1043,1049,1055 'usdccontract.write.approve':749 'use':138,484,770,818,842,1032,1092,1205,1472,1604,1810,1920,1956,2039 'user':146,170 'util':676 'v2':8,34 'valid':1002 'valu':338,343,352,558,563,567,755,815,1034,1339,1468,1577,1685,1779 'vault':15,80,83,87,115,131,369,371,384,391,429,467,985,1036,1522,1997,2108,2113 'via':151,218,366,729,734,1820,1836,1968,2019 'viem':214,1221 'walletclient.writecontract':1330,1459,1568,1676,1770,1824,1840 'wavax':416,418,797,1054 'wavax-usdc':415,1053 'wbtc':408,410,1048 'wbtc-usdc':407,1047 'weth':254,400,402,533,794,993,1042,1446 'weth-usdc':399,992,1041 'weth/wavax/pbtc':1346 'withdraw':16,76,104,311,324,462,468,937,969,1121,1134,1373,1608,1656,1700,1706,2028 'withdrawalmultitoken':938,973 'withdrawalvaultaddress':1379,1400,1414 'without':1699 'wntamount':835,1252,1269,1340,1355,1502,1578 'work':741,2004 'wrap':791,823,1369 'write':136,202,217,704,1942 'www.npmjs.com':2122 'www.npmjs.com/package/@gmx-io/sdk)':2121 'yes':119,123 'yet':207,1804,1950,2000 'zeroaddress':758,772,1219,1298,1300,1428,1430,1535,1537,1647,1649,1751,1753","prices":[{"id":"8ce8ebe8-0a92-4c60-ac5e-d3ebfdb67d0e","listingId":"bc94c53d-69fb-4903-8e8a-a57bfdcd5e9f","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"gmx-io","category":"gmx-ai","install_from":"skills.sh"},"createdAt":"2026-05-18T13:20:37.379Z"}],"sources":[{"listingId":"bc94c53d-69fb-4903-8e8a-a57bfdcd5e9f","source":"github","sourceId":"gmx-io/gmx-ai/gmx-liquidity","sourceUrl":"https://github.com/gmx-io/gmx-ai/tree/main/skills/gmx-liquidity","isPrimary":false,"firstSeenAt":"2026-05-18T13:20:37.379Z","lastSeenAt":"2026-05-18T19:13:29.978Z"}],"details":{"listingId":"bc94c53d-69fb-4903-8e8a-a57bfdcd5e9f","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"gmx-io","slug":"gmx-liquidity","github":{"repo":"gmx-io/gmx-ai","stars":8,"topics":["agent-skills","claude-code-skill","claude-skills","defi","gmx","liquidity","trading"],"license":"mit","html_url":"https://github.com/gmx-io/gmx-ai","pushed_at":"2026-03-20T08:59:28Z","description":"Agent skills for trading perpetuals and swapping tokens on GMX V2.","skill_md_sha":"bda6740aedb40069bbdda52e05a153753d909963","skill_md_path":"skills/gmx-liquidity/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/gmx-io/gmx-ai/tree/main/skills/gmx-liquidity"},"layout":"multi","source":"github","category":"gmx-ai","frontmatter":{"name":"gmx-liquidity","license":"MIT","description":"Provide liquidity on GMX V2 — deposit into GM pools and GLV vaults, withdraw, shift between pools, and query pool data across Arbitrum, Avalanche, and Botanix."},"skills_sh_url":"https://skills.sh/gmx-io/gmx-ai/gmx-liquidity"},"updatedAt":"2026-05-18T19:13:29.978Z"}}