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

[ON HOLD] Don't take protocol fee for in-market limit orders #2188

Closed
wants to merge 31 commits into from

Conversation

narcis96
Copy link
Contributor

@narcis96 narcis96 commented Dec 19, 2023

ON HOLD - will be split into several PRs:

Description

We don't want to take protocol fees for limit orders with in-market price.

Changes

We read the quote from the db and compare the order price with the quote price.

Fixes

#2092

@narcis96 narcis96 requested a review from a team as a code owner December 19, 2023 15:19
@narcis96 narcis96 force-pushed the skip_in_money_protocol_fee branch from 72f4210 to 31aef39 Compare December 19, 2023 15:26
@narcis96 narcis96 force-pushed the skip_in_money_protocol_fee branch from 31aef39 to 05181dd Compare December 19, 2023 15:31
crates/autopilot/src/run_loop.rs Outdated Show resolved Hide resolved
crates/autopilot/src/database/quotes.rs Outdated Show resolved Hide resolved
crates/autopilot/src/database/quotes.rs Outdated Show resolved Hide resolved
crates/autopilot/src/database/quotes.rs Outdated Show resolved Hide resolved
crates/autopilot/src/run_loop.rs Outdated Show resolved Hide resolved
@@ -201,6 +201,7 @@ impl RunLoop {
self.score_cap,
self.solve_deadline,
self.fee_policy.clone(),
HashMap::new(),
Copy link
Contributor

Choose a reason for hiding this comment

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

Would be cool if we could get the correct fee policies as part of the shadow competition as well but that is probably not straight forward since we don't have a DB connection in this case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

correct

Copy link
Contributor

Choose a reason for hiding this comment

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

@MartinquaXD do you maybe know why we don't have the access to db? for security reasons so we don't end up changing something?
I am worried that onboarding new solvers and checking the protocol fee mechanism will be imposible without db connection. OTOH, we do have staging if necesarry.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think when the shadow autopilot was written there was no need to store anything in the DB.
And over all I like that we don't need any DB connection for it to run.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

so do you think is it worth to modify the code of the shadow to be able to read the order and compute the fee policies or maybe is not worth the investment ?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think for testing fee policies we might have to add the original quote to the order (or some other indicator that fees should be applied) in /auction. However, if we decide to go that route we should do it in a separate PR.
With that taken care of the only reason the shadow autopilot would need a DB is to store the data we need before calling /settle which I think is outside of the scope of what the shadow environment was initially envisioned to do. Originally it was only supposed to be a test bed to onboard new solvers without risk.

Copy link
Contributor

@fleupold fleupold left a comment

Choose a reason for hiding this comment

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

We are adding a lot of logic and dependencies to the autopilot runloop due to fees (we are using the run_loops db access to fetch quotes which we pass down into the solve request, we instantiate the run_loop with the fee policies that need to be applied, we have a specific function to compute the fee policies all inside the run_loop).

I wonder how good this will scale. What are the trade-offs of having some fee component which knows about its dependencies (ie a database to look up quotes, the fee policy arguments) and can apply the required fee policy logic to an order?

How do we build this in a way that scales for the other types of fees we want to take eventually? How do we prevent the run-loop from becoming our next "SettlementEncoder" or "SolutionSubmissionStrategy" (ie pieces of code no-one wants to touch anymore because they are so brittle )?

#2157 has some attempt and more context on this discussion I believe.

@fleupold
Copy link
Contributor

The other alternative I see could be to reuse is_order_outside_market_price where it is defined today and keep the market order order class label Market for "inside market price" limit orders. I'm not sure about the implications, maybe @sunce86 has some thoughts.

@sunce86
Copy link
Contributor

sunce86 commented Dec 20, 2023

We are adding a lot of logic and dependencies to the autopilot runloop due to fees (we are using the run_loops db access to fetch quotes which we pass down into the solve request, we instantiate the run_loop with the fee policies that need to be applied, we have a specific function to compute the fee policies all inside the run_loop).

#2157 has some attempt and more context on this discussion I believe.

Yes, we should first merge #2157.

The other alternative I see could be to reuse is_order_outside_market_price where it is defined today and keep the market > order order class label Market for "inside market price" limit orders. I'm not sure about the implications, maybe @sunce86 > has some thoughts.

With regards to network fees, it is too early to do this because we would have Market order with fee_amount = 0. For now, I think it's fine to have is_order_outside_market_price logic in the fee::Policies link and replace it later with order class label.

@fleupold
Copy link
Contributor

because we would have Market order with fee_amount = 0

What's the issue with this? I remember the frontend team asking us to provide the labels. Are we depending on the assumption class::Market <=> fee_amount=0 elsewhere in the codebase?

@sunce86
Copy link
Contributor

sunce86 commented Dec 20, 2023

Wouldn't we end up charging 0 fee in that case?

Copy link
Contributor

@sunce86 sunce86 left a comment

Choose a reason for hiding this comment

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

Logic lgtm. Let's just reorganize the code according to code review comments so it's more aligned with the ddd approach. Also, it needs to rebase after #2157 is merged.

crates/autopilot/src/run_loop.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@fleupold fleupold left a comment

Choose a reason for hiding this comment

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

Concern about the failability of the fee application and that it's part of the critical path of sending the auction rather than building the auction.

crates/autopilot/src/database/quotes.rs Outdated Show resolved Hide resolved
crates/autopilot/src/database/onchain_order_events.rs Outdated Show resolved Hide resolved
crates/autopilot/src/protocol/fee.rs Outdated Show resolved Hide resolved
crates/autopilot/src/run_loop.rs Outdated Show resolved Hide resolved
crates/autopilot/src/run_loop.rs Outdated Show resolved Hide resolved
crates/autopilot/src/protocol/fee.rs Outdated Show resolved Hide resolved
crates/autopilot/src/protocol/fee.rs Outdated Show resolved Hide resolved
crates/autopilot/src/run_loop.rs Outdated Show resolved Hide resolved
@@ -350,6 +350,11 @@ impl OrderData {
self.valid_to,
)
}

