This repository has been archived by the owner on Nov 29, 2023. It is now read-only.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Cross chain execution and payments via UserOps #1
Cross chain execution and payments via UserOps #1
Changes from 9 commits
4689e09
4644179
8babf50
c7bcf39
b917704
66dbb9c
473e08c
bf20e33
aebbd8b
36259fe
c4829f5
fd2842d
a9545dc
437c20f
3cc0fa4
694d432
7be2234
7d74d7c
a1e230c
ded0c82
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
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.
Curious if this is necessary -- should we have had this check before? Should all 4337 wallets have this check?
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.
It also seems to be replicated below?
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.
This is needed since we want to enforce that
crossChain
is only triggered through submitting a UserOp. Otherwise anyone could call withcrossChain
, using a transaction from an EoA, and whateverPaymentChainInfo
orExecutionChainInfo
they wanted. Sincechallenge
is allowed to be called at any time, someone could callcrossChain
with a bogus unsigned state and trigger a challenge using that.It depends on the function and the 4337 wallet! In a lot of cases there will be functions restricted to only some
owner
orentrypoint
(IE: A function to send user funds)This allows the owner of the wallet to call the function using either an EoA account or through submitting a
UserOp
.In our case we need to be a bit stricter, we only want to trigger
crossChain
if aUserOp
has been submitted signed by all the participants. We're relying on the signature validation of the UserOp to protect the call tocrossChain
.I think that's in a separate
execute
function, which can be triggered outside ofcrossChain
. So we need to implement the check in both functions.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.
The ERC 4337 spec specifies that the wallet
SHOULD return SIG_VALIDATION_FAILED (and not revert) on signature mismatch
, so I've changed this from arevert
to returnSIG_VALIDATION_FAILED
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.
Could the structs be renamed to
PaymentInfo
andExecuteInfo
for simplicity? Or does the use ofChain
in those names help clarify what they are?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 think the use of
Chain
helps clarify that info in these structs is specific to a given chain, and should only be honoured on that chain. I don't feel too strongly about it though so I'm happy to change it if others feel differently.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.
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.
Are you replacing the hashlock mechanism with signatures, or just adding to it?
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.
What do you mean by "broadcast it" in this context? Where are Bob and Irene sending the signed
UserOp
?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.
In this example we are replacing the hashlock mechanism, since we're making a cross-chain payment that doesn't use HTLCs.
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.
Broadcast in this case just means send it to the other parties. Bob is broadcasting the state to Alice and Irene, Irene is sending to Alice and Bob.
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.
Can you expand on the scare quotes around "atomic"?
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'm not sure if atomic is the correct word, but I'm trying to describe that once the UserOp is fully signed, we can be guaranteed that the execution can be triggered on either chain.
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.
When we go beyond a single hop, we have "intermediary-intermediary" channels. Is this a bit awkward with the "owner" / "intermediary" roles of the bridge wallet? Will one of the parties just arbitrarily take the role of "owner"?
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 think right now it might be a bit awkward, as once intermediary would play the role of the
owner
and one intermediary would play the role ofintermediary
in the BridgeWallet.To solve this we could implement a specific Intermediary<->Intermediary mode (or separate contract?) for the BridgeWallet that handles the "intermediary-intermediary" use case.
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.
This feels a little suboptimal. I suppose the entrypoint has not been designed with cross chain applications in mind, meaning that we have to make multiple hashes and a signature on each one (and as you say validate all of those combinations).
A "cross chain entrypoint" would ease this, but would be a departure from 4337 norms (I guess?).
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.
With this change I don't think it's too bad. Now instead of generating a unique hash for each chain, all participants just sign the hash based on the first chain. This means we can generate one hash and check all the signatures against that.
I think it's safe to have everyone sign the same
UserOpHash
since we perform a separate check on the chainId and entrypoint based on the calldata in theUserOp
. If you try submitting the UserOp, it will only work if the chain and entrypoint match aExecuteChainInfo
orPaymentChainInfo
.So the cost of
validateCrossChain
would be generating one hash, and then checking 2 signatures for everyBridgeWallet
involved. IE: If we have a multi-hop UserOp with Alice,Irene,Iris,Bob we'd expect theUserOp
to have the following signatures:[AliceSig,IreneSig,IreneSig,IrisSig,IrisSig,BobSig]
. We'd generate one hash and check the6 signatures against that hash.It would also be an easy optimization to omit or skip duplicate signatures so we could get the cost down to generating one hash and checking 1 signature per participant.
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.
Great job anticipating this 👏