diff --git a/docs/amm.md b/docs/amm.md index 4b6464d..48a8094 100644 --- a/docs/amm.md +++ b/docs/amm.md @@ -7,7 +7,7 @@ CoW AMM is an automated market maker running on top of CoW Protocol. > The code is not yet production ready and should not be used to handle large amounts of funds. > For technical aspects of the smart contract, reach out to us on [discord](https://discord.com/invite/cowprotocol) as we push towards production, or simply star the repository to be informed of progress! -## How it works +## Overview The AMM contract itself is a dedicated Safe multisig. It stores reserves of two tokens and allows anyone to create orders between these two tokens on CoW Protocol as long as the trade doesn't decrease the product of the reserves stored on the contract. @@ -15,29 +15,36 @@ It stores reserves of two tokens and allows anyone to create orders between thes The order is based on the `ComposableCoW` framework: this repository only specifies the code needed for the dedicated handler and the related price oracles. All the code for the `ComposableCoW` framework is [here](https://github.com/cowprotocol/composable-cow). -The AMM also provides a view function (`getTradeableOrder`): this function doesn't impact which order is valid or not, but returns an order that can be traded in a way that tries to rebalance the AMM to align with the reference price of a price oracle. +The AMM creates CoW Protocol order at regular time intervals. +These orders are created with a dedicated contract function `getTradeableOrder`: it returns an order that can be traded in a way that tries to rebalance the AMM to align with the reference price of a price oracle. +These orders are provided for convenience to CoW Swap solvers so that a basic CoW AMM usage does not need any dedicated implementation to tap into its liquidity. +More sophisticated solvers can create their own order to better suit the current market conditions. -This order is intended to be picked up automatically by the [watchtower](https://github.com/cowprotocol/watch-tower) without any necessity for the AMM to interact with the CoW Protocol API. -For now, most solvers rely on the order that's automatically generated by the watchtower to balance the AMM. -Eventually, we expect solvers to be aware of the peculiar dynamics of the CoW AMM and create their own orders when settling a CoW Protocol batch. +The [watchtower](https://github.com/cowprotocol/watch-tower) is responsible for automatically creating the AMM order, without any necessity for the AMM to interact with the CoW Protocol API. CoW AMM orders are executed in batches by CoW Protocol solvers. -Only one order per AMM is intended to be executed per batch. -This is currently not enforced on-chain but it's a planned feature of a future version of the CoW AMM. +Only one order per AMM can be executed per batch. Further information on the theoretical research work that serves as the base of CoW AMM can be found in the paper [Arbitrageurs' profits, LVR, and sandwich attacks: batch trading as an AMM design response](https://arxiv.org/pdf/2307.02074.pdf). Batch trading guarantees that despite the minimum viable order follows the constant-product curve (as it's the case for Uniswap v2) the surplus captured by CoW Protocol yields to a better execution price and thus higher profits for liquidity providers. -## Requirements +## Limitations + +The current setup doesn't support pooling liquidity among different users at this point in time. +A new CoW AMM instance needs to be deployed every time a user wants to provide liquidity for a pair. + +## I'm a liquidity provider. How do I create my AMM? + +### Requirements - The CoW AMM funds will be stored in a safe. Every pair of tokens requires its dedicated safe. The owners of the safe have full access to the funds. - The CoW AMM safe needs to use the safe's `ExtensibleFallbackHandler` fallback handler (needed to validate a `ComposableCoW` order). - The CoW AMM safe needs to create a new [`ComposableCoW`](https://github.com/cowprotocol/composable-cow) order that uses the standard deployment of `ConstantProduct` as its handler. -## Order setup +### Order setup -### `ComposableCoW` order +#### `ComposableCoW` order A `ComposableCoW` order is created by calling the function `create(ConditionalOrderParams params, bool dispatch)` on the `ComposableCoW` main contract. @@ -48,7 +55,7 @@ The conditional order parameters should be set as follows: If `dispatch` is set to true, then the order will be automatically picked up on CoW Protocol's orderbook by the [watchtower service](https://github.com/cowprotocol/watch-tower). -### ConstantProduct static input +#### ConstantProduct static input The static input of the constant product handler comprises the following parameters: @@ -72,7 +79,7 @@ appData=0x3232323232323232323232323232323232323232323232323232323232323232 cast abi-encode 'f((address,address,uint256,address,bytes,bytes32))' "($token0, $token1, $minTradedToken0, $priceOracle, $priceOracleData, $appData)" ``` -### Supported price oracles +#### Supported price oracles Price oracles are an abstraction that transform disparate on-chain price information into a standardized price source that can be used by the `ConstantFroduct` to retrieve token price information. @@ -81,7 +88,7 @@ We support the following price oracles: Contract addresses for each supported chain can be found in the file `networks.json`. -#### UniswapV2PriceOracle +##### UniswapV2PriceOracle The Uniswap v2 price oracle returns the limit price that can be computed from an address (pool) that supports the `IUniswapV2Pair` interface. The oracle data needs to include a single parameter: @@ -97,6 +104,24 @@ referencePair=0x1111111111111111111111111111111111111111 cast abi-encode 'f((address))' "($referencePair)" ``` +##### BalancerWeightedPoolPriceOracle + +The Balancer weighted pool price oracle returns the limit price that can be computed from an Balancer pool that come from implements one of the [Balancer weighted pool](https://docs.balancer.fi/concepts/pools/weighted.html) implementations. + +The oracle data needs to include a single parameter: +- `bytes32 poolId`: the [Balancer pool id](https://docs.balancer.fi/reference/contracts/pool-interfacing.html#poolids) representing the weighted pool that will be used to compute the reference price. + +The reference weighted pool can use any weights and token combination. +However, it must be a weighted pool and not a different pool type: there is currently no check in the smart contract to guarantee that the chosen pool if is indeed from a weighted pool. If used with a different type of pool, the output of the oracle is likely to be completely unreliable. + +If the tokens in the AMM orders are not all included in the reference pool, then no order will be created. + +If Foundry is available in your system, you can generate the bytes calldata with the following command: +```sh +poolId=0x1111111111111111111111111111111111111111111111111111111111111111 +cast abi-encode 'f((bytes32))' "($poolId)" +``` + ## 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.