Cover Image for Deep Dive into GMX: Exploring Arbitrum's Leading DeFi Protocol

Deep Dive into GMX: Exploring Arbitrum's Leading DeFi Protocol

Perpetual Futures
Trading

When exploring the Arbitrum ecosystem, you will undoubtedly encounter a particular name: GMX.

GMX (V2) is one of the most popular decentralized finance (DeFi) projects on Arbitrum, with more than $450 million of total value locked (TVL). Moreover, GMX V1 still has a TVL of almost $100 million.

In this article, we want to explore GMX in-depth, from basic introduction to the internal workings of the protocol. We will also learn how to get trading data from GMX using the Bitquery API.

Let's dive in and first learn the basics about GMX.

What is GMX?

According to the GMX documentation, "GMX is a decentralized spot and perpetual exchange that supports low swap fees and low price impact trades."

The spot exchange is similar to any other decentralized exchange (DEX) on the market, like Uniswap or Sushiswap. However, an interesting part that we will be talking about is the perpetual exchange. But what is a perpetual exchange?

Perpetual Exchanges

Perpetual exchanges allow users to trade perpetual futures. Perpetual futures are very similar to regular futures contracts we are familiar with, but the perpetual futures don't have any expiration dates. This allows traders to hold those contracts far into the future.

In the regular financial markets, implementing these futures contracts would be simple. However, how do these perpetual futures contracts work in the DeFi market? That's the question we will answer in the next section.

One thing to note is that different perpetual exchanges might have different mechanisms that they use to achieve the same thing. As we are exploring GMX, we will try to understand how GMX allows users to trade perpetual futures.

How does GMX work?

For any kind of trade, whether it be spot, futures, or perpetual, there needs to be a counterparty to that trade who will take the other side. The same applies to GMX. Whenever a trader opens a position (long or short), the counterparty for that position is the GMX liquidity pool. To understand GMX, we need to understand how the GMX liquidity pool works.

Liquidity Pool

Unlike liquidity pools of Uniswap or any AMM, which has separate liquidity pools for every single pair, GMX has a liquidity pool that allows liquidity providers to deposit their assets into it and receive GLP tokens back. All assets from all LPs are in this pool, and profits or losses for LPs depend on the net profits or losses of the traders on the platform.

The GLP pool also earns fees when traders borrow assets for opening long or short positions. There are also other fees that the GLP pool (and in turn, the LPs) will earn from traders using the GMX platform.

LPs and Traders

We have learned how the GLP pool works, but we didn't get into how traders or LPs actually use the pool or how their assets are used in the trading process. Let's try to dive into that and go over each step that both parties take in the process.

Liquidity Providers (LPs) and Their Assets:

LPs deposit their assets (e.g., ETH and stablecoins) into the GLP pool. In exchange for their deposits, LPs receive liquidity provider (LP) tokens representing their share of the pool. As traders open and close positions in the pool, the value of the pool fluctuates based on the profits and losses of those positions.

LPs earn a share of the trading fees and funding rates paid by traders, which are added to the pool. If a trader's position becomes undercollateralized, it is liquidated, and the remaining collateral is added to the pool, benefiting the LPs.

LPs can monitor the performance of the pool and the value of their LP tokens. When LPs want to withdraw their liquidity, they redeem their LP tokens, receiving their share of the pool's assets (plus or minus any profits or losses).

Traders and Their Positions:

While placing an order, traders have to deposit their collateral (e.g., stablecoins or the asset) into the GMX platform. Traders place orders to open long or short positions in a particular market (e.g., ETH/USDC) with their desired leverage.

For a long position: a. The trader's collateral is added to the pool. b. The pool "lends" the trader the required amount of the asset (e.g., ETH) to open the leveraged long position.

For a short position: a. The trader's collateral (stablecoins) is added to the pool. b. The pool "borrows" the asset (e.g., USDC) from the trader and adds it to the pool's asset balance. c. The pool provides the trader with the stablecoin value of the borrowed asset to open the leveraged short position.

As the market moves, the trader's position is marked-to-market, and profits or losses are reflected in the value of the pool. Traders pay trading fees and funding rates, which are added to the pool.

If a trader's position becomes undercollateralized due to adverse price movements, their position can be liquidated, and the remaining collateral is added to the pool. Traders can monitor their positions and adjust them as needed by adding or removing collateral or closing their positions.

GMX Trading Data

We have seen the technical workings of GMX. Let's try to see the whole process through data. This will help you get trading data from GMX for your trades or some other traders.

To get the GMX trading data, we need to parse the events emitted by the GMX smart contract. For each step, a particular event is emitted. Let's go through each and understand how to fetch those events.

Here are the actions and the events emitted for those actions:

To open or increase a position: IncreasePosition Event Decrease a position: DecreasePosition Event Close a position: ClosePosition Event Liquidate a position: LiquidatePosition Event

With all these actions, there is one more event being emitted called UpdatePosition. This event tracks all the changes in a position. From this event, we can also get details about all the actions taken related to a particular position.

Whenever a new position is created, we can track it with its unique id, which we can find in all the events. The id for each position is called the key.

You can check the details about each event in the GMX GitHub repo in the Vault.sol file. The address of the vault on the Arbitrum network is 0x489ee077994B6658eAfA855C308275EAd8097C4A

