-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into automatic-formatting
- Loading branch information
Showing
7 changed files
with
167 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,8 +7,5 @@ out/ | |
/broadcast/*/31337/ | ||
/broadcast/**/dry-run/ | ||
|
||
# Docs | ||
docs/ | ||
|
||
# Dotenv file | ||
.env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,71 +1,38 @@ | ||
## Foundry | ||
## CoW AMM | ||
|
||
**Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.** | ||
|
||
Foundry consists of: | ||
|
||
- **Forge**: Ethereum testing framework (like Truffle, Hardhat and DappTools). | ||
- **Cast**: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data. | ||
- **Anvil**: Local Ethereum node, akin to Ganache, Hardhat Network. | ||
- **Chisel**: Fast, utilitarian, and verbose solidity REPL. | ||
CoW AMM is an automated market maker running on top of CoW Protocol. | ||
|
||
## Documentation | ||
|
||
https://book.getfoundry.sh/ | ||
|
||
## Usage | ||
|
||
### Build | ||
You can find detailed documentation on the building blocks of this repo in the following files: | ||
|
||
```shell | ||
$ forge build | ||
``` | ||
- [amm.md](./docs/amm.md): details on what a CoW AMM is and how to set it up. | ||
|
||
### Test | ||
## Research | ||
|
||
```shell | ||
$ forge test | ||
``` | ||
Details on the theory behind CoW AMM can be found on the paper [Arbitrageurs' profits, LVR, and sandwich attacks: batch trading as an AMM design response](https://arxiv.org/pdf/2307.02074.pdf). | ||
|
||
### Format | ||
|
||
```shell | ||
$ forge fmt | ||
``` | ||
## Development | ||
|
||
### Dev set up | ||
|
||
You can install git hooks to help you catch simple mistakes before running some git actions like committing. | ||
See the [dedicated instructions](./dev/hooks/install.md) for how to install the hooks. | ||
|
||
### Gas Snapshots | ||
|
||
```shell | ||
$ forge snapshot | ||
``` | ||
|
||
### Anvil | ||
|
||
```shell | ||
$ anvil | ||
``` | ||
|
||
### Deploy | ||
### Build | ||
|
||
```shell | ||
$ forge script script/Counter.s.sol:CounterScript --rpc-url <your_rpc_url> --private-key <your_private_key> | ||
$ forge build | ||
``` | ||
|
||
### Cast | ||
### Test | ||
|
||
```shell | ||
$ cast <subcommand> | ||
$ forge test | ||
``` | ||
|
||
### Help | ||
### Format | ||
|
||
```shell | ||
$ forge --help | ||
$ anvil --help | ||
$ cast --help | ||
$ forge fmt | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
# CoW AMM | ||
|
||
CoW AMM is an automated market maker running on top of CoW Protocol. | ||
|
||
## How it works | ||
|
||
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. | ||
|
||
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. | ||
|
||
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. | ||
|
||
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. | ||
|
||
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 | ||
|
||
- 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 | ||
|
||
### `ComposableCoW` order | ||
|
||
A `ComposableCoW` order is created by calling the function `create(ConditionalOrderParams params, bool dispatch)` on the `ComposableCoW` main contract. | ||
|
||
The conditional order parameters should be set as follows: | ||
- `IConditionalOrder handler`: the address of the standard deployment of `ConstantProduct` for the desired chain. See file `networks.json` for a list of official deployments by chain id. | ||
- `bytes32 salt`: this value is used to make the order unique. It's recommended to use a value that hasn't been used before for an order on the same safe. Note that it's discouraged to use the CoW AMM safe for other orders outside of setting up the AMM, in which case conflicts are not a concern. | ||
- `bytes staticInput`: The configuration values for the CoW AMM. See next section for more details. | ||
|
||
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 | ||
|
||
The static input of the constant product handler comprises the following parameters: | ||
|
||
- `IERC20 token0`: the first of the two tokens traded by the AMM. | ||
- `IERC20 token1`: the second of the two tokens traded by the AMM. | ||
- `uint256 minTradedToken0`: the minimum amount of token0 that needs to be traded for an order to be returned by `getTradeableOrder`. Order with lower traded amount can still be created manually. | ||
- `IPriceOracle priceOracle`: the address of a contract that implements the generic price oracle interface. | ||
See the section below for more information on which price oracles are available. | ||
- `bytes priceOracleData`: the extra oracle information needed to recover the price. | ||
See the section below for more information on how to set this value based on the chosen price oracle. | ||
- `bytes32 appData`: The app data (as defined in a CoW Protocol order) that must be used for the order to be valid. | ||
|
||
If Foundry is available in your system, you can generate the bytes calldata with the following command: | ||
```sh | ||
token0=0x1111111111111111111111111111111111111111 | ||
token1=0x2222222222222222222222222222222222222222 | ||
minTradedToken0=31337 | ||
priceOracle=0x1337133713371337133713371337133713371337 | ||
priceOracleData=0xca11d47a | ||
appData=0x3232323232323232323232323232323232323232323232323232323232323232 | ||
cast abi-encode 'f(address,address,uint256,address,bytes,bytes32)' "$token0" "$token1" "$minTradedToken0" "$priceOracle" "$priceOracleData" "$appData" | ||
``` | ||
|
||
### 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. | ||
|
||
We support the following price oracles: | ||
- `UniswapV2PriceOracle`, based on the limit price of a predefined Uniswap v2 pair. | ||
|
||
Contract addresses for each supported chain can be found in the file `networks.json`. | ||
|
||
#### 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: | ||
- `IUniswapV2Pair referencePair`: the address of a Uniswap pool for the tokens `token0` and `token1`. | ||
|
||
Note that the order of the tokens does _not_ need to be consistent with the order of the tokens in the pool. | ||
The order of the tokens in the constant product static input determines that the price is expressed in terms of amount of token0 per amount of token1. | ||
If the tokens are not the same as those traded on the chosen reference pair, no order will be created. | ||
|
||
If Foundry is available in your system, you can generate the bytes calldata with the following command: | ||
```sh | ||
referencePair=0x1111111111111111111111111111111111111111 | ||
cast abi-encode 'f(address)' "$referencePair" | ||
``` | ||
|
||
## 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. | ||
|
||
The AMM relies on price oracle exclusively for generating orders that will plausibly be settled in the current market conditions, but they aren't used to determine whether an order is valid. | ||
If a price oracle is compromised or manipulated, the main risk is that the liquidity available on CoW protocol will be used suboptimally by the solvers that aren't aware of the custom semantics of a CoW AMM. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters