Development of Perpetual DEX (GMX-style)
GMX v2 — $400M+ TVL, $1B+ daily volume at peak periods. Architecture: traders trade with leverage against liquidity pools (GM pools), liquidity providers earn on fees and take directional risk. Oracle: Chainlink Low Latency Feeds with updates every few seconds, keeper bots for order execution.
If you want to build a perpetual DEX following this model — you'll need to understand each component of this architecture. Here's what happens under the hood.
How the GM liquidity pool model works
GM tokens and pool composition
In GMX v2 each market has its own GM pool: for example, the ETH/USDC market contains ETH (long collateral) and USDC (short collateral). The GM token represents a share in this pool. GM token price = (total assets in pool - total pending PnL of traders) / total GM supply.
This is key: when traders are collectively profitable — GM token price falls (the pool will have to pay out). When traders lose — GM rises. LPs and traders are in a zero-sum relationship.
function getGMTokenPrice(address market) external view returns (uint256) {
MarketProps memory marketData = getMarketData(market);
int256 poolValue = getPoolValue(market); // assets at current prices
int256 pendingPnL = getTotalPendingPnL(market); // unrealized trader PnL
uint256 netValue = uint256(poolValue - pendingPnL);
return netValue * 1e18 / IERC20(market).totalSupply();
}
Impact fees and depth factor
One of the smart mechanics in GMX v2 — price impact for opening positions. If a trader opens a large long that creates an imbalance (longs > shorts), they pay an additional impact fee. A trader balancing the imbalance (opening short in a long-heavy pool) receives a rebate.
This emulates order book depth without an actual order book. The depth factor is a pool parameter controlled by governance that determines how aggressively impact grows with position size.
Smart contract architecture
Modular contract system of GMX v2
GMX v2 is split into several layers:
Router — entry point for users. Accepts orders, sends them to OrderVault.
OrderVault — temporary collateral storage when creating an order. Orders are not executed immediately — this is a two-phase process.
ExchangeRouter — order execution through keeper bots. Keeper checks conditions (limit price reached, oracle updated) and calls executeOrder().
DataStore — single storage for all protocol data through bytes32 keys. This allows updating logic without storage migration.
EventEmitter — separate contract only for events. All events emit through it, which simplifies indexing via The Graph.
This architecture ensures upgradeability: Handler contracts are replaceable without changing DataStore. This is critical for a protocol that will evolve after deployment.
Keeper architecture for order execution
Orders in GMX v2 are not executed synchronously. User creates an order (market/limit/stop-loss) → stored in contract → keeper bots monitor orders → when conditions are met, keeper calls executeOrder().
Why is this needed: to not trust the user to set execution timestamp (frontrunning through execution timing choice). Keeper gets current Chainlink Low Latency price at execution moment — this is fairer for both sides.
Keeper receives execution fee (prepaid by user) for each successful execution. If unsuccessful — fee is returned to user.
// Keeper logic (simplified)
async function processOrders() {
const pendingOrders = await exchangeRouter.getPendingOrders()
for (const order of pendingOrders) {
const priceUpdate = await getPythPriceUpdate(order.indexToken)
try {
await exchangeRouter.executeOrder(order.key, {
priceFeedTokens: [order.indexToken],
priceFeedData: [priceUpdate],
})
} catch (err) {
if (err.message.includes('PRICE_NOT_MET')) continue // limit not reached
logError(order.key, err)
}
}
}
Funding fees and borrowing fees
GMX v2 has two types of continuous fees for position holders:
Borrowing fee — payment for using pool liquidity. Calculated as (openInterest / poolLiquidity) * borrowingFactor * time. At high utilization — more expensive.
Funding fee — balancing mechanism between long and short. The side with larger open interest pays the other side. Accumulates through cumulative index similar to Aave's interest index.
On partial position closure — accumulated fees must be calculated correctly. An error here — direct losses or gains for traders at the pool's expense.
Oracle: Chainlink Low Latency + Pyth
GMX v1 used standard Chainlink feeds (update every few minutes or on >0.5% deviation). This created arbitrage: CEX price moved, Chainlink hasn't updated yet — open position at old price, immediately close at new price.
GMX v2 migrated to Chainlink Low Latency Feeds — updates every few seconds via off-chain signed price attestation. Keeper includes the signed price directly in execution transaction.
Pyth Network — alternative push-oracle system with similar speed. Integration with both systems as primary/fallback — standard for production protocols.
Pool parameters and governance
Each market is managed through DAO parameters:
| Parameter | Typical values | Description |
|---|---|---|
| Max open interest | 10-50M USD | Limit on sum of positions per side |
| Max PnL factor | 0.5 (50% of pool) | Maximum unrealized profit of traders |
| Borrowing factor | 0.0001 per second at 100% utilization | Borrowing fee accrual rate |
| Funding factor | Varies | Rate of transfer from long to short |
| Position impact factor | Varies | Aggressiveness of price impact |
Incorrect parameter calibration — direct attack vector. Oracle manipulation + high max PnL factor = possibility to drain pool through artificially profitable positions.
Development process
Mathematics specification (1-2 weeks). All formulas: borrowing rate, funding rate, price impact, GM token pricing, liquidation price — verified formally down to single line of code.
Core contracts (6-10 weeks). DataStore, EventEmitter, OrderVault, ExchangeRouter, position tracking. Foundry tests with 90%+ coverage, Echidna invariant testing.
Keeper infrastructure (2-3 weeks). TypeScript bots, monitoring, fallback for RPC downtime.
Frontend integration (2-4 weeks). wagmi/viem hooks for pool data, order building, The Graph subgraph for history.
Audit (4-6 weeks). Perpetual DEX — complex protocol. Audit should cover both smart contracts and economic mechanics (economic exploit simulation).
Timeline estimates
MVP perpetual DEX with one market (ETH) and keeper infrastructure — 2-3 months. Full platform with multiple markets, governance, GM tokenomics and frontend — 5-6 months.
Cost calculated after technical specification.







