Skip to content

Commit

Permalink
some restructuring
Browse files Browse the repository at this point in the history
  • Loading branch information
harisang committed Jan 27, 2025
1 parent 0db3677 commit 02bf4f9
Showing 1 changed file with 18 additions and 9 deletions.
27 changes: 18 additions & 9 deletions docs/cow-protocol/reference/core/auctions/accounting.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ sidebar_position: 4
There is an accounting process in place for the solver competition. It is performed separately on each chain. Currently, the execution of the accounting process takes place once a week for all chains the protocol operates on, and each accounting week starts on Tuesday at midnight UTC and concludes a week later at midnight UTC. This accounting process consists of the following:
- calculation of total rewards/penalties, as specified by the [mechanism](/cow-protocol/reference/core/auctions/rewards);
- calculation of protocol and partner fees;
- settlement contract buffers accounting, which consists of (1) calculation of network fees (meant to cover gas) that solvers might deposit in the settlement contract, (2) calculation of protocol and partner fees that solvers might deposit in the settlement contract, and (3) all other imbalances appearing in the settlement contract after a transaction gets executed, for solvers that choose the settlement contract as their execution layer.
- settlement contract buffers accounting, which consists of (1) calculation of protocol and partner fees that solvers might deposit in the settlement contract, (2) calculation of network fees (meant to cover gas) that solvers might deposit in the settlement contract, and (3) all other imbalances appearing in the settlement contract after a transaction gets executed, for solvers that choose the settlement contract as their execution layer.

A summary of the above, that is used to verify the accounting process each week, can be found in this Dune dashboard: https://dune.com/cowprotocol/cow-solver-rewards.

Expand All @@ -33,17 +33,23 @@ We also highlight that performance and quote rewards are both paid in COW. To co

