Skip to content

Learn

Crypto Spot Research

Replay domains: an address match does not bind a signed action

An address can be identical across networks while a signed action belongs to a particular replay domain. To investigate authorization, inspect what was signed and what the verifier checks. A matching address, wallet label or token symbol does not establish that two signed objects authorize the same action.

Keep legacy transaction protection separate from message-signature protection. EIP-155 explains one transaction encoding; it is not a rule for interpreting every signature field named v.

Classify the signed object first

EIP-155, Specification, adds chain identity to the legacy transaction signing payload and describes the corresponding v encoding. The source also retains the older v = 27 or 28 scheme in its stated rules. Record the actual transaction format and network rules instead of treating every older-style signature as automatically impossible.

A typed transaction has its own envelope and fields. A permit is a signed message verified by a token contract. An arbitrary offchain document can use another hashing convention entirely. Do not apply the legacy transaction arithmetic until the object has been identified as using that encoding.

Save raw signed payload, decoded fields, network identity and the parser version. An explorer’s decoded chain name is an interpretation worth checking against the bytes and selected chain context.

A hypothetical legacy decoding table

For the protected legacy encoding, v = 35 + 2 × chainId + parity, where parity is 0 or 1. Thus chainId = floor((v − 35)/2), with parity recovered from the remainder, when the field belongs to that encoding.

vEncoded chainIdParityInterpretation under this encoding
3710Protected legacy payload names chain 1
3811Same chain, other recovery parity
3920Payload names chain 2
4021Same chain, other recovery parity
27 or 28Not encoded this wayOlder conventionDo not label the missing chain field as chain 0

The first calculation is 35 + 2 × 1 + 0 = 37; changing parity gives 38, not another chain. These hypothetical decoding exercises do not authenticate a real transaction or identify which chain supplied a particular RPC response.

A common parsing mistake is applying the same formula to a typed transaction’s 0-or-1 parity. It produces meaningless negative arithmetic because the wrong format was selected. Correct classification precedes calculation.

A permit signature has another domain record

ERC-2612, Specification and Security Considerations, describes a typed permit digest using DOMAIN_SEPARATOR and permit fields. It explains a domain unique to contract and chain, gives a common domain construction and notes chain-split issues for a separator fixed at deployment.

For a supplied permit, retain the actual domain fields and separator used by the token implementation. The familiar construction can include name, version, chainId and verifyingContract. Its documented example is not permission to assume every implementation uses identical fields or updates its separator identically.

Assume fictional token T’s supplied permit message names chain 1 and verifying contract T. Its ECDSA signature may carry a recovery value using the 27-or-28 convention. That does not erase the chain identity inside the signed message’s domain. Conversely, reading 37 from an outer transaction does not prove that a separate embedded message has an adequate domain.

Preserve the two signed objects independently: outer transaction bytes and permit digest inputs. A transaction paying to submit a permit can be correctly chain-bound while the contract’s message verification has different replay properties.

Test domain changes without making an execution claim

Reconstruct the original message digest according to the actual implementation. Then compare the digest construction for a changed chain field or verifying-contract address. Keep all other fields fixed. Where those fields are included correctly, the domain bytes and resulting signed digest change.

This is a check on signed scope, not a demonstration that an alternate submission would succeed or fail on every network. The verifier’s deployed logic, nonce, deadline, account state and other eligibility conditions still matter. Do not broadcast an action to make the research result concrete.

When the decoded domain disagrees with a readable wallet prompt, preserve both artifacts. Determine whether the prompt omitted fields, the parser used the wrong schema or the implementation actually verifies another digest. Do not replace the bytes with the more reassuring display.

Boundary case: two environments share an identifier

A chain-ID field is a namespace component, not a cryptographic certificate of an entire chain’s identity. Two environments with the same identifier can require further separation through verified chain context and application design. Matching addresses and domain fields alone do not establish independent authorization boundaries.

The ERC-2612 source’s cached-separator warning illustrates why a chain split needs implementation-specific review. Record whether the verifier reconstructs relevant domain data or continues to use a stored value. Do not infer current behavior from how a deployment was originally described.

Also distinguish replay scope from asset identity. A perfectly chain-bound signature for one token contract does not prove another same-symbol token has equivalent backing or redemption rights. That is a separate provenance question.

Use a two-column digest worksheet for comparisons. In the first, preserve the original typed content and actual domain; in the second, change exactly one proposed boundary field and mark every other field unchanged. If both chain and contract are changed together, a different digest does not reveal which binding was present. Change-one-field checks expose omissions that a plausible recovered address can conceal.

When a chain field is unavailable, classify it as unavailable rather than assigning the interface’s currently selected network. The user can change an interface selection after signing. The signed bytes and the verifier’s actual domain construction determine scope, while the current screen is only contextual evidence.

A signed-scope checklist

ActionPreserveMistake prevented
Identify object formatRaw envelope, message type and parserApplying legacy-v arithmetic to every signature
Decode transaction domainSigned chain field and recovery conventionTreating parity as a separate network
Reconstruct message domainActual separator and typed fieldsAssuming the outer transaction protects the message
Match verifierNetwork, contract and historical codeUsing today’s implementation for an older signature
Check eligibility separatelyNonce, deadline and relevant stateCalling domain matching completed execution
Preserve chain contextIndependently selected chain identityTreating a shared numeric ID as complete authentication

Reopen the record after a parser correction, implementation change, chain split or conflicting domain reconstruction. Publish exactly which replay domain was authenticated for which signed object. The conclusion should remain narrower than a blanket claim that chain IDs prevent every reuse or that the same address establishes the same rights everywhere.

FAQ

Does v = 27 in a permit prove it has no chain protection?

No. Its message domain can include chain identity separately. Inspect the actual signed digest and verifier.

Does v = 37 identify every type of signed message as chain 1?

No. That decoding applies to the specified protected legacy transaction encoding, not arbitrary messages or other envelopes.