返回文章列表
DAO GovernanceTimelockSmart ContractsProposal Review
🗳️

The DAO Voted Yes. What Exactly Can Execute?

Review a governance proposal from its voted payload to its actual effects, distinguishing proposal identity, timelock authority, executable transactions, and verified outcomes.

iBuidl Research2026-10-1517 min 阅读

TL;DR

A successful vote authorizes a particular proposal under a particular governance implementation. It does not establish that the intended transactions are queued, that their executor has the necessary authority, or that execution achieves the described business result. Verify the payload, deployed contracts, timelock operation, role assignments, and resulting state separately. The worked review below uses OpenZeppelin Contracts v5.4.0 as a pinned reference. A deployed DAO may customize those rules, so its actual code and state control the conclusion.

Review desk: one proposal, three claims

A fictional DAO called Harbor Collective votes to increase a program's spending cap and pay a service provider. The proposal page shows a convincing majority and a green “passed” label. A delegate receives three questions: did the vote authorize these transactions, can someone execute them now, and will execution do what the page promises?

Those questions require different evidence. The vote answers part of the first. The timelock and role configuration answer the second. The target contracts, transaction semantics, and resulting state answer the third. Treating the green label as a substitute for all three compresses a review into a fragile assumption about the interface.

This article's DAO, proposal, amounts, contracts, and intended outcomes are illustrative. It describes a review method, not an audit of a live deployment or a deployable contract recipe. The reference implementation is the tagged OpenZeppelin Contracts v5.4.0 Governor with its timelock extension. The review must be adapted to the code actually deployed.

Harbor's prose says “raise the annual program cap from sixty thousand to ninety thousand units and pay twelve thousand five hundred tokens to the provider.” Before reading the vote count, the delegate asks what “units,” “annual,” “provider,” and “pay” mean in the target system. A beautifully formatted description can remain ambiguous on each point.

The first deliverable is an action manifest. It lists each target contract, the native currency value attached to the call, the encoded call data, the order of calls, and the expected observable change. A reviewer should be able to connect every sentence describing an action with the corresponding payload entry, and every payload entry with an explained purpose.

Manifest A: decode intent into reviewable assertions

Proposal elementQuestion the reviewer must resolve
Spending-cap changeWhich contract and program change, in what unit, for which accounting period?
Token paymentWhich token contract, recipient address, and integer amount?
Attached native valueDoes any call also send native currency, and why?
Call orderDoes payment require the cap change to happen first?
Expected resultWhich state reads or balance changes would show the intended effect?

The manifest is not another summary of the marketing description. It exposes mismatches. A cap expressed in dollars cannot be checked against a token integer without an explicit unit rule. A provider name cannot establish ownership of an address. A payment request does not explain why the payload also grants a continuing allowance.

Keep these mismatches as unresolved review items rather than filling them with plausible guesses. A proposal may need clarification before voting, a replacement proposal, or a bounded explanation of what its current bytes actually do. After the vote, the executor does not acquire a general mandate to repair an ambiguous payload according to personal judgment.

Claim one: these are the actions that won the vote

The reference Governor's proposal identifier is derived from the target array, native-value array, call-data array, and description hash. Its tagged source defines the actual calculation. A reviewer should reproduce it using the correct encoding and compare it with the on-chain proposal, rather than rely on a shortened identifier copied from a screenshot.

This binds particular bytes. Changing the recipient or payment amount changes the proposal identity. So does changing the call order. A description with an apparently harmless textual difference can produce a different description hash. Preserve the exact proposal data and description bytes used by the relevant implementation instead of reconstructing them from rendered prose.

A proposal identifier is also not a universal locator. Record the chain and Governor address beside it. Two independent deployments can discuss identical actions without becoming the same governance process. A review archive that stores only a numeric identifier can attach the right payload to the wrong instance.

Units are part of the authorization

Assume Harbor's fictional payment token uses six decimal places. Twelve thousand five hundred whole tokens correspond to the integer 12,500,000,000. If a payload instead used an eighteen-decimal assumption, its integer would be a trillion times larger. The number of displayed tokens depends on the token's actual representation, not the familiar appearance of its ticker.

