# Zero address breaks auth or payout

Zero owner, threshold, or recipient accepted at init or in signed paths, breaking auth, votes, or settlement

_Area: Smart contract access control and control flow. Seen in 4 disclosed reports; latest 2026-05-04. Updated 2026-10-24._

## How it works
A zero value is treated as a valid input where the code assumes it means "unset" or "self." When address(0) or threshold 0 flows into an initializer, a signed delegation, or a settlement owner field, the downstream logic either silently accepts it or rejects it at the wrong time. The broken assumption is that zero is never a legitimate parameter; the code neither normalizes it nor rejects it consistently across all entry points.

## Where it shows up
- Initializers or factory calls passing `owner()`/`admin` into a validator that rejects zero, after an upgrade renounces ownership [E3](https://bugbountylibrary.com/r/cantina%3Asize_february2025%3A3.1.2.md)
- Two entry points to the same internal function where only one normalizes address(0) (e.g. `delegate` vs `delegateBySig`) [E2](https://bugbountylibrary.com/r/c4%3A2022-08-nounsdao%3AH-01.md)
- Threshold-secret-sharing or recovery setup called with `guardians=[]` and `threshold=0` at account creation [E1](https://bugbountylibrary.com/r/c4%3A2025-11-swafe%3AM-06.md)
- Router forwarding a settlement with `address(0)` as owner instead of the caller's virtual account [E4](https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AM-27.md)
- Upgrade/reinitialize scripts that zero or rename owner, admin, or roles

## How to review
The invariant: every path that consumes an owner, threshold, delegate, or recipient must either reject zero or normalize it identically to sibling paths. Check each call site feeding a zero-capable value into an initializer or validator; diff signed/relayed entry points against their direct counterparts for matching guards; confirm settlement owner is the actual caller, not a sentinel; and trace what a renounced or zeroed state variable does to functions that read it implicitly.

## Variants seen
- Zero threshold makes secret sharing return a constant, so backup ciphertext is derivable from the RIK alone [E1](https://bugbountylibrary.com/r/c4%3A2025-11-swafe%3AM-06.md)
- Missing zero guard in signed delegation desyncs checkpoint accounting and bricks transfers [E2](https://bugbountylibrary.com/r/c4%3A2022-08-nounsdao%3AH-01.md)
- Upgrade renounces ownership to zero, permanently reverting factory functions [E3](https://bugbountylibrary.com/r/cantina%3Asize_february2025%3A3.1.2.md)
- Zero settlement owner means failed settlements can never be retried or redeemed [E4](https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AM-27.md)

## Impact and severity
Outcomes ranged from permanent loss of voting power and blocked NFT transfers [E2](https://bugbountylibrary.com/r/c4%3A2022-08-nounsdao%3AH-01.md), to permanently locked user funds [E4](https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AM-27.md), to broken recovery confidentiality [E1](https://bugbountylibrary.com/r/c4%3A2025-11-swafe%3AM-06.md), to permanent denial of market creation [E3](https://bugbountylibrary.com/r/cantina%3Asize_february2025%3A3.1.2.md). Severity rises when the zero value is written to persistent state or an upgrade, because no later transaction can repair it.

## Why fixes fail
Guards added to one entry point but not the signed/relayed twin leave the desync open [E2](https://bugbountylibrary.com/r/c4%3A2022-08-nounsdao%3AH-01.md); migration scripts that zero ownership without checking downstream readers reintroduce the failure [E3](https://bugbountylibrary.com/r/cantina%3Asize_february2025%3A3.1.2.md).

## Evidence
- E1: https://bugbountylibrary.com/r/c4%3A2025-11-swafe%3AM-06.md
- E2: https://bugbountylibrary.com/r/c4%3A2022-08-nounsdao%3AH-01.md
- E3: https://bugbountylibrary.com/r/cantina%3Asize_february2025%3A3.1.2.md
- E4: https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AM-27.md
