Fast Withdrawals for Low Liquidity Fungible Tokens

Fast Withdrawals for Low Liquidity Fungible Tokens

Background

A common criticism of optimistic rollups (in contrast to ZK Rollups) is withdrawal latency. Since state transitions of ZK rollups are verified on the EVM, they are accepted instantaneously, allowing users to bridge to L1 as soon batches/proofs are posted on chain (assume batches are posted every L1 block after data availibility issues are solved). On the other hand, since the security of optimistic rollups hinges on a “fraud proof window” elapsing, users must wait for the duration of this window after they initiate a withdrawal. Of course, if they didn’t have to wait the duration of the window, the sequencer could steal all of the assets on the rollup at the cost of their collateral. This is clearly a huge UX issue for optimistic rollups, and ZK rollups love pointing it out :).

A clever solution to fix this issue is the concept of “Fast Withdrawals”. Fast withdrawals, from a high level, work as follows:

  • User locks wETH (or any other token) on the L2, signaling their intention to bridge back to the L1
  • Liquidity providers for wETH listens for the withdrawal to be recorded on chain and provides the bridged amount to the user (minus a fee)
  • After the fraud proof window, the liquidity provider withdraws the users liquidity (profitting the fee from before)

This is cool. Unfortunately, the system dependends on the existence of liquidity providers for bridged tokens, who may not exist for low liquidity fungible tokens and definitely do not exist for NFTs.

Protocol

The BOLT (Bridge for Optimistic rollups transferring Low liquidity Tokens. Quite a stretch for an acronym) bridge is a potential way to solve the low liquidity fungible token bridging problem for optimistic rollups.

Setup

Liquidity providers

The BOLT bridge consists of many liquidity providers (LPs) that are verifying incoming state roots (just like the Fast Withdrawals bridge) to put their highly liquid tokens into bridge pools. When a liquidity provider puts their tokens (lets use wETH going forward) into a bridge pool for a certain state update, an equal amount of another token, Slash ETH (slETH) is minted to a bridge vault. Their stake is a “certification” of the correctness of the given state root. The value of slETH is determined as follows:

  1. If the state transition the slETH corresponds to is eventually accepted, the slETH is burned and the LP is able to redeem their wETH back.
  2. If the state transition the slETH corresponds to is successfully challenged, then the wETH backing the slETH will be slashed and the owner of the slETH will be able to redeem the slashed wETH.

LPs will constantly be pooling for state roots, withdrawing liquidity from older bridge pools and putting it into newer ones as time goes on.

Users

For the following explanations we will use a fictional token, SHAKTI, as an example of a low liquidity token. Let’s go through the initialization process:

  • The SHAKTI founders/DAO/whatever decides on a set of L1/L2 liquidity pools from which outsiders can tell the price of SHAKTI in relation to a high liquidity token, say wETH.
  • They then provide the addresses of the liquidity pools and the token itself to the bridge
  • In response to the information provided, a transaction is dispatched to the L2 that deploys a canonical wSHAKTI ERC20 contract is deployed on the L2.

Bridging from L1 to L2:

  • Alice sends SHAKTI to the BOLT bridge on L1
  • Alice then proves that they have done so on the L2, and mints themselves the same amount of canonical wSHAKTI on on the L2

Bridging from L2 to L1 (assuming the sequencer and LPs are honest):

  1. Alice burns their wSHAKTI on the L2. Say they burn 10 wSHAKTI
  2. The sequencer includes the burn transaction in an L1 batch
  3. Alice then proves that they have burned their wSHAKTI on the L2 and does the following actions within a transaction
  • The bridge pool contract, for the state update including her burn transaction reads the price of SHAKTI to ETH from the liquidity pools provided in the initialization step. Say the price is 5 SHAKTI/ETH
  • Alice then buys 200% of the price of their bridged SHAKTI worth of slETH from the bridge vault (remember, this is where slETH is minted to whenever wETH is staked on a state transition) corresponding to the state update including their withdrawal and sends it to a withdrawal vault on the L1. In this case, the price is 5 SHAKTI/ETH and they are bridging back 10 SHAKTI, so they would create a withdrawal vault with: 200% of (10 SHAKTI)(ETH/5 SHAKTI)(slETH/ETH) = 4 slETH in it.
  • After they have created the withdrawal vault, they can remove their proven SHAKTI tokens from the bridge and interact with them freely, happily ever after.
  1. After the state transition for the slETH in mention has been accepted, LPs claim their share of the principal wETH and the fees Alice paid for the slETH. In addition the slETH is all burned.

A couple notes on this step.

  • One cannot “buy” slETH, they can only mint it into withdrawal vaults for a certain price.
  • The price of slETH is determined by the bridge pool. I would guess it would be something like 0.0001 ETH/slETH. This is the profit margin of the LPs.

Bridging from L2 to L1 (assuming the sequencer and LPs are malicious):

  1. Alice does NOT burn their wSHAKTI on the L2
  2. The sequencer posts a state update saying that Alice did burn their wSHAKTI
  3. Alice then proves that they have burned their wSHAKTI on the L2 against the invalid state update and completes the same steps detailed in step 3 above.
  4. After the state transition for the slETH in mention has been successfully challenged, Alice has her SHAKTI on L1 and has probably transferred it to someone else on L2, effectively double spending her SHAKTI. Making it even sharper, the wSHAKTI on L2 is not backed.
  5. This is where the withdrawal vault created in step 3 comes in handy. Now that the state update has been proven invalid, the LPs who provided the slETH in the withdrawal vault are slashed and the slETH turns into wETH.
  6. Assume the price of the SHAKTI to ETH is still 5 SHAKTI/ETH (really it can be anything up to 2x higher than it was during the time of withdrawal). Then whoever holds any wSHAKTI on the L2 can redeem up to the amount of wETH in the withdrawal vault at a price slightly better than the current price, say 4.95 SHAKTI/ETH. The left over wETH is then burned.

Analysis

Ok, now that the protocol has been described, let’s see what it achieves. We assume that the price of the bridged tokens remain the same during the fraud proof window.

If LPs staked on a valid state update, then only honest users will be able to prove withdrawals. They will get their low liquidity tokens instantly for a small fee, and LPs will realize those fees after the state updates are accepted. Yay.

If LPs stake on an invalid state update, they could steal all of the TVL at the bridge (they can engineer the state to reflect that they have burned the entire supply of all tokens at the bridge). Say the TVL is $10 billion dollars. To steal all of the $10 billion from the L2 back to the L1 the LPs would have to lose $20 billion worth of ETH. So, this attack is not cryptoeconomically feasible.

Another variant on this attack would be, the LPs own all $10 billion at the bridge on the L2. They certify an invalid state update, withdraw the $10 billion TVL. Then, after the update is successfully challenged, the LPs withdraw a bit more than $10 billion of the $20 billion slashed ETH. The attacker started out with $10 billion in low liquidity tokens and $20 billion in wETH, and ended up with the $10 billion in tokens and a little more than $10 billion in wETH. Again, this attack is not cryptoeconomically feasible.

Note that these attacks have varying profits depending on the value of the bridged tokens. To increase tolerance to price movement in these tokens, just increase the ratio of slETH needed to withdraw tokens from the bridge.

Final notes

One cool aspect is that it is peer-to-pool-to-peer. Since all slETH is pooled in bridge pools, collateral is thick. This is in contrast to bridges with routers and peer-to-peer liquidity providers, in which parties involved need to play more active roles and liquidity is thinner.

Another cool aspect is that it can be built permissionlessly. The bridge does not require any fundamental changes to the underlying optimistic rollup’s protocol.

So, is this broken? What’s bad about it? How can it be improved?

1 Like

There are a few things here that I don’t understand.

First, do slTokens live on L1 or L2? In general, it’s useful to specify clearly which assets and which activities are on L1 vs L2.

Second, it seems like you may be conflating the Arbitrum sequencer with the validators. The sequencer doesn’t make any claims about the outcome of transactions. Only validators do that, and no one validator has a special role as the “operator” of the chain. If validators disagree, the rollup protocol decides which one is correct–so essentially the L2 chain forks on a disagreement, and the protocol will then prune off the incorrect branch.

Wow, this was terribly written looking back at it. I was probably was sleep deprived, riding out the last few cups of liquid caffeine. Very likely that I’m also a bad writer. Let me try to detail the key points a bit more clearly and explain the result of a bit more thinking I’ve done.

By the way, thanks for clarifying the sequencer/validator terminology. I’m not super familiar with the details of the Arbitrum protocol, so always glad to improve my understanding. Didn’t mean to confuse :slight_smile:

Collateralized Bridging

Think about a collateralized stablecoin like Dai. Dai is “always” backed by a different, more volatile asset because, instead of being able to mint an amount of Dai equivalent to the price of the collateral, vault owners are only allowed to mint, say, 80% of the collateral’s value. So, even if the price of the underlying asset crashed quickly, Dai’s price could tolerate it.

Using the same logic, say SHAKTI is a low liquidity fungible token, and we have a reliable ETH/SHAKTI price feed that all holders of wSHAKTI on the L2 have agreed to (this could be something as simple as a Uniswap TWAP). Then, someone who had bridged 5 SHAKTI from L2->L1 could potentially supply the L1 side of the bridge with 10 SHAKTI worth of ETH (values taken from the price feed) and instantly withdraw their SHAKTI from the bridge.

Now there are 2 cases:

  1. If the bridger later proves that they had indeed bridged their 5 SHAKTI from L2->L1 against an accepted state commitment, they can redeem their collateral.
  2. If it was ever proven that the bridger had NOT bridged the 5 SHAKTI from the L2 to L1, they lose their collateral and any holders of wSHAKTI on the L2 can burn their wSHAKTI, and receive an equivalent value of their tokens in ETH from the collateral plus some premium for inconvenience, say 2%.

