Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Before contributing, make sure you have the following installed:
You can help other users in the community to solve their issues in the [CoW Protocol Discord].

[CoW Protocol Discord]: https://discord.gg/cowprotocol
[CoW Protocol Forums]: https://forum.cow.fi
[CoW Protocol Forums]: https://forum.cow.finance

## Opening an issue

Expand Down
3 changes: 3 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
};
30 changes: 30 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
title: Welcome
sidebar_position: 1
---

# CoW DAO

CoW DAO is on a mission to innovate the most user-protective products in Ethereum. 

Currently, CoW DAO's two main products are [**CoW Protocol**](cow-protocol) and [CoW AMM](https://cow.finance/cow-amm), which it supports with development and marketing resources – including the [CoW Grants Program](https://grants.cow.finance), the [CoW Protocol Explorer](cow-protocol/tutorials/cow-explorer), and the [CoW Swap frontend](cow-protocol/tutorials/cow-swap).

## What is [CoW Protocol](cow-protocol)? 

CoW Protocol is a fully permissionless trading protocol that leverages [fair combinatorial batch auctions](cow-protocol/concepts/introduction/fair-combinatorial-auction) as its price finding mechanism. CoW Protocol uses fair combinatorial auctions to maximize liquidity via Coincidence of Wants (CoWs) in addition to tapping all available on-chain liquidity whenever needed.

## What is [CoW AMM](https://cow.finance/cow-amm)?

CoW AMM is a new type of AMM built from the ground up to protect LPs from price exploitation in the form of [LVR](https://cow.finance/learn/what-is-loss-versus-rebalancing-lvr). Liquidity providers expect their tokens to earn yield, but most liquidity pools are actually not profitable after accounting for stale prices. Arbitrageurs exploit these stale prices at the expense of LPs. CoW AMM fixes LVR once and for all, with liquidity pools proven to outperform reference Balancer and Uniswap pools.

## [Governance](governance)

CoW DAO is of its community, by its community, and for its community. CoW DAO uses a [decentralized governance model](governance) to ensure that the community has full control over the direction of the protocol.

## How to use CoW DAO's documentation

CoW DAO's documentation follows a "Concepts", "Tutorials", "Technical Reference" methodology. For example when a user wants to learn:

- **_What_** something is (example: batch auctions) → see [Concepts](/category/concepts)
- **_How_** to do something (example: create an order) → see [Tutorials](/category/tutorials)
- **_Technical_** information (example: such as SDKs, APIs) - see [Technical Reference](/category/technical-reference)
20 changes: 20 additions & 0 deletions docs/cow-amm/README.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# CoW AMM: The First MEV-capturing AMM

CoW AMM protects LPs from LVR so they can provide liquidity with less risk and more return. CoW AMM achieves close to 5% more in TVL compared to reference pools, protects millions from LVR, and has captured over $100,000 in surplus for LPs to date.

## AMMs don't want you to know about LVR

Liquidity providers expect their tokens to earn yield, but the dirty little secret of AMMs is that most liquidity pools lose money. In fact, hundreds of millions of dollars of LP funds are stolen by arbitrageurs every year. These losses are known as loss-versus-rebalancing (LVR). LVR is a bigger source of MEV than frontrunning and sandwich attacks combined.

## An AMM designed with LPs in mind

CoW AMM eliminates LVR once and for all by using batch auctions to send surplus to LPs

1. Liquidity providers deposit tokens into protected CoW AMM liquidity pools, where traders can access the liquidity
2. Solvers bid to rebalance CoW AMM pools whenever there is an arbitrage opportunity
3. The solver that offers the most surplus to the pool wins the right to rebalance the pool
4. CoW AMM eliminates LVR by capturing arbitrage value for LPs and shielding it from MEV bots

## Deploy liquidity on CoW AMM

Thanks to CoW AMM's integration with Balancer, LPs can now [deploy their liquidity or create a brand new pool in just a few clicks](https://balancer.fi/pools/cow).
6 changes: 6 additions & 0 deletions docs/cow-amm/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"position": 3,
"label": "🌊 CoW AMM",
"collapsible": true,
"collapsed": true
}
9 changes: 9 additions & 0 deletions docs/cow-amm/concepts/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"position": 1,
"label": "Concepts",
"collapsible": true,
"collapsed": true,
"link": {
"type": "generated-index"
}
}
21 changes: 21 additions & 0 deletions docs/cow-amm/concepts/how-cow-amms-work.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
sidebar_position: 2
---

