Providing Liquidity
Provide liquidity to the DEX by placing limit orders or flip orders in the onchain orderbook.
When your orders are filled, you earn the spread between bid and ask prices while helping facilitate trades for other users.
You can only place orders on pairs between a token and its designated quote token. All TIP-20 tokens specify a quote token for trading pairs. PathUSD can be used as a simple choice for a quote token.
Overview
The DEX uses an onchain orderbook where you can place orders at specific price ticks. Orders are matched using price-time priority, meaning better-priced orders fill first, and within the same price, earlier orders fill first.
Unlike traditional AMMs, you specify exact prices where you want to buy or sell, giving you more precise control over your liquidity provision strategy.
Order Types
Limit Orders
Standard orders that remain in the book at a specific price until filled or cancelled.
function place(
address token,
uint128 amount,
bool isBid,
int16 tick
) external returns (uint128 orderId)token- The token address you're trading (must trade against its quote token)amount- The amount of the token denominated intokenisBid-truefor a buy order,falsefor a sell ordertick- The price tick:(price - 1) * 100_000where price is in quote token per token
orderId- Unique identifier for this order
// tick = (0.9990 - 1) * 100_000 = -10
uint128 orderId = exchange.place(
USDC_ADDRESS,
1000e6, // Amount: 1000 USDC
true, // isBid: buying USDC
-10 // tick: price = $0.9990
);// tick = (1.0010 - 1) * 100_000 = 10
uint128 orderId = exchange.place(
USDC_ADDRESS,
1000e6, // Amount: 1000 USDC
false, // isBid: selling USDC
10 // tick: price = $1.0010
);Flip Orders
Special orders that automatically reverse to the opposite side when completely filled, creating perpetual liquidity similar to an automated market maker pool.
function placeFlip(
address token,
uint128 amount,
bool isBid,
int16 tick,
int16 flipTick
) external returns (uint128 orderId)- All parameters from
place(), plus: flipTick- The price where the order will flip to when filled- Must be greater than
tickifisBidis true - Must be less than
tickifisBidis false
- Must be greater than
orderId- Unique identifier for this flip order
// Place a bid at $0.9990 that flips to an ask at $1.0010
uint128 orderId = exchange.placeFlip(
USDC_ADDRESS,
1000e6, // Amount: 1000 USDC
true, // isBid: start as a buy order
-10, // tick: buy at $0.9990
10 // flipTick: sell at $1.0010 after filled
);When this order is completely filled:
- You buy 1000 USDC at $0.9990
- A new order automatically sells 1000 USDC at $1.0010
- When that fills, it flips back to a bid at $0.9990
- This continues indefinitely, earning the spread each time
Understanding Ticks
Prices are specified using ticks with 0.1 basis point (0.001%) precision:
Tick Formula: tick = (price - 1) × 100_000
Price Formula: price = 1 + (tick / 100_000)
Where price is the token price in quote token units.
Example Tick Calculations
| Price | Tick | Calculation |
|---|---|---|
| $0.9990 | -100 | (0.9990 - 1) × 100_000 = -100 |
| $0.9998 | -20 | (0.9998 - 1) × 100_000 = -20 |
| $1.0000 | 0 | (1.0000 - 1) × 100_000 = 0 |
| $1.0002 | 20 | (1.0002 - 1) × 100_000 = 20 |
| $1.0010 | 100 | (1.0010 - 1) × 100_000 = 100 |
Bid vs Ask
- Bid (isBid = true): An order to buy the token using its quote token
- Ask (isBid = false): An order to sell the token for its quote token
For a USDC/USD pair where USD is the quote:
- A bid buys USDC with USD at your specified price
- An ask sells USDC for USD at your specified price
Order Execution Timeline
Orders follow a specific lifecycle:
-
Placement: When you call
place()orplaceFlip():- Tokens are debited from your DEX balance (or transferred if insufficient)
- Order is queued but not yet visible to other contracts
- Returns an order ID immediately
-
End of Block: All queued orders are added to the book:
- Processed in the order they were placed
- Filled flip orders from this block are added first
- Orders become visible and matchable
-
Filling: As market orders execute against your order:
- Your order fills partially or completely
- Proceeds are credited to your DEX balance
- If a flip order fills completely, it creates a new order on the opposite side
Cancelling Orders
Remove an order from the book before it's filled:
function cancel(
uint128 orderId
) external// Cancel order #12345
exchange.cancel(12345);Cancellations execute immediately, and any unfilled portion of your order is refunded to your DEX balance.