# Unvalidated selector and calldata trust

Selector, sender, or inner id read from calldata and trusted without binding to the expected function or owner

_Area: Smart contract access control and control flow. Seen in 28 disclosed reports; latest 2025-05-06. Updated 2026-10-23._

## How it works
Code reads a selector, sender, or identifier out of calldata and trusts it for authorization or dispatch, without confirming it is the value the caller was supposed to supply. The broken assumption: the bytes at a given offset are the field the code thinks they are. Solidity does not reject trailing calldata, so an assembly read can land past the intended argument; a forwarded payload can carry a different inner identifier than the validated outer one; a calldata-suffix sender is only as trustworthy as the forwarder that appended it; a hardcoded offset can point at the wrong parameter.

## Where it shows up
- Selector extracted via inline assembly `calldataload(data.offset)` without validating `data.length`; the selector gates permission [E3](https://bugbountylibrary.com/r/c4%3A2022-08-mimo%3AH-04.md)
- Whitelist checks callee address but not function selector, and the contract is whitelisted to itself [E1](https://bugbountylibrary.com/r/c4%3A2024-02-tapioca%3AH-06.md)
- ERC2771 `_msgSender()` reading a calldata suffix, with a public `setTrustedForwarder` [E2](https://bugbountylibrary.com/r/dhl%3A20250506-crosswise.md)
- Settlement handler decodes a payload without asserting `method_id == Transfer` [E6](https://bugbountylibrary.com/r/c4%3A2024-08-chakra%3AM-02.md)
- Arbitrary calldata forwarded to a trusted module without binding the inner identifier to the validated outer argument [E4](https://bugbountylibrary.com/r/c4%3A2024-03-revert-lend%3AH-03.md)
- Guard parses calldata by hardcoded offset that does not match the real ABI layout [E5](https://bugbountylibrary.com/r/c4%3A2024-01-renft%3AH-04.md)
- Hand-built calldata re-encoding with unchecked offset arithmetic and no offset equality check [E8](https://bugbountylibrary.com/r/c4%3A2023-10-zksync%3AM-07.md)

## How to review
The invariant: every authorization or dispatch decision must come from a value the caller cannot forge or slide. Checklist:
- Selectors read from the first 4 bytes of the intended `data` parameter, with length validated.
- Whitelists cover selectors, not just addresses, and exclude self [E1](https://bugbountylibrary.com/r/c4%3A2024-02-tapioca%3AH-06.md).
- `_msgSender` forwarder setters are access-controlled [E2](https://bugbountylibrary.com/r/dhl%3A20250506-crosswise.md).
- Hardcoded offsets verified against the real ABI layout (4 + 32*n), and tests encode the full multi-arg signature [E5](https://bugbountylibrary.com/r/c4%3A2024-01-renft%3AH-04.md).
- Forwarded calldata's inner identifier (tokenId, position, account) is bound to the validated outer argument [E4](https://bugbountylibrary.com/r/c4%3A2024-03-revert-lend%3AH-03.md).
- Decoders assert the expected method id before acting [E6](https://bugbountylibrary.com/r/c4%3A2024-08-chakra%3AM-02.md).
- Hand-built calldata layouts diffed against the callee's ABI decoder, with safe arithmetic on offsets [E8](https://bugbountylibrary.com/r/c4%3A2023-10-zksync%3AM-07.md).

## Variants seen
- Self-call passes sender check, unlocks arbitrary downstream calls [E1](https://bugbountylibrary.com/r/c4%3A2024-02-tapioca%3AH-06.md)
- Public forwarder setter enables sender spoofing [E2](https://bugbountylibrary.com/r/dhl%3A20250506-crosswise.md)
- Empty bytes let assembly read slide into trailing calldata [E3](https://bugbountylibrary.com/r/c4%3A2022-08-mimo%3AH-04.md)
- Forwarded payload carries a different inner tokenId than the validated one [E4](https://bugbountylibrary.com/r/c4%3A2024-03-revert-lend%3AH-03.md)
- Wrong offset checks the wrong parameter [E5](https://bugbountylibrary.com/r/c4%3A2024-01-renft%3AH-04.md)
- Missing method_id assertion on one chain's handler [E6](https://bugbountylibrary.com/r/c4%3A2024-08-chakra%3AM-02.md)
- Hand-built calldata with unchecked offset arithmetic [E8](https://bugbountylibrary.com/r/c4%3A2023-10-zksync%3AM-07.md)

## Impact and severity
Token theft of approved balances [E1, E2]; non-transfer messages processed as mints/unlocks [E6](https://bugbountylibrary.com/r/c4%3A2024-08-chakra%3AM-02.md); manipulation of another user's position [E4](https://bugbountylibrary.com/r/c4%3A2024-03-revert-lend%3AH-03.md); removal of a safe module without verification [E5](https://bugbountylibrary.com/r/c4%3A2024-01-renft%3AH-04.md); malformed calldata accepted or forced reverts in the bootloader [E8](https://bugbountylibrary.com/r/c4%3A2023-10-zksync%3AM-07.md). Severity tracks reachability: high where privileged operations or token custody are reachable, worse when the contract is whitelisted to itself [E1](https://bugbountylibrary.com/r/c4%3A2024-02-tapioca%3AH-06.md) or the forwarder setter is public [E2](https://bugbountylibrary.com/r/dhl%3A20250506-crosswise.md).

## Evidence
- E1: https://bugbountylibrary.com/r/c4%3A2024-02-tapioca%3AH-06.md
- E2: https://bugbountylibrary.com/r/dhl%3A20250506-crosswise.md
- E3: https://bugbountylibrary.com/r/c4%3A2022-08-mimo%3AH-04.md
- E4: https://bugbountylibrary.com/r/c4%3A2024-03-revert-lend%3AH-03.md
- E5: https://bugbountylibrary.com/r/c4%3A2024-01-renft%3AH-04.md
- E6: https://bugbountylibrary.com/r/c4%3A2024-08-chakra%3AM-02.md
- E7: https://bugbountylibrary.com/r/c4%3A2024-02-ai-arena%3AH-04.md
- E8: https://bugbountylibrary.com/r/c4%3A2023-10-zksync%3AM-07.md
