Skip to main content

TWAP: Time-Weighted Average Price

TWAP is a strategy that splits a large order into equal-sized chunks and executes them at regular time intervals. This helps achieve an average execution price over a defined period, reducing the market impact of large trades.

Why Use TWAP?

Reduce Market Impact

Instead of executing a large trade at once (which can move the price), TWAP spreads the order over time to minimize slippage.

Predictable Execution

Chunks execute at fixed intervals, making the schedule predictable and easy to reason about.

Parameters

When creating a TWAP order, you specify the following parameters:
ParameterTypeDescription
vaultAddressThe vault contract to trade from
ownerAddressThe vault owner (must match vault’s owner)
token_inAddressToken to sell
token_outAddressToken to buy
total_amounti128Total amount of token_in to sell
num_chunksu32Number of execution chunks
interval_secondsu64Time between chunk executions
min_pricei128Minimum acceptable price (7 decimal precision)
max_pricei128Maximum acceptable price (7 decimal precision)
fee_reserve_amounti128Fee reserve for keeper payments

How It Works

1

Order Creation

The owner calls create_twap_order(). The contract validates inputs, calculates chunk_size = total_amount / num_chunks, transfers the fee reserve, and stores the order as Active.
2

Chunk Execution

A keeper calls execute_order(order_id, keeper) when the interval has elapsed since the last execution. The contract:
  1. Verifies the timing condition
  2. Calculates execution_amount = min(remaining, chunk_size)
  3. Updates order state before external calls (reentrancy protection)
  4. Calls vault.execute_keeper_swap() with the calculated min_amount_out
  5. Pays the keeper from the fee reserve
3

Completion

When all chunks are executed (executed_amount >= total_amount), the order status changes to Completed and any unused fees are refunded to the owner.

Example

Splitting a 1,000,000 USDC sell order into 5 chunks at 60-second intervals:
total_amount:      1,000,000 USDC (with decimals)
num_chunks:        5
interval_seconds:  60
min_price:         9,500,000  (0.95 in 7-decimal precision)
max_price:         10,500,000 (1.05 in 7-decimal precision)
fee_reserve:       5 XLM
This creates 5 chunks of 200,000 USDC each, executed every 60 seconds. Each chunk must achieve at least a 0.95 price ratio or the swap will revert.

Slippage Protection

The min_price parameter provides slippage protection for each chunk:
min_amount_out = execution_amount * min_price / 10,000,000
If the Soroswap router cannot provide at least min_amount_out for the chunk, the swap transaction will revert, protecting the vault from unfavorable prices.
Keepers can check can_execute(order_id) before attempting execution to verify that timing conditions are met, avoiding wasted transaction fees.