5/5
## Understanding GMX Swap Fee Calculation: From UI to Smart Contract Decentralized exchanges and platforms like GMX offer sophisticated ways to trade and manage liquidity for synthetic assets. A crucial aspect of using these platforms is understanding how transaction fees are calculated. While the user interface provides a summary, the underlying smart contracts contain the precise logic. This lesson explores how fees, particularly for swaps and related actions, are determined on GMX, bridging the gap between the user-facing elements and the Solidity code. ### Fees Presented in the User Interface When initiating an action, such as swapping ETH for USDC on the GMX platform, the user interface presents several fee-related details: 1. **Price Impact / Fees Percentage:** Often displayed together (e.g., "+0.006% / -0.050%"), this indicates potential price slippage (which could be positive or negative) and a definitive percentage-based fee charged by the protocol. 2. **Estimated Fees:** The UI typically provides an estimate of the core protocol fee in dollar terms (e.g., "< -$0.01"), directly related to the percentage fee mentioned above. 3. **Network Fee:** This is the standard blockchain gas fee required to execute the transaction on the underlying network (e.g., "~$0.08"). This fee compensates network validators/miners, not the GMX protocol itself. While these elements give a good overview, the UI might not explicitly break down every component. Notably, the core protocol fee (like the swap fee) and a potential separate "UI fee" directed to the frontend interface provider are calculated behind the scenes. ### Diving into the Smart Contract Logic: `getSwapFees` To understand the precise fee calculation, we need to examine the GMX smart contracts, specifically within the `gmx-synthetics` repository. The core logic for calculating swap and related action fees resides in the `SwapPricingUtils.sol` contract, within the `getSwapFees` function. This function is designed to calculate the protocol fee and any applicable UI fee based on the context of the user's action. Its key inputs include: * `dataStore`: A reference to the contract storing configuration data like fee percentages. * `marketToken`: The address of the token involved in the market operation. * `amount`: The quantity of the token being swapped, deposited, or withdrawn. * `uiFeeReceiver`: An address that can optionally receive a portion of the fee (the UI fee). * `swapPricingType`: An enumeration indicating the type of action being performed (e.g., Swap, Deposit, Withdrawal). ### Determining the Base Fee Factor The first step within `getSwapFees` is to determine the correct percentage fee, represented as a `feeFactor`, based on the type of action (`swapPricingType`). The code uses conditional logic (`if/else if`) to check the `swapPricingType`: * **`SwapPricingType.Swap`:** For regular token swaps. * **`SwapPricingType.Shift`:** For shifting liquidity positions. * **`SwapPricingType.Atomic`:** For atomic swaps. * **`SwapPricingType.Deposit`:** For adding liquidity. * **`SwapPricingType.Withdrawal`:** For removing liquidity. For each type, the function retrieves the corresponding `feeFactor` from the `dataStore` contract. It uses specific key generation functions (e.g., `Keys.swapFeeFactorKey`, `Keys.depositFeeFactorKey`) to look up the correct, pre-configured fee percentage for that specific action and market token. This design makes fees configurable without needing to redeploy the main contract logic. ### Calculating the Core Protocol Fee Once the appropriate `feeFactor` is identified, the primary protocol fee (`feeAmount`) is calculated. This is done by applying the `feeFactor` to the input `amount`: ```solidity // Simplified representation feeAmount = Precision.applyFactor(amount, feeFactor); ``` The `Precision.applyFactor` function is a utility likely found in a supporting library (`Precision.sol`). It handles the necessary arithmetic, often involving fixed-point math, to accurately calculate the fee amount based on the percentage represented by `feeFactor`. ### Accounting for the UI Fee GMX incorporates an optional UI fee mechanism. If a `uiFeeReceiver` address is specified, the system can allocate a portion of the fees to that address, typically representing the frontend or platform that facilitated the transaction. The calculation involves: 1. Retrieving a `uiFeeReceiverFactor` associated with the `uiFeeReceiver` address. This might involve a call like `MarketUtils.getUiFeeFactor(dataStore, uiFeeReceiver)`, which again queries the `dataStore` for the configured UI fee percentage. 2. Applying this factor to the original input `amount` to determine the `uiFeeAmount`: ```solidity // Simplified representation uiFeeAmount = Precision.applyFactor(amount, uiFeeReceiverFactor); ``` This `uiFeeAmount` is separate from the main `feeAmount` calculated earlier. ### Total Calculated Fees and Net Amount The `getSwapFees` function calculates both the `feeAmount` (main protocol fee) and the potential `uiFeeAmount`. These are the primary fees deducted from the user's input amount *within this part of the contract logic*. The function also calculates the remaining amount after these deductions: ```solidity // Simplified representation amountAfterFees = amount - feeAmount - uiFeeAmount; ``` This `amountAfterFees` represents the principal amount used for the subsequent swap execution or liquidity operation, after the protocol and UI fees (as calculated by this function) have been accounted for. ### Key Takeaways * **Modular Fees:** GMX employs different fee percentages (`feeFactor`) based on the specific action (Swap, Deposit, Withdrawal, Shift, Atomic). * **Configurability:** Fee factors are not hardcoded; they are stored in a separate `DataStore` contract, allowing them to be updated via governance or administrative actions. * **Fee Separation:** The system distinguishes between the core protocol fee (`feeAmount`) and an optional fee directed to the user interface provider (`uiFeeAmount`). * **Utility Libraries:** Helper contracts or libraries (`Precision`, `MarketUtils`, `Keys`) are used for common tasks like percentage calculations and data retrieval, promoting code reuse and clarity. * **UI vs. Contract:** The fees displayed in the UI are a combination of protocol fees (like `feeAmount` and `uiFeeAmount`), network gas fees, and potential price impact, while the `getSwapFees` function specifically calculates the protocol and UI fee components deducted from the principal amount.
Decentralized exchanges and platforms like GMX offer sophisticated ways to trade and manage liquidity for synthetic assets. A crucial aspect of using these platforms is understanding how transaction fees are calculated. While the user interface provides a summary, the underlying smart contracts contain the precise logic. This lesson explores how fees, particularly for swaps and related actions, are determined on GMX, bridging the gap between the user-facing elements and the Solidity code.
When initiating an action, such as swapping ETH for USDC on the GMX platform, the user interface presents several fee-related details:
Price Impact / Fees Percentage: Often displayed together (e.g., "+0.006% / -0.050%"), this indicates potential price slippage (which could be positive or negative) and a definitive percentage-based fee charged by the protocol.
Estimated Fees: The UI typically provides an estimate of the core protocol fee in dollar terms (e.g., "< -$0.01"), directly related to the percentage fee mentioned above.
Network Fee: This is the standard blockchain gas fee required to execute the transaction on the underlying network (e.g., "~$0.08"). This fee compensates network validators/miners, not the GMX protocol itself.
While these elements give a good overview, the UI might not explicitly break down every component. Notably, the core protocol fee (like the swap fee) and a potential separate "UI fee" directed to the frontend interface provider are calculated behind the scenes.
getSwapFees
To understand the precise fee calculation, we need to examine the GMX smart contracts, specifically within the gmx-synthetics
repository. The core logic for calculating swap and related action fees resides in the SwapPricingUtils.sol
contract, within the getSwapFees
function.
This function is designed to calculate the protocol fee and any applicable UI fee based on the context of the user's action. Its key inputs include:
dataStore
: A reference to the contract storing configuration data like fee percentages.
marketToken
: The address of the token involved in the market operation.
amount
: The quantity of the token being swapped, deposited, or withdrawn.
uiFeeReceiver
: An address that can optionally receive a portion of the fee (the UI fee).
swapPricingType
: An enumeration indicating the type of action being performed (e.g., Swap, Deposit, Withdrawal).
The first step within getSwapFees
is to determine the correct percentage fee, represented as a feeFactor
, based on the type of action (swapPricingType
). The code uses conditional logic (if/else if
) to check the swapPricingType
:
SwapPricingType.Swap
: For regular token swaps.
SwapPricingType.Shift
: For shifting liquidity positions.
SwapPricingType.Atomic
: For atomic swaps.
SwapPricingType.Deposit
: For adding liquidity.
SwapPricingType.Withdrawal
: For removing liquidity.
For each type, the function retrieves the corresponding feeFactor
from the dataStore
contract. It uses specific key generation functions (e.g., Keys.swapFeeFactorKey
, Keys.depositFeeFactorKey
) to look up the correct, pre-configured fee percentage for that specific action and market token. This design makes fees configurable without needing to redeploy the main contract logic.
Once the appropriate feeFactor
is identified, the primary protocol fee (feeAmount
) is calculated. This is done by applying the feeFactor
to the input amount
:
The Precision.applyFactor
function is a utility likely found in a supporting library (Precision.sol
). It handles the necessary arithmetic, often involving fixed-point math, to accurately calculate the fee amount based on the percentage represented by feeFactor
.
GMX incorporates an optional UI fee mechanism. If a uiFeeReceiver
address is specified, the system can allocate a portion of the fees to that address, typically representing the frontend or platform that facilitated the transaction.
The calculation involves:
Retrieving a uiFeeReceiverFactor
associated with the uiFeeReceiver
address. This might involve a call like MarketUtils.getUiFeeFactor(dataStore, uiFeeReceiver)
, which again queries the dataStore
for the configured UI fee percentage.
Applying this factor to the original input amount
to determine the uiFeeAmount
:
This uiFeeAmount
is separate from the main feeAmount
calculated earlier.
The getSwapFees
function calculates both the feeAmount
(main protocol fee) and the potential uiFeeAmount
. These are the primary fees deducted from the user's input amount within this part of the contract logic. The function also calculates the remaining amount after these deductions:
This amountAfterFees
represents the principal amount used for the subsequent swap execution or liquidity operation, after the protocol and UI fees (as calculated by this function) have been accounted for.
Modular Fees: GMX employs different fee percentages (feeFactor
) based on the specific action (Swap, Deposit, Withdrawal, Shift, Atomic).
Configurability: Fee factors are not hardcoded; they are stored in a separate DataStore
contract, allowing them to be updated via governance or administrative actions.
Fee Separation: The system distinguishes between the core protocol fee (feeAmount
) and an optional fee directed to the user interface provider (uiFeeAmount
).
Utility Libraries: Helper contracts or libraries (Precision
, MarketUtils
, Keys
) are used for common tasks like percentage calculations and data retrieval, promoting code reuse and clarity.
UI vs. Contract: The fees displayed in the UI are a combination of protocol fees (like feeAmount
and uiFeeAmount
), network gas fees, and potential price impact, while the getSwapFees
function specifically calculates the protocol and UI fee components deducted from the principal amount.
An in-depth analysis to From UI to Solidity: GMX Fees - Follow the path of GMX fee calculation from the frontend interface to the `getSwapFees` function in the smart contracts. Discover how `feeFactor` and `uiFeeFactor` are determined based on action type in `SwapPricingUtils.sol`.
Previous lesson
Previous
Next lesson
Next
Give us feedback
Cyfrin Updraft has partnered with GMX to provide SSCD+ certifications vouchers to the first 25 students who demonstrate the completion of this course and are building on top of GMX. Join the GMX Discord server to redeem your coupon, or navigate to the docs to learn more!
Course Overview
About the course
Mechanics and contract architecture of the GMX protocol
Token pricing and fees
Liquidity: GM pools and GLV vaults
Math, funding rates, liquidation pricing, P&L calculations
Limit orders, take profit orders, stop loss, and stop market orders
Auto-cancel and auto-deleveraging
GLP, esGMX, GMX staking and delegation
DeFi Developer
$75,000 - $200,000 (avg. salary)
Smart Contract Engineer
$100,000 - $150,000 (avg. salary)
Web3 developer
$60,000 - $150,000 (avg. salary)
Web3 Developer Relations
$85,000 - $125,000 (avg. salary)
Smart Contract Auditor
$100,000 - $200,000 (avg. salary)
Security researcher
$49,999 - $120,000 (avg. salary)
Last updated on June 26, 2025
Duration: 8min
Duration: 1h 19min
Duration: 1h 24min
Duration: 16min
Duration: 11min
Duration: 11min
Duration: 6min
Course Overview
About the course
Mechanics and contract architecture of the GMX protocol
Token pricing and fees
Liquidity: GM pools and GLV vaults
Math, funding rates, liquidation pricing, P&L calculations
Limit orders, take profit orders, stop loss, and stop market orders
Auto-cancel and auto-deleveraging
GLP, esGMX, GMX staking and delegation
DeFi Developer
$75,000 - $200,000 (avg. salary)
Smart Contract Engineer
$100,000 - $150,000 (avg. salary)
Web3 developer
$60,000 - $150,000 (avg. salary)
Web3 Developer Relations
$85,000 - $125,000 (avg. salary)
Smart Contract Auditor
$100,000 - $200,000 (avg. salary)
Security researcher
$49,999 - $120,000 (avg. salary)
Last updated on June 26, 2025