GMX is a "decentralised spot and perpetuals exchange". Spot means that users are able to execute their trades (exchanging one crypto token for another) at the spot price, which is the price right at the time of order creation and the simultaneous settlement. Perpetuals are a type of Futures contracts.
Futures are contracts to trade one currency for another. They are created in the present and are to be settled/ executed at a set date/ time in the future, at the price prevalent at that time. These contracts can them be themselves speculated upon and traded in a secondary market. Naturally, as the settlement date nears, the price of the futures contract starts getting closer to the price of the underlying asset itself, until the data of the settlement finally approaches and the contract is executed. As such, the price of the futures contract remains close to the price of the underlying asset. This also makes futures contract a derivative, i.e., they do not have an intrinsic value, rather they derive the value from the underlying asset that is the subject of the futures contract.
Perpetual Futures (or perpetuals, or perps) are a type of futures contract. The only difference is that in this case, there is no settlement date and one can hold a futures contract for an indefinite period of time.
A problem poses itself, however, what if the perp's price deviates too much from the underlying asset's price? To remedy this, perps have a funding rate. The purpose of a funding rate is to keep the price of the perp as close to the price of the underlying asset as possible.
When you enter into a perp contract, you either "long" a a token or "short" it. Longing means to bet that the price of the underlying token will rise in the future, while shorting means betting that it will fall. If a perp is trading above the price of the underlying asset (the spot price), the funding rate is said to be positive. In this case, those who longed the asset pay equal to the funding rate to those who shorted it. In case the perp starts trading at a price lower than the underlying asset's, the funding rate is said to be negative and those who shorted the asset pay those who longed it. This keeps the price of the perp close to the price of the underlying asset.
Another thing to know about about perps is the initial margin and maintenance margin.
The initial margin is the amount of funds a user has o deposit as collateral before he can enter the perp contract. This can be thought of as the amount being bet. The maintenance margin is the amount that the collateral's value cannot fall below (since cryptocurrencies' value can fluctuate by a lot they can devalue overnight). As long as this condition is satisfied, the perp contract remains open and the user keeps paying and receiving the funding rate. The user can finally close the perp and it will be settled according to prevalent market conditions.
The notion of leverage comes from the usage of a lever. Namely, using a lever amplifies the force exerted on an object. As an example, we would have a very hard time pry opening an old, rusty metal door with our bare hands. However, if we jam a lever or crowbar in the gap between the door and the frame, we can exert the same force on the crowbar, but the crowbar will amplify it and the door will be opened.
The same concept is applied in DeFi as well. Platforms providing a 5x leverage, for example, allow a user to deposit $100 worth of a token, and in turn, the user gets an increased buying power and can trade $500 worth of crypto. If a profit is made, the user keeps it all, minus a protocol fee. However, as soon as the protocol detects a loss about to be made, the deposited tokens are liquidated. As such, both profits and losses are amplified. The concepts of initial and maintenance margin apply to the deposited collateral here as well.
Taking peps and leverage together, GMX offers users the use of leverage (1.1x to 30.1x at the time) to buy perps. So, one can deposit 1 ETH and buy a perp on up to 5 ETH. The resulting profits/ losses will be likewise amplified, with the losses being recovered from the deposited 1 ETH. In addition, GMX also offers users to trade perps along with trading tokens at spot price.
Since leverage and perps are usually offered by CEXs who give users their own money in case of leverage, decentralised perp trading platforms like GMX have two options when it comes to providing the funds for leveraged trading:
In the order book mechanism, two opposite orders must exist in order for them both to be executed; there must be a "coincidence of orders". E.g., If user A wants to sell a perp, user B must also be buying the perp for this trade to occur.
In the liquidity pool or shared liquidity mechanism, the money deposited by users is used. As such, one can deposit assets into the GMX asset pool (i.e., provide liquidity) which it will then lend out to users via leverage opportunities, and in turn, the depositors will get Liquidity Provider Tokens (LP Tokens) which represent the share of their contribution to the total liquidity available along with share of the total fee collected (pool? or general?). In case of GMX, this liquidity provider token (LP Token) is called the GLP token (GLP for short). GLP can then be traded further, staked in pools etc. just like any other token.
This section goes over the tokens of the GMX ecosystem, primarily the GLP and GMX tokens. What they are, how are they minted, and what purpose they serve.
GLP (short for GMX LP) is the LP Token. Users receive GLP in return for depositing liquidity into the multi-asset liquidity pool by buying the GLP token. As such, it can be thought of as an index of select tokens and it rebalances automatically on a weekly basis.
It would be worthwhile to understand what an index is generally, and what it is in the context of DeFi. GLP is an index token after all.
Index is a metric that represents the value of several underlying entities.
Arbitrum: Deposit ETH/BTC/LINK/UNI/USDT/DAI/MIM/FRAX -> Get GLP
Avax: Deposit AVAX/ETH/BTC/USDC/USDC.e/MIM -> Get GLP
For each of the assets behind, a Target Weight is assigned to it. Token Weight can be thought of as optimal composition percentage; meaning, the the percentage a given asset ought to compose of the liquidity pool. For example, if ETH has a target weight of 15%, the liquidity pool can have a maximum of 15% ETH. As such, the Target Weight of all assets adds up to 100%. The manner in which the weight mechanism is used is as follows: If an index asset (e.g., ETH) has a target weight of 15% and its current weight is 9%, it is underrepresented in the pool by 6%. The protocol will then reduce the fees required to buy GLP with ETH, this will in turn cause more users to buy GLP with ETH (i.e., deposit ETH into the shared liquidity pool) which will increase the weight of ETH from 9%, moving it closer to the target weight. Similarly, if an index asset e.g., BTC has a target weight of 20% and it's curent weight is 25%, the fees charged when buying GLP with BTC will be increased so that its current weight falls down to 20%. Thus, the amount of each asset in the pool is kept within a specified threshold.
All this control over how much each asset makes up the pool is there to hedge the risk of GLP token holders. If there is a lot of long interest in ETH, ETH will be given a higher target weight so that it constitutes more of the pool. Reason being; since GLP is an index token, if the price of the underlying assets goes up, GLP goes up and if price of said assets falls, GLP falls. Now, if a lot of traders have a long position on a given index token e.g., ETH, this is a signal that ETH will most probably rise (Wisdom of the Crow), as such, the protocol assigns more weight to ETH so it constitutes more of the pool. This is so that when ETH actually goes up and GLP also goes up. In sum, the more traders long a token, the more target weight is assigned to it, the more it constitutes the pool, the more the pool rises in value, the more GLP rises in value. It is in this manner that the weight mechanism hedges the risk of GLP holders.
One fact to acquaint ourselves with is that the liquidity pool (and by extension GLP holders) is the counterparty to the leverage traders. Meaning, if a trader opens a leveraged long position which settled at a profit, the profit is paid out from the shared liquidity pool and GLP holders take the loss. Similarly, if a position experiences a loss, the loss made by the trader is picked up as profit by the liquidity pool and thus the GLP holders profit.
Users provide liquidity to the GMX protocol by buying GLP with the index assets. Users can also exchange the GLP they hold back for any index asset (audit). As the protocols desires to have as much liquidity as possible, one way is to incentivise the GLP holders to stake their GLP tokens for additional rewards.
GMX is the protocol's utility and governance token. Meaning, it can be used to interact with the protocol, earn rewards (see below) and also participate in the governance by voting using the GMX tokens. It essentially represent's the protocol itself, and its value will increase or decrease based on how good the protocol is running.
Unlike GLP tokens which are minted to the user who buys them using one of the index assets, GMX tokens can be bought using any token and are supported on CEX and DEXs.
Escrow is an arrangement whereby a third party temporarily holds one's assets. In this case, when a user's GLP or GMX tokens are staked in the GMX protocol, they are said to be escrowed, and they in turn accrue Escrowed GMX (esGMX) tokens as rewards.
Receive Reward Tokens when upon depositing/ staking the Deposit Tokens in the Reward Token contract. Reward Tokens are instances of the RewardTracker
contract. The point of interaction for all staking, claiming and compounding is the RewardRouter
contract.
Reward Token | Deposit Token | Contract Name | Description | ||
BonusGMX, bnGMX | MintableBaseToken | ||||
StakedGMX, sGMX | GMX, esGMX | RewardTracker | Deposit GMX or esGMX tokens and accrue sGMX tokens. | ||
Staked+BonusGMX, sbGMX | sGMX | RewardTracker | Deposit sGMX token and accrue rewards in sbGMX tokens. | ||
Staked+Bonus+FeeGMX, sbfGMX | bnGMX, sbGMX | RewardTracker | Deposit bnGMX or sbGMX tokens and get rewards in sbfGMX tokens. | ||
FeeGLP, fGLP | GLP | RewardTracker | Deposit GLP and receive rewards in fGLP tokens. | ||
Fee+StakedGLP, sGLP | fGLP | RewardTracker | Deposit fGLP and receive rewards in sGLP tokens. |
For the rewards one has earned, a user has two choices:
Claiming rewards transfers the reward tokens to user wallet.
Compounding essentially auto-reinvests a user's rewards; the user can do it manually as well after claiming rewards.
There are the following rewards in the GMX Protocol:
Buying GLP is synonymous to providing liquidity to the GMX shared pool containing various assets. As such, GLP can be bought with any of the supported assets. Once bought, the GLP held represents a share of the total liquidity and can be redeemed for any of the index assets. GLP tokens accrue the user ETH (or AVAX) fees from swaps and leveraged trading.
GLP Address (Arbitrum): 0x4277f8f2c384827b5273592ff7cebd9f2c1ac258
GLP tokens are auto-staked as soon as they are minted to the user. Which is why totalStaked
and totalSupply
must always be identical, and nonStakingSupply
must always be 0
. These can be treated as invariants.
Execution Flow (Buying + Staking GLP with ETH):
RewardsRouterV2.mintAndStakeGlpETH(_minUsdg, _minGlp)
is called by the frontend and is the user-facing contract for all tokens and rewards. _minUsdg
is how much USDG the asset amount being deposited must be equal to ATLEAST. _minGlp
is how much GLP tokens must be minted to the user in return for depositing the asset ATLEAST.
1. Ensure that some ETH has been sent as msg.value
2. Wrap the ETH using WETH
and approve the GlpManager
contract to spend said WETH.
1. GlpManager.addLiquidityForAccount( _fundingAccount, _account, _token, _amount, _minUsdg, _minGlp)
is then called to add liquidity to the shared pool of various assets, one of which is the asset just being used by the user to buy GLP (i.e., provide liquidity).
2. _validateHandler()
: Ensure caller is the RouterV2 contract.
3._addLiquidity( _fundingAccount, _account, _token, _amount, _minUsdg, _minGlp) private returns (uint256)
: To add _amount
of _token
as liquidity on behalf of _account
:
1. getAumInUsdg(maximise)
: Calculate total value of the Assets Under Management (AUM) in terms of USDG. AUM is the total market value of the assets held in the shared liquidity pool.
1. getAum(maximise)
: Calculate AUM with maximim or minimum price (out of 3 price rounds) from the price feed. Loop over all the index tokens (allWhitelistedTokens
in the Vault
; Vault is the shared liquidity pool) and calculate their vaule taking into consideration their qty in the pool and current market price (max or min of 3 chainlink pricefeed rounds). If the token is a stablecoin, its aum value will be: (amountInPool * price) / 10 ** assetDecimals
); if the token is not a stablecoin, then the mechanism to calculate the AUM is as follows:
1. Calculate the total amount of this token that has been shorted globally. If f global short size for this token > 0:
1. (uint256 delta, bool hasProfit) = getGlobalShortDelta(token, price, size)
: Calculate the global short delta for this token at the current price. Formula for globalShortDelta is: (globalShortSize*priceDelta)/avgPrice
. Here, price delta is the difference between current and avg price of the short positions for the token. If the avgPrice price of shorts is more than the current token price, the hasProfit
is returned as true. This is because the traders who shorted the asset are losing the bet and the counterparty, the GMX pool and by extension GLP holders, stands to profit from this.
2. If a profit is reported, add the delta to the AUM value. Otherwise, deduct the delta from AUM (we deudct this delta from AUM because it represents the profit made by the short traders and as such a loss to the pool).
3. Fetch the guaranteedUSD
value for the token from the vault. guaranteedUsd is the difference between the position size and the collateral deposited for that position. It can be thought of as the amount in USD that is guaranteed when leveraged positions are opened. It is an estimation and can fall if there are sudden price increases. This vaule MUST be updated after liquidations (since amount open positions changes )
2. Fetch the reservedAmount
for the token from the vault
3. Calculate value of the reserved amount reservedAmount*price/10**decimals
and subtract it from the total poolAmount
of the token as calculated earlier. Add the post-deduction poolAmount
to the AUM.
4. Return the AUM value.
2. Convert the received AUM value into USDG: AUM*10**USDGDecimals / PRICE_PRECISION
. Thus, the value in USDG of the total assets under management i.e., present in the shared liquidity pool is returned to _addLiquidityForAccount
.
2. Transfer the asset token amount being deposited by the user (to buy GLP) from the RouterV2
to the Vault
.
3. Buy USDG using the tokens deposited into the Vault, send the minted USDG to the GlpManager
4. GLP mint amount as a result of this deposit = (usdg bought * GLPSupply) / AUMInUsdg
5. Mint GLP and send to the depositor, update the lastAddedAt
timestamp.
6. Return the GLP Mint Amount (after minting GLP)
4. RewardTracker.stakeForAccount()
: Stake the GLP minted to the user in the fGLP reward tracker contract.
5. RewardTracjer.stakeForAccount()
: Stake the user's fGLP in the sGLP tracker.
So, Deposit Asset -> Mint GLP -> Stake GLP (and get fGLP) -> stake fGLP (and get sGLP)
6. Return the GLP amount minted to the user for the deposit.