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:| Parameter | Type | Description |
|---|---|---|
vault | Address | The vault contract to trade from |
owner | Address | The vault owner (must match vault’s owner) |
token_in | Address | Token to sell |
token_out | Address | Token to buy |
total_amount | i128 | Total amount of token_in to sell |
num_chunks | u32 | Number of execution chunks |
interval_seconds | u64 | Time between chunk executions |
min_price | i128 | Minimum acceptable price (7 decimal precision) |
max_price | i128 | Maximum acceptable price (7 decimal precision) |
fee_reserve_amount | i128 | Fee reserve for keeper payments |
How It Works
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.Chunk Execution
A keeper calls
execute_order(order_id, keeper) when the interval has elapsed since the last execution. The contract:- Verifies the timing condition
- Calculates
execution_amount = min(remaining, chunk_size) - Updates order state before external calls (reentrancy protection)
- Calls
vault.execute_keeper_swap()with the calculatedmin_amount_out - Pays the keeper from the fee reserve
Example
Splitting a 1,000,000 USDC sell order into 5 chunks at 60-second intervals:Slippage Protection
Themin_price parameter provides slippage protection for each chunk:
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.