Certain orders come with a list of so-called fee policies; these are fees that can be determined when an execution of an order is observed on-chain. For every CoW Protocol trade, one can check what protocol and partner fees were charged to the order (if any), by searching via the api for the corresponding order (see here: https://api.cow.fi/docs/#/default/get_api_v1_trades). We note that from a solver point of view, protocol and partner fees are treated uniformly, and the only thing that differentiates them is the recipient of the fee; in the first case it is the CoW DAO, while in the second case it is the corresponding partner.

Solvers can decide to collect these protocol fees in the settlement contract, in order to then redirect these funds to the DAO or the relevant partner as protocol or partner fees, respectively,. These amounts are converted to the native token of the chain by using the prices provided in the auction instance where each order got executed.

If a solver decides to collect these fees in the settlement contract, then during the accounting, these fee amounts are converted to the native token, as explained above, and are sent by the main accounting transaction to the appropriate receiver.
## Buffer accounting

As noted, by knowing the fee policies associated with an order and observing the on-chain execution of an order, one can fully determine the protocol fees associated with the execution. For simplicity, the core team maintains the following Dune table (https://dune.com/queries/4364122), that among other things, reveals the amounts charged as protocol and partner fees on a per trade basis. The relevant columns are `protocol_fee` and `partner_fee`. Note that the `protocol_fee` entry is the total protocol and partner fee charged, so in case there is a non-zero partner fee, in order to determine what amount is meant to be sent to the CoW DAO, one needs to subtract the `partner_fee` entry from the `protocol_fee` entry.
As mentioned above, buffer accounting consists of:
- monitoring protocol and partner fees that solvers might deposit to the settlement contract,
- network fees that solvers might deposit to the settlement contract, and
- all other imbalances appearing in the settlement contract after a transaction gets executed, for solvers that choose the settlement contract as their execution layer; we call these imbalances slippage.

## Network fees
### Protocol and partner fees in the settlement contract

Similar to protocol fees, solvers can decide to collect part of the sell amount of an order in the settlement contract, as a network fee that would cover the gas cost associated with the execution of an order. These fees, specified in the sell token, are converted to the native token of the chain, using the prices provided in the auction instance where each order got executed, and are sent to solvers at the end of each accounting week. There is a dedicated table maintained by the core team that exposes the network fees (as well as the protocol fees) charged to each trade, and can be found [here](https://dune.com/queries/4058574).
Solvers can decide to collect these protocol and partner fees in the settlement contract, in order to then redirect these funds to the DAO or the relevant partner as protocol or partner fees, respectively,. These amounts are converted to the native token of the chain by using the prices provided in the auction instance where each order got executed.

### Implementation details
If a solver decides to collect these fees in the settlement contract, then during the accounting, these fee amounts are converted to the native token, as explained above, and are sent by the main accounting transaction to the appropriate receiver.

As noted, by knowing the fee policies associated with an order and observing the on-chain execution of an order, one can fully determine the protocol fees associated with the execution. For simplicity, the core team maintains the following Dune table (https://dune.com/queries/4364122), that among other things, reveals the amounts charged as protocol and partner fees on a per trade basis. The relevant columns are `protocol_fee` and `partner_fee`. Note that the `protocol_fee` entry is the total protocol and partner fee charged, so in case there is a non-zero partner fee, in order to determine what amount is meant to be sent to the CoW DAO, one needs to subtract the `partner_fee` entry from the `protocol_fee` entry.

##### Implementation details

In this section, we share a few details about how protocol and partner fees are computed by observing an on-chain execution. When it comes to protocol and partner fees, one needs to be aware of the fee policies associated with an order. These fee policies are shared with solvers as part of the auction instance sent to them, and are also revealed for each trade in the api (see here: https://api.cow.fi/docs/#/default/get_api_v1_trades). This allows us to fully determine the protocol and partner fees associated with the order.

Expand Down Expand Up @@ -74,14 +80,17 @@ ucp(WETH) = 3005 and ucp(USDC) = 0.999. While the custom trade prices would be s

From the actual on-chain execution, as we mentioned, one can reverse-engineer the solver's execution and determine using the fee policies that the protocol fee is 5 USDC. Which means that the raw buy amount is equal to 3005 USDC. By observing the calldata, we recover the UCP vector, and apply the exchange rate implied by that vector, which gives that the user "should" have sold 3005 * 0.999 / 3005 = 0.999 WETH. Since the user actually sold 1 WETH, we then conclude that the difference, i.e., 1 - 0.999 = 0.001 WETH, was the network fee the solver charged for the trade.

### Network fees in the settlement contract

Similar to protocol fees, solvers can decide to collect part of the sell amount of an order in the settlement contract, as a network fee that would cover the gas cost associated with the execution of an order. These fees, specified in the sell token, are converted to the native token of the chain, using the prices provided in the auction instance where each order got executed, and are sent to solvers at the end of each accounting week. There is a dedicated table maintained by the core team that exposes the network fees (as well as the protocol fees) charged to each trade, and can be found [here](https://dune.com/queries/4058574).

## Slippage
### Slippage

Slippage accounting, that is taking place in all chains the protocol operates on, is performed on a per settlement/transaction basis, and the main query that executes it can be found here: https://dune.com/queries/4070065. Roughly speaking, for each transaction executed on-chain, we compute the raw token imbalances of the settlement contract (i.e., we look at the state of the contract before and after execution, and the difference is what we call token imbalances), we account for protocol, partner and network fees in the cases where solvers deposit them in the settlement contract, and after we subtract those, the remaining imbalances (if any) are converted to the native token of the chain by using some price feed.

The price feed used for the accounting is constructed in this query: https://dune.com/queries/4064601. In a few words, we use the `prices.usd` table of Dune and for a given imbalance on token X that a certain transaction caused, we take the average price of the token in a 1h-interval around the time of the trade, and use this price to evaluate the imbalance. In case the token is missing from the Dune table, we then resort to computing an average price of the token around the time of the trade by using other CoW Protocol trades that sell or buy this specific token, where the other side of the trade is a token with a price in the `prices.usd` table. If none of these succeed, then there is no price associated with the token in the price feed.

### Slippage accounting details
#### Slippage accounting details

We now discuss some more details. To properly do slippage accounting, we start by computing raw imbalances caused by a transaction. The raw imbalance vector of a transaction is defined as follows. Let `buffers(0)` denote the vector that describes all balances the settlement contract holds just before the execution of a transaction. Let `buffers(1)` denote the vector of all balances the settlement contract holds just after the execution of a transaction. The difference of the two vectors, i.e., `buffers(1) - buffers(0)`, is what we call raw imbalances. This is computed in this query on a per transaction basis: https://dune.com/queries/4021644.

Expand Down

0 comments on commit 02bf4f9

Please sign in to comment.