# Replay attack (EIP712 signed transaction)

Biconomy SmartAccount validates nonces[batchId] but not batchId itself, letting an attacker replay a signed EIP712 transaction under a different batchId with the same nonce.

- Payout: Contest reward
- Severity: high
- Program: Biconomy
- Credited: Tointer
- Disclosed: 2023-03-03
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2023-01-biconomy-findings/issues/36
- Library page: https://bugbountylibrary.com/r/c4%3A2023-01-biconomy%3AH-07
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:signature-replay

**Target:** SmartAccount.sol execTransaction / EIP712 signed meta-transaction
**Root cause:** execTransaction checks nonces[batchId] but the batchId is not part of the signed hash in encodeTransactionData, so any batchId sharing the same nonce value accepts the same signature.
**Steps:**
1. Build a SafeTransaction transferring tokens with nonce = getNonce(0).
2. Sign it via safeSignTypedData to get EIP712 signature.
3. Call execTransaction(tx, batchId=0, refundInfo, signature) — succeeds, nonces[0] increments.
4. Call execTransaction with same tx/signature but batchId=1 (nonce still 0) — succeeds again, replaying the transfer.
**How found:** Code reading of execTransaction: noticed nonces[batchId] is checked but batchId is absent from the EIP712 hash, so distinct batchIds with equal nonce accept the same signature.
**Exploitation:** Attacker observes a signed user transaction and resubmits it with a different batchId whose nonce equals the original, causing the same transfer/action to execute repeatedly; first transaction (nonce 0) is replayable unlimited times since 2^256 batchIds share nonce 0.
**Insight:** When a nonce is keyed by an ID, verify the ID itself is bound into the signed digest; otherwise any sibling ID sharing the nonce value becomes a replay vector, and nonce-0 batches are effectively infinite.
