Onchain composability with layer 2 solutions poses some challenges. Doing things offchain is great for scalability, but how do you connect onchain interactions with offchain logic? We want our ZK Rollup exchanges to be part of the composable Ethereum ecosystem. We want other dapps/protocols to use the functionality we provide, and for our users to be able to use functionality provided by other dapps/protocols. Below is how we will go about solving this.
There are two cases users can find themselves in:
- A user has funds in his Ethereum wallet or somewhere else onchain and wants to interact with a Loopring exchange.
- A user has funds stored in a Loopring exchange and wants to use onchain functionality elsewhere.
One of our goals is to bridge this gap between the onchain and offchain worlds with the least amount of friction for the best possible user experience.
We have recently begun speaking and working with several onchain protocols and dapps with the view of working towards integrations. It is a relatively new frontier to explore how existing DeFi primitives, workflows, and money legos can hitch onto a ZKP-scaled exchange protocol, and vice versa.
While we’ll work with the simple situations described in 1 & 2 above, it’s worth noting the bulk of interesting use cases come without the user itself being unaware or interested in what is happening behind the scenes. It will be up to the protocols and products to facilitate the composability between layers — with the ultimate goal of reaching more users, and these users having access to more functionality and liquidity. See section 4 for a few examples.
Before continuing, if you are unfamiliar with Loopring v3 or with ZK Rollup scaling, please read here for a 5 minute primer, or here for a deep dive. What’s most important to understand for this article’s topic is that trading on a Loopring-based exchange requires depositing funds to the exchange’s smart contract, which effectuates the exchange creating an account for this user in its offchain Merkle tree.
1. Onchain ⟷ Offchain
The most obvious solution here would be of course to follow the standard steps for trading on a Loopring exchange:
- Deposit funds from an onchain wallet to the exchange.
- Create an order and wait for the operator to match it with another order & add it to a block.
- Withdraw the funds from the exchange back to the onchain wallet.
This works great if the user wants to have a traditional trading experience. However, doing this for a simple swap, for example, would be slow and provide a sorely subpar user experience.
Luckily, this can be solved by having a mediator. A mediator facilitates the interaction by taking the opposite role onchain and offchain. For example, if an onchain user Alice wants to sell 1 ETH to the offchain user Bob for 100 LRC then:
- The mediator receives the 1 ETH in his onchain wallet from Alice and immediately sends 100 LRC back to her from his onchain wallet.
- The mediator creates an order for 1 ETH/100LRC so it can match with Bob’s order. As a result, the mediator pays 1 ETH in his offchain wallet and receives 100 LRC in his offchain wallet.
For the mediator this is a zero-sum game (when disregarding fees), his funds have just moved between his onchain and offchain wallets:
- The mediator receives 1 ETH onchain and spends 1 ETH offchain
- The mediator receives 100 LRC offchain and spends 100 LRC onchain
In theory, any user on the exchange could facilitate the interaction this way. And if there is enough room for a small spread, can profit by being this bridge. However, having the operator (relayer) do this has major benefits:
- The operator can be sure the trade will happen as/when expected as he is the one that creates the blocks with the trades in it. Another user can run the risk of not having her order matched in time or even not at all.
- The operator benefits directly from the increased trading because he receives trading fees from the trade.
- The operator can provide functionality like this so he can provide a superior user experience to its users.
2. Offchain ⟷ Onchain
As above, the obvious solution would be again to follow the standard steps, but now in a different order:
- Withdrawing from the exchange to the onchain wallet
- Interact with the onchain dapp
- Deposit back to the exchange (if applicable)
Again, the operator is best used as the mediator. If the user wants to interact with a dapp by sending 1 ETH from his offchain wallet, the operator fronts the 1 ETH using the operator’s onchain wallet and onchain a proof of this is stored (to make sure the process can happen trustlessly). This proof can then be used by the operator to transfer 1 ETH from the user’s offchain wallet to the operator’s offchain wallet (this is called a conditional transfer which we’ll implement in a later version of the protocol). This again makes this a zero-sum game for the operator.
By depending on the operator we can close the gap between the onchain and offchain world for any kind of interaction in a trustless way. The only drawback of this solution is the necessity of the operator to store enough funds in his onchain wallet so he can front the necessary assets onchain. This is not capital efficient — unless the incremental trading volume it allows by these services outweighs the capital’s (opportunity) cost. Further, funds can be moved between the operator’s onchain and offchain wallet quite quickly (5 to 10 minutes), so the total amount of funds needed by the operator can be relatively low to support a high amount of economic activity traveling across. Note that solutions like this were already proposed by Gnosis and Starkware, just to name a few.
The design space for these solutions is constrained by quite strict limits in all layer 2 solutions. ZK rollup is actually the best layer 2 solution for schemes like this because of the fairly short finality times (once the proof is submitted onchain we’re sure the work was done correctly). In optimistic rollup, for example, the finality times are much greater, which greatly increases the capital needed by the operator to provide functionality like this.
ZKP improvements in the form of faster proving times would provide an incremental improvement, but the main problem of indirect state updates would still remain for practical reasons. A different solution to this problem would be if ‘everyone’ builds on a single layer 2 solutions. This should indeed be possible with progress in things like recursive SNARKs. The fluidity would still not necessarily be trivial, but solutions would almost certainly arise. If dapps, protocols, and other legos do go to layer 2, but in siloed solutions, the situation would not get easier, and likely more difficult.
4. Example use cases
As an example of who these other puzzle pieces can be in Loopring’s context — besides just an everyday user — think of DEX aggregators, and margin/lending protocols. Both these instances can cut both ways: wanting to pull/source liquidity from a Loopring exchange, and push/supply liquidity to a Loopring exchange.
DEX Aggregators have seen a strong surge in popularity over the past 6 months, with dapps such as 1inch, DEX.AG, Paraswap, and Totle offering swappers the best prices by aggregating liquidity and routing to the best rate. Right now they aggregate onchain sources (Uniswap, Kyber) but want to be able to source liquidity from layer 2 venues, such as a Loopring DEX. [Especially if layer 2 performance allows for spreads to compress, thus hosting the most competitive prices]. Conversely, a Loopring DEX may want to aggregate/include liquidity from these onchain sources as well, to bootstrap/supplement their order book's liquidity.
Margin/lending protocols are an important building block in open finance, allowing lenders to earn interest, and borrowers to access credit (and notably, margin trade). Similarly to the case with DEX aggregators, the protocols, such as bZx for example, would like to be able to pull from Loopring liquidity to fill their order objects’ needs when a user initiates a position. And again, Loopring would like their exchange users to access some of these protocols seamlessly & trustlessly from with their Loopring exchange accounts. A nice solution/workaround to this latter case is when the protocol’s output is a token itself, such as a ‘position token’, which can trivially be listed on a Loopring exchange as it is just an ERC20.
As a slight aside, composability can also be implemented “in bulk” for users of a specific Loopring exchange. For example, users’ funds locked into the exchange can be used collectively for certain DeFi opportunities. A DAO may be setup to manage the deposited funds, and vote to deploy these assets in a lending protocol, or for staking in some other network, etc. Indeed, a Loopring DAO will exist, and besides these DeFi decisions, will govern certain protocol parameters at large.
Thanks to our Chief Architect, Brecht, for writing much of this article.