From 4e06d4dce58933345e3b2ffb8541acabb9af2abb Mon Sep 17 00:00:00 2001 From: Dusan Stanivukovic Date: Fri, 26 Apr 2024 12:07:09 +0200 Subject: [PATCH] [EASY] Move out fee calculation from "into_solution" (#2662) # Description Baseline solver. Moves out fee calculation from the `into_solution` function. This is done as a preparation for a follow up PR, where I will not calculate the sell token price, but instead build `native_price_request` to buy weth in an exact amount needed to cover the gas costs (instead of using 1ETH as a default buy value). The output sell amount of `native_price_request` will directly give us the amount of sell token needed to cover the gas costs - fee. Related to https://github.com/cowprotocol/services/issues/2624, where the `native_price_request` uses 1ETH as buy amount and fails. I don't see any good reason to use 1ETH here as buy amount, as it is not needed. It is perfectly fine to use, for example, 0.01ETH amount that actually covers the gas cost and it's more accurate. --- Cargo.lock | 1 + crates/solvers/Cargo.toml | 1 + crates/solvers/src/boundary/legacy.rs | 2 +- crates/solvers/src/domain/eth/mod.rs | 7 +++++-- crates/solvers/src/domain/solution.rs | 12 ++++-------- crates/solvers/src/domain/solver/baseline.rs | 5 ++++- 6 files changed, 16 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0f300ef995..92c3947b84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4263,6 +4263,7 @@ dependencies = [ "chrono", "clap", "contracts", + "derive_more", "ethcontract", "ethereum-types", "ethrpc", diff --git a/crates/solvers/Cargo.toml b/crates/solvers/Cargo.toml index 13826b32e2..be3693d0d3 100644 --- a/crates/solvers/Cargo.toml +++ b/crates/solvers/Cargo.toml @@ -17,6 +17,7 @@ axum = { workspace = true } bigdecimal = { version = "0.3", features = ["serde"] } chrono = { workspace = true, features = ["serde"], default-features = false } clap = { workspace = true, features = ["derive", "env"] } +derive_more = { workspace = true } ethereum-types = { workspace = true } ethrpc = { path = "../ethrpc" } futures = { workspace = true } diff --git a/crates/solvers/src/boundary/legacy.rs b/crates/solvers/src/boundary/legacy.rs index f37ad1b066..9d1d00674e 100644 --- a/crates/solvers/src/boundary/legacy.rs +++ b/crates/solvers/src/boundary/legacy.rs @@ -437,7 +437,7 @@ fn to_domain_solution( match order.solver_determines_fee() { true => execution .exec_fee_amount - .map(solution::Fee::Surplus) + .map(|fee| solution::Fee::Surplus(fee.into())) .context("no surplus fee")?, false => solution::Fee::Protocol, }, diff --git a/crates/solvers/src/domain/eth/mod.rs b/crates/solvers/src/domain/eth/mod.rs index 6aecdc1095..fab72882d3 100644 --- a/crates/solvers/src/domain/eth/mod.rs +++ b/crates/solvers/src/domain/eth/mod.rs @@ -1,5 +1,4 @@ -use {crate::util::bytes::Bytes, web3::types::AccessList}; - +use {crate::util::bytes::Bytes, derive_more::From, web3::types::AccessList}; mod chain; pub use { @@ -45,6 +44,10 @@ impl From for Ether { } } +/// A token amount in wei, always representing the sell token of an order. +#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd, From)] +pub struct SellTokenAmount(pub U256); + /// Like [`Gas`] but can be negative to encode a gas discount. #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)] pub struct SignedGas(i64); diff --git a/crates/solvers/src/domain/solution.rs b/crates/solvers/src/domain/solution.rs index 0ffa5815a1..4e1a0644ca 100644 --- a/crates/solvers/src/domain/solution.rs +++ b/crates/solvers/src/domain/solution.rs @@ -126,11 +126,7 @@ pub struct Single { impl Single { /// Creates a full solution for a single order solution given gas and sell /// token prices. - pub fn into_solution( - self, - gas_price: auction::GasPrice, - sell_token: auction::Price, - ) -> Option { + pub fn into_solution(self, fee: eth::SellTokenAmount) -> Option { let Self { order, input, @@ -144,7 +140,7 @@ impl Single { } let fee = if order.solver_determines_fee() { - Fee::Surplus(sell_token.ether_value(eth::Ether(gas.0.checked_mul(gas_price.0 .0)?))?) + Fee::Surplus(fee) } else { Fee::Protocol }; @@ -299,7 +295,7 @@ pub enum Fee { Protocol, /// An additional surplus fee that is charged by the solver. - Surplus(U256), + Surplus(eth::SellTokenAmount), } impl Fee { @@ -307,7 +303,7 @@ impl Fee { pub fn surplus(&self) -> Option { match self { Fee::Protocol => None, - Fee::Surplus(fee) => Some(*fee), + Fee::Surplus(fee) => Some(fee.0), } } } diff --git a/crates/solvers/src/domain/solver/baseline.rs b/crates/solvers/src/domain/solver/baseline.rs index d97e92ead2..5265afa9a4 100644 --- a/crates/solvers/src/domain/solver/baseline.rs +++ b/crates/solvers/src/domain/solver/baseline.rs @@ -189,6 +189,9 @@ impl Inner { } let gas = route.gas() + self.solution_gas_offset; + let fee = sell_token_price + .ether_value(eth::Ether(gas.0.checked_mul(auction.gas_price.0 .0)?))? + .into(); Some( solution::Single { @@ -198,7 +201,7 @@ impl Inner { interactions, gas, } - .into_solution(auction.gas_price, sell_token_price)? + .into_solution(fee)? .with_id(solution::Id(i as u64)) .with_buffers_internalizations(&auction.tokens), )