Two-way pegs on Binance Chain: BEP3 and beyond
A discussion on two-way peg systems, featuring an in-depth analysis of BEP3, it’s trustlessness, environment, and further improvements
Binance Chain, like any other decentralized exchange, faces the eternal problem that has been plaguing DEXs for ages: Exchanges thrive on allowing users to trade a wide variety of tokens/coins, but how can a DEX list tokens from other chains while remaining decentralized?
So far the possible solutions that have been proposed are the following:
- Custodian Model: Using wrapped tokens maintained by a custodian
- Atomic swaps
Custodian Model
A custodian (in this case, Binance) creates a new native token in Binance Chain and sets up a system that lets anyone exchange this new native token for the real one it represents.
In the case of BTC, this means minting a new token called BTC.B and allowing users to exchange their BTCs for it through Binance’s centralised exchange.
Atomic Swaps
It is also possible to use atomic swaps to trade tokens native to binance chain for tokens native to some other chain in a totally trustless way.
Atomic swaps work through a multi-stage mechanism that makes sure that either the whole trade is completed or no part of it is, making it so it’s impossible for one side to cheat by obtaining some funds without having honored their part of the trade. We’ll illustrate how these work using an example: Alice, who owns 1 BTC, will trade it with Bob for 1 BNB through an atomic swap:
- Alice locks her BTC into a smart contract that says “If Alice reveals her secret before X minutes, send this bitcoin to Bob, otherwise, send it back to her”
- Bob locks his BNB in the same way
- Alice then proceeds to reveal her secret in order to get Bob’s BNB
- By revealing her secret, her BTC transaction is unlocked and Bob claims her BTC for himself
As explained before, this mechanism is atomic, meaning that it guarantees that either everything will happen or nothing will, there’s no way it’ll get partially done. But while the trustlessness of it is perfect, everything isn’t rosy in atomic swap land, as these mechanisms have an important set of drawbacks that have prevented them from getting any real-world usage:
- They’re slow due to the fact that steps 2 and 3 must wait for the previous step to finalize, so there’s no skipping the waiting time of new transactions on both chains, which in Bitcoin is around 1 hour
- They are always worse for one part of the deal, usually the party initiating the first step. This is because Bob can always wait some time and take the trade only if the price has moved in his favor, at the expense of Alice, who will be trading at a worse rate (another way of looking at it is that Alice is granting Bob an option on her BTC, at her expense)
- They are expensive, as they require 2 transactions on each chain for every trade
A new foe has appeared: Introducing BEP3 pegs
Overall, the previous solutions are not perfect, as they either require a high level of trust in a centralized entity or have many drawbacks. For these reasons, Binance came up with the BEP3 peg, a new kind of peg for tokens native to Smart contract enabled chains, such as Ethereum, EOS or NEO.
BEP3 draws inspiration from atomic swaps to construct a mechanism that takes the Custodian Model and strips away the trust required in some parts of the system. But enough descriptions, let’s look at the mechanism itself.
Porting tokens to Binance Chain
BEP3 maintains the figure of a custodian, which they call deputy, an entity that is in charge of initially creating a new token inside Binance Chain, deploying a smart contract in the other chain and supporting the continuous transition of tokens. Afterwards, whenever a user wants to port their tokens over to binance chain the following steps are taken:
- User locks their original tokens inside the smart contract along with a hash of a secret only known to the user, these tokens then remain locked unless the secret is not revealed in under X minutes, in which case they will get sent back to the user
- The deputy discovers that some tokens have been locked and sends a message to Binance Chain saying “User has locked Y tokens, if his secret is revealed before this deadline hand him the equivalent amount in pegged tokens”
- User reveals the secret in Binance Chain and retrieves the pegged tokens
- Deputy relays the secret to the smart contract and locks the tokens permanently
Redeeming pegged tokens
Once the user wants to redeem their pegged tokens for real ones the process can be reverted, the steps are reproduced here for the sake of completion but if this is trivial for you feel free to skip to the next section or just look at the diagram:
- User locks some pegged tokens on Binance Chain using a special transaction that allows the deputy to retrieve them if the user’s secret is revealed before a deadline and, if that does not happen, they are sent back to the user
- Deputy relays this information to the smart contract, which unlocks some tokens temporarily and allows the user to claim these upon revelation of his secret
- User reveals his secret and claims the smart contract’s unlocked tokens
- Deputy relays the secret to Binance Chain and retrieves the user’s tokens
But wait, this requires trust in the deputy!
You might have realised that, while the process for getting new tokens in and out of the system has been made trustless due to the properties inherited from atomic swaps, there’s still some trust required to make everything work, namely the responsibility of relaying information between both chains falls squarely into the hands of the custodian, meaning that for the whole system to work everyone must trust the custodian to relay these messages honestly.
This responsibility might not seem important, but because users are expected to hold the pegged tokens for non-instant periods of time, this pokes a big hole in the trust model of the whole system: if the custodian is hacked or turns malicious it can start relaying fake information to Binance Chain saying that one of his accounts has locked a huge amount of tokens, then proceed with the atomic swap to get the pegged tokens and finally redeem these tokens for real ones, draining all the funds from the smart contract and rendering all the pegged tokens worthless.
But hold on! While this might seem like a fatal flaw of BEP3, it’s important to take into account the environment BEP3 pegs operate it, as that changes the whole security model.
Piggybacking on issuer trust
Let’s entertain the following thought experiment: What if the deputy is the same entity that issued the tokens, the very same entity that gives the tokens all their value? In the cryptocurrency space, it’s pretty common for a token to derive all of its value from an entity, examples of these are exchange tokens that can be used to pay for fees, tokens that grant their stakeholders a portion of a company’s benefits… All these tokens only have value because people trust that the companies that give them utility will hold their promises, if tomorrow an exchange decided to stop allowing the payment of fees using their token, the token would lose all it’s value, plummeting to zero.
Because of the inherent trust that we place in these entities, if they become deputies in the BEP3 process for their own token, the trust model doesn’t change at all. Being a deputy requires trust from their users, but, because these users already need to trust the entity, no new trust is required, all thanks to the fact that this new requirement just piggybacks on the previous level of trust that was placed on the issuer.
But you may say that there are some cases in which there isn’t a single trusted issuer, like in the case of Ethereum for example, or it’s possible that such issuer doesn’t want to run a deputy process. Are these tokens doomed to require a trusted custodian for them to be traded on Binance Chain? Do not fret, as this is all solved by the ultimate solution: A 100% trustless peg brought to you by our ace in the hole, SPV proofs!
A primer on SPV proofs
Simple Payment Verification, usually abbreviated to SPV, is a system outlined in the original Bitcoin Whitepaper that enables light clients (wallets running on low-end systems) to verify that a transaction has been included in Bitcoin and therefore a payment has been made.
This is possible because, when Satoshi designed Bitcoin, he used a data structure called Merkle tree to store the transactions in each block. A Merkle tree is nothing fancy tho, it’s just a structure created by grouping all the transactions in pairs and hashing them together, then proceeding to hash the resulting hashes together and continuing this process till there is only one hash left, called the Merkle root. This creates a tree where every node has two children, which can be used to create their parent node.
Now, the cool thing about Merkle trees is that someone that only knows the Merkle root/top hash can verify if a transaction is part of the tree, that is if it’s been included in a Bitcoin block. This is done by taking the nodes that are in the path that connects the Merkle root with one of the bottom transactions and bundling them together to create a proof:
With that proof, our original user that only had access to the top hash can follow the path back to the roots in a verifiable way, he can check that Hash1 and Hash0 hashed together generate the top hash, meaning that Hash1 and Hash0 are its legitimate children, then apply this same check to Hash0–0 and Hash0–1, thus asserting that these two are also part of the original block, and, finally, check that L1 is the source of Hash0–0, proving that L1 is included in the block, therefore confirming it as an accepted Bitcoin transaction.
But why are SPV proofs so important?
SPV proofs might not seem to be that big of a deal, after all, if you can verify Bitcoin transactions by running a full node, why’d you jump through all these hoops to do just the same? Well, the thing is that running a full node requires downloading the entire blockchain, but if we use SPV proofs we only need to know the Merkle root of each block in order to verify the transactions, so we only have to store 80 bytes per block, instead of the much larger size per block required for full nodes. This decrement of over 99.99% makes running the verification inside a smart contract feasible, a total impossibility if we were to download every single block.
Lord of the SPV: The return of the trustless peg
Now, armed with the tools to verify transactions from another chain inside a smart contract, we can tackle the problem we set out to solve: Making the peg trustless. We will do that by extending the original BEP3 process in order to remove the parts that required trust in the deputy, which if you remember the discussion from earlier, are the parts of the protocol where the deputy acts as an oracle between both chains, relaying information between them. This is done in two situations, when new pegged tokens are issued and when they are redeemed.
For token redemption this seems pretty easy, tokens on Binance Chain can be burned by sending them to the null address and then an SPV proof of this transaction can be relayed by anyone to the smart contract, which will then verify that the transaction actually happened on Binance Chain and send the unlocked tokens to the entity that burned the tokens.
The other case, which involves minting new pegged tokens when real tokens are locked on the smart contract, proves to be much harder to decentralize, as there are no smart contracts on Binance Chain, preventing transaction verification on that side of the peg. We can get around this while maintaining good performance with the following system:
Let’s start by keeping the figure of the deputy and its responsibilities, which are composed of relaying the information to Binance Chain, minting new tokens there and giving them to the users that have locked tokens on the other chain. But, in this new protocol, we’ll add an emergency mechanism, an escape hatch that allows anyone to ring the alarm whenever the deputy behaves incorrectly, prove his bad behavior and freeze everything in order to give all the tokens back to their current rightful owners. After this process has been completed, a new custodian can be selected and the peg restarted.
But how does this actually look like? Well, a typical activation of the emergency mechanism will follow these steps:
- Custodian sends tokens to some address that has not previously locked tokens on the smart contract, essentially minting pegged tokens out of thin air, therefore destroying the backing of the peg.
- A user finds out about this, creates an SPV proof of the fraudulent transaction described in the previous step and sends it to the smart contract.
- The smart contract verifies the validity of the proof and checks that the address where the pegged tokens were sent has not previously locked tokens. If both conditions hold, the contract enters an emergency state, which prevents new tokens from being locked, takes the AppHash of the last known good block (the last block before the fraudulent transaction took place) and pins it as the final token distribution, taking a snapshot of all the token balances at that point.
- Users can then submit proofs proving the value of their balances of pegged tokens at the moment the AppHash was created along with proof of ownership of the addresses that held those coins (this can be as simple as signing a message with that account’s private key). Upon successful verification, they’d be allowed to withdraw in real tokens the amount of pegged tokens that they held at that point in time.
Note: This scheme can lead to an attack where the custodian can rollback transactions of the pegged tokens by waiting till a transaction happens and then sending a fraudulent transaction in the same block, when that is reported that block will not be included in the final distribution of tokens, therefore, in practical terms, it’s as if the custodian has managed to remove that transaction. This can be fixed by implementing a system that tracks the origin of the tokens in any balance and only redeems those that do not come from fraudulent custodian mints, but this system is much more complex.
Improving step by step
It is also important to note that, even if we were to forget all this discussion on trustlessness, a big advantage of BEP3 pegs lies in its inherent transparency.
It is a fact that BEP3 represents a huge improvement in that field, as it allows anyone to check the state of the peg and verify whether it is fully backed. This is especially important in the space of cryptocurrency exchanges since most big exchange failures have been caused by a continued draining of the funds, which eventually left the exchanges powerless. On the other hand, exchanges have usually been able to recover from big flashy one-off hacks, either by socializing the losses, covering them with something else or other mechanisms.
Considering this is especially important when taking into account that the approach taken to Binance Chain has been one of iterative and continuous improvement. Rather than wait for the perfect solution to come, it has been pushing for solutions that can be implemented quickly and that improve the status quo. Viewed through this lens, BEP3 provides an important advantage over the opaqueness of other systems and thus succeeds in its goal of improving the current state.
Appendix: The dark side of SPV proofs
While SPV proofs might seem like a boon, it would be a mistake to assume that a client relying on SPV proofs has the same level of security of a full node. This is because SPV proofs do not prove that a transaction is valid, only that it is included in the longest chain. This means that verification by SPV proofs relies on the assumptions that the miners will verify the blocks for you and that the majority of miners are honest.
If either of these assumptions break, it would be possible for a miner to create a new block containing invalid transactions, such as transactions that spend money created out of thin air, then push that block into the longest chain and, while full nodes would verify the block, discover that it contains invalid transactions and dump it along with the whole chain, SPV nodes will tag along and accept that chain and all the blocks that come with it, therefore accepting that invalid transaction as valid.
Some argue that this security problem is quite minimal due to the fact that, if a successful 51% attack is conducted, double spends become possible, compromising the whole system, at which point it is moot to discuss the level of the compromise given that one of the basic security assumptions of bitcoin has been broken. Nevertheless, it remains a security problem that should be taken into account.
Luckily, the past few years have seen an abundance of research on that topic, as new schemes and protocols to bridge the security gap between SPV and full nodes have appeared. These are usually referred to as fraud proofs in the literature and are commonly based on proving that a block contains an invalid transaction, as once proof of that is constructed it can be relayed to all SPV nodes, affording them the same security that full nodes have.
If you’d like to dig deeper into that I recommend checking this survey of the field, but be aware that currently this is a hot research topic and it’s quite possible that the linked survey is heavily outdated by the time you are reading this.
To learn more about BEP3 check out the original BEP and its official documentation page.