ERC-20 makes the decimals metadata optional. For a real proposal, establish the unit from the actual token contract and reliable integration evidence. Do not assume that every fungible token has eighteen decimals or that every asset using the same symbol is the same deployed contract.

The spending cap needs equally careful reading. It could be a whole-token amount, a smallest-unit amount, a rate, a per-transaction ceiling, or a remaining allowance. A reviewer cannot infer the unit from an integer alone. Inspect the relevant target implementation and explain the exact meaning of the proposed state change in the manifest.

For the fictional annual cap, ask what resets the period. A value of ninety thousand could replace the ceiling for a particular year, apply to every future period, or increase a cumulative lifetime authorization. These interpretations have different consequences even if the payload contains one visually simple number.

A function label does not establish the call's meaning

Decoded call data is an aid to inspection, not a proof of behavior. Confirm the ABI matches the deployed target and inspect how that target interprets its inputs. A proxy adds the implementation and upgrade authority to the evidence set. A familiar function name can point to unfamiliar logic in a customized deployment.

The review should also follow nested actions. A call to a controller may forward work to another contract; a target may use an address stored in mutable state. Harbor's manifest should identify the dependencies that determine the recipient and amount at execution. Otherwise the review describes only the first call in a longer action path.

This is where prose and payload review meet. If the proposal says “one payment” but the transaction sets a reusable spending permission, the discrepancy is substantive. If it says “raise this year's cap” while changing a permanent default, the claimed scope is wrong. The right response is to state the actual effect, not to assume voters intended whichever interpretation looks safer.

Claim two: the approved payload can reach the target

The OpenZeppelin governance guide explains that, with a timelock executor, the timelock needs the relevant assets and permissions. The Governor and timelock are separate contracts with separate responsibilities. Harbor's target does not automatically recognize the Governor as the privileged caller merely because tokenholders voted there.

Construct a small authority map. Identify which account can schedule timelock operations, which can execute ready operations, which can cancel them, and which can administer roles. Then inspect who holds the target's spending or configuration authority. A map drawn from the intended architecture is only a hypothesis until checked against deployed state.

The caller that matters may be the timelock

Suppose Harbor's spending contract allows only its administrator to raise a cap. If its administrator is still a setup wallet, a transaction from the timelock can fail despite a successful vote. Conversely, the setup wallet may retain a direct path to change the cap without any vote. These are two consequences of the same incomplete authority transfer.

The delegate should not fix the review by assuming that a later transaction will grant the missing role. That role change is itself an action requiring authority and potentially governance. Record whether it is already completed, included in the approved batch, or merely planned. Each status gives the proposal a different execution dependency.

The tagged GovernorTimelockControl extension queues the batch through the timelock and derives a salt incorporating the Governor address. It also tracks a timelock operation identifier separately from the proposal identifier. The delegate should establish that connection from the correct module, rather than treating the two identifiers as interchangeable hashes.

This reference module uses a zero predecessor when scheduling its batch. A generic timelock can support predecessor dependencies, but the existence of that feature does not mean this proposal automatically waits for another separately scheduled operation. If Harbor requires an earlier action, inspect the actual scheduling path and target conditions instead of inferring a dependency from a document's order.

Open execution is different from open scheduling

The reference TimelockController permits an executor role to be opened to everyone through its designated configuration. That lets someone submit an already authorized, ready operation. It does not let that person replace the target, amount, or call data with new actions under the existing operation identity.

This distinction changes an operational question. An open executor can reduce reliance on one maintainer being available when an operation becomes ready. It does not guarantee that someone will pay transaction fees, that the target call succeeds, or that the DAO has monitored the operation correctly. Liveness still needs an owner even when submission is permissionless.

Additional scheduling authority creates a different concern. A proposer on the timelock may be able to queue privileged actions without the Governor's voting path. The delegate needs to ask why each proposer exists and what it can reach through the timelock. The trust boundary is the entire authority graph, not the fraction of tokens that participated in this one vote.

Administrative roles deserve the same attention. The OpenZeppelin access-control guide discusses timelock setup and administration. For Harbor, the review should distinguish a temporary deployment administrator, self-administration through the timelock, and any continuing external authority. A label such as “DAO controlled” is incomplete when an unmentioned account can alter the role configuration.

