Repository navigation
Description
Description
MultiSigDeleGator accepts only EOAs as signers:
- The initializer,
addSignerandreplaceSignerrevert withInvalidSignerAddresswhen the new signer has code (initializer, addSigner, replaceSigner). _isValidSignatureaccepts only ECDSA signatures.
As a result, any account that validates its signature through ERC-1271 (isValidSignature) instead of ECDSA cannot be a signer today. This rules out:
- Another
MultiSigDeleGator(a nested multisig). - A
HybridDeleGator, for example a user who signs with a passkey. - An EOA that already has EIP-7702 code, for example one upgraded to
EIP7702StatelessDeleGator. - Any other smart contract wallet that implements ERC-1271.
The EIP-7702 case is also inconsistent. The code check runs only when a signer is added. An EOA that already has EIP-7702 code is rejected. An EOA that gets EIP-7702 code after it was added stays a signer and keeps signing with ECDSA.
Proposal
Accept smart contract accounts as signers and check their signatures with ERC-1271. EOA signers keep using ECDSA. One multisig signature can contain both.
Use cases
- Nested groups. Boards, DAOs or family trusts where one member is itself a group. For example, a 2-of-3 team multisig is one signer of a 3-of-5 treasury multisig.
- Passkey users. A member who signs with a passkey through a
HybridDeleGator. - EIP-7702 users. A member whose EOA is upgraded with EIP-7702 can be added at any time, not only before the upgrade.
Context
The EOA-only rule was added on 2024-07-07 (874329e). EIP-7702 was then a two-month-old draft, and "has no code" was a reliable way to tell an EOA from a contract. Since then, this repo added its own EIP-7702 account, EIP7702StatelessDeleGator (2025-01-31, d522a38), and EIP-7702 went live on Ethereum mainnet with Pectra (2025-05-07). An EOA can now have code, so the check no longer reliably tells EOAs and contracts apart. This causes the inconsistency described above, and is one more reason to revisit the rule now.
Accepting only EOAs was a deliberate design choice. The contract documents that signers "MUST be EOAs" (NatSpec), and a test checks that a DeleGator is rejected as a signer (test).
I have a working implementation with tests and docs, and will open a PR shortly after this issue. If there are other reasons for the EOA-only rule, I am happy to address them, change the approach, or close both.
Technical Details
- Signer management (the initializer,
addSignerandreplaceSigner) accepts smart contract accounts.address(0)and the DeleGator's own address are rejected. - One multisig signature can combine ECDSA signatures from EOA signers and ERC-1271 signatures from contract signers. The current rules stay: exactly
thresholdsignatures, sorted by signer address. - Existing ECDSA signatures stay valid, so existing multisigs and clients keep working.
- Existing proxies can upgrade without a storage migration.
- A contract signer that rejects the signature, or fails, makes the whole multisig signature invalid. Validation reports this as an invalid signature and does not revert.
Trade-offs
- Trust in signer code. A contract signer's approval depends on its own validation logic, and that logic can change, for example through a proxy upgrade or a new EIP-7702 delegation. Only the signer's own controller can make such changes, so trust stays with the signer. But the multisig no longer decides how each approval is checked.
- Security-sensitive scope. Signature validation becomes more complex and calls external contracts.
- Cost for EOA signers. Validation must tell EOA and contract signatures apart. Depending on the signature encoding, this can add a cost to multisigs that use only EOA signers.
Limitations
- ERC-4337 bundlers. This proposal targets EntryPoint v0.8 and later. Some contract signers, such as a nested
MultiSigDeleGatoror aHybridDeleGator, read their own storage to validate a signature. The bundler validation rules (ERC-7562) do not allow this for unstaked accounts, so public mempool bundlers reject such UserOps. The EntryPoint v0.8 release notes extend this storage access to all staked entities (see References). Unstaked accounts with such signers need a stake or a private bundler, also after the upgrade. Delegation redemption is not affected. - Gas per contract signer. Each contract signer, and each nested level, adds validation gas.
- Signers that are not deployed yet. A contract signer must be deployed before it can sign. Support for ERC-6492 can be a follow-up.
Acceptance Criteria
- Existing EOA-only multisigs accept and reject the same signatures as before.
- An EOA signer that gets EIP-7702 code after it was added can still sign with a plain ECDSA signature.
- A smart contract account can be set as a signer with the initializer,
addSignerandreplaceSigner.address(0)and the DeleGator's own address are rejected. - One multisig signature can mix EOA and contract signers. It still needs exactly
thresholdsignatures, sorted by signer address. - If a contract signer's
isValidSignaturereverts, returns no data or returns anything other than0x1626ba7e, the multisig signature is invalid. The multisig's ownisValidSignaturethen returns0xffffffffand does not revert. - Existing proxies can upgrade to the new implementation without a storage migration.
documents/MultisigDeleGator.mddescribes the signature format for contract signers, and the trade-offs and limitations above.- Tests cover the scenarios below.
Scenario: nested multisig
- GIVEN a 2-of-3
MultiSigDeleGatorRootwith signers Alice (EOA), Bob (EOA) andSub - AND
Subis a 2-of-2MultiSigDeleGatorwith signers Carol (EOA) and Dave (EOA) - WHEN Alice signs a hash
- AND Carol and Dave sign the same hash for
Sub - THEN
Root.isValidSignatureaccepts the combined signature
Scenario: contract signer fails
- GIVEN a
MultiSigDeleGatorRootwith a contract signerFaulty - AND
Faulty.isValidSignaturereverts, which ERC-1271 allows for an invalid signature - WHEN a multisig signature for
Rootincludes an entry forFaulty - THEN
Root.isValidSignaturereturns0xffffffff(invalid signature) and does not revert
Scenario: EIP-7702 account as signer
- GIVEN an EOA upgraded with EIP-7702 to
EIP7702StatelessDeleGator - WHEN it is added with
addSigner - THEN the call succeeds
- AND a signature from this account counts as one of the
thresholdsignatures
References
- ERC-1271: Standard Signature Validation Method for Contracts
- EIP-7702: Set Code for EOAs
- EntryPoint v0.8 release notes, item 13b: "Allow storage access for all staked entities".
- Safe: smart account signatures: prior art. Safe multisigs accept both EOA and contract owners.
Activity