This repository demonstrates how EIP7702 can allow a user to delegate a cross chain action via an ERC7683 order.
ERC7683 generally supports a cross-chain user flow where the user can create an intent on an origin chain containing call data to be executed on a destination chain. This destination chain execution should be funded by assets deposited on the origin chain.
This 7683 intent can be combined with an EIP7702-compatible smart contract wallet deployed on the destination chain to allow the destination chain calldata execution to look like it was sent from the user's EOA, instead of from the smart contract wallet address.
This repository contains contracts and scripts demonstrating this flow.
- User signs destination UserOp (
UserOp = [{calldata, target},{},...]
). - (optional) User signs destination 7702 delegation.
- User creates 7683 order containing 1 & 2.
- User sends
open
transaction on origin chainOriginSettler
5 Relayer sees 7683 order. - Relayer sends fill on destination chain
DestinationSettler
- If fill requires user delegation to be set up, relayer must include this in their fill txn, which should be a type 4 txn.
- Fill sends the funds to the user’s EOA.
- Fill calls
XAccount.xExecute
on user’s EOA with the UserOp - User’s EOA performs UserOp.
- If fill is submitted successfully and as user ordered in 7683 order, filler gets refund
OriginSettler
: Origin chain contract that user interacts with to open an ERC7683 cross-chain intent. Theopen
function helps the user to form an ERC7683 intent correctly containing thecalldata
that the user wants to delegate to a filler to execute on the destination chain.- The
open
function also optionally lets the user include a 7702 authorization that the user wants the filler to submit on-chain on their behalf. This can be used to allow the user to set thecode
of their destination chain EOA to theXAccount
contract. - In the 7683 order, includes the 7702 authorization data and the destination chain calldata in a
FillInstruction
- The
DestinationSettler
: Destination chain contract that filler interacts with to fulfill a ERC7683 cross-chain intent. Thefill
function is used by thefiller
to credit the user's EOA with any assets that they had deposited on theOriginSettler
when initiating the 7683 intent and subsequently execute anycalldata
on behalf of the user that was included in the 7683 intent.- The
fill
function will delegate execution ofcalldata
to theXAccount
7702-compatible proxy contract so it is a prerequisite that the user has already set their destination chain EOA'scode
toXAccount
via a 7702 transaction. The authorization should submitted by the user or delegated to the filler to set. - As stated above, the
OriginSettler#open
function can be used by the user to include a 7702 authorization to be submitted by the filler on the destination chain. This way the user can complete the prerequisite 7702 transaction and delegate thecalldata
execution in the same 7683 intent.
- The
XAccount
: Destination chain proxy contract that users should set as theircode
via a 7702 type 4 transaction. Verifies that any calldata execution delegated to it was signed by the expected user.
- Relayer that will pick up 7683 order and fill it on destination.
The main architecture decision we made was whether to place the destination chain signature verification logic in the DestinationSettler
or the XAccount
contract. By placing this in the latter, we are implicitly encouraging there to be many different types of destination chain settlement contracts, that offer different fulfillment guarantees and features to fillers, that all delegate UserOp execution to a singleton XAccount
contract. The user needs to trust that XAccount
will do what its supposed to do.
The alternative would be to instead encourage that the DestinationSettler
contract is a singleton contract that should be trusted by users. Any fulfillment logic enforced in the settlement contract would be shared across all users. This would make the XAccount
contract much simpler. We decided against this as we believe there are opinionated settlement contract features that would greatly improve user and filler UX but that we didn't want to include in a singleton contract.
For example, the settlement contract should ideally protect against duplicate fulfillment of the same 7683 order and simultaneously allow the user to protect fillers from colliding fill transactions. These features would require the fill
function on the settlement contract to include parameters like exclusiveRelayer
and enforce logic like checking if fillStatuses[fillHash] = true
. But, we believe there are strong arguments for why these features are opinionated and do not belong in a generalized DestinationSettler
contract.
This best-practices document was very useful in guiding design of XAccount