PerformanceBlog
Tempo MCP serverGive agents search and read tools for Tempo docs
Skip to content
LogoLogo

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.

Orderbook liquidity 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)

Parameters:

  • token - The token address you're trading (must trade against its quote token)
  • amount - The amount of the token denominated in token
  • isBid - true for a buy order, false for a sell order
  • tick - The price tick: (price - 1) * 100_000 where price is in quote token per token

Returns:

  • orderId - Unique identifier for this order

Example: Place a bid to buy 1000 USDG at $0.9990

// tick = (0.9990 - 1) * 100_000 = -10
uint128 orderId = exchange.place(
    USDG_ADDRESS,
    1000e6,      // Amount: 1000 USDG
    true,        // isBid: buying USDG
    -10          // tick: price = $0.9990
);

Example: Place an ask to sell 1000 USDG at $1.0010

// tick = (1.0010 - 1) * 100_000 = 10
uint128 orderId = exchange.place(
    USDG_ADDRESS,
    1000e6,      // Amount: 1000 USDG
    false,       // isBid: selling USDG
    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)

Parameters:

  • All parameters from place(), plus:
  • flipTick - The price where the order will flip to when filled
    • Must be greater than or equal to tick if isBid is true
    • Must be less than or equal to tick if isBid is false

Returns:

  • orderId - Unique identifier for this flip order

Example: Place a flip order providing liquidity on both sides

// Place a bid at $0.9990 that flips to an ask at $1.0010
uint128 orderId = exchange.placeFlip(
    USDG_ADDRESS,
    1000e6,      // Amount: 1000 USDG
    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:

  1. You buy 1000 USDG at $0.9990
  2. The same order ID automatically rests as an ask for 1000 USDG at $1.0010 and emits OrderFlipped
  3. When that fills, it flips back to a bid at $0.9990
  4. 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

PriceTickCalculation
$0.9990-100(0.9990 - 1) × 100_000 = -100
$0.9998-20(0.9998 - 1) × 100_000 = -20
$1.00000(1.0000 - 1) × 100_000 = 0
$1.000220(1.0002 - 1) × 100_000 = 20
$1.0010100(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 USDG/USD pair where USD is the quote:

  • A bid buys USDG with USD at your specified price
  • An ask sells USDG for USD at your specified price

Order Execution Timeline

Orders follow a specific lifecycle:

  1. Placement: When you call place() or placeFlip():

    • Tokens are debited from your DEX balance (or transferred if insufficient)
    • Order is immediately added to the active book and visible to other contracts
    • Returns an order ID immediately
  2. 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, the same orderId is immediately rewritten on the opposite side and an OrderFlipped event is emitted

Cancelling Orders

Remove an order from the book before it's filled:

function cancel(
    uint128 orderId
) external

Example:

// Cancel order #12345
exchange.cancel(12345);

Cancellations execute immediately, and any unfilled portion of your order is refunded to your DEX balance.

Flip-order indexing

Indexers and analytics:

  • Subscribe to the OrderFlipped(orderId, newSide, newTick, ...) event on the DEX
  • Key order state by orderId and let it change side and tick over its lifetime
  • Do not expect nextOrderId to advance per flip

Frontends and SDKs:

  • Surface the persistent orderId across the flip lifecycle in user-facing order status

Smart contracts and tooling:

  • Do not assert that flipTick != tick; same-tick flips are valid

See the compatibility section of TIP-1056 for additional migration guidance.