Brewing @ Boltz: Hold Reverse Swaps
TL;DR: This post attempts to distill the idea of hold reverse submarine swaps, what we are working on behind the scene, and what the…
TL;DR: This post attempts to distill the idea of hold reverse submarine swaps, what we are working on behind the scene, and what the future holds for us.
Cutting the Jargon
An altruist reader of our blog rightly pointed out that lightning to on-chain swaps on Boltz has one major flaw, which we were aware of and actively working to counter.
What prevents a user from locking up all of the boltz funds by opening a lot of reverse swaps…
It won’t cost the customer (they just add their btc address) but will cost boltz because they’re locking up on chain…medium.com
To summarize the issue in layman’s terms — Boltz was locking funds (the coins the user intended to buy) before the user paid the invoice (the coins the user intended to sell). It opened up Boltz to a spam vector, wherein, any motivated malicious third party could repeatedly start a swap and bail out before paying the invoice. This would result in Boltz locking up on-chain funds over and over again while losing a few satoshis on on-chain fee every single time. Moreover, Boltz also pays the opportunity cost of locked-up funds for the duration of the swap timeout.
When it rains, it pours
As if these vulnerabilities weren’t enough of the trouble already, the reverse swap flow also had an inherent design flaw: the sweeping, or the claiming of funds by the user client had to work, or the user could lose funds.
We encountered many instances where we had to manually refund back the coins to the user because their browser failed to claim the fund. It could be caused by an unstable internet connection, browser crash, or any of the million things gone wrong on the client-side. For a non-custodial crypto exchange like Boltz, safeguarding the user fund is the bread and butter, so solving this issue was extremely important. We brainstormed many methods to counter this, including now-defunct Protocol 11, but we wanted a solution that didn’t break the atomicity of the swap, so we kept looking.
Till it finally dawned on us
A different kind of lightning invoice — hold invoice, have the potential to solve our problem. Folks at lightning labs were quick to detail the new swap architecture enabled by hold invoices in a blogpost.
Hold invoice is simply a lightning invoice with an added quirk: instead of locking and settling the HTLC (hashed time-locked contracts) immediately when the payment arrives, the HTLC is only locked, not settled. This enables an interesting flow on the receiver’s end — they can choose whether to settle or cancel the HTLC. From the sender’s perspective, a hold invoice looks identical to a regular lightning invoice, which makes it compatible with all existing lightning wallets. There have been many interesting use cases of hold invoice now in production — that extended the lightning implementation to accommodate new flows, which in turn improved the user experience by orders of magnitude. For example, our friends at Breez used hold invoices to build Lightning Rod, which enables asynchronous lightning payments.
Let Bob send the preimage first
Cutting to the chase, our new reverse submarine swap architecture made use of hold invoices in such a manner that the user now creates the preimage and locks up the lightning funds before Boltz, which means there is now a non-negligible cost of locked funds when deciding to bail out from a swap. This significantly reduces the spam attack vector, since it’s simply not for free anymore to bail out from a swap. The following picture depicts our new swap flow and gives a high-level idea of the process.
Step 1: Bob creates a hash of the locally generated preimage and sends it with the “start swap” HTTP request to the Boltz server.
Step 2: Boltz makes use of the said hash to create a hold invoice. Boltz then sends the invoice to Bob.
Step 3: Bob receives the invoice and pays it with her lightning wallet. What really happens is, that the signed HTLC from Bob’s wallet is sent to Boltz, but the payment is held by Boltz and not executed at this point because it is still missing Bob’s preimage to do so.
Step 4: Boltz then locks up the on-chain coins using a swap script that requires Bob to reveal the preimage when claiming.
Step 5: Bob claims the locked on-chain funds that subsequently reveals the preimage.
Step 6: Boltz then uses that preimage to unlock the lightning payment.
This new reverse submarine swap dramatically reduces the spam attack vector and also eradicates the problem of the user losing funds when claiming fails client-side. It substantially improves the user experience of Boltz. If you are a developer, you can look at our documentation for the new swap flow lifecycle. You can also hack around with our new endpoint for creating reverse swaps. Shoutout to our friends at Breez for helping us to test and improve our new endpoint!
What’s brewing next
A lot is happening at Boltz, and we cannot wait to reveal what’s next. We have some exciting announcements to make, which will be huge for the community as a whole and us. Non-custodial and private trading of digital assets remains our core ethos, and we will continue to work towards making it a reality.
Till next time, Adios and happy swapping!