# STATUTES_MAX_IDX Excludes the Governance Fee Slot

Off-by-one in statutes_mutation.clsp caps mutation_index at 38, so governance fee statute at index 39 can never be updated, freezing fee changes.

- Payout: Contest reward
- Severity: medium
- Program: Circuit Puzzles
- Credited: 0xasen
- Disclosed: 2025-08-21
- Write-up quality: 6/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_circuit_puzzles.pdf#3.3.1
- Library page: https://bugbountylibrary.com/r/cantina%3Acircuit_puzzles%3A3.3.1
- Tags: domain:web3 impact:dos kind:contest platform:cantina sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:governance

**Target:** Chialisp statutes mutation puzzle (statutes_mutation.clsp)
**Root cause:** STATUTES_MAX_IDX=39 but guard uses `(> STATUTES_MAX_IDX mutation_index)`, requiring mutation_index < 39, so index 39 (STATUTE_GOVERNANCE_BILL_PROPOSAL_FEE_MOJOS) is rejected; mutate-list also rejects index == list length.
**Steps:**
1. Read statutes_utils.clib: STATUTES_MAX_IDX=39, STATUTE_GOVERNANCE_BILL_PROPOSAL_FEE_MOJOS=39.
2. Note guard in statutes_mutation.clsp: `(> STATUTES_MAX_IDX mutation_index)` allows only indices ≤38.
3. Observe governance.clsp asserts statute at index 39 via assert-statute, expecting mutability.
4. Submit governance spend with statute_index=39 and new fee X; guard `(> 39 39)` is false, spend aborts.
5. Fix: change to `(>= STATUTES_MAX_IDX mutation_index)` and update mutate-list bound to allow final position.
**How found:** Code review comparing the mutation guard's strict inequality against the max index constant and the governance contract's expectation that slot 39 is mutable.
**Insight:** When a max-index constant doubles as both a count and a valid slot id, check every bound comparison for > vs >=; cross-reference consumers that assert on the highest slot to confirm intent.
