Skip to content

Commit

Permalink
Merge pull request #2584 from get10101/feat/funding-fee-extravaganza
Browse files Browse the repository at this point in the history
Funding fee feature
  • Loading branch information
luckysori authored Jun 4, 2024
2 parents dd8b524 + c8a55a8 commit c507a18
Show file tree
Hide file tree
Showing 100 changed files with 4,303 additions and 953 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,10 @@ jobs:
./target/debug/coordinator &> ./data/coordinator/regtest.log &
just wait-for-coordinator-to-be-ready
echo "Coordinator successfully started."
echo "Starting coordinator postgrest server"
just postgrest-coordinator
echo "Started coordinator postgrest server"
- name: Run maker
run: |
just run-maker-detached
Expand Down
56 changes: 56 additions & 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 coordinator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ parking_lot = { version = "0.12.1" }
payout_curve = { path = "../crates/payout_curve" }
prometheus = "0.13.3"
rand = "0.8.5"
reqwest = { version = "0.11" }
rust_decimal = { version = "1", features = ["serde-with-float"] }
rust_decimal_macros = "1"
semver = "1.0"
Expand Down
2 changes: 2 additions & 0 deletions coordinator/example-settings/prod-coordinator-settings.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ close_expired_position_scheduler = "0 0 12 * * *"
close_liquidated_position_scheduler = "0 0 12 * * *"
update_user_bonus_status_scheduler = "0 0 0 * * *"
collect_metrics_scheduler = "0 0 * * * *"
generate_funding_fee_events_scheduler = "* * * * *"
whitelist_enabled = false
whitelisted_makers = []
min_quantity = 1
maintenance_margin_rate = 0.1
order_matching_fee_rate = 0.003
index_price_source = "Bitmex"

[xxi]
off_chain_sync_interval = 5
Expand Down
2 changes: 2 additions & 0 deletions coordinator/example-settings/test-coordinator-settings.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ close_expired_position_scheduler = "0 0 12 * * *"
close_liquidated_position_scheduler = "0 0 12 * * *"
update_user_bonus_status_scheduler = "0 0 0 * * *"
collect_metrics_scheduler = "0 0 * * * *"
generate_funding_fee_events_scheduler = "1/5 * * * * *"
whitelist_enabled = false
# Default testnet maker
whitelisted_makers = ["035eccdd1f05c65b433cf38e3b2597e33715e0392cb14d183e812f1319eb7b6794"]
min_quantity = 1
maintenance_margin_rate = 0.1
order_matching_fee_rate = 0.003
index_price_source = "Test"

[xxi]
off_chain_sync_interval = 5
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE IF EXISTS rollover_params;
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CREATE TABLE rollover_params
(
id SERIAL PRIMARY KEY NOT NULL,
protocol_id UUID NOT NULL REFERENCES dlc_protocols (protocol_id),
trader_pubkey TEXT NOT NULL,
margin_coordinator_sat BIGINT NOT NULL,
margin_trader_sat BIGINT NOT NULL,
leverage_coordinator REAL NOT NULL,
leverage_trader REAL NOT NULL,
liquidation_price_coordinator REAL NOT NULL,
liquidation_price_trader REAL NOT NULL,
expiry_timestamp TIMESTAMP WITH TIME ZONE NOT NULL
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
drop table if exists funding_rates;
drop table if exists funding_fee_event;
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
CREATE TABLE funding_rates
(
id SERIAL PRIMARY KEY NOT NULL,
start_date TIMESTAMP WITH TIME ZONE NOT NULL,
end_date TIMESTAMP WITH TIME ZONE NOT NULL,
rate REAL NOT NULL,
timestamp TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE funding_fee_events
(
id SERIAL PRIMARY KEY NOT NULL,
amount_sats BIGINT NOT NULL,
trader_pubkey TEXT NOT NULL,
position_id INTEGER REFERENCES positions (id) NOT NULL,
due_date TIMESTAMP WITH TIME ZONE NOT NULL,
price REAL NOT NULL,
funding_rate REAL NOT NULL,
paid_date TIMESTAMP WITH TIME ZONE,
timestamp TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- To prevent generating duplicates for the same position.
UNIQUE (position_id, due_date)
);

CREATE TABLE protocol_funding_fee_events
(
id SERIAL PRIMARY KEY NOT NULL,
protocol_id UUID REFERENCES dlc_protocols (protocol_id) NOT NULL,
funding_fee_event_id INTEGER REFERENCES funding_fee_events (id) NOT NULL,
timestamp TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
);
16 changes: 13 additions & 3 deletions coordinator/src/bin/coordinator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use coordinator::cli::Opts;
use coordinator::db;
use coordinator::dlc_handler;
use coordinator::dlc_handler::DlcHandler;
use coordinator::funding_fee::generate_funding_fee_events_periodically;
use coordinator::logger;
use coordinator::message::spawn_delivering_messages_to_authenticated_users;
use coordinator::message::NewUserMessage;
Expand Down Expand Up @@ -41,6 +42,7 @@ use std::sync::Arc;
use std::time::Duration;
use tokio::sync::broadcast;
use tokio::task::spawn_blocking;
use tokio_cron_scheduler::JobScheduler;
use tracing::metadata::LevelFilter;
use xxi_node::node::event::NodeEventHandler;
use xxi_node::seed::Bip39Seed;
Expand Down Expand Up @@ -319,12 +321,10 @@ async fn main() -> Result<()> {
);

let sender = notification_service.get_sender();
let notification_scheduler = NotificationScheduler::new(sender, settings, network, node);
let scheduler = NotificationScheduler::new(sender, settings.clone(), network, node).await;
tokio::spawn({
let pool = pool.clone();
let scheduler = notification_scheduler;
async move {
let scheduler = scheduler.await;
scheduler
.add_rollover_window_reminder_job(pool.clone())
.await
Expand Down Expand Up @@ -371,6 +371,16 @@ async fn main() -> Result<()> {
tracing::error!("Failed to set expired hodl invoices to canceled. Error: {e:#}");
}

generate_funding_fee_events_periodically(
&JobScheduler::new().await?,
pool.clone(),
auth_users_notifier,
settings.generate_funding_fee_events_scheduler,
settings.index_price_source,
)
.await
.expect("to start task");

tracing::debug!("Listening on http://{}", http_address);

match axum::Server::bind(&http_address)
Expand Down
15 changes: 8 additions & 7 deletions coordinator/src/db/dlc_protocols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,10 @@ pub(crate) fn get_dlc_protocol(
DlcProtocolType::ForceClose => dlc_protocol::DlcProtocolType::ForceClose {
trader: PublicKey::from_str(&dlc_protocol.trader_pubkey).expect("valid public key"),
},
DlcProtocolType::Rollover => dlc_protocol::DlcProtocolType::Rollover {
trader: PublicKey::from_str(&dlc_protocol.trader_pubkey).expect("valid public key"),
},
DlcProtocolType::Rollover => {
let rollover_params = db::rollover_params::get(conn, protocol_id)?;
dlc_protocol::DlcProtocolType::Rollover { rollover_params }
}
DlcProtocolType::ResizePosition => {
let trade_params = db::trade_params::get(conn, protocol_id)?;
dlc_protocol::DlcProtocolType::ResizePosition { trade_params }
Expand Down Expand Up @@ -173,7 +174,7 @@ pub(crate) fn create(
previous_protocol_id: Option<ProtocolId>,
contract_id: Option<&ContractId>,
channel_id: &DlcChannelId,
protocol_type: dlc_protocol::DlcProtocolType,
protocol_type: impl Into<DlcProtocolType>,
trader: &PublicKey,
) -> QueryResult<()> {
let affected_rows = diesel::insert_into(dlc_protocols::table)
Expand All @@ -185,7 +186,7 @@ pub(crate) fn create(
dlc_protocols::protocol_state.eq(DlcProtocolState::Pending),
dlc_protocols::trader_pubkey.eq(trader.to_string()),
dlc_protocols::timestamp.eq(OffsetDateTime::now_utc()),
dlc_protocols::protocol_type.eq(DlcProtocolType::from(protocol_type)),
dlc_protocols::protocol_type.eq(protocol_type.into()),
))
.execute(conn)?;

Expand Down Expand Up @@ -216,8 +217,8 @@ impl From<DlcProtocolState> for dlc_protocol::DlcProtocolState {
}
}

impl From<dlc_protocol::DlcProtocolType> for DlcProtocolType {
fn from(value: dlc_protocol::DlcProtocolType) -> Self {
impl From<&dlc_protocol::DlcProtocolType> for DlcProtocolType {
fn from(value: &dlc_protocol::DlcProtocolType) -> Self {
match value {
dlc_protocol::DlcProtocolType::OpenChannel { .. } => DlcProtocolType::OpenChannel,
dlc_protocol::DlcProtocolType::OpenPosition { .. } => DlcProtocolType::OpenPosition,
Expand Down
Loading

0 comments on commit c507a18

Please sign in to comment.