# Incorrect encoding of bytes for EIP712 digest in `TitleGraph` causes signatures generated by common EIP712 tools to be unusable

TitlesGraph.checkSignature hashed raw bytes instead of keccak256(data) per EIP712, so ethers.js signTypedData signatures never validate, breaking acknowledgeEdge/unacknowledgeEdge.

- Payout: Contest reward
- Severity: medium
- Program: Titles
- Credited: 0x73696d616f
- Disclosed: 2024-04-17
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2024-04-titles-judging/issues/74
- Library page: https://bugbountylibrary.com/r/sherlock%3A2024-04-titles%3AM-1
- Tags: domain:web3 impact:dos kind:contest platform:sherlock sev:medium tech:evm tech:solidity technique:source-review vuln:signature-replay

**Target:** TitlesGraph Solidity contract (acknowledgeEdge/unacknowledgeEdge signature check)
**Root cause:** The checkSignature modifier builds the EIP712 digest with keccak256(abi.encode(ACK_TYPEHASH, edgeId, data)) instead of hashing the dynamic bytes field first, violating EIP712 encodeData which requires keccak256(data).
**Steps:**
1. Read TitlesGraph.checkSignature: `digest = _hashTypedData(keccak256(abi.encode(ACK_TYPEHASH, edgeId, data)))`.
2. Sign Ack(edgeId,data) with ethers.js `signer.signTypedData(domain, types, value)` using data `0xabcd`.
3. Recompute digest in Foundry two ways: raw `abi.encode(ACK_TYPEHASH, edgeId, data)` vs `abi.encode(ACK_TYPEHASH, edgeId, keccak256(data))`.
4. Observe ethers.js signature matches the keccak256(data) variant, not the contract's raw-bytes variant, so validation fails.
**How found:** Compared the contract's digest reconstruction against the EIP712 spec's encodeData rule for dynamic bytes, then cross-checked ethers.js signTypedData output against both Foundry-computed digests to confirm the mismatch.
**Insight:** When auditing EIP712 signature checks, verify each dynamic field (bytes/string) is keccak256-hashed before abi.encode; cross-check the contract digest against ethers.js signTypedData output to catch spec deviations that silently break all off-chain signers.
