# function selector clashes between proxy and implementation can shadow critical admin functions A Solidity function selector is the first 4 bytes of the keccak256 hash of its signature, meaning different function names can produce identical selectors. Since the proxy and implementation share the same function namespace through [[delegatecall executes code from another contract using the callers storage context|delegatecall]], a selector collision means the proxy intercepts calls intended for the implementation (or vice versa). This can silently shadow critical admin functions like `upgradeTo` or lock upgrade paths entirely. Transparent proxies solve this by routing based on caller identity: if `msg.sender` equals the proxy admin, the call executes on the proxy; all other callers are unconditionally delegated to the implementation. This eliminates clashing but adds gas overhead from the per-call admin address check. UUPS proxies are not susceptible because all custom functions live in the implementation and the proxy has only the fallback. Diamond proxies (EIP-2535) solve clashing by design through explicit selector-to-facet mapping. Since [[abi types are not self-describing so the decoder must know the interface to interpret values]], selector-only routing provides no type safety; the 4-byte selector is all that distinguishes functions. CPIMP weaponizes intentional per-selector routing: since [[double-delegation chains in CPIMP attacks forward all calls to the legitimate implementation preserving normal protocol functionality while granting hidden attacker control]], CPIMP's shadow implementation uses a dispatch table to intercept only specific functions (e.g., transfers), making targeted theft stealthy because the protocol otherwise functions normally. **Detection:** `solc --hashes` outputs function selectors, Slither's Function ID printer enumerates all selectors in a contract, and `slither-check-upgradeability` specifically checks proxy-implementation selector conflicts. --- Relevant Notes: - [[delegatecall executes code from another contract using the callers storage context]]: the mechanism that creates the shared namespace - [[abi types are not self-describing so the decoder must know the interface to interpret values]]: selector-based routing lacks type metadata - [[storage layout must remain consistent across proxy implementation versions]]: another constraint on proxy architecture alongside selector management - [[double-delegation chains in CPIMP attacks forward all calls to the legitimate implementation preserving normal protocol functionality while granting hidden attacker control]]: the attacker-weaponized version: intentional per-selector dispatch routing specific operations to malicious implementations - [[EIP-2535 Diamond proxy facet storage collisions occur when multiple facets write to non-namespaced storage slots]]: diamonds solve selector clashing via explicit mapping but introduce storage collision risks Topics: - [[vulnerability-patterns]]