Skip to content

cowprotocol/solver-rewards

Repository files navigation

CoW Protocol: Solver Accounting

Code style: black

Installation & Usage (Quickstart)

make install
cp .env.sample .env    <----- Copy your Dune and orderbook credentials here!

Fill out your Dune credentials in the .env file.

Generate the solver-payouts with for the accounting period 7 days (with today as end date).

python -m src.fetch.transfer_file

To generate order data for the current month to upload to Dune run the following command.

python -m src.data_sync.sync_data --sync-table order_data

For more advanced usage of these scripts see below.

Summary of Accounting Procedure

In what follows Accounting Periods are defined in intervals of 1 week and accounting is performed on the time interval

StartTime <= block_time < EndTime

Testing & Contributing

Testing

To run the unit tests

make test-unit

To run the query tests, you must first have a local instance of the database running

docker build -t test_db -f Dockerfile.db .
docker run -d --name testDB -p 5432:5432 test_db
python -m pytest tests/queries/

or just

make test-db

If you have the local database running you can run the entire suite of tests with

python -m pytest tests/

This project conforms to Black code style. You can auto format the project with the following command:

black ./

However, many IDEs can be configured to auto format on save.

Advanced Payout Generation

looking at the script help menu can help provide a list of options!

$  python -m src.fetch.transfer_file --help 

usage: Fetch Complete Reimbursement [-h] [--start START] [--post-tx] [--dry-run]

options:
  -h, --help            show this help message and exit
  --start START         Accounting Period Start. Defaults to previous Tuesday
  --post-tx     Flag indicating whether multisend should be posted to safe (requires valid env var `PROPOSER_PK`)
  --dry-run     Flag indicating whether script should not post alerts or transactions.
  --ignore-slippage
                        Ignore slippage computations

The solver reimbursements are executed each Tuesday with the accounting period of the last 7 days. The default accounting period is 7 days with end date equal to the current date. If the payout script can not be run on Tuesday, one will have to specify the start date to specify the correct accounting period.

To generate the CSV Transfer file manually run the "quickstart" variant of the script. A more fine-tuned variant of the script execution could look like this:

python -m src.fetch.transfer_file --start 2023-03-14 --post-tx True

which would run for the accounting period March 14 - 21, 2023, using the Post CIP-20 reward scheme and post the payout transaction directly to the safe (i.e. without generating a CSV file).

Validating the Payout Transaction

Please visit this Notion document. In particular see Validation by Example section.

Payout Verification

Manual verification against Safe transaction exports

After the transactions are proposed on-chain, you can cross-check them against the Dune query output using src/verification/compare_output_files.py.

Inputs required:

File Description
Dune Rewards Export Dune solver-rewards export (per-solver row with name, solver_address, reward_target, quote_reward, native_token_transfer, cow_transfer, …)
Mainnet COW Safe CSV Transaction export from the COW Safe (mainnet). Download from the Safe UI → Transactions → Export.
Network native Safe CSV Transaction export from the native Safe (e.g. Arbitrum). Same export procedure.

Running the script:

python3 src/verification/compare_output_files.py <dune-solver-rewards>.csv \
    --cow-safe-csv  "<mainnet-txs-file>.csv" \
    --native-safe-csv "<network-txs-file>.csv" \
    --fees-csv      "<fees-dune>.csv" \
    --protocol-fee-safe <dao-safe-address> \
    --network <network-name>

The script uses set-based matching: every Safe transaction row must either match a Dune entry (by recipient address and amount, within a 0.01 % tolerance) or be flagged as an unmatched transfer warning. Every Dune entry with a reward above the threshold must have a corresponding Safe row, or an error is raised.

Exit status is 0 when no errors are found (warnings are still printed).

What the script checks:

  • Every solver with quote_reward > 1 COW has a matching COW transfer to its reward_target.
  • Every solver with native_token_transfer > 0.001 ETH has a matching native transfer.
  • Every solver with cow_transfer > 1 COW has a matching COW transfer to its reward_target.
  • The net protocol fee transfer (protocol_fee_in_native_token from the fees CSV) to the DAO safe matches.
  • Remaining transfers to the DAO safe are labelled as partner fee tax (warning).
  • Any other Safe transaction row not matched to a solver or fee is flagged as unmatched (partner fee warning).
  • Amounts match within 0.01 % relative tolerance.
  • Native transfers sent to the solver address (rather than the reward target) produce a warning.

--fees-csv and --protocol-fee-safe are optional but both must be provided together to enable protocol fee verification.

Additional Notes

Also, it might happen that the slippage of a solver is bigger than the ETH payout. In this case, please do not proceed with the payout, until the root cause is known. Feel free to reach out the project maintainers to do the investigation.

Note that we must wait some time after the period has ended for some data to finalize ( e.g. prices.usd, ethereum.transactions our event data, etc...). Hence, the scripts should not be executed immediately after the accounting period has ended.

After generating the transfer file and double-checking the results, please create the multi-send transaction with the link provided in the console.

Inform the team of this proposed transaction in the #dev-multisig Slack channel and follow through to ensure execution. It is preferred that the transaction be executed by the proposer account(eth: 0xd8Ca5FE380b68171155C7069B8df166db28befdd).

Docker

This project has a strict requirement of python >= 3.10 which may not be common version for most operating systems. In order to make the reimbursement effort seamless, we have prepared the following docker container.

# Prepare environment variables
cp .env.sample .env  # Fill in your Dune Credentials
# Run (always ensuring latest version is being used).
docker run --pull=always -it --rm \
  --env-file .env \
  -v $PWD:/app/out \
  ghcr.io/cowprotocol/solver-rewards:main \
  src.fetch.transfer_file \
  --start 'YYYY-MM-DD'

and (usually after about 30 seconds) find the transfer file written to your current working directory.

Managing Dependencies

Python libraries can be added to the requirements.in file. After this pip-compile or python -m pip-compile will update the requirements.txt for you (you may have to install the libry manually first). Warning: this might take a long time for large changes or when you run pip-compile for the first time. Running the command with the -v flag can help keep track of what's happening.

About

Data Aggregation for Solver Reimbursement & Rewards Distributor

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages