Loopring Protocol 3.0: zkSNARKs for Scalability
By: Matthew Finestone
Tags: Scalability, Zero Knowledge Proofs, Decentralized Exchange, Version3, Blockchain

Using blockchains to trade blockchain-based assets makes sense. We all know it. Any other situation is rather puzzling. So why, as traders, are we giving our cherished, trustless, magical money to trusted intermediaries? Why are we trading IOUs? Why would we ever move our assets off the open platforms that promise to permeate all corners of finance and beyond?

Many of us are guilty of doing just that. Meanwhile, with the current state of centralized exchanges, we don’t know whether to be more fearful of losing crypto to outside hackers, or inside jobs. We also haven’t a clue what is real volume and what is fake. Although, people are figuring it out.

To be honest, however, there are (were) good reasons that cryptocurrencies and tokens traded on centralized exchanges: trading on a DEX is not (always) fun or feasible. There, we said it.

UX, liquidity, and scalability are the three big obstacles commonly listed. Our fellow builders, particularly in the Ethereum DeFi community, have made absolutely incredible progress on many fronts: deeper liquidity is awakening, and beautiful dapps are offering an experience as simple as web 2.0.

Scalability, though, especially as it pertains to trustless trading, has remained elusive. And let’s face it, without massively scaling DEXs (or massively scaling Ethereum a layer below) we won’t realize our ambitions. With that in mind, Loopring R&D has been focusing heavily on scalability solutions over the past 6 months.

Our new release, Loopring Protocol 3.0, stares squarely at scalability, and uses one of the most promising tools to help solve it: zero knowledge proofs.

High Level Overview of Zero Knowledge Proofs 🔐

We’ve always had scalability on our minds. That’s what influenced our design decision from the beginning (1.0 and 2.0): a hybrid model, with off-chain order messaging, and on-chain settlement. Do as much as possible off-chain, and use the blockchain only when needed, for mission critical guarantees.

Protocol 3.0 is kind of like that — just taken to its extreme and logical conclusion. Now, we can do much, much more off-chain, including settlement…while still remaining secure.

We achieve this by using zero knowledge proofs (ZKPs), a cryptographic tool that can be used by someone, a prover, to prove they’ve done some computation or know some ‘secret’ — without actually peeling back the curtain to give a verifier a look at said computation or secret.

That sounds like it’s pretty useful for privacy, right? I can, for example, prove to some investment group that I have >X dollars, the threshold to join their club, without divulging exactly how many dollars I have. And the group can be certain I’m telling the truth. Pretty mind-bending. It’s also the stuff that powers (or shields) some of the leading privacy focused coins like ZCash.

Besides privacy, though, ZKPs are also extremely useful for scaling complex systems. Instead of proving I have >X dollars, I can also prove that, as a DEX owner, my users’ have their proper balances in their accounts, that I’ve settled their trades appropriately, processed withdrawals, etc… all the DEX-y computations you can think of. And instead of executing this in blockchain smart contracts, I do this off-chain, and come up with a small proof that still makes everyone know I’m telling the truth.

That’s what Protocol 3.0 aims for: scalability without sacrificing security.

In 3.0, pertinent data such as account balances and trade history are kept off-chain in Merkle trees. By doing so, trades can be settled between users just by updating the tree off-chain, with no need for slow, expensive token transfers on-chain.

We do not give up security guarantees by doing this. ZKPs assure that what was claimed to be true and executed, is true and executed. The protocol is still 100% non-custodial, and fully secure for end users — even when DEX operators are malicious, they cannot steal your tokens.

With all computations done off-chain, we can speak to the Ethereum chain much less frequently, and with much lighter loads. In fact, all DEXs submit to Ethereum is that proof we mentioned — a proof that certifies everything that a DEX has done off-chain is correct.

With ZKPs, specifically zkSNARKs — the form we have chosen to work with — the proof can be checked trivially and efficiently (in milliseconds) by verifiers, or, in our case, a smart contract built to verify proofs.

High Level Overview of Loopring Protocol 3.0 📝

Anyone can create a new exchange on the Loopring protocol. An exchange has an owner and an operator.

The owner is who handles business-related functions, like registering tokens, putting the exchange in maintenance mode, and setting the operator.

The operator is responsible for creating, committing and proving blocks.

Blocks are not Ethereum blocks in this sense — they are simply chunks of DEX related work, such as trade settlements. A block changes the Merkle tree from the existing state to the new state by doing the state changes required in all the work in the block. The correctness of the work in a block needs to be proven and submitted to the Ethereum chain. This is done by creating a ZK proof.

For the highest throughput, 3.0 currently supports off-chain balances only. These balances are stored in Merkle trees. Users deposit and withdraw tokens to our smart contracts, and their balance will be updated in the Merkle trees. [Note: You don’t need to trust a custodian. It is trustless. No risk of losing funds.]

Going it alone

Block submission needs to be done sequentially so the Merkle tree can be updated from a known old state to a new state. To allow concurrent settling of orders by independent parties, we allow the creation of stand-alone exchange contracts. Every exchange contract operates independently. User accounts and orders cannot be shared over different exchanges contracts.

Or working together

Alternatively, DEXs can decide to use the same exchange contract so orders and user accounts can be shared — if they desire. This also avoids the need to setup its own infrastructure to handle block creation and creating proofs.

The operator can be a simple Ethereum address, or can be a complex contract allowing multiple operators to work together to submit and prove blocks. It is left up to the exchange for how this is set up.

Such an operator contract can also be used to enforce an off-chain data availability system. A simple scheme could be that multiple parties need to sign off on a block before it can be committed. This can be checked in the operator contract. As long as one member is trustworthy and actually shares the data, then data availability is assured.

Similarly, the exchange owner can also be a contract! One scenario is that the exchange owner can be some sort of governance contract, or DAO, managing many DEXs within.

All of this is completely left up to the DEX and can be updated when needed without disrupting the exchange.

Statefulness, Stickiness

Because of the above, we envision most trading will be done on a single exchange contract using contracts as the exchange owner/operator. This not only increases liquidity, but also improves the efficiency, latency and throughput because blocks contain work from all DEXs.

This is also important because it dramatically enhances the possibility for ‘statefulness’ in the Loopring protocol — the act of holding valuable state, users, and liquidity. A coordinated, thriving group of DEXs will not easily disband/fork. This adds to Loopring’s defensibility, continuity, and value.

[For more details on how such a group of DEXs built on one contract can implement flexible business logic and share orders/fees, see here.]

One final remark on that note is, given the off-chain account balances, there is some baked-in user stickiness to a DEX that a trader uses (and likes) under this framework. So a well-performing DEX, or group of DEXs using the same contract, can build and hold a devoted user base. We’re pleased with this, because after all, it is our goal to support successful DEXs atop the protocol.

Throughput and Cost Figures 🐆

So let’s get to the good part— how much improvement are we looking at?

Our current implementation achieves 450 trades per second on Ethereum without on-chain data availability and 80 trades per second on Ethereum with on-chain data availability. For reference, past versions of Loopring (and other DEXs) did ~2 trades per second.

*Doesn’t include off-chain proof generation cost. Very conservative estimate is $0.005; likely much cheaper.

And we’re just getting started: throughput will improve significantly even in the near term. With two very near term improvements alone, relating to a more efficient hash function and simplified fee circuit, we will be able to do ~10,000–20,000 rings/Ethereum block or ~1,000 trades/second without on-chain data availability.

[To see how these figures were calculated, please see here.]

This is incredibly exciting. At last, we have the tools to allow DEXs to approach true commercialization, and to compete against their centralized counterparts.

Of course, we still have orders of magnitude to go to reach the required throughput for when millions of assets are tokenized and constantly changing hands. But we are supremely confident we will get there; by using layer two scaling solutions such as ZKPs, and riding layer one (Ethereum) scaling improvements such as sharding, etc.

[On-chain data availability means the entire DEX history is available on the Ethereum chain, allowing any third party to reconstruct the state of the exchange at any point in time. Please see design doc for detail.]

Other Features 🎄

Scalability is the focus and driver behind protocol 3.0, but there are many other awesome features that have been implemented. Some are inherited/enhanced from 2.0, while others were only made possible in the current design. For a full list of features, check out this quick doc, and for the full spec, we highly recommend reading the full design doc. A few notables include:

Option for on-chain data-availability, or DEXs can opt-out for even greater throughput & lower cost.

All ERC20 tokens and ETH are supported by default. ETH is supported, no need to wrap it for WETH .

. All tokens can be used for trading fees, with LRC realizing benefits.

Allow partial order matching (aka partial fill) and automatic order-scaling.

An enhanced version of Dual Authoring prevents orders/trades from being stolen by middlemen (enhanced on top of 2.0).

Support a unique feature called Order Aliasing.

DEX operators can stake LRC to “buy” credit, or, skin-in-the-game.

Support a “maintenance mode”, where DEX operators can purchase time to upgrade backends within a time window.

A built-in mechanism to force DEX operators to fulfill duties on time (especially for handling deposits and withdrawals).

Additional Utilities for LRC 🚴🏾

While I won’t expand on all the features above, I’ll touch on the final three. These are super interesting because:

A. They lend themselves to ensuring DEXs act even more faithfully and fairly.

B. While optimizing for good behaviour, they inherently provide additional uses for LRC.

Staking

An exchange stakes LRC. Anyone, not just owner/operators, can add to the stake of an exchange. Withdrawing the stake is only allowed when the exchange is properly shutdown and all user balances are withdrawn.

The stake ensures that the exchange behaves correctly. This is done, among other ways, by 1) burning the stake if a block isn’t proven in time, and 2) only allowing the stake to be withdrawn when the exchange is shutdown by automatically returning the funds of all its users.

Exchanges with a large stake have a lot to lose by not playing by the rules and have nothing to gain because the operator can never steal funds for itself.

Note: Staking is not mandatory because security is there by default. However, it provides added skin-in-the-game, and can be used to differentiate a DEX. Importantly, however, it does guard users against data-availability problems. When data availability isn’t used, even if the Merkle tree cannot be rebuilt by anyone but the operator, this mechanism still ensures all funds will be returned to users, otherwise the exchange loses its stake.

Maintenance Mode

The exchange owner can put the exchange temporarily in a suspended state. This can be used, for example, to update the back-end of the exchange.

The exchange owner can purchase downtime, which means burning LRC in return for downtime. This can be done multiple times to extend the downtime.

This is needed because the operator must handle on-chain requests, otherwise the exchange can go into withdrawal (shutdown) mode, which is irreversible. Maintenance mode thus allows the exchange to temporarily disable on-chain requests (which he may otherwise not be able to process in time). But these types of user requests are meant to guarantee that users can actually withdraw when they want — so the maintenance cost is to ensure an exchange cannot be in maintenance mode for an indefinite amount of time.

Timely Execution for Deposits/Withdrawals

Everyone hates to wait. Especially for their money.

If the exchange operator is slow to handle user withdrawals or deposits, the operator fee is reduced linearly. And if the operator doesn’t automatically transfer the tokens back to the user’s address after a withdrawal request, he is fined (from his stake), with 50% of the fine used to reward the party that wants to do it (a user can always choose to do this himself), and 50% burned.

Actually, one more feature

Order aliasing is pretty cool, so let’s explain it a bit here. This allows a trader to reuse the same trade history slot in multiple orders. Besides being used to safely update an order without risk of both orders being filled, it also allows for some interesting filling logic between orders.

For example, a user could create an order selling X tokenZ for either N tokenA or M tokenB (or even more tokens) while using the same ‘slot’. The user is guaranteed never to spend more than X tokenZ, but will have bought [0, N] tokenA and/or [0, M] tokenA.

A real use case would be for selling a token for one of the available stablecoins. Or selling a token for ETH or WETH. In these cases, the user may be indifferent to which specific token she buys, but wants to increase her chance of being filled.

Flexible fee model remains

The fee model introduced in protocol 2.0 remains; traders and DEXs can continue to pay and earn fees in any token, but LRC receives protocol-level lower burn rates, with total supply decreasing in-line with network usage.

When DEXs Feel Like CEXs 💸

As mentioned at the beginning, DEX trading will no longer feel like DEX trading. In fact, we’ll probably be able to stop using the word ‘DEX’ altogether…trading crypto will just be known to happen on DEXs — obviously. 3.0 represents the beginning of this shift.

Trading on a DEX built atop Loopring Protocol 3.0 will feel like you are trading as fast and easily as ever. Settlements can be signalled instantly.

Trading Flow

Users create orders using accounts created on the exchange. Orders are added to the order books of the DEX.

The DEX matches the order with another order, signs the ring using the ring-matcher private key and the dual-author keys of the orders. The order gets completely filled in the ring:

The GUI of the DEX can be updated immediately with the state after the ring settlement. The order can be shown as filled, but not yet verified.

with the state after the ring settlement. The order can be shown as filled, but not yet verified. The DEX sends the ring to the operator(s) of the exchange. Operator needs to commit the block soon after receiving rings.

The operator generates the proof and verifies the block within the maximum time allowed.

The DEX could now show an extra ‘Verified” symbol for the filling of the order. An order can be in the following states:

Unmatched in an order-book

in an order-book Matched by the DEX

by the DEX Commited in a block

in a block Verified in a block by a proof

in a block by a proof Finalized when the block it was in is finalized (so all blocks before and the block containing the ring settlement are verified)

Only when the block is finalized is the ring settlement irreversible.

Challenges 🌔

While there are a few potential challenges, the most salient is that SNARKs require ‘trusted setups’. While we won’t dig into it here, just know that some trusted setups, if not performed properly (randomly), can theoretically allow adversaries to construct false proofs. However, the good news is that this problem is largely becoming solved: Sonic: Nearly Trustless Setup.

Closing Thoughts 🔭

We are super thrilled by Loopring Protocol 3.0’s prospects. We feel as though the world can finally stop treating DEXs as play-things, and instead begin to appreciate that this is how value will be transferred in a tokenized future. We’re grateful to play a part in it.

What’s also really striking to us is just how fast moving and fluid the DEX space is. There are dozens of protocols and projects, and even though we’ve been around a while (in crypto terms), we are 100% aware that we must stay moving and thinking or be rendered obsolete. It’s humbling and motivating.

Once more, please have a look at the complete 3.0 design doc, and stay tuned for when we open the repo in the coming week. After that, we expect a testnet implementation within the next month or two, and a mainnet version within the next six months.

If you’d like to get involved in building or helping out with 3.0, please reach out to foundation@loopring.org.