From 7630b301c7bd3a1e9b07d3abf6c3ac27678a2f9b Mon Sep 17 00:00:00 2001 From: Daniel Karzel Date: Mon, 20 Sep 2021 20:35:33 +1000 Subject: [PATCH] Work in PR comments --- daemon/src/db.rs | 5 ++--- daemon/src/maker_cfd_actor.rs | 2 +- daemon/src/model/cfd.rs | 30 +++++++++++++++++++++++++++--- daemon/src/setup_contract_actor.rs | 4 ++-- daemon/src/taker_cfd_actor.rs | 2 +- daemon/src/to_sse_event.rs | 4 ++-- 6 files changed, 35 insertions(+), 12 deletions(-) diff --git a/daemon/src/db.rs b/daemon/src/db.rs index 4eea931..ab2b11c 100644 --- a/daemon/src/db.rs +++ b/daemon/src/db.rs @@ -1,8 +1,7 @@ use crate::model::cfd::{Cfd, CfdState, Order, OrderId, Origin}; use crate::model::{Leverage, Position}; -use anyhow::Context; +use anyhow::{Context, Result}; use rocket_db_pools::sqlx; - use sqlx::pool::PoolConnection; use sqlx::{Acquire, Sqlite, SqlitePool}; use std::convert::TryInto; @@ -244,7 +243,7 @@ async fn load_latest_cfd_state( pub async fn load_cfd_by_order_id( order_id: OrderId, conn: &mut PoolConnection, -) -> anyhow::Result { +) -> Result { let order_uuid = serde_json::to_string(&order_id)?; let row = sqlx::query!( diff --git a/daemon/src/maker_cfd_actor.rs b/daemon/src/maker_cfd_actor.rs index 1e37d66..b931335 100644 --- a/daemon/src/maker_cfd_actor.rs +++ b/daemon/src/maker_cfd_actor.rs @@ -155,7 +155,7 @@ pub fn new( let (sk, pk) = crate::keypair::new(&mut rand::thread_rng()); let cfd = load_cfd_by_order_id(order_id, &mut conn).await.unwrap(); - let margin = cfd.calc_margin().unwrap(); + let margin = cfd.margin().unwrap(); let maker_params = wallet.build_party_params(margin, pk).unwrap(); diff --git a/daemon/src/model/cfd.rs b/daemon/src/model/cfd.rs index fd5617c..d57d280 100644 --- a/daemon/src/model/cfd.rs +++ b/daemon/src/model/cfd.rs @@ -266,7 +266,7 @@ impl Cfd { } } - pub fn calc_margin(&self) -> Result { + pub fn margin(&self) -> Result { let margin = match self.position() { Position::Buy => { calculate_buy_margin(self.order.price, self.quantity_usd, self.order.leverage)? @@ -277,7 +277,7 @@ impl Cfd { Ok(margin) } - pub fn calc_counterparty_margin(&self) -> Result { + pub fn counterparty_margin(&self) -> Result { let margin = match self.position() { Position::Buy => calculate_sell_margin(self.order.price, self.quantity_usd)?, Position::Sell => { @@ -288,7 +288,7 @@ impl Cfd { Ok(margin) } - pub fn calc_profit(&self, current_price: Usd) -> Result<(Amount, Usd)> { + pub fn profit(&self, current_price: Usd) -> Result<(Amount, Usd)> { let profit = calculate_profit(self.order.price, current_price, dec!(0.005), Usd(dec!(0.1)))?; Ok(profit) @@ -305,6 +305,30 @@ impl Cfd { }, } } + + #[allow(dead_code)] + pub fn refund_timelock_in_blocks(&self) -> u32 { + self.order + .term + .mul_f32(Cfd::REFUND_THRESHOLD) + .as_blocks() + .ceil() as u32 + } + + /// A factor to be added to the CFD order term for calculating the refund timelock. + /// + /// The refund timelock is important in case the oracle disappears or never publishes a + /// signature. Ideally, both users collaboratively settle in the refund scenario. This + /// factor is important if the users do not settle collaboratively. + /// `1.5` times the term as defined in CFD order should be safe in the extreme case where a user + /// publishes the commit transaction right after the contract was initialized. In this case, the + /// oracle still has `1.0 * cfdorder.term` time to attest and no one can publish the refund + /// transaction. + /// The downside is that if the oracle disappears: the users would only notice at the end + /// of the cfd term. In this case the users has to wait for another `1.5` times of the + /// term to get his funds back. + #[allow(dead_code)] + const REFUND_THRESHOLD: f32 = 1.5; } fn calculate_profit( diff --git a/daemon/src/setup_contract_actor.rs b/daemon/src/setup_contract_actor.rs index 99fa0ca..f2aebe4 100644 --- a/daemon/src/setup_contract_actor.rs +++ b/daemon/src/setup_contract_actor.rs @@ -66,8 +66,8 @@ pub fn new( AllParams::new(own, own_punish, other, other_punish, own_role) }; - if params.other.lock_amount != cfd.calc_counterparty_margin().unwrap() { - panic!("Sorry, have to panic 😬 - the amounts that the counterparty sent were wrong, expected {} actual {}", cfd.calc_counterparty_margin().unwrap(), params.other.lock_amount) + if params.other.lock_amount != cfd.counterparty_margin().unwrap() { + panic!("Sorry, have to panic 😬 - the amounts that the counterparty sent were wrong, expected {} actual {}", cfd.counterparty_margin().unwrap(), params.other.lock_amount) } let own_cfd_txs = create_cfd_transactions( diff --git a/daemon/src/taker_cfd_actor.rs b/daemon/src/taker_cfd_actor.rs index 1f6113e..0e3cd9d 100644 --- a/daemon/src/taker_cfd_actor.rs +++ b/daemon/src/taker_cfd_actor.rs @@ -102,7 +102,7 @@ pub fn new( let (sk, pk) = crate::keypair::new(&mut rand::thread_rng()); let cfd = load_cfd_by_order_id(order_id, &mut conn).await.unwrap(); - let margin = cfd.calc_margin().unwrap(); + let margin = cfd.margin().unwrap(); let taker_params = wallet.build_party_params(margin, pk).unwrap(); diff --git a/daemon/src/to_sse_event.rs b/daemon/src/to_sse_event.rs index 1028876..61e3fe8 100644 --- a/daemon/src/to_sse_event.rs +++ b/daemon/src/to_sse_event.rs @@ -60,7 +60,7 @@ impl ToSseEvent for Vec { .map(|cfd| { // TODO: Get the actual current price here let current_price = Usd::ZERO; - let (profit_btc, profit_usd) = cfd.calc_profit(current_price).unwrap(); + let (profit_btc, profit_usd) = cfd.profit(current_price).unwrap(); Cfd { order_id: cfd.order.id, @@ -82,7 +82,7 @@ impl ToSseEvent for Vec { // TODO: Depending on the state the margin might be set (i.e. in Open we save it // in the DB internally) and does not have to be calculated - margin: cfd.calc_margin().unwrap(), + margin: cfd.margin().unwrap(), } }) .collect::>();