The proposal looks awesome! We worked on a very similar set of contracts under the name of “Sequence”, in short is pretty much the same system, with the key difference that handleOp
and verifyUserOp
are bundled together on the same execute
function. The relayer has to simulate this execute
function with a fixed amount of gas and see if it’s going to get paid or not before sending the transaction.
The contracts are here: https://github.com/0xsequence/wallet-contracts
The cool thing is that our system could be upgraded to support this new standard, after all wallets are upgradable, and we could split our execute
function into verifyUserOp
and handleOp
.
The only roadblock I see is that we already have our own “Wallet factory”, it uses CREATE2 in pretty much the exact same way ERC4337 does (https://github.com/0xsequence/wallet-contracts/blob/master/src/contracts/Factory.sol) and wallets are indeed counter-factual, but afaik ERC4337 wallets must be created using the EntryPoint
contract as factory. Thus our wallet addresses couldn’t benefit from the initCode
property on the relayer network, because the resulting addresses would be different.
I wonder if this is an implementation detail or something by design, because by allowing contracts as wallet factories we could allow existing smart contract wallet implementations to be retrofitted without having to re-deploy all counter-factual accounts. I imagine this issue affects not only Sequence but also Gnosis, Argent, etc.
A possible solution could be to split initCode
into two fields: initCode
and initAddress
, the creation of the wallet involves calling initAddress
with initCode
as data, after that EntryPoint
could validate if the account address now contains code.
The trusts assumptions are the more or less the same, and any restrictions put on initCode
(call external contracts, use timestamp, etc) could also be applied to initAddress
.