Skip to main content

import HistoricalFact from './_gpv2.md'

GPv2Settlement

Architecture

A settlement comprises of:

  • A list of traded tokens with their corresponding price in the batch
  • A list of trades to execute
  • A list of interactions

A solver monitors on-chain liquidity and on receiving batch-auction instances from the Protocol, it determines which orders can be matched, the clearing prices of the settlement, and what extra liquidity is necessary from the blockchain.

Normally, all orders in a settlement are settled with uniform clearing prices, which means that every user receives the same price for the same token.

If the transaction does not revert, each order will be executed during a settlement and the user will receive the desired token after the settlement.

Guarantees and Invariants

The parameters of the order are verified for validity:

  • The signature for the order matches the user's address
  • The order is not expired
  • The order was not previously filled
  • The current prices are equal to or better than what is specified in the order

Trades

Trades contain a description of the users' orders, a signature for verifying its validity, and the executed amount (for partially fillable orders).

The contract decodes the order parameters from the trade.

Interactions

Interactions allow solvers to execute arbitrary calls to any on-chain contract. Normally, they are used to interact with other on-chain liquidity providers, for example, to make a swap call to Uniswap.

Protocol fee collection

Interactions are also used for accounting / bookkeeping purposes as well. As trades are executed, the Protocol collects a fee from each trade and stores this in the settlement contract (known as internal buffers). At regular intervals, the Protocol withdraws the fees from the settlement contract to the Protocol's treasury Safe.

tip

Solvers are NOT able to directly access user funds through interactions. There are strict guarantees enforced by the settlement contract over movement of user funds.

caution

Allowing interactions by solvers, creates the possibility of malicious solvers that can steal funds from the settlement contract. This is why the Protocol only allows interactions to be executed by allow-listed solvers, and requires that the solver post a bond to the Protocol before it can be allowed.

Data Types and Storage

GPv2Order.Data struct

The GPV2Order.Data is the one of the most important data structures in the Protocol. It:

  • defines the parameters of an order
  • is the basis of which the order digest is determined using EIP-712 and subsequently signed by the user

In code, it is defined as:

struct Data {
IERC20 sellToken;
IERC20 buyToken;
address receiver;
uint256 sellAmount;
uint256 buyAmount;
uint32 validTo;
bytes32 appData;
uint256 feeAmount;
bytes32 kind;
bool partiallyFillable;
bytes32 sellTokenBalance;
bytes32 buyTokenBalance;
}
FieldDescription
sellTokenERC-20 token sell
buyTokenERC-20 token to buy
receiverThe address that will receive the proceedings of the trade. If this field is address(0) (ie. the zero address 0x00...0), then the user who signed the trade is going to receive the funds.
sellAmountAmount of sellToken that is sold in wei.
buyAmountAmount of buyToken that is bought in wei
validToUNIX timestamp (in seconds) until which the order is valid
appDataExtra information about the order. Not enforced by the smart contract outside of signature verification (may be used for referrals etc).
feeAmountAmount of fees paid in sellToken wei
kindbuy or sell
partiallyFillablepartially fillable (true) or fill-or-kill (false)
sellTokenBalanceFrom where the sellToken balance is withdrawn
buyTokenBalanceWhere the buyToken is deposited
Balance locations

The sellTokenBalance and buyTokenBalance fields the keccak256 hash of the balance location. The following table describes the possible values and their meaning:

ValueDescription
erc20User's ERC-20 balance via approvals given to the GPv2VaultRelayer (default)
externalUser's ERC-20 balance via approvals given to the Balancer vault
internalUser's internal Balancer vault balance

orderUid

The orderUid is a unique identifier for an order. It is 56 bytes and defined as:

orderUid = orderDigest ‖ owner ‖ validTo

Where:

  • orderDigest is the EIP-712 digest of the GPv2Order.Data struct (32 bytes)
  • owner is the address of the order owner (20 bytes)
  • validTo is the timestamp until which the order is valid (4 bytes)
  • is the concatenation operator

filledAmounts

The filledAmounts mapping stores the amount of an order that has been filled. It is defined as:

mapping(bytes => uint256) public filledAmounts;

The key is the orderUid and the value is the amount of the order that has been filled.

caution

Do NOT rely on the filledAmounts mapping to determine if an historical order has been filled. This is because the respective slot in the mapping may be freed by a solver after the order has expired to save gas.

Functions

This section will cover the main functions that are used by users and solvers.

For users

setPreSignature

This function allows a user to pre-sign an order, which can be used if for some reason the user is unable to sign with eth_sign, EIP-712, or ERC-1271. This is most useful for smart contracts that have neither a private key, nor implement ERC-1271, but still want to use CoW Protocol.

function setPreSignature(bytes calldata orderUid, bool signed) external;

invalidateOrder

This function allows a user to invalidate (cancel) an order:

function invalidateOrder(bytes calldata orderUid) external;

For solvers

settle

This function is permissioned and can only be called by solvers passing the allow-list authentication. It executes a settlement:

function settle(
IERC20[] calldata tokens,
uint256[] calldata clearingPrices,
GPv2Trade.Data[] calldata trades,
GPv2Interaction.Data[][3] calldata interactions
) external nonReentrant onlySolver;

Indexing

Events that are indexed are:

  • Trade - on any trade
  • Interaction - on any interaction
  • Settlement - which solver executed the settlement
  • OrderInvalidated - when an order is invalidated
  • PreSignature - when pre-signing or revoking a pre-signed signature

Off-chain

As this is the main contract of CoW Protocol, all the off-chain infrastructure is built around it. This includes:

  • The Protocol
  • Solvers