FlowX Finance on Sui
FlowX Finance is a DEX on Sui with two AMM models: a classic constant-product AMM (V1) and a Uniswap V3-style concentrated liquidity market maker (CLMM). The V1 AMM uses PairMetadata<X, Y> pools stored in a shared Container, while the CLMM uses tick-based Pool<X, Y> objects stored in a shared PoolRegistry.
Package IDs
| Package | Original ID | Description |
|---------|------------|-------------|
| AMM V1 (Core) | 0xba153169476e8c3114962261d1edc70de5ad9781b83cc617ecc8c1923191cae0 | Factory, Pair, Router, swap_utils for constant-product AMM |
| CLMM (Core) | 0x25929e7f29e0a30eb4e692952ba1b5b65a3a4d65ab5f2a32e1ba3edcb587f26d | Pool, PoolManager, SwapRouter, PositionManager for concentrated liquidity |
Source Files
Decompiled Move source:
- AMM V1:
packages/mainnet_most_used/0xba/153169476e8c3114962261d1edc70de5ad9781b83cc617ecc8c1923191cae0/decompiled_modules/ - CLMM (latest v7):
packages/mainnet_most_used/0xde/2c47eb0da8c74e4d0f6a220c41619681221b9c2590518095f0f0c2d3f3c772/decompiled_modules/
Architecture
AMM V1
- Container (shared object): Holds all pairs in a
Bag, keyed by LP name string. Created at init, one global instance. - PairMetadata<X, Y>: Constant-product pool with
reserve_x,reserve_y,lp_supply,fee_rate. Stored insideContainer.pairs. - LP<X, Y>: Fungible LP token type with
Supplymanaged by the pair. Minimum 1000 locked on first mint. - Treasury: Holds the fee recipient address for protocol fees.
- Token ordering: Pairs are always stored in canonical order determined by
swap_utils::is_ordered<T0, T1>()(lexicographic comparison of type names). - Default fee rate: 30 basis points (0.3%) set on pair creation. Fee denominator is 10000.
CLMM
- PoolRegistry (shared object): Manages all CLMM pools as dynamic object fields. Pools are keyed by
(coin_type_x, coin_type_y, fee_rate). - Pool<X, Y>: Concentrated liquidity pool with
sqrt_price,tick_index,liquidity, tick bitmap, observations (TWAP), reward infos, reserves. Uses SwapReceipt pattern for payment. - Position (owned NFT): Represents a concentrated liquidity range with
tick_lower_index,tick_upper_index,liquidity, accrued fees and rewards. Display name: "FlowX CLMM Liquidity Positions". - PositionRegistry (shared object): Tracks total number of open positions.
- Versioned: Version gating object for upgradeable contracts.
- Fee rate denominator:
1_000_000. Pre-configured tiers: 100 (0.01%, tick spacing 2), 500 (0.05%, tick spacing 10), 3000 (0.3%, tick spacing 60), 10000 (1%, tick spacing 200). - Flash loans via
pool::flash/pool::repaywith FlashReceipt.
Key Modules
AMM V1
| Module | Purpose |
|--------|---------|
| factory | Container creation, pair management, fee rate admin |
| pair | PairMetadata struct, swap, mint (add liquidity), burn (remove liquidity), LP token management |
| router | Entry points: swap_exact_input, swap_exact_output, add_liquidity, remove_liquidity, multi-hop swaps |
| swap_utils | get_amount_out, get_amount_in, quote, is_ordered |
| treasury | Protocol fee recipient management |
| math | sqrt, min/max, pow helpers |
| comparator | Byte-level comparison for type ordering |
| type_helper | Type name string conversion |
CLMM
| Module | Purpose |
|--------|---------|
| pool | Pool struct, swap, flash loan, modify_liquidity, collect fees/rewards, state queries |
| pool_manager | PoolRegistry, pool creation, pool borrowing, admin operations |
| swap_router | swap_exact_input, swap_exact_output (handles token ordering) |
| position_manager | open_position, increase_liquidity, decrease_liquidity, collect, close_position |
| position | Position NFT struct, field accessors |
| tick_math | Tick-to-sqrt-price conversions, min/max bounds |
| liquidity_math | Liquidity calculations from amounts and price ranges |
| sqrt_price_math | Price-based amount calculations |
| oracle | TWAP observation management |
| tick, tick_bitmap | Tick state and initialized tick traversal |
Common Integration Patterns
AMM V1: Swap Exact Input (entry point)
// Single-hop swap with exact input amount
// Container is the shared FlowX AMM object
router::swap_exact_input<TokenIn, TokenOut>(
clock, // &Clock
container, // &mut Container
coin_in, // Coin<TokenIn>
min_amount_out, // u64
recipient, // address
deadline, // u64 (timestamp_ms)
ctx, // &mut TxContext
);
// Programmable: returns Coin<TokenOut> directly
let coin_out = router::swap_exact_input_direct<TokenIn, TokenOut>(
container, coin_in, ctx
);
// Multi-hop (2 hops): TokenIn -> Mid -> TokenOut
router::swap_exact_input_doublehop<TokenIn, Mid, TokenOut>(
clock, container, coin_in, min_amount_out, recipient, deadline, ctx
);
// Multi-hop (3 hops)
router::swap_exact_input_triplehop<T0, T1, T2, T3>(
clock, container, coin_in, min_amount_out, recipient, deadline, ctx
);
AMM V1: Add / Remove Liquidity
// Add liquidity (auto-creates pair if needed)
router::add_liquidity<TokenX, TokenY>(
clock, container, coin_x, coin_y,
amount_x_min, // u64
amount_y_min, // u64
recipient, // address -- receives LP tokens
deadline, ctx,
);
// Remove liquidity
router::remove_liquidity<TokenX, TokenY>(
clock, container,
lp_coin, // Coin<pair::LP<TokenX, TokenY>>
amount_x_min, // u64
amount_y_min, // u64
recipient, deadline, ctx,
);
CLMM: Swap
// Exact input swap via swap_router (handles ordering automatically)
let coin_out = swap_router::swap_exact_input<TokenIn, TokenOut>(
pool_registry, // &mut PoolRegistry
fee_rate, // u64 (e.g., 3000 for 0.3%)
coin_in, // Coin<TokenIn>
min_amount_out, // u64
sqrt_price_limit, // u128 (0 for no limit)
deadline, // u64 (seconds)
versioned, // &Versioned
clock, ctx,
);
// Exact output swap
let coin_out = swap_router::swap_exact_output<TokenIn, TokenOut>(
pool_registry, fee_rate, coin_in,
exact_amount_out, sqrt_price_limit, deadline,
versioned, clock, ctx,
);
CLMM: Open Position + Add Liquidity
// 1. Open position with tick range
let position = position_manager::open_position<TokenX, TokenY>(
position_registry, pool_registry,
fee_rate, // u64
tick_lower, // i32::I32
tick_upper, // i32::I32
versioned, ctx,
);
// 2. Add liquidity to the position
position_manager::increase_liquidity<TokenX, TokenY>(
pool_registry, &mut position,
coin_x, coin_y,
amount_x_min, amount_y_min,
deadline, versioned, clock, ctx,
);
// 3. Transfer position to user
transfer::public_transfer(position, sender);
CLMM: Flash Loan
let (balance_x, balance_y, receipt) = pool::flash<T0, T1>(
pool, amount_x, amount_y, versioned, ctx
);
// ... use balances ...
// Must repay with fee
pool::repay<T0, T1>(pool, receipt, repay_balance_x, repay_balance_y, versioned, ctx);
Pool Queries
// AMM V1
let (reserve_x, reserve_y) = pair::get_reserves<X, Y>(pair_metadata);
let fee = pair::fee_rate<X, Y>(pair_metadata);
let lp_supply = pair::total_lp_supply<X, Y>(pair_metadata);
// CLMM
let (reserve_x, reserve_y) = pool::reserves<X, Y>(pool);
let sqrt_price = pool::sqrt_price_current<X, Y>(pool);
let tick = pool::tick_index_current<X, Y>(pool);
let liquidity = pool::liquidity<X, Y>(pool);
let fee_rate = pool::swap_fee_rate<X, Y>(pool);
Related Skills
sui-framework-- Core Sui types (Coin, Balance, Clock, TxContext)cetus-- Alternative CLMM DEX on Sui (similar CLMM architecture)turbos-- Alternative CLMM DEXkriya-- Alternative AMM/PMM DEXdeepbook-- CLOB DEX on Sui
Scan to join WeChat group