# Partial signature replay/frontrunning attack on session calls

Sequence session calls sign each call individually; a reverted multi-call leaves nonce unconsumed, letting an attacker replay a valid subset of calls.

- Payout: Contest reward
- Severity: high
- Program: Sequence
- Credited: montecristo
- Disclosed: 2025-11-21
- Write-up quality: 8/10
- Original: https://code4rena.com/reports/2025-10-sequence#h-02
- Library page: https://bugbountylibrary.com/r/c4%3A2025-10-sequence%3AH-02
- Tags: domain:web3 impact:funds-loss impact:integrity kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:business-logic vuln:signature-replay

**Target:** Smart wallet Calls module / SessionSig session signature validation
**Root cause:** Nonce is consumed inside execute() but reverts with the whole tx on BEHAVIOR_REVERT_ON_ERROR failure, and session signatures are validated per-call hash rather than bound to the full payload, so individual call signatures remain valid after a revert.
**Steps:**
1. Build a session payload of calls [A, B, C] each signed individually via hashCallWithReplayProtection(payload, i).
2. Submit execute(packedPayload, encodedSignature); call C reverts with BEHAVIOR_REVERT_ON_ERROR, reverting the whole tx and leaving the nonce unconsumed.
3. Extract calls [A, B] and signatures [SigA, SigB] from the now-public failed payload.
4. Truncate the calls array and callSignatures array to length 2 (e.g. via assembly mstore(calls,1)/mstore(callSignatures,1)).
5. Re-submit execute() with the truncated payload and reused signatures; calls A and B execute successfully without C.
**How found:** Code reading of Calls.execute/_execute and SessionSig.hashCallWithReplayProtection: noticed nonce consumption reverts with the tx on BEHAVIOR_REVERT_ON_ERROR, and that signatures are per-call hashes rather than bound to the full payload, enabling subset replay.
**Exploitation:** Attacker observes a failed multi-call session (or frontruns it in mempool), reuses the still-valid per-call signatures to execute only the profitable subset of calls, e.g. executing only the WETH->WBTC swap leg and then arbitraging WBTC->WETH, or griefing the legitimate session by consuming the swap.
**Escalation:** Mempool frontrunning of multi-call sessions to selectively execute a profitable subset before the legitimate full payload, causing financial loss or griefing.
**Insight:** When signatures are per-call and nonce consumption is coupled to execution success, a reverted batch leaves every individual call signature valid; check whether signature scope matches the full payload and whether nonce is committed before any revertible execution.
