# ACL membership checks ignore entries after the first 64

K2 router ACL membership checks bound iteration by MAX_RESERVES (64), so blacklist/whitelist entries past slot 63 are silently ignored, letting blacklisted accounts keep using reserve and liquidation flows.

- Payout: Contest reward
- Severity: medium
- Program: K2
- Credited: v12
- Disclosed: 2026-08-20
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2026-04-k2#m-17
- Library page: https://bugbountylibrary.com/r/c4%3A2026-04-k2%3AM-17
- Tags: domain:web3 impact:integrity kind:contest platform:code4rena sev:medium tech:rust technique:source-review vuln:access-control vuln:business-logic

**Target:** KineticRouter ACL storage/membership checks (Soroban/Rust contracts)
**Root cause:** ACL membership helpers iterate with list.len().min(MAX_RESERVES), reusing the 64-reserve protocol limit as an ACL size bound, while setters store unbounded Vec<Address> lists.
**Steps:**
1. Admin calls `set_reserve_blacklist` (or liquidation/swap-handler setters) with >64 addresses; full list is persisted.
2. Membership check `is_address_blacklisted_for_reserve` scans only `list.len().min(MAX_RESERVES)` = first 64 entries.
3. Place target account at index >=64 in the blacklist.
4. Call `supply`/`borrow`/`withdraw`/`repay`/`flash_loan`/`swap_collateral`/`liquidation_call`; `validate_reserve_blacklist_access` returns false-negative, so the blacklisted account proceeds.
5. Conversely, whitelisted addresses at index >=64 are denied despite being configured.
**How found:** Code review of ACL setters vs membership helpers: noticed setters store unbounded Vec<Address> while checks bound iteration by MAX_RESERVES, a write/read mismatch.
**Exploitation:** A blacklisted or non-whitelisted account positioned in the tail of an ACL list bypasses enforcement and continues to supply, borrow, withdraw, repay, flash-loan, swap, and aToken-gated actions for the affected reserve; no capital or chaining required, only operator-configured list >64.
**Insight:** When a protocol constant like MAX_RESERVES is reused as an iteration bound for admin-configured lists, compare setter storage bounds against check bounds; tail entries beyond the constant silently escape enforcement.
