- Convert their
ETHintoWETH - Approve the vault relayer for spending their
WETH - Create their order
Architecture
An intermediary smart contract is used to wrapETH into WETH and create an intent on behalf of the user. This contract then expresses the users’ intent to trade on CoW Protocol using an ERC-1271-signed intent.
The user interacts with Eth-flow to deposit ETH via createOrder. The Eth-flow contract will then create an intent on behalf of the user that will be placed into the Order Book by the Protocol and settled by solvers - the same way as if the user had wrapped their ETH to WETH and created the intent themselves.
The proceeds will go to the user and not to the exchange because we specify the user as the receiver in the Eth-flow contract intent.
User intent / Contract intent
EveryETH sell intent from a user (“user intent”) is transformed into a WETH sell intent in the Eth-flow contract (“contract intent”).
This intent is implicitly created when the user deposits ETH, by emitting an on-chain event that is indexed by the off-chain components of the protocol.
The user’s intent is a subset of the contract intent as some parameters are implicit (such as the sell token being ETH and the receiver being the user). The following table describes the parameters of the user intent.
The user intent described below is not a valid intent for the settlement contract. It represents the data used by the Eth-flow contract for bookkeeping. The contract intent (
GPv2Order.Data) is that which is settled by the Protocol.| Parameter | User | Contract | Limitation |
|---|---|---|---|
sellToken | ETH | WETH | |
buyToken | any | same as user | |
receiver | != address(0) | same as user | Must NOT be the zero address as this has the meaning of self in CoW Protocol |
sellAmount | any | same as user | |
buyAmount | any | same as user | |
validTo | any | type(uint32).max | Required to be fixed at the maximum point in the future as filledAmount in GPv2Settlement contract is relied upon which can be cleared by freeFilledAmountStorage |
appData | any | same as user | |
feeAmount | any | same as user | |
kind | sell | sell | Limited to sell intents only as dust from buy intents left in the Eth-flow contract would not be economical for a user to withdraw |
partiallyFillable | any | same as user | |
sellTokenBalance | erc20 | erc20 | Only erc20 implemented |
buyTokenBalance | erc20 | erc20 | Only erc20 implemented |
Contract order signing
The contract order usesERC-1271 signatures.
The signature is empty, since all information needed to verify the order can be found on-chain.
Signature verification in a settlement works as follows:
- The intent digest is computed as part of the settlement process and is the message that is assumed to be signed by the Eth-flow contract with
ERC-1271. The digest is used to retrieve theownerand thevalidTofrom the intent mapping. - The intent
validTois checked against the current timestamp. - The intent must be valid (should be set and not invalidated).
ERC-1271.
Guarantees / Invariants
- A user can have multiple open intents
Data Types and Storage
EthFlowOrder.OnchainData
This struct contains the parts of a user intent that need to be stored on chain.
owner:
owner = address(0)⇒ unsetowner = address(0xffffffffffffffffffffffffffffffffffffffff)⇒ invalidated
Modifying the
validTo field does not change the contract intent digest.EthFlowOrder.Data
This struct collects all parameters needed to describe a single user trade intent.
| Field | Description |
|---|---|
... | Same as GPv2Order.Data |
quoteId | quoteId returned by Order book API when requesting a quote for this order |
Users should provide a valid
quoteId when placing an order. This is not enforced by the Eth-flow contract, however quotes may be used as a basis to determine whether the automated refunding service should refund an order that has expired or not. In all cases, the user is able to manually refund the portion of their order that has not been matched.orders
The Eth-flow contract stores users’ intents as a mapping:
GPv2Order.Data struct digest) from the user intent parameters.
There is a possibility of a collision in the digest. There could be two different Eth-flow intents that end up having the same digest. In this case, only one of the two intents can be created and the contract would revert if trying to create the second one.
Functions
All interactions with the Eth-flow contract require an Ethereum transaction by the user and incur a gas cost in addition to the protocol fee.
For users
createOrder
For when a user wants to sell ETH:
- The amount of
ETHsent along with the transaction must be exactly what is needed to cover the sell amount plus the fees. - The order must be valid at the time the transaction is mined.
invalidateOrder
For when a user wants to invalidate an intent and return the ETH to the intent creator:
order is the same intent struct used to create the intent.
Intents can be invalidated in two ways:
- The user who created the intent calls this function. Every valid intent can be invalidated at any time by its creator.
- After the intent has expired, any address can trigger its invalidation. This is done to allow CoW Protocol to provide a service to automatically refund unmatched orders to the users.
invalidated.
Automatic Refund Service
CoW Protocol operates an automatic refund service that monitors expired Eth-flow orders and refunds unmatched ETH back to users. However, this service has specific criteria to ensure it only refunds orders that had reasonable execution parameters.Slippage Tolerance Requirements
The automatic refund service will only refund orders that were created with a minimum slippage tolerance of 2%. This requirement exists because:- Orders with very low slippage tolerance have a higher probability of expiring without execution
- The 2% threshold helps distinguish between orders that failed due to market conditions versus those with unrealistic execution parameters
Automatic Refund Eligibility
Automatically refunded:- Eth-flow orders with 2% or higher slippage tolerance
- Orders that expire without being matched
- Orders created through CoW Swap interface (uses 2% default)
- Orders created through CoW Widget (uses 2% default)
- Eth-flow orders with less than 2% slippage tolerance
- Users must use the manual refund tool to recover their ETH
Default Settings
CoW Swap Interface & CoW Widget
Both the CoW Swap interface and CoW Widget set 2% slippage tolerance as the default for Eth-flow orders. Users who don’t modify this default setting will automatically qualify for the refund service if their orders expire.For Integrators
If you’re integrating CoW Protocol and want your users’ Eth-flow orders to be eligible for automatic refunds, ensure that:- The default slippage tolerance is set to at least 2%
- Users are informed about the slippage requirements for automatic refunds
- Consider displaying a warning if users set slippage below 2% that they may need to manually refund expired orders
Do you need to manually recover funds from an Eth-flow intent? Use the manual refund tool. Simply enter the TX hash of the Eth-flow intent creation transaction and the tool will generate a transaction that will invalidate the intent and return the funds to the user. For more details about automatic vs manual refunds, see the Automatic Refund Service section above.
Indexing
The Eth-flow contract has events that are indexed by the Protocol. These events are:OrderPlacement
Off-chain
There are two components in services that are used in the off-chain infrastructure for Eth-flow:- Protocol - adds the intent to the order book
- Refunder - automatically refunds unmatched intents