## CodeDive

In Glow V1, the happy path for governance follows a five step process, outlined below:

### 1. Proposal Creation

• Users call one of the `create*Proposal` entry points (`createGrantsProposal`, `createGCACouncilElectionOrSlashProposal`, etc.).  
• Each function:
  
1. Calculates the nomination cost (`costForNewProposalAndUpdateLastExpiredProposalId`).  
2. Burns the caller's nominations via `_spendNominations`.  
3. Stores a `Proposal` struct in `_proposals` and, if its vote count tops the leaderboard, records it in `mostPopularProposalOfWeek`.

### 2. Collecting Votes

• Additional nominations can later be attached with `useNominationsOnProposal`.  
• Once the popularity week ends, long-staked GLW holders record ratify/reject votes through `ratifyOrReject`.  
• Votes accumulate in `_proposalLongStakerVotes`.

### 3. Eligibility Window

A proposal becomes executable when:
• Its popularity week has finished **and**  
• The four-week ratify/reject & veto window (`_NUM_WEEKS_TO_VOTE_ON_MOST_POPULAR_PROPOSAL`) has elapsed.

### 4. Execution Engine (`syncProposals`)

Anyone can invoke `syncProposals()` to process the backlog **sequentially—oldest first**.

```
1function syncProposals() public {
2    ...
3    for (_nextWeekToExecute; _nextWeekToExecute < currentWeek; ++_nextWeekToExecute) {
4        uint256 proposalId = mostPopularProposalOfWeek[_nextWeekToExecute];
5        ...
6        handleProposalExecution(_nextWeekToExecute, proposalId, proposalType, proposal.data);
7    }
8}
```

If any execution reverts, the loop aborts and `lastExecutedWeek` remains unchanged, blocking every subsequent proposal.

### 5. Type-specific Dispatch (`handleProposalExecution`)

`handleProposalExecution` decodes the payload and forwards the action to the correct subsystem:

```
1if (proposalType == IGovernance.ProposalType.VETO_COUNCIL_ELECTION_OR_SLASH) {
2    (address oldMember, address newMember, bool slashOldMember) = abi.decode(data,(address,address,bool));
3    success = IVetoCouncil(VETO_COUNCIL).addAndRemoveCouncilMember(oldMember, newMember, slashOldMember);
4}
```

Other branches cover Grants payouts, GCA requirement changes, RFC logging, etc.  
Success or failure is stamped via `_setProposalStatus`, and an event is emitted.

### Where It Broke

During **week 76**, the queued [proposal](https://etherscan.io/tx/0xb1e67aab227864bb2000230023a86721d386a44fd676749fc01f08b6a97a2988) was a `VETO_COUNCIL_ELECTION_OR_SLASH`.  
When `syncProposals()` hit the dispatch above, the call to `VetoCouncil.addAndRemoveCouncilMember()` **reverted with `CallerNotGovernance`** because the Veto Council contract's immutable `governance` field had been mis-wired to the GLW token address during deployment:

```
1// DeployGuardedLaunch.s.sol
2vetoCouncilContract = new VetoCouncil(address(glow), address(glow), startingVetoCouncilAgents);
3//                          ^^^^^^^^^^^^^^^^^^^^^  (should be Governance)
```

The revert bubbled up, terminated the `for` loop, and left `lastExecutedWeek` stuck.  
Because `syncProposals()` insists on synchronous, chronological execution (`week == lastExecutedWeek + 1`), **the entire Governance pipeline froze**—no subsequent proposals (including grant payouts) can progress until a redeploy wires the Veto Council to the correct Governance address.

## Impact

- **Governance execution frozen.** No on-chain grants, parameter changes, or council elections can complete.  
- **Grants moved off-chain.** The Foundation will aid in an off-chain grant process manually until V2 is operational.  
- **No funds at risk.** Contract balances and state remain intact; the issue is a logic lock, not a security breach.

## Preventing These Issues

Ultimately, the value of any post-mortem lies in the concrete safeguards it inspires. The four mitigations below - type-safe constructors, AI-assisted static analysis, end-to-end deploy-script tests, and dual-review canary deployments - turn the lessons of this incident into hard guardrails baked into our tooling and release flow. Together they make a repeat of the mis-wiring error mechanically unlikely and surface any similar faults long before they can reach mainnet.

- **Strongly-typed constructors in new code.** All new contracts receive explicit interface parameters; misuse fails at compile time.
  - Deployment scripts pass interface-typed objects instead of plain addresses, eliminating class-mismatch errors.
- **AI-assisted static analysis.** New codebases run an LLM ruleset that flags duplicated or suspicious constructor arguments before merge.
- **Comprehensive deploy-script tests.** Each script forks mainnet, executes the deployment end-to-end, and asserts post-deploy invariants, blocking any transaction that does not wire contracts correctly.
- **Mandatory multi-party review and canary execution.** Every mainnet deploy requires dual-signature review of calldata and a post-deploy smoke test on a fork, preventing mis-configured contracts from reaching production.

### Author: Glow Team
