Skip to main content

tokens

This module provides utilities for token price conversions, amount calculations, and token relationship operations in the GMX protocol. It handles conversions between USD values and token amounts, price formatting for contracts, and various token comparison utilities.

Methods​

The tokens utility module exports functions for price format conversions, token amount calculations, token data lookups, relationship checks, and ratio utilities.

Price conversions​

parseContractPrice​

parseContractPrice(price: bigint, tokenDecimals: number): bigint

Converts a contract-format price (price × 10^tokenDecimals) to a 30-decimal SDK price (price × 10^30). Internally: price × expandDecimals(1, tokenDecimals).

import { parseContractPrice } from "@gmx-io/sdk/utils/tokens";

const sdkPrice = parseContractPrice(contractPrice, 18);

convertToContractPrice​

convertToContractPrice(price: bigint, tokenDecimals: number): ContractPrice

Converts a 30-decimal SDK price to contract format by dividing by 10^tokenDecimals.

Order builders use this conversion for position order price fields such as triggerPrice and acceptablePrice before creating contract calldata. For example, a DOGE $0.04 trigger price is 40000000000000000000000000000n in SDK price format. Since DOGE has 8 decimals, the contract-format value is 400000000000000000000n.

import { convertToContractPrice } from "@gmx-io/sdk/utils/tokens";

const contractPrice = convertToContractPrice(1800n * 10n ** 30n, 18);

convertToContractTokenPrices​

convertToContractTokenPrices(prices: TokenPrices, tokenDecimals: number): { min: ContractPrice; max: ContractPrice }

Converts both minPrice and maxPrice from 30-decimal SDK format to contract format.

import { convertToContractTokenPrices } from "@gmx-io/sdk/utils/tokens";

const contractPrices = convertToContractTokenPrices({ minPrice: 1800n * 10n ** 30n, maxPrice: 1802n * 10n ** 30n }, 18);

getMidPrice​

getMidPrice(prices: TokenPrices): bigint

Returns (minPrice + maxPrice) / 2.

import { getMidPrice } from "@gmx-io/sdk/utils/tokens";

const midPrice = getMidPrice({ minPrice: 1800n * 10n ** 30n, maxPrice: 1802n * 10n ** 30n });

Token amount conversions​

convertToTokenAmount​

convertToTokenAmount(
usd: bigint | undefined,
tokenDecimals: number | undefined,
price: bigint | undefined
): bigint | undefined

Converts a USD value (30-decimal) to a token amount. Returns undefined when any argument is undefined or price <= 0.

import { convertToTokenAmount } from "@gmx-io/sdk/utils/tokens";

const wethAmount = convertToTokenAmount(
1000n * 10n ** 30n, // $1000 USD
18, // WETH decimals
1800n * 10n ** 30n // WETH price
);
// ≈ 0.556 WETH in 18-decimal units

convertToUsd​

convertToUsd(
tokenAmount: bigint | undefined,
tokenDecimals: number | undefined,
price: bigint | undefined
): bigint | undefined

Converts a token amount to USD (30-decimal). Returns undefined when any argument is undefined.

import { convertToUsd } from "@gmx-io/sdk/utils/tokens";

const usdValue = convertToUsd(
5n * 10n ** 17n, // 0.5 WETH
18,
1800n * 10n ** 30n // WETH price
);
// $900 as 30-decimal bigint

convertBetweenTokens​

convertBetweenTokens(
tokenAmount: bigint | undefined,
fromToken: TokenData | undefined,
toToken: TokenData | undefined,
maximize: boolean
): bigint | undefined

Converts tokenAmount of fromToken to an equivalent amount of toToken. Returns tokenAmount directly when the two tokens are equivalent.

When maximize is true, uses fromToken.prices.maxPrice and toToken.prices.minPrice (maximizes value received). When false, uses fromToken.prices.minPrice and toToken.prices.maxPrice (minimizes value received, conservative estimate).

import { convertBetweenTokens } from "@gmx-io/sdk/utils/tokens";

// Estimate how much USDC you get for 1 WETH (maximize=false → conservative)
const usdcAmount = convertBetweenTokens(1n * 10n ** 18n, wethTokenData, usdcTokenData, false);

Token data lookups​

getTokenData​

getTokenData(
tokensData?: TokensData,
address?: string,
convertTo?: "wrapped" | "native"
): TokenData | undefined

Looks up a token by address in tokensData. When convertTo is provided, follows the token's wrappedAddress or nativeTokenAddress pointer before returning.

import { getTokenData } from "@gmx-io/sdk/utils/tokens";

const wethData = getTokenData(tokensData, nativeEthAddress, "wrapped");
const nativeData = getTokenData(tokensData, wethAddress, "native");

getGmToken​

getGmToken(chainId: ContractsChainId, marketTokenAddress: string): Token

