Fees
This page documents fee types, execution fee calculation, and how to retrieve fee parameters from the DataStore.
UI fee
UI fees are charged on top of the base protocol fee. The percentage is based on the uiFeeFactor configured for the uiFeeReceiver address you pass when creating an action. For more information, see Running a frontend.
Configure the UI fee percentage for your address by calling ExchangeRouter.setUiFeeFactor. The uiFeeFactor is a percentage value over 10^30. For example, if the uiFeeFactor is 2 * 10^25, the percentage charged is (2 * 10^25) / (10^30) = 0.00002 = 0.002%. The call reverts with InvalidUiFeeFactor if the value exceeds the maximum.
The maximum uiFeeFactor is capped by dataStore.getUint(Keys.MAX_UI_FEE_FACTOR).
The effective uiFeeFactor is snapshotted into each request when it is created. Changing the configured factor later does not change pending deposits, withdrawals, orders, shifts, GLV deposits, or GLV withdrawals.
You can pass the uiFeeReceiver value for the following actions:
- Deposits
- Withdrawals
- Swap orders
- Increase and decrease position orders (Market Increase, Limit Increase, Market Decrease, Limit Decrease, Stop-Loss, Take-Profit)
- GLV deposits
- GLV withdrawals
- Shifts
For deposits, withdrawals, and swaps, the fee is a percentage of the input amount. For increase and decrease position orders, the fee is a percentage of the position size change.
UI fees are credited when deposits, withdrawals, and orders execute. Call ExchangeRouter.claimUiFees to claim accumulated fees at any time. The caller's address (msg.sender) is used as the uiFeeReceiver for the claim.
Execution fee
Creating a deposit, order, withdrawal, shift, GLV deposit, or GLV withdrawal request requires sending an executionFee as the transaction value.
During creation, the contracts verify that the provided executionFee is at least the minimum, calculated as:
tx.gasprice * GasUtils.adjustGasLimitForEstimate(dataStore, estimatedGasLimit, oraclePriceCount)
To calculate the estimatedGasLimit, use the appropriate function:
- For deposits:
GasUtils.estimateExecuteDepositGasLimit - For withdrawals:
GasUtils.estimateExecuteWithdrawalGasLimit - For orders:
GasUtils.estimateExecuteOrderGasLimit - For shifts:
GasUtils.estimateExecuteShiftGasLimit - For GLV deposits:
GasUtils.estimateExecuteGlvDepositGasLimit - For GLV withdrawals:
GasUtils.estimateExecuteGlvWithdrawalGasLimit
Because tx.gasprice fluctuates based on network usage, add a buffer to reduce the risk of the creation transaction reverting. If the provided executionFee is below the minimum, the transaction reverts with InsufficientExecutionFee. Upon execution, any excess execution fee is refunded to the request's account address.
Funding
For an overview of how funding fees work, see adaptive funding.
Retrieve funding fee parameters from the DataStore using these keys. All keys are per-market. The minimum and maximum funding-factor keys additionally include the paying side.
| Key | Description |
|---|---|
FUNDING_FACTOR | Base funding factor per second |
FUNDING_EXPONENT_FACTOR | Exponent applied to the open interest imbalance ratio |
FUNDING_INCREASE_FACTOR_PER_SECOND | Rate at which the funding factor increases per second |
MIN_FUNDING_INCREASE_RATE_PER_SECOND | Minimum amount by which adaptive funding increases per second while the imbalance is non-zero |
FUNDING_DECREASE_FACTOR_PER_SECOND | Rate at which the funding factor decreases per second |
MIN_FUNDING_FACTOR_PER_SECOND | Minimum funding factor per second, keyed separately for long-paying and short-paying states |
MAX_FUNDING_FACTOR_PER_SECOND | Maximum funding factor per second, keyed separately for long-paying and short-paying states |
THRESHOLD_FOR_STABLE_FUNDING | Imbalance threshold below which funding stays stable |
THRESHOLD_FOR_DECREASE_FUNDING | Imbalance threshold below which the funding factor decreases |
Borrowing
For an overview of how borrow fees work, see borrow fees.
Retrieve borrow fee parameters from the DataStore using these keys. Each market uses one of the two models below.
Global settings
These global DataStore keys affect borrowing calculations across all markets.
| Key | Description |
|---|---|
SKIP_BORROWING_FEE_FOR_SMALLER_SIDE | If true, the side with smaller open interest pays zero borrow fees |
USE_OPEN_INTEREST_IN_TOKENS_FOR_BALANCE | Controls how open interest balance is compared: when true, uses openInterestInTokens multiplied by the current index token price (notional value); when false, uses the openInterest USD values recorded at position entry |
Kink model
| Key | Description |
|---|---|
OPTIMAL_USAGE_FACTOR | Utilization threshold where the rate slope increases |
BASE_BORROWING_FACTOR | Base rate factor below optimal utilization |
ABOVE_OPTIMAL_USAGE_BORROWING_FACTOR | Rate factor applied above optimal utilization |
Some markets configure this model without an effective kink: OPTIMAL_USAGE_FACTOR is set to 100%, while BASE_BORROWING_FACTOR and ABOVE_OPTIMAL_USAGE_BORROWING_FACTOR are set to the same annualized rate. This preserves a single borrowing-rate slope across the valid utilization range.
Curve (power) model
| Key | Description |
|---|---|
BORROWING_FACTOR | Per-market borrowing factor for longs and shorts |
BORROWING_EXPONENT_FACTOR | Per-market exponent for longs and shorts |
Position and swap fees
Retrieve position and swap fee parameters from the DataStore using these keys. Fee factors are percentage values over 10^30.
Position fees
| Key | Description |
|---|---|
POSITION_FEE_FACTOR | Percentage fee deducted on position increase and decrease, based on position size change |
POSITION_IMPACT_FACTOR | Price impact factor for position actions |
MAX_POSITION_IMPACT_FACTOR | Cap on negative price impact for positions |
MAX_POSITION_IMPACT_FACTOR_FOR_LIQUIDATIONS | Cap on negative price impact applied during liquidations |
POSITION_IMPACT_EXPONENT_FACTOR | Exponent for position price impact calculation |
POSITION_IMPACT_POOL_DISTRIBUTION_RATE | Rate at which the position impact pool is distributed to the market pool |
PRO_DISCOUNT_FACTOR | Fee discount factor applied to pro-tier traders |
Swap fees
| Key | Description |
|---|---|
SWAP_FEE_FACTOR | Percentage fee deducted on swaps, based on swap amount |
ATOMIC_SWAP_FEE_FACTOR | Percentage fee deducted on atomic swaps using on-chain price feeds |
SWAP_IMPACT_FACTOR | Price impact factor for swaps |
SWAP_IMPACT_EXPONENT_FACTOR | Exponent for swap price impact calculation |
ATOMIC_SWAP_FEE_TYPE | Type flag that determines the atomic swap fee behavior |
Deposit and withdrawal fees
| Key | Description |
|---|---|
DEPOSIT_FEE_FACTOR | Percentage fee deducted on deposits, based on deposit amount |
WITHDRAWAL_FEE_FACTOR | Percentage fee deducted on withdrawals, based on withdrawal amount |
ATOMIC_WITHDRAWAL_FEE_FACTOR | Percentage fee deducted on atomic withdrawals using on-chain price feeds |
Liquidation fees
| Key | Description |
|---|---|
LIQUIDATION_FEE_FACTOR | Percentage fee deducted when a position is liquidated |
Fee receiver factors
These parameters control the share of collected fees allocated to the fee receiver. Each is a percentage value over 10^30.
| Key | Description |
|---|---|
POSITION_FEE_RECEIVER_FACTOR | Share of position fees allocated to the fee receiver |
SWAP_FEE_RECEIVER_FACTOR | Share of swap fees allocated to the fee receiver |
BORROWING_FEE_RECEIVER_FACTOR | Share of borrow fees allocated to the fee receiver |
LIQUIDATION_FEE_RECEIVER_FACTOR | Share of liquidation fees allocated to the fee receiver |
Relay fees
These parameters control fee calculation for Gelato relay (gasless) transactions.
| Key | Description |
|---|---|
GELATO_RELAY_FEE_MULTIPLIER_FACTOR | Multiplier applied to the relay fee calculation |
GELATO_RELAY_FEE_BASE_AMOUNT | Base fee amount for relay transactions |
MAX_RELAY_FEE_SWAP_USD | Global maximum USD value of a relay-fee token swap |
MAX_RELAY_FEE_SWAP_USD_FOR_SUBACCOUNT | Additional maximum USD value of a relay-fee token swap when the call is made by a subaccount |
The current production configuration sets MAX_RELAY_FEE_SWAP_USD to 100 USD. The cap is enforced when feeSwapPath is non-empty and limits oracle-mispricing exposure while converting the fee token. Exceeding it reverts with MaxRelayFeeSwapExceeded.
Subaccount relay calls are checked against both caps. After the global check passes, the relay router also compares the fee value against MAX_RELAY_FEE_SWAP_USD_FOR_SUBACCOUNT and reverts with MaxRelayFeeSwapForSubaccountExceeded when the subaccount cap is exceeded. This limits a malicious subaccount's ability to pair a large negative-impact fee swap with a personal positive-impact swap. Read both values from the DataStore rather than assuming the subaccount cap equals the global one, and size delegated relay-fee swaps against the lower of the two.
Atomic operation parameters
These parameters control behavior for atomic (synchronous) operations that use on-chain price feeds.
| Key | Description |
|---|---|
MAX_ATOMIC_ORACLE_PRICE_AGE | Maximum acceptable age for oracle prices in atomic operations |
Advanced parameters
These parameters control specialized protocol behavior.
| Key | Description |
|---|---|
DATA_STREAM_SPREAD_REDUCTION_FACTOR | Factor applied to reduce the bid-ask spread from data stream oracle prices |
GLV_SHIFT_MAX_LOSS_FACTOR | Maximum acceptable loss factor when executing GLV shifts |
BUYBACK_GMX_FACTOR | Factor controlling GMX token buyback from protocol fees |
BUYBACK_MAX_PRICE_IMPACT_FACTOR | Maximum price impact allowed for buyback operations |