Querying Trading Data

Let's say you want to get trading data for all positions a particular trader has created. We can query all the IncreasePosition events and filter the first instance of each key. That's how we can get all the positions opened by traders. Let's see the query, and note that you need to filter the keys with regards to the first instance of the key.

You can try the following query in the Bitquery IDE.

{
  EVM(dataset: archive, network: arbitrum) {
    Events(
      where: {Log: {SmartContract: {is: "0x489ee077994B6658eAfA855C308275EAd8097C4A"}, Signature: {Name: {is: "IncreasePosition"}}}, Arguments: {includes: {Name: {is: "account"}, Value: {Address: {is: "0x92812499fF2c040f93121Aab684680a6e603C4A7"}}}}}
      orderBy: {descending: Block_Time}
    ) {
      Log {
        Signature {
          Name
          Parsed
          Signature
        }
      }
      Arguments {
        Name
        Type
        Value {
          ... on EVM_ABI_Boolean_Value_Arg {
            bool
          }
          ... on EVM_ABI_Bytes_Value_Arg {
            hex
          }
          ... on EVM_ABI_BigInt_Value_Arg {
            bigInteger
          }
          ... on EVM_ABI_Address_Value_Arg {
            address
          }
          ... on EVM_ABI_String_Value_Arg {
            string
          }
          ... on EVM_ABI_Integer_Value_Arg {
            integer
          }
        }
      }
      Block {
        Time
      }
    }
  }
}

We have arranged all the increase position events in descending order using block time. This will help you filter the event where each key appeared first.

Now that we see an open position, how can we calculate profits or losses for each position?

If the position is closed, we can get the pnl for that position from the ClosePosition event, which has a realized pnl field in it. One caveat is that the ClosePosition event doesn't have a field called account, so we can't directly get all closed positions for a particular trader. Instead, we have to filter it for each position by using the value of the key.

We have seen how to get all trades in the above query, which provides us with the value of the key using which each position is identified. Let's use one of the keys from the result of the above query to see if that position is closed, and if it is, what is the realized pnl.

We are going to use the above query with changed filters. We need to use the event name as ClosePosition, and to filter using the key value, we can change the argument filter accordingly.

You can try the following query in the Bitquery IDE.

{
  EVM(dataset: archive, network: arbitrum) {
    Events(
      where: {Log: {SmartContract: {is: "0x489ee077994B6658eAfA855C308275EAd8097C4A"}, Signature: {Name: {is: "ClosePosition"}}}, Arguments: {includes: {Name: {is: "key"}, Value: {Bytes: {is: "37e9c03e31d64c92f3fc9f4a443f7918a163b0698364c96c48cb59ab201911b7"}}}}}
      orderBy: {descending: Block_Time}
    ) {
      Log {
        Signature {
          Name
          Parsed
          Signature
        }
      }
      Arguments {
        Name
        Type
        Value {
          ... on EVM_ABI_Boolean_Value_Arg {
            bool
          }
          ... on EVM_ABI_Bytes_Value_Arg {
            hex
          }
          ... on EVM_ABI_BigInt_Value_Arg {
            bigInteger
          }
          ... on EVM_ABI_Address_Value_Arg {
            address
          }
          ... on EVM_ABI_String_Value_Arg {
            string
          }
          ... on EVM_ABI_Integer_Value_Arg {
            integer
          }
        }
      }
      Block {
        Time
      }
    }
  }
}

From on-chain data, we can only see the pnl for closed positions. However, if you want to see the unrealized pnl, which will be for open positions, you need the current price of the asset along with the details of the position, and you can calculate that on your machine.

Conclusion

Analyzing and understanding the vast trading data on GMX is crucial for traders, analysts and researchers alike. This is where services like Bitquery's blockchain API come into play. By providing a GraphQL interface to directly query the GMX contract events and data on-chain, Bitquery empowers users to extract valuable insights.

Whether you want to track open positions, monitor liquidations, analyze trader behavior or calculate profit/loss, Bitquery's API lets you construct custom queries tailored to your needs. The ability to filter, sort and transform this on-chain data programmatically opens up new possibilities for building trading dashboards, alerts, analysis tools and more on top of the innovative GMX protocol. As the DeFi ecosystem evolves, leveraging robust data APIs will be key to unlocking the full potential of these decentralized markets.

About Bitquery

Bitquery is a set of software tools that parse, index, access, search, and use information across blockchain networks in a unified way. Our products are:

  • Coinpath® APIs provide blockchain money flow analysis for more than 24 blockchains. With Coinpath’s APIs, you can monitor blockchain transactions, investigate crypto crimes such as bitcoin money laundering, and create crypto forensics tools. Read this to get started with Coinpath®.
  • Digital Assets API provides index information related to all major cryptocurrencies, coins, and tokens.
  • DEX API provides real-time deposits and transactions, trades, and other related data on different DEX protocols like Uniswap, Kyber Network, Airswap, Matching Network, etc.

If you have any questions about our products, ask them on our Telegram channel or email us at sales@bitquery.io. Also, subscribe to our newsletter below, we will keep you updated with the latest in the cryptocurrency world.

Subscribe to our newsletter

Subscribe and never miss any updates related to our APIs, new developments & latest news etc. Our newsletter is sent once a week on Monday.