feat(swap): support EIP-7702 wrapping delegates (ERC-7739 / MA v2) for CoW orders#2984
Closed
mgrabina wants to merge 1 commit into
Closed
feat(swap): support EIP-7702 wrapping delegates (ERC-7739 / MA v2) for CoW orders#2984mgrabina wants to merge 1 commit into
mgrabina wants to merge 1 commit into
Conversation
…r CoW orders Three-way wallet branching in the CoW swap flow: - contract -> setPreSignature on-chain (unchanged) - delegated-eoa-wrapping -> EIP-1271 off-chain via customEIP1271Signature - eoa / delegated-eoa-plain -> EIP-712 off-chain (unchanged) New `classifyAccount` helper (src/helpers/eip7702.ts) vendored from the cow-sdk proposal in cowprotocol/cow-sdk#878; drop when upstream merges. Inspects on-chain code for the canonical 23-byte 0xef0100 marker and looks the delegate up in a `WRAPPING_DELEGATES` allowlist. The allowlist is empty today, so the new wrapping branch is unreachable until populated. New `sendOrderForWrappingDelegate` in cow/orders.helpers.ts uses `tradingSdk.postLimitOrder` with `additionalParams.signingScheme: SigningScheme.EIP1271` and a `customEIP1271Signature` callback that forwards the wallet's raw signTypedData bytes verbatim — no `(order, sig)` ABI tuple wrap. CoW resolves verification via `isValidSignature` on the EOA, which EIP-7702 dispatches to the delegate. Production behavior is unchanged the day this lands. The new path activates only once known wrapping delegates are added to the allowlist (Alchemy MA v2, ZeroDev Kernel v3, Biconomy Nexus, etc.). Reviewed with codex; no blocking compatibility issues.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
📦 Next.js Bundle Analysis for aave-uiThis analysis was generated by the Next.js Bundle Analysis action. 🤖 This PR introduced no changes to the JavaScript bundle! 🙌 |
Contributor
Author
|
Superseded by cow-sdk-side auto-routing (no interface-v3 changes needed). New cow-sdk PR will detect wrapped sigs by byte length in |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
contract->setPreSignatureon-chain (unchanged)delegated-eoa-wrapping-> EIP-1271 off-chain viacustomEIP1271Signature(new)eoa/delegated-eoa-plain-> EIP-712 off-chain (unchanged)Why now
Production EOAs are increasingly running 7702 delegates. The dominant delegate today (Metamask Smart Account) returns raw ECDSA from
signTypedData_v4and works via the existing EIP-712 path. Delegates that force ERC-7739 / ERC-7579 wrapping return non-65-byte bytes that don'tecrecoverto the owner — CoW's EIP-712 path rejects them. This PR routes those orders through EIP-1271 instead, with the bytes forwarded verbatim to CoW'sisValidSignaturecheck on the EOA address (which EIP-7702 dispatches to the delegate).Cross-repo coordination
classifyAccount+signOrderForWrappingDelegatehelpers. This PR vendors them insrc/helpers/eip7702.ts; swap to the upstream import once the cow-sdk PR merges and ships in a release.What changed
src/helpers/eip7702.ts(new) —classifyAccount(user, provider)returns'eoa' | 'delegated-eoa-plain' | 'delegated-eoa-wrapping' | 'contract'based oneth_getCodeand aWRAPPING_DELEGATESallowlist (empty today). Vendored from cow-sdk PR until upstream releases.src/components/transactions/Swap/helpers/cow/orders.helpers.ts— addssendOrderForWrappingDelegatethat callstradingSdk.postLimitOrderwithadditionalParams.signingScheme: SigningScheme.EIP1271and acustomEIP1271Signaturecallback. The callback usesOrderSigningUtils.signOrderto do typed-data signing; the wallet wraps internally per its delegate's spec, and the resulting bytes are forwarded verbatim (no(order, sig)ABI tuple wrap, unlike the SDK's default EIP-1271 path).src/components/transactions/Swap/actions/SwapActions/SwapActionsViaCoW.tsx— replaces the existingisSmartContractWallet ? presign : sendOrderbinary with the three-wayclassifyAccountbranch.Backwards compatibility
isSmartContractWallethelper atsrc/helpers/provider.tsis untouched and still consumed byuseUserContext,useGetConnectedWalletType,useSwapTokenApproval, andorders.helpers.ts(for the EOA-onlysendOrderguard).delegated-eoa-wrappingtriggers new code, and that branch is gated on the empty allowlist.Codex backwards-compat review
Ran
codex execagainst the diff. Findings:src/helpers/eip7702.tswas untracked at audit time; now committed in this push.classifyAccountis stricter than the legacyisEip7702EOA(drops thecode === accountfallback the legacy helper had). Standard EIP-7702 delegation behavior is preserved per the spec.OrderSigningUtils.signOrderhas v3/eth_signfallbacks on RPC errors; once wrapping delegates are populated, this path depends on those delegates supporting the typed-data flow (expected).customEIP1271Signaturetype matches our callback signature; default(order, sig)ABI wrap is correctly bypassed when the callback is provided.Verification
./node_modules/.bin/tsc --noEmit -p tsconfig.json: clean./node_modules/.bin/prettier ... --check: cleanRelated Linear: SDK-823.