Skip to content

Commit

Permalink
Add documentation for solvers (#24)
Browse files Browse the repository at this point in the history
Adds instruction for solvers on how to create and use custom orders.

---------

Co-authored-by: mfw78 <[email protected]>
  • Loading branch information
fedgiac and mfw78 authored Feb 19, 2024
1 parent e133988 commit ae8f240
Showing 1 changed file with 72 additions and 0 deletions.
72 changes: 72 additions & 0 deletions docs/amm.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,78 @@ referencePair=0x1111111111111111111111111111111111111111
cast abi-encode 'f((address))' "($referencePair)"
```

## I'm a solver. How do I use CoW AMM liquidity?

CoW AMM orders already appear in the CoW Protocol orderbook, so you're already using its liquidity.
However, CoW AMMs allow solvers to specify custom buy and sell amounts, as long as the order preserves or increase the constant product invariant of the token reserves.

CoW AMMs can be treated as a liquidity source akin to Uniswap or Balancer weighted pools with uniform weights.
Each CoW AMM is a pair that trades two tokens.

Importantly, surplus for a CoW AMM order is measured differently when computing the solver reward payout.

### Indexing CoW AMMs

CoW AMM pairs can be detected by listening to the [`ConditionalOrderCreated` events](https://docs.cow.fi/cow-protocol/reference/contracts/periphery/composable-cow#indexing) emitted by the `ComposableCoW` instance for the current chain (see the [official docs](https://docs.cow.fi/cow-protocol/reference/contracts/periphery) for the current deployment addresses).

The order owner is a CoW AMM if its [handler](https://docs.cow.fi/cow-protocol/reference/contracts/periphery/composable-cow#conditionalorderparams) is the contract `ConstantProduct`. Official deployment addresses for the contracts in this repo can be found in the file [`networks.json`](../networks.json).

The field `staticInput` represents the parameters of the AMM, as for example the traded tokens. A description of each parameter can be found in the [instructions on how to create an order](#constantproduct-static-input).

The AMM reserves are the owner's balance of the two tokens traded by the AMM.

There are a few caveats to listening to these events:
- CoW AMM orders can be cancelled at any time with a call to [`ComposableCoW.remove`](https://docs.cow.fi/cow-protocol/reference/contracts/periphery/composable-cow#remove).
There is no corresponding event onchain, but the current validity state can be tracked with [`ComposableCoW.singleOrders`](https://docs.cow.fi/cow-protocol/reference/contracts/periphery/composable-cow#singleorders).
- While it's strongly discuraged behavior, there's nothing stopping the same CoW AMM from trading multiple pairs.
A batch can include only a single custom order per AMM address (this is because a solver can `commit` to only a single order per AMM address).
Moreover, if the AMM trades two overlapping pairs, settling one order may affect the reserve balance of an unrelated pair after the order is executed.
- Even if an event is emitted, the order may be impossible to settle.
This can happen for example if the encoding of `staticInput` is invalid.

### Settling a custom order

You need to choose a valid CoW Swap order with the following restrictions:

- `sellToken`: any token in the pair.
- `buyToken`: the other token in the pair.
- `receiver`: must be `RECEIVER_SAME_AS_OWNER` (zero address).
- `sellAmount`: any value.
- `buyAmount`: any value such that, after trading these exact amounts, the product of the token reserves is no smaller than before trading.
- `validTo`: at most 5 minutes after the block timestamp at execution time.
- `appData`: must be the value specified in `staticInput`.
- `feeAmount`: must be zero.
- `kind`: any value.
- `partiallyFillable`: any value.
- `sellTokenBalance`: must be `BALANCE_ERC20`.
- `buyTokenBalance`: must be `BALANCE_ERC20`.

You also need to compute:
- the order hash `hash` as defined in the library `GPv2Order`, and
- the order signature (example code that generates a valid signature is [the `getTradeableOrderWithSignature` function in the ComposableCoW repo](https://github.com/cowprotocol/composable-cow/blob/main/src/ComposableCoW.sol)).

This order can be included in a batch as any other CoW Protocol orders with three extra conditions:
- One of the pre-interaction must set the commitment by calling `ConstantProduct.commit(hash)`.
- Must contain at most one order from the AMM in the same batch.
- One of the post-interactions must reset the commitment by calling `ConstantProduct.commit(EMPTY_COMMITMENT)`.

The last step (clearing the commit) is technically not required for the batch to settle successfully, however it makes the settlement overall cheaper, since it resets the storage slot.
However, leaving the commit set means that no AMM orders will appear in the orderbook until the commit is reset.
Not clearing the commit at the end of the batch is considered slashable behavior.

### Surplus

The surplus for a CoW AMM order is measured differently depending on which AMM order is executed.

If picking the default CoW AMM order (that is, it's settled with the empty commitment), then the surplus is computed exactly like any other CoW Swap order.

Otherwise, if we call `X` (resp. `Y`) the reserves of sell (resp. buy) token, and `x` (resp. `y`) the sell (resp. buy) amount, then the order surplus is computed as:
```
x (Y + y)
surplus = y - --------- .
X
```

## Risk profile

The risks for the funds on the AMM are comparable to the risks of depositing the same reserves on a constant-product curve like Uniswap v2.
Expand Down

0 comments on commit ae8f240

Please sign in to comment.