-
Notifications
You must be signed in to change notification settings - Fork 84
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. |
} | ||
|
||
/// Total fee (protocol fee + network fee). Equal to a surplus difference |
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.
Silly question: what is the difference between network and gas fees in this context?
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 essentially a synonym. We’ve never officially settled on what to call this fee, and here’s why:
The total fee, which we now call the executed fee
, is calculated as the difference between UCP and custom prices for an order. If we assume protocol fees are not taken (set to 0), this difference is supposed to represent gas costs.
Now, let’s consider how solvers report these prices. Normally, if a solver expects to spend $10 on gas for an order, they report UCP and custom prices so that the difference reflects this cost. These values are then stored in the settlement contract.
But solvers aren’t obligated to stick to this. They could report $20 instead, meaning their custom prices are worse, making their solution less competitive with a lower score. This isn’t rational since they gain nothing from it, but it’s possible. A more realistic case is solvers reporting $5 (less than expected gas costs). This makes their custom prices better, making their solution more competitive. Solvers are incentivized to do this because even with underreported costs, they might still profit from rewards, say $50 of COW. In some cases, solvers might even report $0, which still leaves them positive and increases their competitiveness.
There’s another twist. Solvers are no longer required to report UCP prices once colocated. They can always set UCP equal to custom prices, and we’d have no way to estimate gas costs. Alternatively, solvers could bake gas costs into slightly reduced custom prices, leaving us unable to deduce what was actually spent on gas.
So, what do we call this fee? Gas fee, network fee, solver fee? It used to represent gas costs when we controlled the driver, but now it could mean anything. It might represent gas costs, half the gas costs, zero, or even negative values. In the latter case, solvers offer better custom prices than UCP 🤯 , effectively estimating zero or negative gas fees while still giving users a bit more than they gained on-chain, just to secure a juicy reward. This suggests our rewards are too high and should be lowered to create an equilibrium, incentivizing solvers to estimate custom prices properly—where "properly" means UCP minus gas costs.
Ultimately, this fee feels like a relic from the pre-colocation world. Deprecating it might be the right move, but it’s non-trivial to approximate gas costs per order in a batched settlement. For now, it persists because the frontend needs it to show users estimated costs.
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.
Actually, thanks for bringing this up. After some thinking, I don't think my previous implementation was good enough. It definitely changes the expectation on the final executed_fee
value in all of these special cases, so I reverted back to previous implementation - executed_fee
and protocol_fee
being completely decoupled.
Bottom line, assuming that executed_fee
represents protocol_fee + gas fee and always >= than protocol_fee
is just not guaranteed.
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.
Oh, thanks a lot. That is much clearer now 🙌
/// 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.
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.
Fix 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.