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

Include fees + File for checking final ETH slippage for single tx hash #31

Merged
merged 21 commits into from
Aug 23, 2024

Conversation

shubhagarwal03
Copy link
Contributor

@shubhagarwal03 shubhagarwal03 commented Aug 15, 2024

As the title suggests, this PR incorporates protocol and network fees which are also being written to a table in solver_slippage DB called "fees".

Still need to discuss how we want to calculate the net slippage, e.g. should it be written to its own table? If not, pull data from all other tables at the end of a period and calculate the slippage using price feeds?

Since this is unknown and we don't have a currently running daemon for latest data, I've temporarily added a file test_single_hash.py to output all data that is used throughout the steps of finding net slippage, i.e. raw token imbalances, protocol fees, network fees, raw slippage, and final slippage in ETH using price feed.
I've found it useful for debugging/cross-checking.

@fhenneke fhenneke changed the base branch from main to restructures August 15, 2024 13:35
@harisang harisang changed the base branch from restructures to main August 19, 2024 21:16
@shubhagarwal03 shubhagarwal03 marked this pull request as ready for review August 20, 2024 23:24
return current_quote_sell_amount - self.sell_amount
raise ValueError(f"Order kind {self.kind} is invalid.")

def compute_surplus_fee(self) -> int:
Copy link
Contributor

Choose a reason for hiding this comment

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

Although surplus_fee is the term the backend uses, i feel it would be clearer if we just name it total_fee.

cc @fhenneke

Copy link
Contributor

Choose a reason for hiding this comment

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

Using total_fee is fine as well. But I would object that the total fee is a clear concept in our context. But adding more documentation might resolve that.
surplus_fee is nice because it is clear that it is a quantity expressed in surplus. What the backend did with that by converting back to sell tokens is a bit unintuitive. The meaning in this code will probably clash with what backend does.
Maybe surplus_reduction or something similar might work.

Copy link
Contributor

Choose a reason for hiding this comment

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

let's add at least some comment to clarify what this is computing

sell_token_clearing_price: int
buy_token_clearing_price: int

def volume(self) -> int:
Copy link
Contributor

Choose a reason for hiding this comment

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

@fhenneke is the naming of the function accurate? In case there is a protocol fee, this is not really the volume but rather the remaining amount after the protocol fee has been subtracted

Copy link
Contributor

Choose a reason for hiding this comment

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

That is the definition of volume I use. The same as for surplus. It is not the hypothetical "what would volume have been if there were no fee?" but rather "what is the volume?".

We could have another raw_volume function but that would not be used for anything. Or is there a use case?

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess one issue i have is that if we talk about, e.g., an order having 1% volume fee, this volume we are talking about here is not the one we should check in order to compute that fee.

Copy link
Contributor

Choose a reason for hiding this comment

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

This is exactly the same issue as for surplus, is it not?

Because of that we always have to use modified factors in computing protocol fees in the autopilot, e.g. here.

Copy link
Contributor

Choose a reason for hiding this comment

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

I would argue that surplus is mainly from a user point of view so defining surplus for a sell order as executed_buy_amount - limit_price makes sense to me. I.e., since we explicitly say that score is surplus plus protocol fees, referring to surplus as the portion the user receives seems fine.

But i haven't thought too much about it, tbh.

Copy link
Contributor

Choose a reason for hiding this comment

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

To me it is perfectly consistent to use this very function for computing volume. This is the volume (in the surplus token) of the order. Dune uses that number for volume as well in some cases (if there is no price for the other token).

We need exactly this function to compute protocol fees. In principle it could be renamed. But I am in favor of keeping the name.

Using a different definition is not possible unless a volume factor is added as parameter

def volume_before_fees(self, volume_factor):
    if self.kind == "sell":
        return self.buy_amount / (1 - volume_factor)
    if self.kind == "buy":
        return self.sell_amount / (1 + volume_factor)

So the volume would then depend on which fees are applied. It would not be a property of the trade itself. Might be a helpful function.

Comment on lines 601 to 606
# if __name__ == "__main__":
# tx_hash = HexBytes(
# "0xbd8cf4a21ad811cc3b9e49cff5e95563c3c2651b0ea41e0f8a7987818205c984"
# )
# protocol_fees, network_fees = batch_fee_imbalances(tx_hash)
# print(protocol_fees)
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be removed

@harisang
Copy link
Contributor

harisang commented Aug 22, 2024

If you are confident this PR works, i would suggest merging it so that we start getting some fee calculations, as it is non-trivial to review and there are a lot of dependencies here and there. We can work towards cleaning it up at some other point, with the following in mind:

  • as is, it cannot compute fees for old enough txs, so we cannot backfill
  • currently it depends on fetching onchain data, using the api and also fetching the autopilot instance. Ideally i would like to only rely on one source, and that probably should be the api. This will allow this to extend to other chains more easily.

@harisang
Copy link
Contributor

Attempted to fix the mypy errors but it seems not a one-line change so reverted and will wait for @shubhagarwal03 to take care of these

@fhenneke
Copy link
Contributor

If you are confident this PR works

Regarding the fee computation, I am pretty confident it works. It is using the code from the circuit breaker which has proven to be correct.

The main change from the circuit breaker is the addition of network fees. Here, the implementation looks a lot cleaner than what we used before. If that part looks reasonable to you, the computations should be fine.

The data fetching could potentially be an issue, depending on the node setup used. The circuit breaker has problems with that at the moment. But token imbalances are processed with some delay, right? Then there would be no problem.

@harisang
Copy link
Contributor

Ok sorry for the mess. Now my changes are properly reverted

src/fees/compute_fees.py Outdated Show resolved Hide resolved
src/test_single_hash.py Outdated Show resolved Hide resolved
@harisang
Copy link
Contributor

I am merging although not confident if this works, but we can address issues in a follow-up PR

@harisang harisang merged commit 15cf06d into main Aug 23, 2024
3 checks passed
This was referenced Aug 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants