Skip to content

Commit

Permalink
Fedimint sweep estimation fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
TonyGiorgio committed Feb 2, 2024
1 parent 05037a6 commit e0feda1
Showing 1 changed file with 36 additions and 24 deletions.
60 changes: 36 additions & 24 deletions mutiny-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1308,27 +1308,37 @@ impl<S: MutinyStorage> MutinyWallet<S> {
let fedimint_client = federation_lock
.get(federation_id)
.ok_or(MutinyError::NotFound)?;
let fees = fedimint_client.gateway_fee().await?;

// if the user provided amount, this is easy
if let Some(amt) = amount {
return Ok(Some(self.node_manager.get_lsp_fee(amt).await?));
}
let (lsp_fee, federation_fee) = {
if let Some(amt) = amount {
// if the user provided amount, this is easy
(
self.node_manager.get_lsp_fee(amt).await?,
(calc_routing_fee_msat(amt as f64 * 1_000.0, &fees) / 1_000.0).floor() as u64,
)
} else {
// If no amount, figure out the amount to send over
let current_balance = fedimint_client.get_balance().await?;
log_debug!(
self.logger,
"current fedimint client balance: {}",
current_balance
);

// If no amount, figure out the amount to send over
let current_balance = fedimint_client.get_balance().await?;
log_debug!(
self.logger,
"current fedimint client balance: {}",
current_balance
);
let amt = max_spendable_amount(current_balance, &fees)
.map_or(Err(MutinyError::InsufficientBalance), Ok)?;
log_debug!(self.logger, "max spendable: {}", amt);

let fees = fedimint_client.gateway_fee().await?;
let amt = max_spendable_amount(current_balance, &fees)
.map_or(Err(MutinyError::InsufficientBalance), Ok)?;
log_debug!(self.logger, "max spendable: {}", amt);
// try to get an invoice for this exact amount
(
self.node_manager.get_lsp_fee(amt).await?,
current_balance - amt,
)
}
};

// try to get an invoice for this exact amount
Ok(Some(self.node_manager.get_lsp_fee(amt).await?))
Ok(Some(lsp_fee + federation_fee))
}

async fn create_lightning_invoice(
Expand Down Expand Up @@ -2303,14 +2313,13 @@ fn max_spendable_amount(current_balance_sat: u64, routing_fees: &GatewayFees) ->
let current_balance_msat = current_balance_sat as f64 * 1_000.0;

// proportional fee on the current balance
let prop_fee_msat =
(current_balance_msat * routing_fees.proportional_millionths as f64) / 1_000_000.0;
let base_and_prop_fee_msat = calc_routing_fee_msat(current_balance_msat, routing_fees);

// The max balance considering the maximum possible proportional fee.
// This gives us a baseline to start checking the fees from. In the case that the fee is 1%
// The real maximum balance will be somewhere between our current balance and 99% of our
// balance.
let initial_max = current_balance_msat - (routing_fees.base_msat as f64 + prop_fee_msat);
let initial_max = current_balance_msat - base_and_prop_fee_msat;

// if the fee would make the amount go negative, then there is not a possible amount to spend
if initial_max <= 0.0 {
Expand All @@ -2329,11 +2338,8 @@ fn max_spendable_amount(current_balance_sat: u64, routing_fees: &GatewayFees) ->
// we increment by one and check the fees for it
let new_check = new_max + 1.0;

// this is the new proportional fee to check with
let prop_fee_sat = (new_check * routing_fees.proportional_millionths as f64) / 1_000_000.0;

// check the new spendable balance amount plus base fees plus new proportional fee
let new_amt = new_check + routing_fees.base_msat as f64 + prop_fee_sat;
let new_amt = new_check + calc_routing_fee_msat(new_check, routing_fees);
if current_balance_msat - new_amt <= 0.0 {
// since we are incrementing from a minimum spendable amount,
// if we overshot our total balance then the last max is the highest
Expand All @@ -2347,6 +2353,12 @@ fn max_spendable_amount(current_balance_sat: u64, routing_fees: &GatewayFees) ->
Some((new_max / 1_000.0).floor() as u64)
}

fn calc_routing_fee_msat(amt_msat: f64, routing_fees: &GatewayFees) -> f64 {
let prop_fee_msat = (amt_msat * routing_fees.proportional_millionths as f64) / 1_000_000.0;
let base_and_prop_fee_msat = routing_fees.base_msat as f64 + prop_fee_msat;
base_and_prop_fee_msat
}

#[cfg(test)]
fn max_routing_fee_amount() {
let initial_budget = 1;
Expand Down

0 comments on commit e0feda1

Please sign in to comment.