# substrate-0002: CWE-407 — Aura/BABE/BEEFY is_member() linear authority scan

**Severity:** MEDIUM
**Files:**
  - `substrate/frame/aura/src/lib.rs:443`
  - `substrate/frame/babe/src/lib.rs:508`
  - `substrate/frame/beefy/src/lib.rs:738`
**Function:** `IsMember::is_member`

## Description

All three consensus pallets implement `IsMember::is_member` using
`.iter().any(|id| id == authority_id)` — an O(A) linear scan over the
authority list. The authority list can grow to the configured validator set size
(typical: 100–1000 validators).

`is_member` is part of the `IsMember` trait used by other pallets to gate
authority-only calls, including session management and equivocation reports.
While not called on every block unconditionally, any extrinsic validation path
that calls `is_member` pays O(A) per call.

## Root Cause

```rust
// aura/src/lib.rs:443
Authorities::<T>::get().iter().any(|id| id == authority_id)
```

The authority list is stored as a `BoundedVec`. The fix is to either:
1. Use a `BTreeSet` / `StorageMap` keyed by authority ID for O(log A) lookup, or
2. Sort the `BoundedVec` and use binary search for O(log A).

## Fix

Replace linear `.iter().any()` with a sorted binary search or an auxiliary
`AuthoritiesSet` storage map for O(1) membership checks.

## Speedup

At A=1000 authorities: ~500× fewer comparisons on average (binary search: ~10).
Practical speedup bounded by authority set size; at Polkadot scale (~300): ~150×.

## Status

PATCHED (see patch/substrate-0002-is-member-binarysearch.patch)