It is easy to see that the bridge remains backed in case 1. In case 2, the bridge remains backed as long as
1.02*n*price(SHAKTI) <= price(COLLATERAL) = 2*n*price_old(SHAKTI)
Where price_old(SHAKTI) returns the price of SHAKTI when the collateral was provided. So, as long as SHAKTI does not surge more than about 2x in the time is takes to accept the state commitment from which a proof of bridging fraud can be created, the bridge is backed in case 2.

Pooled, collateralized bridging

Ok, this is pretty good, but it sucks. It makes it super capital inefficient and unusable for honest bridgers because they essentially need to pay 2x the value they are bridging every time they bridge low liquidity fungible tokens from L2->L1. How can we get rid of this?

Essentially, we allow “collateral providers” (CPs) to assess the integrity of different, unconfirmed state commitments. For any commitments that they deem to be correctly computed, they put ETH into a pool with a bunch of other CPs, attesting to the claim that “state commitment XYZ is correct”. Note that this is all happening on the L1.

When a CP puts 1 ETH into a pool, they are allowed to mint themselves 1 slETH. The slETH is valued as follows

  • It has 0 value if the state commitment that it corresponds to is accepted, and the CP can redeem the underlying ETH
  • If the state commitment is proven incorrect, then the holder of the slETH is able to claim an equivalent amount of ETH

Joining this with the previous scheme, bridgers need to prove their L2 transaction where they bridged SHAKTI to the L1 against a state commitment, but now they don’t need to provide twice the bridging value in ETH, they need provide twice the bridging value of ETH in slETH!

This is much cheaper than ETH, because it only has value in the case that the corresponding state commitment is slashed. This is the same reason car insurance is “cheap” compared to paying for fixes to your car because it only pays off in the case where your car breaks.

This gets rid of the capital efficiency problems and is only realized as a small fee from the POV of the user (they don’t even need to be aware of what slETH is).

The analysis and final notes from my previous post hold, with the slight modification that slETH can be sold on the open market and can be traded and part of DeFi like any other token. I was thinking it would be a problem for a CP to hold their own slETH, but I don’t think it’s an issue anymore.

So, as a summary, here’s how a withdrawal would work:

  1. Burn 5 wSHAKTI on the L2
  2. Wait for a CP to collateralize a correct state commitment with the state after your burn tx from (1) on the L1
  3. Buy 10 wSHAKTI worth of ETH in slETH corresponding to (2) on the L1
  4. Prove your burn tx from (1) to the bridge against the state commitment from (2) on the L1
  5. Withdraw 5 SHAKTI and leave the slETH from (3) at the bridge on the L1

The optimistic case:
6. The state commitment from (2) gets accepted and the CP withdraws the underlying ETH in the pool and secures more state commitments happily ever after, all on the L1

The unoptimistic case:
6’. The state commitment from (2) get rejected and an the slETH at the L1 side of the bridge is converted into ETH from the pool
7’. Users can burn, collectively, up to 5 wSHAKTI on the L2 and redeem some of the ETH from (6’) on the L1 at a slightly better price

Either way, the bridge is backed under the condition from above.

Hopefully that makes more sense. Let me know if you have comments or questions!

One question about this approach is how it compares to an alternative where the CP just atomically swaps the 5 wSHAKTI on L2 for 4.999 SHAKTI on the L1. The CP should be fine with this because it can know which state commitments will eventually be confirmed–indeed, that’s the reason it would be willing to sell slETH cheaply in your scheme.

Yep, that would be analogous to the “fast withdrawals” version of this. I totally think it’s possible for one off solutions, but I think the collateralized bridge is dominant for a couple reasons:

  1. CPs do NOT need to know what the underlying token being transferred is. They can act at a level of abstraction because they are only selling slETH. They don’t need to make the market on every single token here and there in small projects. Chains that give the best experiences to small dapps will likely be the ones that have the next wave of large blockchain adoption on them.
  2. Bridgers get access to better prices. There may not be someone to provide liquidity for these low liquidity tokens. Even if there exist liquidity providers, there may be so few that prices are terrible for bridgers. In the case of the collateralized bridge, the bridge will always have enough liquidity to suffice any bridging needs from the L2->L1. The only cost is buying the slETH, which is ideally abundant because ETH has the highest liquidity (collateral can be in any token with a price feed).

So yeah, those are a couple reasons I think this solution is better than the “fast withdrawal” solution for low liquidity tokens.

That seems useful.

In Nitro, withdrawal messages from L2 to L1 (and any other L2-to-L1 messages) are summarized in a merkle accumulator, which covers all of the messages sent by the L2 since the Nitro chain started.

It would be interesting to build a system where someone can deposit an ETH and specify a particular (messageNum, accumulatorHash) pair, and receive a token redeemable for an ETH if message number messageNum turns out to have that accumulatorHash, plus another token redeemable for an ETH if that messageNum turns out to have a different accumulatorHash.

Alternatively, one could build something like that but using (L2BlockNumber, L2BlockHeaderHash) pairs.

1 Like

So how do you ensure that security is not attacked? This situation has happened many times in 2021-2022.

What kind of attack are you suggesting? Can you say more about what kinds of attack(s) might possibly be enabled if this mechanism was deployed?