Cross-rollup DEX with smart contracts only on the destination side

The challenge with pooling is that the pool would have to somehow own the funds on the rollup A side, and I’m avoiding the assumption that any ability to do anything other than direct single-key ownership on the rollup A side exists.

This is totally right. We cannot ban its equivalents.

Finally, I understood the meaning of your specification.

Your proposal is much more general, right, in the sense that it not only addresses the difficulties that rollups A and B might have, but any L2 (with metadata support or steganography in the low order value bits) with any other L2 (with smart contract support), and any L2 with mainchain? Basically, it’s a general purpose high speed off ramp from ‘basic’ L2’s to anything with smart contract support. Nice!

1 Like

Right, I guess that’s true! The only requirements are that (i) it must eventually be possible to create a proof of payment from the source L2 to the destination L2, and (ii) there must be a bound on how many transactions can take place in the source L2 within a particular span of time.

Write very good, very good

1 Like

Right, it could be a protection from Atomic swap fee&lock attack.
Alice and Ivan could make an agreement of an Atomic swap exchange on some chainC with available smart-contracts.
Then Alice starts a swap with coinA, and if Ivan does not send an appropriative transaction with coinB, Alice can make the punishment on chainC.

There shouldn’t be even a transaction on chainC.
Alice and Ivan can just store signed agreement, and only if one of them cheats, another party can reveal an agreement to smart-contract on chainC.

yes,but will the payment proof be difficult,since it‘s depended on merkle or SNARK.just like we know that zk rollup solution is possible, but it’s not easy. I doubt if we can have a general solution for the payment proof either.

And btw, if the payment proof can be solved, can the Ivan B account be set to transfer the fund to Alice B automatically after Ivan is proved to have do evil.

then we could, entirely on the IVAN_B side, add a mechanic by which Alice can sell her withdrawal slot to someone else. This could even be integrated with the “Ivan fast path” mechanic: after some delay (eg. this could even be 1batch) not just Ivan but anyone could route a transaction through IVAN_B to pay Alice and take over ownership of the withdrawal slot.

For this part, related scenarios can involve incentive mechanisms, like the yield farming thing.

1 Like

Hey guys, I want to work on this, but proving transactions that happened on one chain on another does not seem obvious to me, maybe you can point me to some resources to help me out ?

Hey I’ve tried checking out your GitHub in search for a technical document but your page has

for most links. I couldn’t find anything useful on Google either. Your GH profile doesn’t point to an org: Juderegev (Yoda) · GitHub

I’m not into making baseless claims but maybe a mod should look into that comment?

1 Like

You can do this with Merkle proofs.

Remember that we are talking about rollups, whose roots are committed to in the Ethereum chain. Merkle proofs can prove that a transaction or state change took place in a particular block whose root we can verify by inspecting the Ethereum base chain.

Note that this does require the rollup execution to be able to see the Ethereum base chain, but I think this is already supported functionality in many of them.

@vbuterin Does that mean cross rollup transfer can happen off chain (I only need to pay a few cents to transfer my WETH from ZkSync to Arbitrum)?

The rate on Hop exchange is just horrible now (using AMM), so I am wondering if I can just implement what you described for much less fee. Thanks!

If by “off-chain” you mean “without hitting L1”, then yes. The transfer does require a transaction on ZkSync and a transaction on Arbitrum, both of which are much cheaper than Ethereum base layer.

Thanks for the clarification! So I assume in the future for most users, it would be fiat → L2, L2 → L2, which are all very cheap. And occasionally may be L2 to other blockchain L1 if they needed?

Right, that’s definitely the goal! L1 becomes a layer for L2s to make commitments, in addition to sometimes being a place users send transactions in emergency situations if the L2 they are on breaks and they need to withdraw to L1 and re-deposit their funds to another L2 directly.

2 Likes

Could this be used for a trust-minimized BTC / ETH dex?

Smart contract on the ETH side, as described above. You’d also need a contract that tracks the canonical BTC chain.

Sketch of how an ETH contract might track the latest Bitcoin block without a trusted oracle.

Anyone can submit new BTC block headers to the contract. If the total work is higher than the currently-stored head, then the current head is replaced. Concretely the contract would store a mapping from block height > block hash.

Actually validating BTC blocks would be gas cost prohibitive. It might become possible in future if zk advances to where we can succinctly prove Bitcoin block validity. In meantime, the contract would only verify the header / PoW.

Even without tx validation, the contract has reasonable security. Posting invalid blocks with >0 confirmations still requires outrunning the valid BTC hashrate.

Finally, this BTC mirror contract lets you prove that a given Bitcoin transaction was included at a given block height. If necessary, the contract can charge a small fee for supplying those proofs, using the collected fees to incentivize people to publish new BTC blocks / compensate them for gas.

Then, to swap BTC for ETH:

  • Ivan2 is a smart contract containing ETH, Ivan1 is a BTC address.
  • Alice sends to Ivan1. If Ivan fails to send corresponding ETH, then she can withdraw from Ivan2 directly by proving her transaction to Ivan1 at some minimum block depth.

Swapping ETH to BTC works conversely. Alice sends eth to the Ivan2 contract. She can take it back n blocks later, unless Ivan posts a proof that he sent her the correct amount of bitcoin from Ivan1.

Hi all,
We are seriously considering implementing this approach (or something very similar) at ChainSafe.

There seems to be a sticking point around the proof though. I understand how access to L1 header hashes on one rollup allows for proving a transaction that occurs in any other rollup.

The issue is that I can’t find any evidence of an existing rollup that makes L1 header hashes available to the execution. Unless I am mistaken, making header hashes trustlessly available would require changing the rollup validation logic to require block producers to include them for some window in the past.

Does anyone have any further insight into this?

1 Like

I actually talked to Optimism and Arbitrum about this in the context of cross-L2 bridge work. The summary is that indeed none of them yet support L1 block hash or state root access in their present form, but there is no technical reason why it can’t be done, and I know there are either specific plans or a lot of interest in implementing it.

Until that happens, the easiest workaround is to have a contract on L1 that reads recent block hashes and makes deposit messages into the L2 passing along those block hashes at regular intervals.

2 Likes

I also talked to Optimism and Arbitrum about it a year ago when I wrote GitHub - yoavw/cross-rollup-bridge which relied on this capability to avoid the periodic L1 transactions. Arbitrum suggested that it’ll make more sense to have a higher level functionality in a precompile. If L2 only exposes the L1 state root, then each L2 transaction requires a fairly large proof. Calldata is the primary cost for rollups so it makes sense to optimize.

The suggestion was for the sequencer to still include a recent L1 state root in each batch, to be covered by fraud proofs, but then use it in the precompile to offer things such as getStorageSlot(account,slot) and getBalance(account). The proof itself doesn’t need to be in calldata.

If @Willem-ChainSafe is going to build this, then it’s worth revisiting this issue with Optimism and Arbitrum. But in the meantime a periodic L1 blockhash update via the canonical bridges should work fine.

How is fee determined? It can’t be controlled directly by Ivan, or he could make it 1 and walk away with TRADE_VALUE, but it also can’t be a fixed fee because L1 calldata costs fluctuate so Ivan’s transaction to IVAN_B could cost more than the fee. I guess IVAN_B must calculate the fee, taking L1 costs into account.

Luckily both Arbitrum and Optimism have a precompile/predeploy with the L1 gas price paid by the sequencer, but it can only be used for estimation, since calldata is compressed and I think the actual size is unknown to the contract. IVAN_B should probably overestimate fee by assuming no calldata compression.