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

Filter limit orders during auction cutting #752

Merged
merged 8 commits into from
Nov 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/autopilot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ path = "src/main.rs"
anyhow = { workspace = true }
approx = "0.5"
async-trait = { workspace = true }
bigdecimal = { workspace = true }
chrono = { workspace = true }
clap = { workspace = true }
contracts = { path = "../contracts" }
Expand Down
3 changes: 3 additions & 0 deletions crates/autopilot/src/arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ pub struct Arguments {
/// in COW base units
#[clap(long, env)]
pub cip_14_reward_cap: Option<f64>,

#[clap(long, env, default_value = "0")]
pub limit_order_price_factor: f64,
}

impl std::fmt::Display for Arguments {
Expand Down
3 changes: 3 additions & 0 deletions crates/autopilot/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,9 @@ pub async fn main(args: arguments::Arguments) {
risk_adjusted_rewards,
args.ethflow_contract,
args.max_surplus_fee_age * 2,
args.limit_order_price_factor
.try_into()
.expect("limit order price factor can't be converted to BigDecimal"),
);
solvable_orders_cache
.update(block)
Expand Down
43 changes: 42 additions & 1 deletion crates/autopilot/src/solvable_orders.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
use crate::{database::Postgres, risk_adjusted_rewards};
use anyhow::{Context as _, Result};
use bigdecimal::BigDecimal;
use chrono::Utc;
use futures::StreamExt;
use model::{auction::Auction, order::Order, signature::Signature, time::now_in_epoch_seconds};
use model::{
auction::Auction,
order::{Order, OrderClass},
signature::Signature,
time::now_in_epoch_seconds,
};
use number_conversions::u256_to_big_decimal;
use primitive_types::{H160, H256, U256};
use prometheus::{IntCounter, IntGauge};
use shared::{
Expand Down Expand Up @@ -63,6 +70,7 @@ pub struct SolvableOrdersCache {
reward_calculator: Option<risk_adjusted_rewards::Calculator>,
ethflow_contract_address: H160,
surplus_fee_age: Duration,
limit_order_price_factor: BigDecimal,
}

type Balances = HashMap<Query, U256>;
Expand Down Expand Up @@ -95,6 +103,7 @@ impl SolvableOrdersCache {
reward_calculator: Option<risk_adjusted_rewards::Calculator>,
ethflow_contract_address: H160,
surplus_fee_age: Duration,
limit_order_price_factor: BigDecimal,
) -> Arc<Self> {
let self_ = Arc::new(Self {
min_order_validity_period,
Expand All @@ -117,6 +126,7 @@ impl SolvableOrdersCache {
reward_calculator,
ethflow_contract_address,
surplus_fee_age,
limit_order_price_factor,
});
tokio::task::spawn(update_task(
Arc::downgrade(&self_),
Expand Down Expand Up @@ -187,6 +197,9 @@ impl SolvableOrdersCache {
self.metrics,
)
.await;

let orders = self.filter_mispriced_limit_orders(orders, &prices);

let rewards = if let Some(calculator) = &self.reward_calculator {
let rewards = calculator
.calculate_many(&orders)
Expand Down Expand Up @@ -236,6 +249,34 @@ impl SolvableOrdersCache {
pub fn last_update_time(&self) -> Instant {
self.cache.lock().unwrap().orders.update_time
}

/// Filter out limit orders which are far enough outside the estimated native token price.
fn filter_mispriced_limit_orders(
&self,
mut orders: Vec<Order>,
prices: &BTreeMap<H160, U256>,
) -> Vec<Order> {
orders.retain(|order| {
if order.metadata.class != OrderClass::Limit {
return true;
}

// Convert the sell and buy price to the native token (ETH) and make sure that sell
// with the surplus fee is higher than buy with the configurable price factor.
let sell_native = (order.data.sell_amount + order.metadata.surplus_fee)
* prices.get(&order.data.sell_token).unwrap();
let buy_native = order.data.buy_amount * prices.get(&order.data.buy_token).unwrap();
let sell_native = u256_to_big_decimal(&sell_native);
let buy_native = u256_to_big_decimal(&buy_native);
if sell_native >= buy_native * self.limit_order_price_factor.clone() {
true
} else {
tracing::debug!(order_uid = %order.metadata.uid, "limit order is outside market price, skipping");
false
}
});
orders
}
}

/// Filters all orders whose owners are in the set of "banned" users.
Expand Down
1 change: 1 addition & 0 deletions crates/e2e/tests/e2e/services.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ impl OrderbookServices {
None,
H160::zero(),
Default::default(),
0.97.try_into().unwrap(),
);
let order_validator = Arc::new(
OrderValidator::new(
Expand Down