# How CoW AMMs Work

## FM-AMMs

The [“Function-Maximizing” AMM](https://arxiv.org/abs/2307.02074) is a novel AMM mechanism that tackles the shortcomings of the CF-AMM design and eliminates LVR. The FM-AMM batches trades together, executing all the orders in a batch at the same uniform clearing price. This price is such that the AMM “moves up the curve” with each trade. Since anyone can submit trades to the FM-AMM while its batch is open, competition between arbitrageurs guarantees that FM-AMM always trades at the correct, equilibrium price.

## CoW AMM

CoW AMM is a production-ready implementation of an FM-AMM that supplies liquidity for trades made on CoW Protocol. Solvers compete with each other for the right to trade against the AMM. The winning solver is the one that moves the AMM curve higher.

CoW AMM pools are optimal for every token pair that is not stable-to-stable. Since volatility dictates the amount of LVR that takes place in any given liquidity pool, CoW AMM pools are most effective for volatile token pairs where arbitrage outweighs LP fees.

## Getting Started with CoW AMM

To facilitate easy liquidity providing, CoW DAO has partnered with Balancer to implement CoW AMMs into the Balancer ecosystem. LPs can [use the Balancer app](https://balancer.fi/pools/cow) to LP direclty on one of over a dozen liquidity pools.

In the next section, LPs can learn how to create their own CoW AMM pools for brand new assets either on Balancer or outside the platform.
23 changes: 23 additions & 0 deletions docs/cow-amm/concepts/the-problem-of-lvr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
sidebar_position: 1
---

# The Problem of LVR (Loss-versus-rebalancing)

First coined by a team of researchers from [Columbia University,](https://arxiv.org/abs/2208.06046) LVR is a form of arbitrage that occurs whenever an AMM has an outdated (stale) price in comparison to some other trading venue.

Arbitrageurs exploit this difference by trading from the AMM to the more liquid exchange (usually a centralized exchange like Binance), correcting the arbitrage and extracting value from LPs in the process.

# How LVR Works

Most AMMs (such as Uniswap) are examples of constant function automated market makers—CF-AMMs. These AMMs take in two assets and automatically re-calculate prices after each trade to ensure ample liquidity at all times. This means the AMMs experience asset price discovery as they are being traded against.

However, since crypto assets trade on various platforms including centralized exchanges, the prices on a CF-AMM may be outdated compared to the more liquid prices on a centralized exchange. This discrepancy allows arbitrageurs to trade between the liquid exchange and the outdated AMM, correcting prices and capturing arbitrage in the process.

"Loss-versus-rebalancing" is the scenario where an LP provides liquidity to a CF-AMM whose prices are stale compared to a more liquid venue like a centralized exchange. By leaving their funds in the liquidity pool, they are not making as much money as they could be if they were to constantly "rebalance" between the AMM and the exchange. Thus, they incur a "loss" compared to what they would have in a "rebalancing" strategy.

# The Impact of LVR on LPs

Many liquidity providers haven’t even heard of LVR, but it costs them 5–7% of their liquidity, resulting in hundreds of millions lost each year. In fact, when accounting for LVR, many of the largest liquidity pools are not profitable for LPs at all.

Due to these losses, LVR is a type of MEV (maximal extractable value) that accounts for more price exploitation than frontrunning and sandwich attacks combined.
9 changes: 9 additions & 0 deletions docs/cow-amm/tutorials/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"position": 2,
"label": "Tutorials",
"collapsible": true,
"collapsed": true,
"link": {
"type": "generated-index"
}
}
56 changes: 56 additions & 0 deletions docs/cow-amm/tutorials/cow-amm-deployer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
sidebar_position: 1
---

# Deploying a CoW AMM Using Balancer

In this short tutorial, we describe how you can create and deploy their own Balancer CoW AMM.

**You may also deploy a CoW AMM through the Balancer UI using [this guide.](https://cow.finance/learn/how-to-create-a-lvr-protected-liquidity-pool-on-cowamm)**

The proposed transactions and interactions can be executed through any smart contract or EOA transaction builder, Etherscan "Write Contract," from other UI mechanisms, or directly from the console.

The current factory contract addresses are the following:

- Ethereum Mainnet: [`0xf76c421bAb7df8548604E60deCCcE50477C10462`](https://etherscan.io/address/0xf76c421bAb7df8548604E60deCCcE50477C10462#code)
- Gnosis Chain: [`0x703Bd8115E6F21a37BB5Df97f78614ca72Ad7624`](https://gnosisscan.io/address/0x703Bd8115E6F21a37BB5Df97f78614ca72Ad7624#code)
- Arbitrum One: [`0xE0e2Ba143EE5268DA87D529949a2521115987302`](https://arbiscan.io/address/0xe0e2ba143ee5268da87d529949a2521115987302#code)
- Base: [`0x03362f847B4fAbC12e1Ce98b6b59F94401E4588e`](https://basescan.org/address/0x03362f847b4fabc12e1ce98b6b59f94401e4588e#code)
- Avalanche: N/A
- Polygon: N/A
- BNB: N/A
- Linea: N/A
- Plasma: N/A
- Sepolia Testnet: [`0x1E3D76AC2BB67a2D7e8395d3A624b30AA9056DF9`](https://sepolia.etherscan.io/address/0x1E3D76AC2BB67a2D7e8395d3A624b30AA9056DF9#code)

These contracts can be verified through [this](https://github.com/balancer/cow-amm) repository.

1. In order to create a new pool, one first needs to call the `newBPool` function of the factory contract. An example transaction that creates a new pool can be found [here](https://etherscan.io/tx/0x7543a97853827e267ecd3c1309509ac7704e4f85a53fbfacd6060f461d85bad8#eventlog). The relevant `LOG_NEW_POOL` log also reveals the address of the newly created pool; in our example transaction, it is `0x81530e9B069c69F6671A0A9d7Ee337cafEF419F6`.

:::note

In case ABI of the factory contract is not fetched, the ABI from the Sepolia network can be used.
:::

1. The next step is to approve the tokens we want to add to the pool; this can be done by calling the `approve()` function on the contract of the relevant ERC-20 token that is being added to the pool, where the "spender" needs to be set to the newly created BPool address from (1).

:::caution

One needs to take the token's decimals into account in order to set the correct approval.
:::

1. The next step is to bind the approved tokens to the pool, by using the `bind()` function of the newly created pool contract. We need to do one bind per token that will be added to the pool. Note that the `denorm` parameter should always be set to 1000000000000000000 (i.e., 10^18).

2. We can then set the swap fee; this is the fee trades will pay if they trade permissionlessly (i.e., outside of the batch), and this is done by calling the `setSwapFee()` function of the pool contract. The fee parameter needs to be specified in wei, hence, a 10% fee would be 100000000000000000 (i.e., 10^17)

:::note

In order to guarantee full LVR protection, the fee should be set to 100%.
:::

:::caution

The fee parameter is an unsigned integer where 10^18 corresponds to 100% of fee. Note that 100% is actually not a valid value though, but one can set up to 99.99%.
:::

1. The final step is to finalize the pool by calling the `finalize()` function of the newly created pool contract.
107 changes: 107 additions & 0 deletions docs/cow-amm/tutorials/cow-amm-for-solvers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
---
sidebar_position: 3
---

# CoW AMM Liquidity for Solvers

## 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 increases 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 Balancer CoW AMMs

CoW AMM pairs can be detected by listening to the `COWAMMPoolCreated` events emitted by the `BCowFactory` instance for the current chain (see the [official contract repository](https://github.com/balancer/cow-amm) for the current deployment addresses).
All addresses of Balancer CoW AMMs are sent as part of the auction instance as `surplusCapturingJitOrderOwners`.

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

### Creating CoW AMM orders with the helper contract

Integrating CoW AMM orders requires adding a JitOrder with the CoW AMM. This order should be described from the CoW AMM pool's perspective. So if a user wants to sell token A to buy token B and you would like to settle (part of) this order with a CoW AMM, then you would need to add a JitOrder from the CoW AMM's perspective to match (part of) this order. In other words, you would be adding a JitOrder for the CoW AMM to sell token B to buy token A. You can do this by calling the `orderFromBuyAmount` because the user’s amount is exactly how much you would want the pool to receive, asking for the amount of tokens in exchange.

[The source code for the helper contract can be found here.](https://github.com/balancer/cow-amm/blob/main/src/contracts/BCoWHelper.sol) The `orderFromBuyAmount` and 'orderFromSellAmount' methods return the order, preInteractions, postInteractions, and signature. This can be used to generate the order (JitOrder) and check prices.

This order generated by the BCoWHelper contract will contain the limit prices for which the CoW AMM is willing to trade. Trading at exactly these limit prices will not generate surplus for the CoW AMM, any price improvement from these limit prices will be surplus captured by the CoW AMM.

One thing to keep in mind when using the helper contract to generate these JitOrders is that both the `orderFromSellAmount` and `orderFromBuyAmount` methods return an order where the `partiallyFillable` field is marked as true. However, since the driver does not support partially fillable JitOrders, it replaces the partiallyFillable field with false. This means that the `partiallyFillable` field must be set to false before passing the solution to the driver and the signature of both the JitOrder and the commit hash in the pre-interaction should be updated accordingly.

Doing this will generate additional surplus in the solver competition (assuming you trade at a better price than the provided limit price). For example, if a solver would like to settle a user using outside liquidity that trades a pair for which there is a CoW AMM, then that solver can compare those prices with that of the CoW AMM. This (or part of this) interaction can then be replaced with the CoW AMM to generate additional surplus. This way the solver can integrate CoW AMMs by solving as if these CoW AMM's do not exist, and then check whether some of the outside interactions can be replaced by CoW AMMs (note: UPC and EBBO apply to CoW AMMs as well).

Another way that a solver can use CoW AMM's is by using outside liquidity from the competition/auction to trade with the CoW AMM, thereby re-balancing the AMM and receiving an additional surplus for doing so if the prices of the CoW AMM is off relative to the outside world.

The helper contracts are deployed here:

- [Mainnet](https://etherscan.io/address/0x03362f847b4fabc12e1ce98b6b59f94401e4588e#code)
- [Arbitrum](https://arbiscan.io/address/0xdb2aeab529c035469e190310def9957ef0398ba8#code)
- [Gnosis](https://gnosisscan.io/address/0xdb2aeab529c035469e190310def9957ef0398ba8#code)
- [Base](https://basescan.org/address/0x467665d4ae90e7a99c9c9af785791058426d6ea0#code)
- Avalanche N/A
- Polygon N/A
- BNB N/A
- Linea N/A
- Plasma N/A

### 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`.

:::note

The sell and buy amount specified are the limit amounts of the order. The actual executed amounts are determined using prices from the auction.
In that regard, CoW AMM orders behave exactly like normal trader orders.

:::

You also need to compute:

- the order hash `hash` as defined in the library `GPv2Order`, and
- the order signature

Example code that generates an order can be found in [the `order` function of the BCoWHelper contract](https://github.com/balancer/cow-amm/blob/04c915d1ef6150b5334f4b69c7af7ddd59e050e2/src/contracts/BCoWHelper.sol).

This order can be included in a batch as any other CoW Protocol orders with two extra conditions:

- One of the pre-interactions must set the commitment by calling `BCoWPool.commit(hash)`.
- Must contain at most one order from the AMM in the same batch.

:::note

Solvers using the non co-located driver should add a [`JitTrade`](https://github.com/cowprotocol/services/blob/95ecc4e01b7fd06ec0b71c6486cb2cdd962e5040/crates/solvers/openapi.yml#L744C1-L774C52) and a [`preInteraction`](https://github.com/cowprotocol/services/blob/95ecc4e01b7fd06ec0b71c6486cb2cdd962e5040/crates/solvers/openapi.yml#L920C1-L925C46) to their solution.

:::

### Surplus

The surplus for a CoW AMM order is measured the same way as other orders, by comparing the traded amounts to limit amounts.

When creating a CoW AMM order it is therefore encouraged to use the smallest possible limit amount which does not violate the invariant of the pool.

If we call `X` (resp. `Y`) the reserves of sell (resp. buy) token, and `x` (resp. `y`) the executed sell (resp. buy) amount, then the minimal buy amount is `x Y / (X - x)`
and the order surplus with that choice for the limit amount is:

```
x Y
surplus = y - ----- .
X - x
```

Maximizing this quantity will lead to the largest score in the solver competition.
Loading
Loading