Passed is not queued, and ready is not executed

Use the governance API documentation to interpret the reference proposal and operation states. A vote can succeed before its operation is scheduled. A scheduled operation can be waiting or ready. A ready operation still requires an execution transaction. Interface labels should correspond to these distinct conditions.

The review record should contain the scheduling transaction, operation identifier, readiness timestamp, and current state at a named block. A countdown calculated from an assumed delay is weaker evidence than the operation's recorded timestamp. If the minimum delay changes, do not recalculate an existing operation's schedule from today's setting without checking the implementation.

Voting and timelock delay can also use different time bases. ERC-6372 specifies clock discovery for compatible contracts, while the reference timelock schedules in timestamp seconds. A voting deadline displayed as a block-based timepoint should not be converted into a precise wall-clock execution promise using a convenient constant.

Funding is an amount at an address, not a treasury headline

Suppose Harbor's dashboard shows twenty thousand payment tokens in its treasury. The approved payment needs twelve thousand five hundred. That comparison looks sufficient until the delegate checks where the tokens sit. They may be held by a separate vault, while the approved call expects the timelock itself to own and transfer them.

The review must identify the actual payer under the target path. If a vault will pay, inspect the authority and limits that allow it to do so. If the timelock will pay, inspect its relevant balance. The sum of assets across every DAO-associated address is not automatically spendable by the contract that will execute this operation.

Native currency is a separate funding question. Each payload entry can attach a native value, and the transaction also needs a fee payer. The token amount, native value, and execution fee should not be combined into one vague “funded” status. For the fictional proposal, a zero-native-value token transfer can still require someone to submit and pay for the execution transaction.

This distinction can reveal an incomplete proposal rather than a malicious one. A preparatory treasury transfer may be missing, or the chosen payment path may point at the wrong custody contract. The delegate should describe the exact dependency. Moving funds casually to whatever address makes a simulation pass can create a new exposure that voters did not evaluate.

Claim three: a successful transaction delivers the promised result

Harbor's operation is ready. An executor simulates the batch against a recent chain state and discovers that the payment fails. That finding does not retroactively invalidate the vote. It identifies a gap between authorization and executability. The next task is to classify the gap accurately before proposing a response.

Case B: authority changed while the proposal waited

Suppose the target's administrator moved to a replacement controller after the proposal was queued. The approved bytes still name the old target and the timelock still recognizes the operation. The target's current permission check can nevertheless reject the call. Scheduling preserved the authorized payload; it did not freeze every dependency used when that payload runs.

A simulation report should therefore include its block, caller path, balances, implementation versions, and relevant role state. Simulating as a privileged human wallet when execution will come from the timelock answers the wrong question. A simulation against yesterday's implementation may also miss a dependency changed by a separate upgrade.

If the payload is no longer suitable, inspect the DAO's actual cancellation and reproposal paths. Do not assume that anyone who dislikes the result can cancel, or that a ready operation expires automatically. Harbor's governing contracts determine which actions remain available. A delegate's review can identify the need for a new decision without claiming authority to make it.

Case C: the second call reverts

The reference timelock runs a batch as one transaction and checks low-level call success. If a later call reverts and the transaction reverts, earlier state changes in that same transaction do not remain committed. Thus Harbor should not report “cap raised, payment failed” from intermediate traces as though both were lasting outcomes of one reverted batch.

Atomicity does not make every batch order equivalent. Raising a cap before paying may pass a check that would reject payment in the opposite order. Two calls may also interact through balances or mutable configuration. The manifest's call order is part of the authorized behavior and should be simulated as a complete batch, not as a collection of unrelated successful calls.

Neither should atomicity be stretched across separate transactions. If the DAO queues an upgrade in one operation and a payment in another, the success of the first does not make the second succeed automatically. The review needs to show any enforced dependency, and it must consider the state left behind if only one operation executes.

Case D: the call succeeds but the payment does not

A low-level successful call is not always the same as the business action succeeding. ERC-20 specifies a boolean return for transfer functions and tells callers to handle false. A token can return false without reverting. A generic caller that checks only low-level call success has not necessarily interpreted that return value as a failed token transfer.

