# Governance logic may enter a deadlock

zkSync Governance: a compromised securityCouncil can spam cancel to block all owner upgrades, and a compromised owner can never be replaced, deadlocking governance.

- Payout: Contest reward
- Severity: medium
- Program: zkSync
- Credited: erebus
- Disclosed: 2024-02-29
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-10-zksync-findings/issues/260
- Library page: https://bugbountylibrary.com/r/c4%3A2023-10-zksync%3AM-13
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic vuln:governance

**Target:** Governance.sol upgrade scheduling/cancellation logic
**Root cause:** securityCouncil holds cancel permission over all pending operations while owner is the sole proposer and cannot executeInstant, so either actor being compromised permanently blocks upgrades with no recovery path.
**Steps:**
1. owner schedules upgrade via `scheduleTransparent`/`scheduleShadow`
2. compromised securityCouncil calls `cancel(_id)` on every pending operation, including `updateSecurityCouncil` proposals
3. owner cannot call `executeInstant` and delay is non-zero, so proposals never execute
4. alternatively compromised owner is sole proposer, so no upgrade (e.g. `updateSecurityCouncil`) can ever be scheduled
**How found:** Enumerated each governance actor's permissions and reasoned about self-calls via execute/executeInstant, observing that cancel is granted to securityCouncil while proposal rights are exclusive to owner, creating mutual blocking.
**Exploitation:** A single compromised governance key (owner or securityCouncil) permanently halts the upgrade mechanism: securityCouncil cancels every owner proposal, or owner refuses to propose removal of itself. No value extraction described; impact is governance liveness.
**Insight:** When auditing governance, map each actor's permission set and ask which single key compromise is unrecoverable; asymmetric cancel-vs-propose rights between two roles is a classic deadlock vector.
