Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add protocol fee #333

Merged
merged 35 commits into from
Feb 5, 2024
Merged

Add protocol fee #333

merged 35 commits into from
Feb 5, 2024

Conversation

fhenneke
Copy link
Collaborator

@fhenneke fhenneke commented Jan 15, 2024

This PR adds changes to solver rewards due to the introduction of protocol fees.

The implementation in this PR is intended to make solvers oblivious to protocol fees. This means that the quality of a solution as defined in CIP-20 in our accounting is needs to be equal to what the solver computed without knowledge of protocol fees.

CIP-20 specifies that quality = surplus + fee in ETH. With protocol fees, the surplus is reduced by some amount, the protocol fee. This means that the quality is now something like quality = surplus + protocol_fee + fee in ETH. Here, surplus refers to the surplus users receive, protocol_fee is the fee the protocol charges, and fee is a fee set by solvers or the protocol for covering network costs. All token amounts are converted to ETH using native prices of the auction.

One problem is, that fees set by solvers for covering network costs are not directly observable for the autopilot. For those orders, the autopilot only computes a total fee in the sell token by comparing what a user did send to the protocol to what they would have sent to receive the same amount of buy tokens if they had traded at uniform clearing prices. Let us call this term total_fee and it is in the sell token. Let us further use the term total_surplus for the surplus a solver perceives who is oblivious to protocol fees. The inconsistency corrected in this PR comes from the fact that the solver perceives a quality of total_surplus * surplus_native_price + fee * sell_native_price. This is different from surplus * surplus_native_price + total_fee * sell_native_price. Instead, the reward script needs to compute surplus * surplus_native_price + protocol_fee * protocol_fee_native_price + fee * sell_native_price. The fee for network costs needs to be reconstructed from observations. The driver currently computes the total fee in the sell token as total_fee = fee + protocol_fee * protocol_fee_clearing_price / sell_clearing_price. Thus the network fee is total_fee - protocol_fee * protocol_fee_clearing_price / sell_clearing_price. Since the ratio of clearing prices is equal to the ratio of traded amount if there were no fee at all, protocol_fee_clearing_price / sell_clearing_price = (amount_sent - total_fee) / amount_received, the correction to the total fee to compute the actual fee for network costs becomes network_fee_correction = (amount_sent - total_fee) / amount_received * protocol_fee.

The implementation in this PR depends on the current implementation of protocol fees in the driver. With drivers ran by solvers, this is not possible anymore. By then we should be ready to rank by surplus + protocol_fee. This value is easy to compute for the driver and no correction of network fees is required anymore.

TODO

  • Wait for staging database changes.
  • Add protocol fee result to batch rewards.
  • Add consistent test case.
  • Sync data to dune.

this adds the tables orders, order_quotes, trades to the test database.
a new test using this data was added. it covers
- market orders (normal reward)
- partially fillable orders (no reward)
- in market limit orders (no reward)
- new table fee_policy
- changes old order data to give nicer numbers (quote test does not
  change)
populate_test_db.sql Outdated Show resolved Hide resolved
populate_test_db.sql Outdated Show resolved Hide resolved
- change `priceimprovement` to `surplus`
- remove price improvement from query
- typo in order_execution table
- create new test database for protocol fees
- add new test for protocol fees
- use less data
- use separate file
- add start and end parameters
- avoid division by zero bug
- compute network fee correction instead of network fee
- change batch rewards query
- add tables to batch reward database
- add a few comments
- reorder terms
- fix typos
- new protocol_fee_eth field in payouts
- subtract protocol fee from eth reimbursement
- update tests: add one new test, update old tests (also for quote rewards)
@fhenneke
Copy link
Collaborator Author

The protocol fee is now used in the creation of transfers. It is deducted from the ETH payment. A simple test case was added to check the calculation in test_payouts.py line 450.

src/fetch/payouts.py Outdated Show resolved Hide resolved
@fhenneke fhenneke changed the title [Draft] Add protocol fee query Add protocol fee Jan 22, 2024
@fhenneke fhenneke marked this pull request as ready for review January 22, 2024 18:19
@fhenneke fhenneke requested a review from harisang January 22, 2024 18:20
-adds one additional transfer in eth to a safe set up for the collection
of protocol fees
- protocol fees are computed by multiplying amounts in the protocol fee
token with native prices from the auction
- use sell amount as baseline for volume cap for sell orders
- correctly compute cap for buy orders
- remove unnecessary case for 100% volume cap
@harisang
Copy link
Contributor

Looks good overall! Will test it locally as well once we have the data on Dune and do some sanity checks before approving.

also added comment on how test values are computed
also adapted the test
@fhenneke
Copy link
Collaborator Author

fhenneke commented Jan 29, 2024

I compared the transfers to solvers created using the command

python -m src.fetch.transfer_file --start 2024-01-22 --min-transfer-amount-wei "1000000000000000" --min-transfer-amount-cow-atoms "20000000000000000000"

to the output of our solver payment query on dune. The numbers agree.

I also compared the amount of ETH transfered to the protocol fee safe to this query (where the block range is obtained from that query). There is a small discrepancy (12.121 ETH vs 12.130 ETH) which could be due to staging data on dune from Monday last week not being fully correct. Will check again tomorrow with data starting on Tuesday when we officially enabled protocol fees.

Generally the code in the PR seems to work. We should use it for the payments tomorrow.

Transfer(
token=None,
recipient=PROTOCOL_FEE_SAFE,
amount_wei=payout_df.protocol_fee_eth.sum(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe i had cast the right-hand side to int. Will need to double-check if this is still needed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added the cast. (It is a bit worrying that we do not have a test to check for that.)

otherwise the creation of transfers fails.
(for some reason this is not covered in a test)
@fhenneke fhenneke merged commit 2bda2b1 into main Feb 5, 2024
6 checks passed
@fhenneke fhenneke deleted the protocol_fee branch February 5, 2024 09:51
@github-actions github-actions bot locked and limited conversation to collaborators Feb 5, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants