How ERC-8010 Works

A deep dive into the signature wrapper format and verification procedure.

Signature Wrapper Format

1

inner_signature

The original ECDSA signature (or any format the delegate contract expects). Typically 65 bytes.

+
2

context

ABI-encoded tuple: (authorization, init_to, init_data)

  • authorization: EIP-7702 signed auth tuple (chain_id, address, nonce, yParity, r, s)
  • init_to: (optional) initializer contract address
  • init_data: (optional) initializer calldata
+
3

context_length

4 bytes, uint32 big-endian. The byte-length of the context. Used to parse where the context ends and the MAGIC begins.

+
4

MAGIC

32-byte constant:

0x8010801080108010801080108010801080108010801080108010801080108010

Verification Flow

// verifyHash(address, digest, wrapped_signature)

// Step 1: Check for MAGIC
if (wrapped_signature.last32Bytes == MAGIC) {
  // ERC-8010 path: pre-delegation
  parse wrapped_signature → (innerSig, authorization, initTo, initData)

  if (account.code == 0xef0100 || delegate){
    // Already delegated → use ERC-1271
    return account.isValidSignature(digest, innerSig)
  }

  // Not yet delegated → simulate via eth_call
  return eth_call(
    authorizationList: [authorization],
    calls: [
      initTo.call(initData), // optional
      account.isValidSignature(digest, innerSig)
    ]
  )
}

// Step 2: No MAGIC → fall back to ERC-6492
else {
  return verifyErc6492Signature(address, digest, wrapped_signature)
}

Related Standards