- Loopring zkRollup users can interact with L1 dapps directly from L2 cheaply by utilizing the power of batching and zero-knowledge proofs.
- Loopring now supports cheap and capital-efficient cross L2-L2 transfers.
- Centralized exchanges (CEX) can easily support withdrawing directly to Loopring’s zkRollup using standard L1 functionality while still reaping the cost savings of L2. It’s also much easier for CEXs to allow users to deposit to a decentralized exchange cheaper.
- Ethport will be available as part of the Loopring 3.7 release.
Our current zkRollup is great at doing transfers and order book/AMM trades on L2 cheaply. While transfers and trades are the things people want to do most often, they also sometimes want to do more complex things that requires them to interact with L1. With the current gas prices on Ethereum this is expensive.
Withdrawal costs for CEXs are also high, and with every L2 having its own particularities it’s not always easy for CEXs to have native support. A standard L1 interface, which hides all the implementation details while still proving the L2 cost savings, would be a big win.
More and more L2s are also live on mainnet each day, and users want to move between these without having to go through L1 by doing a withdrawal from L2 and then a deposit to another L2.
Even as more functionality is being migrated directly to L2 in the future, it will take a while before this is fully realized. Some (or even most) of the liquidity may even remain on L1 for the time being until the more general L2s are more mature. We need something that helps bridge (pun intended) this transitional period.
Doing as much work as possible on L2 is key to make things cheap enough so people aren’t priced out. Often it’s possible to batch many L1 transactions together so the L1 gas cost can be shared. L2 transactions are used to do the bulk of the work and only a single L1 transaction is needed for all users together, reducing the gas cost significantly.
zkRollups are especially well fit to help solve this problem because L2 state is finalized immediately on L1 as long as the validity proof is provided immediately. This not only means operations like withdrawals are fast out of the box, we can also immediately use L2 data to do L1 transactions without having to worry an invalid L2 state transition needs to be reverted.
As is often the case, the best solution depends on the specific problem and the desired user experience. Let’s first give some more details what tools Loopring now has in its tool bag and what problems they each solve before explaining how this will be presented to users.
Liquidity Providers 💸
This is basically the status quo on Loopring today. We depend on dedicated liquidity providers to provide liquidity on L2. Liquidity is of course also provided between users themselves sometimes. If for example someone wants to enter a vault and another user wants to exit that vault, just by allowing those users to trade against each other at least one user has already achieved his goal. The best scenario is where users can always just trade amongst themselves, but that’s unpredictable and won’t always be possible in a reasonable amount of time.
The downside of this approach is that liquidity providers only have a limited amount of funds they can utilize. They also need to keep these funds available for use at all times. zkRollups are actually very good at this because capital is never locked up for long (deposits and withdrawals are fast in zkRollups) so even a limited amount of funds can be reused quickly. Still, it’s not capital efficient and we can do better.
Single Phase Converter
To solve capital efficiency we can make use of flash minting on L2 (something we’ve been thinking about for almost a year). Because we are on L2 every token has flash minting built in and we can create as many tokens as needed. So we can
- Flash mint the amount of tokens all users combined want to buy so all trades can be filled on L2 (can be thousands of trades)
- Fill all trades on L2 at the predicted exchange rate
- Withdraw all the collected tokens users sold
- Use those tokens to do the L1 transaction to get real tokens the users bought (and were already distributed on L2)
- Use those tokens to pay off the flash loan
This is the perfect solution when the exchange rate is fully deterministic when doing the trades on L2 and the L1 transaction can never fail (e.g. ETH/WETH, or a smart contract doing arbitrary logic that only the L2 itself can interact with). But if
- The exchange rate can change unpredictably (often the case when any user can interact with the smart contract on L1)
- The L1 transaction that needs to be done can fail for whatever reason
there is a risk that the flash mint cannot be repaid. And if the flash mint cannot be repaid it is impossible to submit the block on-chain as it would be invalid. This would mean having to revert all trades on L2, create a new block with new transactions, recreate the zero-knowledge proof,… Which in theory is okay, but is something that we want to avoid in practice.
Double Phase Converter
To solve the predictability problem we can do the trade in two phases. In the first phase we first collect all users funds in a dedicated vault solely for a specific token swap. Instead of directly swapping to the token the user wants to buy, we first give the user a token representing his share in the vault (at a fixed 1:1 ratio). Afterwards the L1 transaction can be done and the actual exchange ratio can be observed. In the second phase the amount of tokens received in the conversion can be distributed pro rata in a following block to all users.
The Bridge is a more powerful design than the Converter, but is also a bit more expensive per user transaction because of some additional L1 overhead. The bridge can not only do batched token swaps like the converter in a more flexible way, it also supports L1 transactions that cannot be reduced to a simple token swap.
The Bridge allows efficient on-boarding to Loopring using batched deposits. Instead of every user having to onboard the zkRollup individually, batch deposit functionality is made available directly on L1 with a standard L1 smart contract function which allows on-boarding a batch of users together. This way the number of expensive L1 token transfers can be reduced to just a single L1 transfer per unique token while the distribution to each user is handled by much cheaper L2 transfers. This allows even centralized exchanges to easily support Loopring using standard L1 infrastructure.
The Bridge also allows efficient L1 transactions directly from L2. This is done by first collecting all funds for these transactions in a Bridge account on L2 so we can minimize the number of L1 token transfers. Then in the L1 Bridge contract (the owner of the L2 Bridge account) we run over all transfers to the Bridge (which is done using a conditional transfer, with the condition being that the transfer is processed by the Bridge contract). By also having the user sign some extra data next to the transfer the Bridge knows which L1 transaction the users wants to do with the provided funds. The bridge batches all these transactions together, groups them on the type of L1 transaction and sends them to a Connector associated with that type . These Connectors are simple contracts that do the transformation between all the user transactions and the batched transaction. The bridge provides a universal interface which allows users to connect to any Connector contract, even if we don’t know what that connector does!
Each user can provide custom data to the Connector (what data is accepted depends on the Connector), which allows batching but with customizable behavior per user. For example, if a bunch of users want to swap tokens on Uniswap, each user can set his desired slippage. The Connector can then only do a batched swap for the users where the slippage requirement is met, but for all other users funds are simply returned. Another example for cross L2 transfers is that the user can set the address he wants to send funds to on the other L2.
Some transactions will require funds to be sent back to users on L2, other transactions (like a transfer to another rollup) will not. The connector will make use of the same batch deposit functionality to do this if necessary.
Ethport is the user friendly product built on top of these designs.
- Uses liquidity available on L2 if possible
- If an optimized converter is available and can be used it will be used to batch all similar L1 transactions together as cheaply as possible
- Otherwise use the general Bridge
Often it will be necessary for users to wait a bit until either enough users want to do similar transactions or another user/a liquidity provider shows up that can help facility the desired transaction more quickly. We’ll call general dapp integrations Terminals. Each distinct batch-able operation inside a Terminal is call a Gate.
For example, if a user want to deposit ETH inside the Yearn ETH vault, the user will have to go to the Yearn Terminal and wait for the L1 transaction to lift off at the ETH Gate.
We’ll be adding terminals and gates gradually depending on user demand.
Loopring is an Ethereum zkRollup protocol for scalable, secure exchanges & payments. Loopring builds non-custodial, high-performance products atop our Layer-2, including the Loopring Wallet — a mobile Ethereum smart wallet, and the Loopring Exchange — an L2 orderbook and AMM DEX. To learn more, you can sign up for our Quarterly Update or see Loopring.org.