Closed ok300 closed 5 days ago
This should be correct, as the additionally sent BTC amount needs to be refunded back to the sender using prepare_refund
/ refund
Don't we also need the matching Boltz status for a swap to be actually refundable?
For the swap states
swap.expired
where bitcoin were sent andtransaction.lockupFailed
, the user needs to submit a refund transaction to reclaim the locked chain bitcoin. https://docs.boltz.exchange/v/api/lifecycle#chain-swaps
The Boltz status is transaction.claimed
.
@ok300 why do we care about the swapper status here? If we know use added more funds to that address then it seems right to me to mark it as refundable. Where do you see an issue here?
True, we don't need it. I thought we need the swapper status to agree with our status (refundable), but the refund doesn't need interaction as we can build the refund tx ourselves.
Then the key question is: do we support address re-use?
If yes:
refund_tx_id
, we should instead store a vector of refund txs (or only a single "latest" refund tx id?)new_refund
method, as it now only takes the first utxo when building the refund tx (there could be more than one)I think the important items here are:
I am not sure if we need atm to change the refund_tx_id field to be a vector as we can define it as the last_refund_tx_id (unless it has a bad affect on our logic)
I ran some tests and have two questions:
1) If we have a Receive Chain Swap that is
timeout_block_height
then non-cooperative refund
will only work after timeout_block_height
. This means until then, these funds cannot be used or refunded, even though we know the swap can only be refunded.
Q: Is this desired behavior?
2) I noticed we only monitor chain swaps for this amount of blocks
/// Number of blocks to monitor a swap after its timeout block height
pub const CHAIN_SWAP_MONITORING_PERIOD_BITCOIN_BLOCKS: u32 = 4320;
This means if address re-use happens after this time (30 days), we will not pick it up.
Q: should I remove this and instead let it monitor chain swaps forever?
: Is this desired behavior?
It is the only option. non-cooperative refund can't work within the lock height range.
should I remove this and instead let it monitor chain swaps forever?
It is a tradeoff so we won't get into performance issues. Users can use the rescan_swaps themselves in that cases (or periodically).
: Is this desired behavior?
It is the only option. non-cooperative refund can't work within the lock height range.
Forgot to mention: this also means list_refundables
only shows it as refundable after the lock height timeout.
In normal cases (no address re-use), refundable swaps are shown in list_refundables
as soon as we know it can be refunded, because
So it is correct (and the only possible way) that list_refundables
only shows such swaps as refundable after the lock height timeout.
I will document this in the docs.
Short update:
Testing the situation above (address re-use + attempt refund after lock height timeout) I found that:
list_refundables
correctly shows the swap as refundable, but only shows the swap amount instead of the actual refundable amount (script_balance.confirmed
)
This can be fixed by having our list_refundables
do an onchain lookup for the current confirmed balance in the lockup script.
prepare_refund
and refund
will only consider the first utxo, so it doesn't refund the full amount. This is part of the Boltz client logic that builds the refund tx:
For this, I'll prepare a fix in the Boltz client crate to consider all available utxos for the non-cooperative refund.
Scenario:
transaction.claimed
(the final status from the initial completed swap)Refundable
Example instance: testnet swap
7u5RFB8HQNdp
tb1pnvkd06a3q7e45pdtkyz4x3kdhnkarxespnz8uwsf7386kt2x2kpsqxaku7
( open in mempool explorer )On SDK startup: