The thing we ultimately want is a way to have some fungible token on Ethereum that implements ERC-777 (or, because we can’t have nice things, ERC-20) that can be redeemed by its holder for BTC. Let’s call this token BTC Fungible Token (BTC-FT). The simplest way to create BTC-FT is to have a user (Alice) put some amount of ETH into escrow along with a promise that if someone demands some amount of BTC, Alice will send the BTC to them or lose their escrow.
As an example, imagine that 1 BTC == 100 ETH, Alice would put 125 ETH into escrow and in exchange she would get 1 BTC-FT on the Ethereum network. Alice then trades her 1 BTC-FT token for some Unisocks which keeps her warm at night. Bob, acquires 1 BTC-FT (via any means) sometime later and redeems the 1 BTC-FT with Alice, giving her his Bitcoin address. Alice now has a choice to make. Either she sends Bob 1 BTC to the address he specified, or if she does nothing for 24 hours Bob will get the 125 ETH in escrow. Since 125 ETH is worth more than 1 BTC, Bob actually would prefer it if Alice didn’t follow through! However, if she does, then Bob gets 1 real BTC as he desired.
A note on Alice’s responsiveness
Alice must be constantly online/vigilant so she can quickly respond to BTC demands. We want the time between demand and delivery to be low, which means the timeout needs to be low. This means that regular users cannot take on the role of BTC-FT creator, it requires advanced users who are running automated services that fulfill BTC demands automatically. This is fine because what we really care about is that we don’t have to trust Alice. Our goal here isn’t to make it so anyone can become a BTC-FT liquidity provider.
All of the above is possible on Ethereum and it is all relatively easy (the hardest part is BTC transfer proofs, but that is a previously solved problem). The problem lies in the fact that the BTC:ETH exchange rate is not fixed, and can be quite volatile. Imagine if the value of 1 BTC increased to 200 ETH, Alice only has 125 ETH in escrow which means if Bob shows up and demands 1 BTC, it is in Alice’s best interest to just let him have her 125 ETH collateral instead of giving him 1 BTC (which is now worth 200 ETH)!
If we had a price feed on Ethereum that told us the value of 1 BTC in ETH, then we could add margin calls into the system. A margin call happens when the amount of collateral (ETH) that Alice has locked up gets too low and the system tries to force Alice to close out her position by acquiring 1 BTC-FT and trading it in for her own escrow, or adding more ETH into escrow so that she is no longer at risk. This incentive comes in the form of threatening Alice with the loss of all of her escrowed funds. For example, if the value of 1 BTC reached 120 ETH, the system may auction off Alice’s 125 ETH for however much BTC-FT it can get for it (expected to be a little over 1 BTC-FT in this case).
Since Alice would rather have 125 ETH than 1 BTC (valued at 120 ETH), she is incentivized to solve the problem herself before the value of 1 BTC reaches 120 ETH.
The Centralized Price Feed
There are several projects that make it this far, and all of the above is trustless and censorship resistant EXCEPT the price feed. Most projects that try to solve this problem just say, “oh, we’ll solve the price feed later, for now we will just provide the price feed manually as a way of bootstrapping the system”. The problem is that the price feed is the hard part of this problem! All of the above is relatively easy, I was able to describe the whole thing in 5 paragraphs above and it could be implemented by a competent team in a number of months.
The problem with a centralized price feed is that he who controls the price feed controls the escrow. Imagine the market value of 1 BTC is 100 ETH, and Alice has 125 ETH in escrow backing a promise to transfer 1 BTC to anyone who gives her 1 BTC-FT (just like our example above). Now imagine that the person providing the price feed to the system (Carol) suddenly updates the price feed claiming that 1 BTC is worth 1,000,000 ETH! Alice will immediately get margin called with extreme prejudice because she is way underwater! This means Alice, who moments ago had 125 ETH in escrow for a promise of 1 BTC-FT will now lose all of her escrow. Since 100 ETH is worth 1 BTC in reality, and she had a promise to deliver 1 BTC in the future, her total loss here is 25 ETH. If Alice had more in escrow backing her 1 BTC then her losses would be even higher.
When we ignore the price feed problem, we have a trustless and censorship resistant system. By adding in a centralized price feed we no longer have a trustless system: Alice needs to trust that Carol will not screw her. Maybe Carol is a very nice person but what if she gets hacked, or perhaps someone coerces her with a wrench? We not only need to trust that Carol isn’t malicious, we also need to trust that she has impenetrable operational security and manages to remain anonymous in the face of motivated attackers.
A Potential Solution
How do we get a price feed for BTC:ETH so that we can margin call Alice when her collateral gets too low due to price volatility? The answer is, unfortunately, complicated. One thing that you may note is that we don’t actually need a full price feed, we only need a lower bound on the value of 1 BTC in ETH. That is, we need to know that 125 ETH (the amount Alice has in collateral) is at worth at least 1 BTC. If this is true, then we don’t need to margin call Alice and we don’t otherwise care what the value of 1 BTC in ETH is.
One potential solution is to constantly be auctioning ETH in collateral for BTC-FT. Since 1 BTC-FT is redeemable at any time for 1 BTC, we can assume that an auction of ETH will end up going for a little over the value of 1 BTC, with the amount over depending on how much competition there is from bidders. This auction would give us our lower bound; after it is over we would be able to say that “105 ETH (the size of the auction) is worth at least 1 BTC-FT (the proceeds of the auction), and 1 BTC-FT is worth about 1 BTC, therefore if Alice has 125 ETH in escrow she has more than 1 BTC worth in escrow.
There are a couple problems with this approach:
- Whose collateral do we auction off? The simplest solution here is to just auction off the collateral of the lowest collateralized person. The problem here is that no one wants their collateral to be auctioned off because your debt will be cleared for almost certainly more than it is worth (meaning, more of your collateral will be taken than 1 BTC worth). This leads to a problem where participants are constantly fighting to not be the lowest collateralized individual. This may sound good, but it can become a problem if no one wants to create BTC-FT because the collateral requirements are too high due to a race to the not-bottom.
- Price feed updates are relatively slow. Reverse auctions like this take time, and the price can change a lot over the span of the auction. You don’t want it to be too fast because then you end up with a non-competitive auction, but you don’t want it too slow because then big price swings can occur without the price feed being able to respond. The bigger the potential for price swings between price feed updates, the higher the margin call threshold you need in order to weather them.
Overall, this solution isn’t terrible, and while it may not work flawlessly with economically rational actors, it may work well enough when real humans are involved. The price feed swings may be small enough to allow us to have a long auction period (e.g., 6 hours) and humans may be willing to let themselves be auctioned off rather than covering their debt (we see this behavior in Maker currently which has a steep penalty on top of the auction).
Another option is to allow people to (on a separate market from the one above) create offers to buy BTC at a specific collateralization. As an example, Bob would create an order on an open market where he says, “I’ll lock 100 ETH as payment to the first person who puts down 10 ETH as collateral and promises to pay me 1 BTC within 6 hours.” If Alice has some BTC that she is interested in selling for ETH, she can accept Bob’s offer by locking up 10 ETH, then transferring 1 BTC to him, and then proving the transfer on Ethereum which would result in her getting her 10 ETH back and Bob’s 100 ETH. If Alice fails to transfer the 1 BTC, then after 6 hours Bob get’s Alice’s 10 ETH.
This doesn’t give us the BTC-FT that we desire, but it does give us a price feed of sorts. If we look at all of the open offers on this market, we can get a rough idea of how much 1 BTC is worth. In particular, 1 BTC is worth approximately a little more than the highest priced offer that is currently unclaimed. If Bob and David both have offers to buy 1 BTC for 90 ETH and 100 ETH, and no one has any offers to buy 1 BTC for more than that, then we can assume that 1 BTC is worth more than 100 ETH. For our BTC-FT token, we only need to know the lower bound of the BTC price, which this gives us.
Unsurprisingly, there are some problems with this approach:
- If you have an interest in buying/selling BTC, why would you use this instead of the BTC-FT that is built on top of it? We essentially are creating two separate markets for BTC:ETH that are competing with each other. If this system is not liquid enough, then we don’t get good price feed data.
- What happens if no one creates any offers? If there is zero liquidity, the system may not result in good price feed data. We may end up with the only offers available being super low-ball offers that no one wants to take which will result in our price feed being way off (too low), thus not allowing us to properly margin call.
- How do we decide what an appropriate escrow amount for the BTC seller is (essentially the option price as time-value-of-money on the escrow)? In the above example we have a 10% escrow requirement for the BTC seller, but should that be 5% or 15%? What happens when BTC:ETH volatility increases, should we adjust the escrow amount accordingly? We could let each BTC buyer choose their desired escrow percentage, but then we run into the problem of pulling price feed data since someone with a 1000% escrow percentage will not be taken even if the offer is good, thus giving us a bad lower bound (too high).
A fungible BTC token on Ethereum is hard because of the price feed. Any solution that hand waves over the price feed as a “thing we’ll solve later” is hand waving over the hardest part of the problem! There may be solutions to the decentralized price feed that are good enough for the problem at hand but they all come with some caveats that may or may not be deal breakers.
If anyone wants to build either of the systems described above, please do so! I have considered building this stuff myself but keep ending up on other projects and would rather see something happen in this space than me clutching my ideas to my chest.