/// Checks if the order is a market order.
pub fn within_market(&self, quote_sell_amount: &U256, quote_buy_amount: &U256) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: you can extend OrderData inside the order_quoting.rs module to allow using the quote type as an argument here which makes this nicer to read.

pub trait OrderPricing {
    fn within_market(&self, quote: &Quote) -> bool;
}
impl OrderPricing for OrderData {
    /// Checks if the order is a market order.
    fn within_market(&self, quote: &Quote) -> bool {
        self.sell_amount.full_mul(quote.buy_amount) >= quote.sell_amount.full_mul(self.buy_amount)
    }
}

@sunce86 sunce86 added the E:4.2 Protocol Fee Implementation See https://github.com/cowprotocol/pm/issues/29 for details label Dec 29, 2023
crates/autopilot/src/domain/fee/policy.rs Outdated Show resolved Hide resolved
crates/autopilot/src/run_loop.rs Outdated Show resolved Hide resolved
crates/autopilot/src/run_loop.rs Outdated Show resolved Hide resolved
crates/autopilot/src/domain/fee/policy.rs Outdated Show resolved Hide resolved
@sunce86 sunce86 mentioned this pull request Jan 3, 2024
2 tasks
Copy link
Contributor

@fleupold fleupold left a comment

Choose a reason for hiding this comment

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

I think this is a great step in the right direction! Could you please create a separate PR for the refactoring that changes SolvableOrdersCache.current_auction to return the domain model (without any logic changes)?

And then add the fee policy and application logic to the domain model in a separate PR?

Moving driver_model into the new structure should also be a separate PR imo.

crates/autopilot/src/solvable_orders.rs Show resolved Hide resolved
crates/autopilot/src/boundary/order.rs Show resolved Hide resolved
crates/autopilot/src/domain/auction/order.rs Show resolved Hide resolved
@@ -0,0 +1,4 @@
pub mod quote;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are all these new files? Can't they be moved from existing dtos? Can we maybe leave that to a different PR (to keep the size of this one manageable)?

crate::domain::{self},
};

pub mod postgres;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the module structure should be infra::persistence::postgres::dto::{auction, order, fee, quote}

@sunce86 sunce86 changed the title Don't take protocol fee for in-market limit orders [ON HOLD] Don't take protocol fee for in-market limit orders Jan 5, 2024
sunce86 added a commit that referenced this pull request Jan 6, 2024
# Description
Subset of changes from #2188

Orderbook's `get_auction()` now returns a new Auction type (let's call
it `dto::Auction`). `dto::Auction` is a struct that contains the orders
in a format that is used between `autopilot` and `drivers`.

Note that it is allowed for `dto::Auction` to contain fields which type
belongs to `model`. This is to make sure no bugs were introduced due to
serialization/deserialization and to reuse the code. If we want to
decouple these dependencies we can do it in a separate PR for easier
review.

Other than that, I introduced a `domain::Auction` that is built from
`dto::Auction` and used within autopilot's `RunLoop`. The idea is to
gradually eliminate all type dependencies from `RunLoop` so that it
works only with `domain` types, which would make it trivial to move it
to domain at the end.

## How to test
Existing tests.

#TODO
Update e2e tests.
sunce86 added a commit that referenced this pull request Jan 9, 2024
# Description
A subset of changes from
#2188 (part 2)

# Changes
<!-- List of detailed changes (how the change is accomplished) -->

- [ ] Move fee policies to `domain`
- [ ] No fee policies for in-market limit orders

## How to test
Existing tests.
ahhda pushed a commit that referenced this pull request Jan 10, 2024
# Description
A subset of changes from
#2188 (part 2)

# Changes
<!-- List of detailed changes (how the change is accomplished) -->

- [ ] Move fee policies to `domain`
- [ ] No fee policies for in-market limit orders

## How to test
Existing tests.
sunce86 added a commit that referenced this pull request Jan 15, 2024
# Description
Third part of the #2188

Moves driver_api to a separate `solvers` module in `infra`.

Next up, moving the driver dtos into `infra`.
@sunce86
Copy link
Contributor

sunce86 commented Jan 15, 2024

Closing as the last 4th part of this PR is tracked here: #2286

@sunce86 sunce86 closed this Jan 15, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Jan 15, 2024
@sunce86 sunce86 deleted the skip_in_money_protocol_fee branch January 20, 2024 22:00
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
E:4.2 Protocol Fee Implementation See https://github.com/cowprotocol/pm/issues/29 for details
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants