Notes on paying for liquidity for privacy tech: regarding JoinMarket, Wasabi Wallet and P2EP
Lots of privacy tech in bitcoin like coinjoin, coinswap, tumblebit and Lightning Network require many entities to come together to agree to make certain kinds of transactions. This creates a requirement that the right resources (coins) have to be in the right place, at the right time, in the right quantity. This isn't a software or tech problem, its an economic problem of liquidity.
Today Wasabi Wallet, JoinMarket and P2EP (pay-to-end-point) represent three ways of solving this liquidity problem. This post is about comparing them and wondering where we can go from here.
Wasabi Wallet works by having users provide liquidity for each other. The time-liquidity is increased by slowing down the process; coinjoin's happen at set intervals and users must wait for rounds (unless enough entities arrive before the time is up), and coinjoins only happen at fixed bitcoin quantities (unless all the entities want to coinjoin more). The entities meet up at a server which uses chaumian blind signatures so that nobody knows the link between inputs and outputs.
JoinMarket works by liquidity being traded in exchange for money. Liquidity-takers pay for the privilege of choosing the exact time and quantity of the coinjoin, while liquidity-makers earn that money but cannot choose the time and quantity and must run high-uptime computers which are always ready to coinjoin. This is similar to how market makers work in any market such as a BTC/USD exchange; market makers are always ready to take the other side of a trade, but in return they earn a bid-ask spread.
P2EP works by combining the coinjoin liquidity event with a goods-and-services liquidity event. When a customer and merchant make an economic transaction between them, they also make a coinjoin transaction. The customer is the liquidity-taker who chooses the time and quantity of the coinjoin, and the merchant goes along with it as the liquidity-maker.
Lightning Network also has liquidity requirements. It solves them with a combination of ideas. For opening channels there is a liquidity requirement, it seems the plan is to use something analogous to P2EP where channels are opened at the same time as paying somebody on-chain (Although this video is from 2016 so maybe the thinking has moved on since then). For routing transactions through already-existing channels liquidity is traded for money in an analogous way to JoinMarket.
theres many reasons we dont use cattle as money, but a major reason is that if a customer is paying for something worth less than one cow, they cant chop up the cow and retain the same value. imagine if you had to chop off a cows head and hand it over to a merchant when you bought groceries.
similarly if you're a merchant who has been selling groceries all day, at the end of the working day you might have a bunch of cow's heads that customers paid you with. it's not possible to combine up all the cow's heads together to get one cow of the same value.
similarly, if you're an entrepreneur and you increase the efficency of your business by 5% on year, you'll find it very difficult to measure and assess a payment in cattle which was 5% different from last year.
so divisibility is a very important property of money, as important as fungibility.
bitcoin is scalable in a very important way: that a single UTXO can hold any amount of bitcoin value in it with O(1) scaling, meaning anything from 1 satoshi to 21 million bitcoins can be held with the same amount of block space this is one reason why layering works for scalability this property is lost with fixed denominations
real life example here: https://www.reddit.com/r/WasabiWallet/comments/ca9ht5/i_have_50_mixed_bitcoin_in_wasabi_500_addresses/ someone mixes 50btc with wasabi and has 500 addresses with 0.1 btc each, and it seems he cant do anything with the money now without degrading his privacy
gratis-liquidity systems have privacy-demanders transacting with each other. since they all want privacy presumably none of them will share their privacy-relevant-information with an adversary and so all of them will have their secrets safe.
by contrast paid-for-liquidity systems have privacy-demanders transacting with middlemen who dont care about their privacy but only about their fees (they might care about privacy but its not assumed in the design of the system). so an adversary
the wasabi wallet server could do it, by having a list of UTXOs to watch and if one of them gets queued and then suddenly populating the coinjoin only with the server's own coins. It would still be a coinjoin but it would gain no privacy.
Paying for anonymity not liquidity - the next step in joinmarket and privacy
In a JoinMarket-like system, entities pay for liquidity but what they actually want to buy isn't liquidity but anonymity which is slightly different.
why does someone coinjoining 0.01 btc get roughly a thousand times less privacy than someone coinjoining 10 btc? it means that someone who owns 10btc has the money to create a thousand sybil liquidity makers which could attempt to be every maker in the 0.01btc user's coinjoin. it doesnt make sense that privacy increases with the size of the coinjoin. also this somewhat damages the divisibility of bitcoin as small coins are qualitatively less private than large coins.
what is needed is a way to have the cost of running a liquidity maker bot be the same for all coinjoin amounts
fidelity bonds could be a solution. liquidity makers would have the opportunity to lock up bitcoins in a time-locked address, takers would take into account the amount of bitcoins locked up (and to a lesser extent the locktime) when making a decision about who to coinjoin with. takers would be programmed to first consider the size of the fidelity bond before all other considerations, as it is an expensive-to-fake indicator.
i imagine that makers will put 90% or 95% of their working capital into the fidelity bond with the rest available for coinjoining. so a taker who wants to coinjoin 0.01btc can know that their makers actually own 10btc or whatever amount it might be.
note that the private keys for the bitcoins in the fidelity bond can be stored offline. takers will need to be provided with digital signatures which prove that the maker really owns those bitcoins, but they only need to be created very rarely. if the fidelity bond has a time lock of 6 months then the maker only needs to sign a signature offline once every 6 months
this would solidify the taker-maker split in joinmarket, takers could never become temporary makers if it ever happened that they were willing to wait in order to save fees. for a long time i was reluctant to do this, because its beneficial for privacy if makers are also sometimes motivated only by privacy, that is why i made the patientsendpayment script where people could be makers and earn fees while making a payment. in hindsight of the 3 years that joinmarket has been running, this has not happened. i dont think patientsendpayment was ever used more than a handful of times, it seems coinjoin fees are far too low to motivate a transactor who could just as easily be a taker and choose their own coinjoin amount and time. in joinmarket-clientserver the patientsendpayment script has been missing for months and nobody seems to have complained or even noticed.
coinjoin fees would go up obviously, as there would be less supply of bitcoins but also coinjoin demand could go up because joinmarket could be seen as providing better privacy coinjoin fees today are very low so even if they went up 100x because of this feature they would still be low especially when considering how much block space coinjoins use and how expensive that can be in miner fees
relations with the 693 problem
i was originally motivated to solve the 693 problem because of the sybil problem, solving 693 made it more expensive to be a sybil attacker. this fidelity bond solution is even better in that respect
recovery from seed of fidelity bond bitcoins
its nice to be able to recover all coins just from a seed phrase backup, fortunately thats not too difficult even with the free timelock parameters an easy way to do this is to constrain fidelity bonds in joinmarket to have the timelock parameter be at midnight on the first of every month. when recovering a seed phrase generate all the bitcoin addresses corresponding to each public key within the gap limit, and each time lock between when joinmarket was released and the year 2050. there are only 12 months in a year and so this time period requires only around 500 addresses to be scanned for for each public key. that number of addresses is easily realistic with bitcoin core, electrum servers or something like neutrino.
relation to coinswap
i originally came up with this when trying to design a joinmarket-like system that used coinswap.
liquidity is good, good stuff should be paid for because there's no free lunch
the privacy created by paid-for liquidity could be massively improved by fidelity bonds
must write about the divisibility of money, fixed-denomination protocols damage that "we all know fungibility is a necessary property of money, but so is divisibility. we dont use cattle as money because you cant chop a cow in half and retain its value when you want to buy something worth half-a-cow. fixed-denomination privacy tech like tumblebit and wasabi wallet wont work well because they destroy the divisibility of money. trading divisibility for fungibility is a losing proposition, prove me wrong" "cows are actually fungibile for most purposes (if you have a beef farm with more than around 50 cows you dont know all their names, they are essentially fungible to you especially when they're converted into meat) but fungibility isnt enough to make cows money" "tumblebit suffered from this as well (link the 800-output tx, where all 800 have to be the same size)" "for economic activity prices need to be able to change by small amounts" e.g if an entrepanure runs a business and manages to make it 5% more efficent, they could change prices by 5% to pass savings on, that wouldnt be possible with fine divisibility https://twitter.com/chris_belcher_/status/1095655423212957698