---
# System prepended metadata

title: Milkman

---

# Milkman

## Problem

Historically, trying to create trades on CoW protocol from a smart contract has been either painful / clunky or impossible, depending on your use-case. At Yearn, we would create a sell order and create a Gnosis transaction to sign that sell order on-chain, but by the time the transaction gets 3/3 the minOut we set has gone out of range and we need to go through the process again. 

And of course, since as a part of this flow someone needs to be generating off-chain CoW orders, this means regular smart contracts can't use CoW. For example, a borrow/lend application couldn't decide to liquidate collateral through CoW.

## Milkman as a solution

To sell assets through Milkman, you call `requestSwapExactTokensForTokens`, which has a UniV2-like interface. Some bots take it over from there, and you should have the tokens you bought in 1-5 minutes.

```plantuml
@startuml
participant User
participant "Milkman Contract" as Milkman
participant "CoW Settlement Contract" as Settlement
participant "Milkman Bots" as Bots
participant "CoW Solvers" as Solvers

User -> Milkman: requestSwapExactTokensForTokens()
User -> Milkman: 1 ETH
Bots -> Milkman: pull event
Bots -> Solvers: create order
Solvers -> Solvers: best price competition
Solvers -> Settlement: settle()
Settlement -> Milkman: isValidSignature()
Milkman -> Milkman: run checks
Milkman -> Settlement: true
Milkman -> Settlement: 1 ETH
Settlement -> User: 2000 DAI
@enduml
```

This works in the following way:
- when you create a swap request, it fires an event
- a bunch of off-chain Milkman bots pick up this event, and create a corresponding CoW order, with the `from` field set to Milkman's address
- solvers go through normal CoW process, compete on best price & call `settle` on the CoW settlement contract
- the settlement contract call's Milkman's `isValidSignature` function, which runs checks on the order to make sure it's good (e.g., fee isn't too high, minOut isn't too low, etc.)
- if all goes according to plan, the token that the user's selling gets pulled out of the settlement contract and the token that they're buying gets sent to them

## Price checkers (this is for a technical audience, so not sure if this is necessary)

Easy breezy, right? Well, not so fast. This is the actual interface of Milkman:

```
requestSwapExactTokensForTokens(
    uint256 amountIn,
    IERC20 fromToken,
    IERC20 toToken,
    address to,
    address priceChecker,
    bytes calldata priceCheckerData
)
```

Although most of this should look familiar to anyone who's worked with UniV2, there are two new fields: `priceChecker` and `priceCheckerData`. Price checkers are how Milkman verifies that an order's `minOut` and `fee` are acceptable. For example, one price checker checks how much `toToken` the user would receive if they sold their tokens to SushiSwap, and then only allows orders that have a `minOut` of at least 99% of what the user would get on SushiSwap.

`priceCheckerData` is data that Milkman will pass to the price checker to verify your order, and may be optional or required depending on your price checker. Which price checker you choose depends on the tokens you're selling. For example, the SushiSwap price checker would be useful for selling TOKE to ETH, since Sushi has the most liquid TOKE markets. Chainlink, on the other hand, could be good for selling WBTC, since Chainlink has a BTC oracle that's updated hourly.

The list of existing price checkers is as follows:
- SushiSwap
- Uniswap V2
- Uniswap V3
- Curve
- Chainlink

But anyone can create their own; it's completely permissionless! 

Examples of interacting with Milkman are [here](https://github.com/charlesndalton/milkman/blob/main/docs/EXAMPLES.md). There's also a handy Python SDK, milkman_py, that abstracts away some of the raw abi encoding. 
