From 26a2c6b3e768c7a4094685a285c52381037f3318 Mon Sep 17 00:00:00 2001 From: Martin Beckmann Date: Wed, 10 Apr 2024 11:13:07 +0200 Subject: [PATCH] [EASY] Make gas offset configurable (#15) Same as https://github.com/gnosis/solvers/pull/7 but without the changes to the simulation logic (which lead to problems). This PR basically now just allows to configure the gas that should be added to any swap proposed by dex solvers to have an easy knob to tweak to adjust the cost coverage of the dex solvers. --- src/domain/dex/mod.rs | 3 ++- src/domain/solution.rs | 8 +++----- src/domain/solver/dex/mod.rs | 14 +++++++++++++- src/infra/config/dex/file.rs | 13 +++++++++++++ src/infra/config/dex/mod.rs | 1 + 5 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/domain/dex/mod.rs b/src/domain/dex/mod.rs index 40b607c..aae497d 100644 --- a/src/domain/dex/mod.rs +++ b/src/domain/dex/mod.rs @@ -108,6 +108,7 @@ impl Swap { gas_price: auction::GasPrice, sell_token: Option, simulator: &infra::dex::Simulator, + gas_offset: eth::Gas, ) -> Option { let gas = if order.class == order::Class::Limit { match simulator.gas(order.owner(), &self).await { @@ -141,7 +142,7 @@ impl Swap { interactions, gas, } - .into_solution(gas_price, sell_token) + .into_solution(gas_price, sell_token, gas_offset) } pub fn satisfies(&self, order: &domain::order::Order) -> bool { diff --git a/src/domain/solution.rs b/src/domain/solution.rs index 07fb86e..ca6c5e9 100644 --- a/src/domain/solution.rs +++ b/src/domain/solution.rs @@ -116,15 +116,13 @@ pub struct Single { } impl Single { - /// An approximation for the overhead of executing a trade in a settlement. - const SETTLEMENT_OVERHEAD: u64 = 106_391; - /// 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: Option, + gas_offset: eth::Gas, ) -> Option { let Self { order, @@ -147,7 +145,7 @@ impl Single { Fee::Surplus( sell_token?.ether_value(eth::Ether( swap.0 - .checked_add(Self::SETTLEMENT_OVERHEAD.into())? + .checked_add(gas_offset.0)? .checked_mul(gas_price.0 .0)?, ))?, ) @@ -198,7 +196,7 @@ impl Single { ]), trades: vec![Trade::Fulfillment(Fulfillment::new(order, executed, fee)?)], interactions, - gas: Some(eth::Gas(Self::SETTLEMENT_OVERHEAD.into()) + self.gas), + gas: Some(gas_offset + self.gas), }) } } diff --git a/src/domain/solver/dex/mod.rs b/src/domain/solver/dex/mod.rs index 90d4f18..62bfc1c 100644 --- a/src/domain/solver/dex/mod.rs +++ b/src/domain/solver/dex/mod.rs @@ -6,6 +6,7 @@ use { domain::{ auction, dex::{self, slippage}, + eth, order::{self, Order}, solution, solver::dex::fills::Fills, @@ -38,6 +39,10 @@ pub struct Dex { /// Handles 429 Too Many Requests error with a retry mechanism rate_limiter: rate_limit::RateLimiter, + + /// Amount of gas that gets added to each swap to tweak the cost coverage of + /// the solver. + gas_offset: eth::Gas, } /// The amount of time we aim the solver to finish before the final deadline is @@ -61,6 +66,7 @@ impl Dex { concurrent_requests: config.concurrent_requests, fills: Fills::new(config.smallest_partial_fill), rate_limiter, + gas_offset: config.gas_offset, } } @@ -177,7 +183,13 @@ impl Dex { let swap = self.try_solve(order, &dex_order, tokens, gas_price).await?; let sell = tokens.reference_price(&order.sell.token); let Some(solution) = swap - .into_solution(order.clone(), gas_price, sell, &self.simulator) + .into_solution( + order.clone(), + gas_price, + sell, + &self.simulator, + self.gas_offset, + ) .await else { tracing::debug!("no solution for swap"); diff --git a/src/infra/config/dex/file.rs b/src/infra/config/dex/file.rs index d97a32f..9ac18ee 100644 --- a/src/infra/config/dex/file.rs +++ b/src/infra/config/dex/file.rs @@ -58,6 +58,12 @@ struct Config { /// Settings specific to the wrapped dex API. dex: toml::Value, + + /// Amount of gas that gets added to each swap to adjust the cost coverage + /// of the solver. + #[serde(default = "default_gas_offset")] + #[serde_as(as = "serialize::U256")] + gas_offset: eth::U256, } fn default_relative_slippage() -> BigDecimal { @@ -84,6 +90,12 @@ fn default_max_back_off() -> Duration { Duration::from_secs(8) } +fn default_gas_offset() -> eth::U256 { + // Rough estimation of the gas overhead of settling a single + // trade via the settlement contract. + 106_391.into() +} + /// Loads the base solver configuration from a TOML file. /// /// # Panics @@ -137,6 +149,7 @@ pub async fn load(path: &Path) -> (super::Config, T) { config.max_back_off, ) .unwrap(), + gas_offset: eth::Gas(config.gas_offset), }; (config, dex) } diff --git a/src/infra/config/dex/mod.rs b/src/infra/config/dex/mod.rs index 056d337..94f799b 100644 --- a/src/infra/config/dex/mod.rs +++ b/src/infra/config/dex/mod.rs @@ -23,4 +23,5 @@ pub struct Config { pub concurrent_requests: NonZeroUsize, pub smallest_partial_fill: eth::Ether, pub rate_limiting_strategy: rate_limit::Strategy, + pub gas_offset: eth::Gas, }