owned this note
owned this note
Published
Linked with GitHub
# Milkman
![](https://i.imgur.com/SOwYtIJ.jpg =100x)
**Description:**
Today, the primary interface to the CoW Protocol is the CowSwap UI, hosted at [cowswap.exchange](https://cowswap.exchange). This has made it hard for Gnosis Safes to route their order flow through the CoW Protocol, and impossible for regular smart contracts that aren't connected to the internet. For example, it would be impossible today for a borrow/lend platform or a debt-based stablecoin to use the CoW Protocol to liquidate collateral.
To solve these problems, for ourselves and others, we introduce a smart contract interface to the CoW Protocol called Milkman. Smart contracts can call *milkman.requestSwapExactTokenForTokens*, and orders will be submitted and executed asynchronously.
**Design:**
*Goals:*
- <ins>Do not add any new trust assumptions</ins>
- As abstracted away from the user as possible, without breaking above rule
- Gas-efficient
*Assumptions:*
- The same UID cannot be executed by the CoW protocol multiple times
*Considerations:*
- Users can requests swaps for such a small amount that it doesn't pay for gas, and we can't create an order
- Users can requests swaps with all of the same parameters in the same block (e.g., two 100 USDC->YFI swaps). This means we can't store orders as hashes of these parameters alone.
- If a single order can be used to sign multiple UIDs at the same time, this leads to an unsteady state. As an example, let's say that Alice is swapping 100 USDC to YFI, and so there's 100 USDC in contract. Eve requests a swap of 100 USDC to OMG. If she can use that order to sign two UIDs, she can potentially get all 200 USDC to buy OMG that gets sent to her.
- Multiple swaps can be requested before any of them are executed.
*Swap lifecycle:*
- When a user first requests a swap, this swap is 'requested.'
- From there, a keeper needs to:
- create an order UID via the CoW Protocol API
- submit this UID to the contract, along with the parameters, such as fromToken, toToken, minOut, etc.
- After the contract receives the UID and order parameters, it
- verifies that these two match. This is possible because UIDs are generated deterministically using order parameters.
- verifies that minOut is some reasonable amount. This id done through a *priceChecker*, passed in by the user. For example, one priceChecker could check Uniswap V3 to ensure that minOut is at least 95% of what you would get by selling to Uniswap.
- Signs the order UID by calling *cowProtocolSettlement.setPreSignature(UID, true)*
- 'Pairs' the UID and the requested swap, ensuring that this requested swap cannot be used to sign any more UIDs
- At this point, the order should be executed asynchronously via the CoW Protocol. Once it is executed, anyone can call proveExecution. Although this doesn't do much by itself, it will revert if the order is not executed, which could be used to build some kind of keeper reward mechanism on top.
- However, not all signed UIDs will be executed. For example, the market could have moved, and minOut could no longer be valid. After a period of 50 blocks, a keeper can prove that an order has not been executed, which moves the swap back into the requested state.
*State diagram:*
```plantuml
[*] -> Requested : request swap
Requested -down-> Paired : pair swap with UID
Paired -> [*] : prove execution
Paired -up-> Requested : prove not executed\n&& 50 blocks elapsed
```