# Dutch Auctions

Common implements a fully on-chain order book, where each order is, in a sense, a separate dutch auction (or even more general, see the details below).&#x20;

## High Level Overview

### Traditional Limit Orders

In a traditional order book, the user typically submits a `LimitOrder` having the following parameters:

* `token_in` - token the user wants to sell
* `token_out` - token the user wants to buy
* `amount_in` - how many tokens user wants to sell
* `price` - determines how many tokens user wants to buy, specifically, the want at least `price*amount_in` tokens of type `token_out`.

Such an order sits in the order book until matched by a matching engine. Matching happens against orders in the opposite direction. Orders are matched if they are "crossing", i.e., when both price constraints can be satisfied at the same time. The price at which the trade is executed depends on the matching engine. Orders can be matched partially. Typically some kind of fee is deducted after a trade happens.&#x20;

### On-chain "Dutch" Orders

A Dutch auction is an auction mechanism for selling an asset, in which an initial price `p_start` is selected for the auctioned item, and then, as the auction progresses, the price gradually decreases, little by little. At the moment when a buyer is satisfied by the current price, they bid, and win the auction right away, paying the current price for the item. Assuming that the initial price `p_start` was set correctly (higher than what's the item worth) then the auction finishes with the item being sold at an optimal price.

Common uses the Dutch auction mechanism to implement generalized limit orders. Roughly speaking, if the user has some `token_in` asset and they want to sell `amount_in` of them for `token_out` asset, then they can set some initial price `p_start` and limit price `p_stop` and let the tokens be traded over some time, at the price varying linearly between `p_start` and `p_stop` over a selected time segment. Of course, it is natural to set `p_start` to be a price that is higher than the current stop market price, so that the auction achieves its goal of trading the assets at a price favorable to the user.

The order book consists then of a set of "living" orders – orders whose prices change in time.&#x20;

Orders are matched not via a centralized matching engine but via a permissionless group of "fillers" who are actors who can fill one or more orders at the same time. Fillers compete with each other to make profit from arbitrage opportunities.&#x20;

## Details of Dutch Orders

### Creating Orders

To create an order user sends the following transaction

```rust
fn create_order(token_in, token_out, amount_in, price_curve, expiration_time) {...}
```

Where `token_in`, `token_out`, `amount_in` are self-explanatory, and:

* `price_curve` is a function that takes timestamp as an argument and outputs a price that is acceptable for this order at this time. For instance:
  * For limit orders we have `price_curve(t) = const`
  * For dutch auctions we have `price_curve(t) = ((t1 - t)p1 + (t-t2)p2)/(t1-t2)` i.e., a linear function with a specific timestamp `t1, t2` and price `p1, p2` parameters
  * We could have more general price curves too, for instance exponential, which would be useful for price discovery of very exotic tokens.
* `expiration_time` is a timestamp when the order is automatically cancelled. It can be set to `infty` in order to make the order live till being filled, or manually canceled.&#x20;

As a result, an order, with a unique `order_id` is created and stored in the contract.

Note that as part of the `create_order` transaction, the user locks `amount_in` tokens `token_in` in the order book contract.&#x20;

### Filling Orders

To fill an order or multiple orders one uses the following contract call:

```rust
fn fill(order_ids: Vec<OrderId>, executor_contract: Address) {
    let orders = {order[order_id] for order_id in order_ids}
    let prices = current prices of orders;
    for order in orders {
        transfer order.amount_in of order.token_in to executor_contract;
    }
    // The results array contains info on what amount of which order was filled
    let results = executor_contract.execute(orders, prices);
    
    Validate results (details below) 
    // Validate that the executor_contract transferred enough token_in and token_out 
    // for each order. Specifically:
    // 1. >= (amount_in-filled) of token_in
    // 2. >= (amount_in-filled)*price of token_out.
    // If validation fails, rollback.
    
    Update orders to take into account filled amounts.
}
```

Note that the above requires developing an executor contract, so it is expected to be used by a professional filler only. A simplified call for casual traders will be also provided to make it simpler.

The `fill` method can be logically split into 3 steps:

1. Send input funds to the `executor_contract`
2. Execute a callback by the `executor_contract`
3. Receive the swapped funds from the `executor_contract`&#x20;

There are a few reasons why the proposed implementation of `fill` (based on steps 1. 2. 3. as above) is convenient for the fillers:

* When creating a transaction, the filler cannot predict: 1) if some of the orders they try to fill will not get filled (partially) before the transaction lands on chain, 2) what will be the timestamp of the block their transaction is included. This implies that the filler doesn't know the final amounts of the order and the price at which it will be executed. That's why the `execute` call includes both `orders` and `prices` and is expected to make the final decision on what to trade and how.
* In case when an order is filled, or the price is not the expected one, the `execute` method can simply abort, in order to rollback the transaction.
* Thanks to the fact that the step `1.` happens before `3.` it is possible for the filler to fill orders without any liquidity held by the filler. Specifically, `fill` is a variant of a flash-loan. What the filler can do for instance is:
  * Fill one order by trading it against an AMM
  * Fill two orders by trading them against each other.
  * Any combination of these, as long as it's atomic.

### Cancelling Orders

Orders can be cancelled at any time by the user who submitted them, in which case they get a full refund on what remains untraded (`token_in`) + the amount in `token_out` that was traded.

### Fees

### Incentives for Fillers