Returns a Token for a GM pool token by cloning the GM stub token and replacing its address with marketTokenAddress.

import { getGmToken } from "@gmx-io/sdk/utils/tokens";

const gmToken = getGmToken(42161, marketTokenAddress);

getGlvToken​

getGlvToken(chainId: ContractsChainId, glvTokenAddress: string): Token

Returns a Token for a GLV vault token by cloning the GLV stub token and replacing its address with glvTokenAddress.

import { getGlvToken } from "@gmx-io/sdk/utils/tokens";

const glvToken = getGlvToken(42161, glvTokenAddress);

Token relationship checks​

getIsEquivalentTokens​

getIsEquivalentTokens(token1: Token, token2: Token): boolean

Returns true when the tokens are interchangeable: same address, a native/wrapped pair, or two synthetic tokens with the same symbol.

import { getIsEquivalentTokens } from "@gmx-io/sdk/utils/tokens";

getIsEquivalentTokens(nativeEthToken, wethToken); // true

getIsWrap / getIsUnwrap / getIsStake / getIsUnstake​

getIsWrap(token1: Token, token2: Token): boolean
getIsUnwrap(token1: Token, token2: Token): boolean
getIsStake(token1: Token, token2: Token): boolean
getIsUnstake(token1: Token, token2: Token): boolean

Classify a token-pair operation as wrap (native → wrapped), unwrap (wrapped → native), stake (native or wrapped → staking token), or unstake (staking token → wrapped). Used by swap routing to short-circuit path selection for these special cases.

import { getIsWrap, getIsUnwrap } from "@gmx-io/sdk/utils/tokens";

getIsWrap(nativeEthToken, wethToken); // true
getIsUnwrap(wethToken, nativeEthToken); // true

Ratio utilities​

getTokensRatioByPrice​

getTokensRatioByPrice(p: {
fromToken: Token;
toToken: Token;
fromPrice: bigint;
toPrice: bigint;
}): TokensRatio

Computes a TokensRatio (exchange rate and which token is "largest") from two prices.

import { getTokensRatioByPrice } from "@gmx-io/sdk/utils/tokens";

const ratio = getTokensRatioByPrice({
fromToken: wethToken,
toToken: usdcToken,
fromPrice: 1800n * 10n ** 30n,
toPrice: 1n * 10n ** 30n,
});

getTokensRatioByAmounts​

getTokensRatioByAmounts(p: {
fromToken: Token;
toToken: Token;
fromTokenAmount: bigint;
toTokenAmount: bigint;
}): TokensRatio

Computes a TokensRatio from two token amounts.

import { getTokensRatioByAmounts } from "@gmx-io/sdk/utils/tokens";

const ratio = getTokensRatioByAmounts({
fromToken: wethToken,
toToken: usdcToken,
fromTokenAmount: 1n * 10n ** 18n,
toTokenAmount: 1800n * 10n ** 6n,
});

getTokensRatioByMinOutputAmountAndTriggerPrice​

getTokensRatioByMinOutputAmountAndTriggerPrice(p: {
fromToken: Token;
toToken: Token;
fromTokenAmount: bigint;
toTokenAmount: bigint;
triggerPrice: bigint;
minOutputAmount: bigint;
}): TokensRatioAndSlippage

Extends getTokensRatioByAmounts to also compute the allowed slippage in basis points based on the trigger price and minimum output amount.

import { getTokensRatioByMinOutputAmountAndTriggerPrice } from "@gmx-io/sdk/utils/tokens";

const ratioAndSlippage = getTokensRatioByMinOutputAmountAndTriggerPrice({
fromToken: wethToken,
toToken: usdcToken,
fromTokenAmount: 1n * 10n ** 18n,
toTokenAmount: 1800n * 10n ** 6n,
triggerPrice: 1800n * 10n ** 30n,
minOutputAmount: 1790n * 10n ** 6n, // 1790 USDC minimum
});

getAmountByRatio​

getAmountByRatio(p: {
fromToken: Token;
toToken: Token;
fromTokenAmount: bigint;
ratio: bigint;
shouldInvertRatio?: boolean;
allowedSwapSlippageBps?: bigint;
}): bigint

Converts fromTokenAmount to a target-token amount using a pre-computed TokensRatio.ratio. Pass allowedSwapSlippageBps to reduce the output by a slippage tolerance.

import { getAmountByRatio } from "@gmx-io/sdk/utils/tokens";

const usdcOut = getAmountByRatio({
fromToken: wethToken,
toToken: usdcToken,
fromTokenAmount: 1n * 10n ** 18n,
ratio: triggerRatio.ratio,
shouldInvertRatio: triggerRatio.largestToken.address === usdcToken.address,
allowedSwapSlippageBps: 50n, // 0.5% slippage
});