# Signed payload replay without nonce binding

Signature or vote tally reused after state change; check nonce, chain and state binding

_Area: Smart contract access control and control flow. Seen in 3 disclosed reports; latest 2025-02-24. Updated 2026-10-25._

## How it works
A signature (or a threshold tally) is treated as a one-time authorization, but nothing in the verified payload ties it to a single use. The contract checks that the signer approved *some* message, then mutates state. If the same message can be presented again — because no nonce is consumed, no chain/contract binding exists, or the tally is reset — the authorization is replayed. The broken assumption: "a valid signature means this action has not happened yet."

## Where it shows up
- Signature verification paths with no nonce, no consumed-signature mapping, no chainId/verifying-contract in the signed hash.
- State transitions that can return to a prior value (approve/unapprove, order change, completion reset), leaving old signatures valid.
- Library or helper functions missing the caller/state guard the main contract applies (e.g. a missing `onlyActive`-style modifier).
- EVM reimplementations that skip `SetNonce` on some branch, or reset nonce only for contract creation [E2](https://bugbountylibrary.com/r/c4%3A2024-11-nibiru%3AM-07.md).
- Multisig tallying that clears votes before/around the external call, so same-block votes re-reach threshold [E3](https://bugbountylibrary.com/r/c4%3A2023-07-axelar%3AM-07.md).

## How to review
Identify every signed payload and ask: what makes this signature single-use? The invariant: each authorization must be consumable exactly once, bound to chain, verifying contract, and the current state it authorizes. Check that a nonce or executed-hash is marked before any external call, and that reverting state cannot revive an old signature. For EVM ports, diff nonce handling branch-by-branch against geth's state transition; every branch must increment the sender nonce [E2](https://bugbountylibrary.com/r/c4%3A2024-11-nibiru%3AM-07.md). For threshold logic, confirm the tally is cleared atomically with execution and cannot be re-satisfied by concurrent votes [E3](https://bugbountylibrary.com/r/c4%3A2023-07-axelar%3AM-07.md). Confirm helper/library entry points enforce the same guards as the main path [E1](https://bugbountylibrary.com/r/c4%3A2022-08-rigor%3AH-04.md).

## Variants seen
- Signature reuse across state changes with no nonce in escrow order/completion flows [E1](https://bugbountylibrary.com/r/c4%3A2022-08-rigor%3AH-04.md).
- Missing modifier on a library function allowing out-of-band state reset that re-enables replay [E1](https://bugbountylibrary.com/r/c4%3A2022-08-rigor%3AH-04.md).
- Nonce reset only on one EVM message type, replayable when bundled with others [E2](https://bugbountylibrary.com/r/c4%3A2024-11-nibiru%3AM-07.md).
- Vote tally reset enabling double execution of one proposal [E3](https://bugbountylibrary.com/r/c4%3A2023-07-axelar%3AM-07.md).

## Impact and severity
Led to draining project funds [E1](https://bugbountylibrary.com/r/c4%3A2022-08-rigor%3AH-04.md) and repeated execution of governance/multisig proposals [E3](https://bugbountylibrary.com/r/c4%3A2023-07-axelar%3AM-07.md); nonce manipulation opened replay of EVM calls [E2](https://bugbountylibrary.com/r/c4%3A2024-11-nibiru%3AM-07.md). Severity rises with value at stake and when replay is silent (no revert, no event) or reachable by an ordinary participant.

## Why fixes fail
Fixing one path (adding a nonce to `changeOrder`) leaves sibling paths (`setComplete`, `unApprove`) replayable [E1](https://bugbountylibrary.com/r/c4%3A2022-08-rigor%3AH-04.md); nonce handling fixed for creation but not call/transfer branches still replays [E2](https://bugbountylibrary.com/r/c4%3A2024-11-nibiru%3AM-07.md).

## Evidence
- E1: https://bugbountylibrary.com/r/c4%3A2022-08-rigor%3AH-04.md
- E2: https://bugbountylibrary.com/r/c4%3A2024-11-nibiru%3AM-07.md
- E3: https://bugbountylibrary.com/r/c4%3A2023-07-axelar%3AM-07.md
