-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: hashed cross domain submarine sends #226
base: main
Are you sure you want to change the base?
Conversation
|
||
We can take inspiration by replicating a commit / reveal scheme for data sent between chains. Enabling cross chain transactions between contracts where the intent remains hidden until the reveal on the destination chain. | ||
|
||
Unlike [Submarine Sends](https://libsubmarine.org/) which also provides the ability to make the commit transaction indistinguishable from a normal value transfer, the funds and commitment have to be accounted for and propogated through the `L2ToL2CrossDomainMessenger` which can allow for an external entinty to differentiate between a hashed cross domain submarine send and not. However this is not a problem since DeFi attacks rely on understanding the intent of the transaction which we show remains masked. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: entinty
-> entity
bytes32 commitment = keccak256(payload) | ||
``` | ||
|
||
By posting just the commitment, **only the the submitting user with knowledge of the preimage would be able to reveal the transaction** when relaying. If this user encounters issues between submission and relay, the preimage for that data is also lost. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: only the the submitting
-> only the submitting
|
||
By sending the commitment hash between L2s via the L2ToL2CrossDomainMessenger, we gain the ability to privately send transactions. However, submarine sends are typically accompanied with funds with the transaction. i.e Bridge and Swap. | ||
|
||
The SuperchainTokenBridge & ETH bridge are designed as single cross chain messages. Thus the cross domain submarine contract needs to be able to receive and escrow sent funds prior to excuting the reveal transaction. Thus, a cross domain submarine transaction requires 2 relays on the destination |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: prior to excuting
-> prior to executing
2. Relay message the propogated commitment and details about funds owed to the target. | ||
|
||
Sample snippet on how this can work for ETH. Generalizable to SuperchainERC20s | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not entirely sure, but it sounds like apps will basically have one submarine contract per chain per app, and they will do submarine sends via this one submarine contract. If this is true (pls confirm), then what happens when there is a race condition on the token amount / swap? e.g. if two users send ETH (from same or diff chain) to the same submarine contract on the one chain, users can have their onward transaction processed out of order. Or is there a baseline assumption that interop txns will be ordered?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good q!
Yep just like how apps integrate with the SuperchainTokenBridge or L2ToL2CrossDomainMessenger, they can integrate with this. Probably would have a handler contracts on both sides that integrates with the DEX
This design retains the same ordering properties of the token bridge and messenger. There is no enforced ordering. Relayers can relay messages in whatever order they would like.
Since the submarine sender specifies the relayer ahead of time (labs likely would provide a public goods one). I would imagine here we would prolly relay in order as much as possible. However this would not be enshrined in the sumbarine contract.
If you wanted to enforce ordering though, you could do that in the handler contract. what are your thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally ordering should be enforced on the protocol level because any sort of cross chain action that involves an initial token transfer followed by some defi action would have this race condition, meaning each protocol would have to implement this logic. It could be as simple as having certain messages be contingent on a transfer (so until your token transfer passes, we cannot progress). I think this is something hyperlane is going to implement.
Re: the submarine send contract, it would make sense if this could be wrapped together with an interchain account router type feature, as it would mean that crosschain features that require no new contracts could just involve a crosschain transfer followed by multicalls to execute the remainder of the defi logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because any sort of cross chain action that involves an initial token transfer followed by some defi action would have this race condition
Maybe I misunderstood. The ordering for this part is enforced. The hashed defi action cannot occur before the funds are available in the destination. And this can be batched together so that it does not require separate txs.
Ordering for that is enforced here:
// Ensure delivery before marking the commitment as pending
require(messenger.successfulMessages(sentETHMsg));
The ordering that is not enforced is between two unrelated submarine actions.
Can you elaborate on the interchain account feature here? The sender is agnostic of any particular target
. So it would be compatible with any crosschain action
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I misunderstood. The ordering for this part is enforced. The hashed defi action cannot occur before the funds are available in the destination. And this can be batched together so that it does not require separate txs.
Got it, then that's fine. If the transactions are always batched or at least dependent on a prior txn, then race conditions are not an issue.
Can you elaborate on the interchain account feature here? The sender is agnostic of any particular target. So it would be compatible with any crosschain action
The interchain account router allows you to chain arbitrary calls on the destination, e.g. on receiving funds, the contract can swap them for a different asset, and then deposit them into a contract (or something like that). My expectation is that most users that use interop will want the ability to do something like this at least initially, and it would not make sense for each protocol to deploy their own multicall as the recipient of the instructions (i.e. it should be folded into the interop contracts). Does that kind of make sense?
This means that when interop ships, it would be easy for an app developer to create a webapp/contract that allows users to bridge cross chain then do things on other chains, without having to deploy any contracts on other chains at all. They could craft payloads that they can submit on any origin chain, which could be executed on any destination chain against any contracts that already exist on that chain.
Of course, as protocols more heavily integrate interop, this will become less relevant. But at least it lessens the barrier to doing things crosschain on day 1.
|
||
The salt can ensure commitments are always unique. However it is the responsibility of the dapp to ensure this. It's already unlikely in DeFi that calldata might be the exact same as they depend on token inputs and minimum expected outputs. And even if they are the same, they must be pending during the same time window. | ||
|
||
However an attacker that realizes that a dapp is using the same salt could try to fontrun some expected (target,message) combos with submarine sends that where the target always fails. All this would achieve in the current sample code snippet is halting delivery of submarine sends with the same commitment (already unlikely). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: fontrun
-> frontrun
|
||
By posting just the commitment, **only the the submitting user with knowledge of the preimage would be able to reveal the transaction** when relaying. If this user encounters issues between submission and relay, the preimage for that data is also lost. | ||
|
||
To solve for this, the payload is encrypted and posted as calldata to the submitting transaction. By using ECDH, Elliptic Curve Diffie-Hellman, the data can be encrypted against any public key, allowing for the user to designate a 3rdparty to conduct the relay on their behalf. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest leaving this preimage posting unspecified. If a user wants to post it encrypted onchain they can, but many implementations may prefer an out of band dissemination
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea that's a good point! This all can be encoded as opaque bytes represented with 1 argument. Everything else should be good
|
||
We can take inspiration by replicating a commit / reveal scheme for data sent between chains. Enabling cross chain transactions between contracts where the intent remains hidden until the reveal on the destination chain. | ||
|
||
Unlike [Submarine Sends](https://libsubmarine.org/) which also provides the ability to make the commit transaction indistinguishable from a normal value transfer, the funds and commitment have to be accounted for and propogated through the `L2ToL2CrossDomainMessenger` which can allow for an external entinty to differentiate between a hashed cross domain submarine send and not. However this is not a problem since DeFi attacks rely on understanding the intent of the transaction which we show remains masked. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: propogated
=> propagated
Description
Provide a public utility to conduct hashed cross domain sends, primarily for DeFi applications.