The reference timelock's low-level call path does not generically decode every target's business return convention. OpenZeppelin's SafeERC20 utility illustrates why token integrations need a deliberate handling strategy. This does not mean a governance reviewer should retrofit a wrapper after the vote; the approved target path must already have the required semantics.

For Harbor's payment, verify the actual token behavior and expected balance effects. If the selected asset has transfer fees or another mechanism that changes the recipient's net amount, a call requesting twelve thousand five hundred tokens may not deliver that amount to the provider. The proposed action and its success criterion need to use the same economic quantity.

The same principle applies beyond payments. A controller might accept a request into a pending state rather than activate a new cap immediately. A bridge might accept a message without completing its destination action. The source-chain transaction's success establishes what that transaction committed, not every later effect described in the proposal's prose.

Case E: the provider requests a different recipient

While the proposal waits, the service provider asks Harbor to send payment to a new address. The request may be legitimate, but the approved bytes still name the original recipient. An executor cannot preserve the existing operation identity while substituting a different destination. The review should separate the validity of the business request from the authority available to carry it out.

Harbor needs an authenticated record of the request and the governance process appropriate to its contracts. A new proposal may be necessary; cancellation of the original may also be necessary and may require a particular authorized account. If the old operation remains executable, approving a replacement without addressing it can create two live payment paths.

The payment reviewer should therefore reconcile the original proposal, any cancellation evidence, and the replacement authorization before declaring the provider's request resolved. A forum edit alone does not change an already authorized transaction. Likewise, a private agreement between contributors does not establish what the on-chain executor is permitted to submit.

Case F: approval and payment leave different ongoing powers

Harbor could pay a provider through a direct transfer, or it could authorize another contract to spend tokens on the provider's behalf. Those paths can produce similar immediate balance effects while leaving different continuing permissions. The review should include the authority that remains after the intended invoice has been settled.

For the fictional twelve-thousand-five-hundred payment, a much larger reusable allowance would need its own explanation. The delegate should ask who can exercise it, what prevents additional spending, and whether its intended duration matches the proposal's description. A one-time business expense does not, by itself, justify a continuing permission of unspecified scope.

The same question applies to the spending-cap action. Raising a cap can enlarge future discretion even after today's payment is complete. State who will be able to use the remaining authorization and under what program rules. Otherwise the review can verify the immediate transfer accurately while overlooking the more consequential persistent change.

Close the review with state evidence

After execution, collect the transaction receipt and resulting contract state at a specified block. Harbor's record should establish whether the cap changed in the intended program and period, whether the provider received the intended asset and amount, and whether any continuing permissions changed. These are separate assertions with separate evidence.

Events help locate actions, but their meaning comes from the emitting implementation. A transfer-shaped event is not a universal proof of an economic payment, and an execution event does not explain every target's internal business result. Use events alongside state reads and target semantics, rather than treating a familiar event name as the conclusion.

A before-and-after balance comparison also needs the right boundary. Other transactions in the same block can pay the provider or move funds away. A comparison between two block snapshots may therefore include more than Harbor's operation. Use transaction-level evidence where necessary to attribute the change, and explain any netting assumptions when only coarser observations are available.

For a provider that forwards incoming funds immediately through contract logic, the final balance may not retain the full payment. The review should follow the agreed payment semantics rather than require every recipient to hold the assets indefinitely. This is another reason to define the postcondition before execution: the evidence should test the approved action, not an improvised expectation about what balances ought to look like afterward.

Also distinguish current state from execution-time state. A later governance action may change the cap again. Reading today's value alone can make a successful earlier proposal appear ineffective or can falsely credit it for a later change. A useful archive anchors the before-and-after comparison to the transaction being reviewed.

The review can then assign a precise outcome: authorized but not queued, queued and waiting, ready but blocked by a named dependency, executed with verified postconditions, or executed without the intended economic result. These descriptions support follow-up. A single success badge hides the very distinctions delegates need when something remains unfinished.

For the next proposal, preserve the action manifest beside the discussion and voting record. The DAO's institutional memory becomes stronger when another delegate can connect the same approved bytes to the same authority path and verified effects. Governance quality includes that chain of explanation from voter intent to committed state.

Sources

更多文章