-
Notifications
You must be signed in to change notification settings - Fork 86
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
[BLOCKED] Save executed fee in surplus token #3184
base: main
Are you sure you want to change the base?
Conversation
Is this script ready? It would be worth posting it in the description under a spoiler. Also, I am not sure I understand how the old entries will be identified; the script will probably explain it. |
Not yet ready, currently implementing it. |
/// Fee per trade in a solution. These fees are taken for the execution of the | ||
/// trade. | ||
#[derive(Debug, Clone)] | ||
pub struct FeeBreakdown { | ||
/// Fee reported by solvers, representing difference between UCP and custom | ||
/// prices. | ||
pub executed: eth::TokenAmount, | ||
/// Breakdown of protocol fees. | ||
pub protocol: Vec<ExecutedProtocolFee>, | ||
/// Surplus token in which all the fees were taken. | ||
pub token: eth::TokenAddress, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be helpful to include details from your comment somewhere here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but I would still first look into the script before approving this PR.
Current version of migration code can be observed here (under function convert_executed_fee): cowprotocol/data-migration@76dc7bd#diff-1d06da761111802c793c6e5ca704bfa0d6336d0becf87fddff02d81548a838abR129 The code is not clean since we want to primarily focus on logic and the code is practically used one time. |
Could you make a PR there so it will be possible to ask questions about the migration? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will manually execute a migration immediately after this PR is merged.
Is it important that this happens after the PR is merged? I assume this needs to be synchronized with the frontend to not show nonsensical values?
Asking because this comment implies to me that there should be 2 batches of DB updates (one set for staging and one set for prod).
/// Fee reported by solvers, representing difference between UCP and custom | ||
/// prices. | ||
pub executed: eth::TokenAmount, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just by reading the struct and comments it's not really clear to me what this field is.
It sounds like this is just the sum of all protocol fees but I think since we need to account for the gas in the breakdown this is all protocol fees + gas fees.
In that case I think it would be nicer to have a field like gas_costs
and a public member function total_fees()
. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is how I implemented it initially, but I had to revert those changes. I commented here on the reasons why.
/// Breakdown of protocol fees. | ||
pub protocol: Vec<ExecutedProtocolFee>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The order of items also indicates the order in which the fee policies got applied, right?
Seems important enough to point out in a comment.
}, | ||
bigdecimal::Zero, | ||
}; | ||
|
||
mod math; | ||
|
||
pub use math::FeeBreakdown; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Seems like the original location of FeeBreakdown
makes more sense (i.e. in trade/mod.rs
).
fn fee_in_buy_token(order: &Order, quote: &OrderQuote) -> U256 { | ||
order.metadata.executed_fee * quote.buy_amount / quote.sell_amount | ||
fn fee_in_buy_token(order: &Order) -> U256 { | ||
order.metadata.executed_fee |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this now only correct when order
is a buy order given that fees should now always be computed in the surplus token?
In that case I would add an assert for that.
@@ -182,7 +160,7 @@ impl Trade { | |||
policy: *policy, | |||
fee, | |||
}); | |||
total += fee.amount; | |||
total += fee; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Safer would be to use checked_add()
.
fn surplus_fee( | ||
&self, | ||
surplus: eth::TokenAmount, | ||
factor: f64, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe use FeeFactor
here instead of f64
so we can ensure on type-level that factor
cannot have value of 1 (so there will be no division by 0).
Same for volume_fee()
.
Self::Jit(trade) => trade.sell.token, | ||
Self::Fulfillment(trade) => match trade.side { | ||
order::Side::Buy => trade.sell.token, | ||
order::Side::Sell => trade.buy.token, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding new function to implementation of Fulfillment
type like get_token_by_side()
(or similar), will remove the code duplication (here and Self::Jit()
case below).
Blocked by frontend team. I need a confirmation that frontend team switched to using
executed_fee
field introduced in #2966Description
This PR implements item (3) from #2963
Previously, executed fees were saved and displayed in the sell token. With this change, executed fees will now be saved and expressed in the surplus token.
This change applies to all orders settled after this PR is merged.
Follow-Up Tasks
Migrate Historical Fees to Surplus Token
I will manually execute a migration immediately after this PR is merged.
Current version can be observed here (under function
convert_executed_fee
): cowprotocol/data-migration@76dc7bd#diff-1d06da761111802c793c6e5ca704bfa0d6336d0becf87fddff02d81548a838abR129Fix Remaining Issue
After the migration, we need to update the following code reference:
https://github.com/cowprotocol/services/blob/main/crates/database/src/orders.rs#L575
Changes
executed_fee
in surplus token instead of in sell tokenHow to test
Expanded one unit test.
Existing e2e tests.