★ delegatecall/call in proposal execution without allowlist
A governance & admin factor in the v1.7.0 rubric. Measured per protocol on a s cadence.
Methodology how we score #
**What this measures** This factor identifies whether a protocol's governance executor contract uses delegatecall or call with an attacker-supplied target address — and does so without enforcing an allowlist of permitted targets. When an on-chain governance system delegates execution to an arbitrary address passed in the proposal payload, the proposal's bytecode effectively gains full execution context of the executor contract, including its storage, balances, and admin roles.
**Why it matters** Unrestricted delegatecall in proposal execution is a complete governance takeover primitive. OpenZeppelin's governance security guidance highlights that "a contract controlled by a single proposer has all the power over the timelock and can submit whichever transaction they like" — but the situation is worse when the executor itself will delegatecall any address the proposal specifies, because the attacker does not even need proposer privileges if they can pass a malicious payload through a legitimate-looking vote. The attack surface is particularly dangerous in protocols that adopted early OpenZeppelin Governor patterns without the later-added callRestricted executor, or that use custom execution registries with handler contracts.
**Green / Yellow / Red** Green is assigned when the governance executor enforces a strict allowlist of callable targets, or when proposal execution is limited to predefined function selectors and addresses with no external delegatecall path. Yellow covers protocols with a partial allowlist that does not cover all execution paths, or where the allowlist is itself admin-modifiable without governance. Red is assigned when governance proposal execution invokes delegatecall or call with a proposal-supplied target and no allowlist is enforced on-chain.
**Common gray cases** This factor is grayed when the protocol has no on-chain governance execution and all proposals are executed manually by a multisig, or when source code for the executor is unavailable for verification.
**Notable historical examples** - **Furucombo** ($14M, 2021): Handler registry accepted proxy contracts as targets; delegatecall from the outer proxy into a malicious inner handler enabled storage collision drain. - **Raft** ($3.3M, 2023): Delegatecall with an uninitialized storage slot caused attacker's profit to route to the burn address, but the pattern demonstrates how unguarded delegatecall creates unpredictable execution outcomes.
**★ Critical factor** This factor alone is sufficient to trigger a D or F grade under rubric v1.7.0 — a single red assessment here overrides all other category scores. An unrestricted delegatecall in governance execution converts any passed proposal into a full arbitrary-code-execution event against the executor's storage and funds.
Measurement what to look for #
Determine whether the governance executor contract uses `delegatecall` or `call` with proposal-supplied target, without enforcing an allowlist of permitted targets.