治理提案通过后为何迟迟未执行
投票通过不等于自动执行。提案通过后,通常需要经历时间锁等待期、执行队列排队和执行人手动触发三道关。2025年Scroll DAO的治理停摆事件就暴露了治理投票与执行之间的脱节问题。
步骤1:确认投票通过后的执行流程——时间锁的延迟窗口
做什么:检查项目使用的时间锁合约参数,确认提案是否需要经过时间锁等待。
怎么做:
治理提案通过后,会进入时间锁(Timelock)队列,而不是立即执行。
常见的时间锁延迟为2-3天。例如,Scroll DAO的治理设计中包含3天的time lock窗口;OpenZeppelin的TimelockController默认延迟也通常设置在这个范围内。
这段时间是留给社区的最后检查窗口——如果发现提案有问题,可以在这期间退出或发起反对。
做到什么程度算完成:你确认了当前提案的可执行时间(ETA),知道还需要等多久才能执行。
步骤2:用区块浏览器查时间锁状态
做什么:在Eth erscan或类似浏览器的"Read Contract"中调用时间锁合约的查询函数。
怎么做:
isOperationPending(id):确认操作是否仍在等待中。isOperationReady(id):确认操作是否已到达可执行时间。getTimestamp(id):获取该操作可执行的具体时间戳。返回的时间戳转换为北京时间后,就是提案最早可执行的时间。
做到什么程度算完成:你查到了提案的状态——是"Pending(等待中)"、"Ready(可执行)"还是"Done(已完成)"。
关键提醒:时间锁的状态显示为"Ready",只表示"可以执行了",不代表"已经执行了"。执行需要有人(通常是执行人角色)手动调用execute函数。
步骤3:检查执行人角色是否有人负责
做什么:确认谁有权限执行提案,以及这个人是否还在岗。
怎么做:
OpenZeppelin的TimelockController中有
PROPOSER_ROLE(提案人)和EXECUTOR_ROLE(执行人)两个角色。提案通过后,需要具备
EXECUTOR_ROLE的地址调用execute方法。如果执行人是DAO的多签钱包,需确认多签是否正常工作。如果执行人是项目团队,需要确认团队是否有专人负责此操作。
Scroll DAO案例:治理负责人离职后,即使投票通过,执行也陷入停滞——"谁去点那个执行按钮"成了问题。
做到什么程度算完成:你明确了当前的执行人是谁,以及他是否具备执行的能力和意愿。
步骤4:如果时间锁状态为"Done",确认是否已执行成功
做什么:查看CallExecuted事件,确认提案是否已真正执行。
怎么做:
在时间锁合约的事件日志中,找
CallExecuted事件——它会记录执行时间和执行人。如果只有
CallScheduled(排期)但没有CallExecuted,说明提案还在等待执行。如果提案状态显示为"Done"但操作没有生效,可能是
execute调用成功了但目标合约的执行失败了(比如前置条件变化导致调用失败)。
做到什么程度算完成:你确认了提案是否已真正被执行,还是卡在某个环节。
前置条件
在追查前,确认你知道提案对应的时间锁合约地址和操作ID(通常在投票通过后的公告或链上日志中可以查到)。
常见失败原因
执行人没有及时操作:时间锁到时间后,不会自动执行,必须由执行人手动调用。如果执行人休假了或忘了,提案就会卡在"Ready"状态。
执行人离职或角色变更:Scroll DAO的事件显示,当治理负责人离开后,已通过的提案因无人推进而停滞。
提案执行依赖链下操作:有些提案既需要链上执行,也需要链下配合(如更新前端、发布文档)。链上执行完了,但链下部分没跟上,用户感知上会觉得"还没执行"。
风险提醒
资金风险:时间锁的延迟窗口是保护机制,但也是风险窗口——如果提案内容有风险,延迟给了退出时间,但不会自动防止执行。
账户风险:如果提案状态显示"Ready"但一直没人执行,说明治理的执行链条可能断裂。对于资产规模大的项目,这种断裂可能影响资金调度。
确认你已经正确完成的标志:你在时间锁合约中调用了isOperationReady(id),或看到了对应的CallScheduled和CallExecuted事件。如果你能明确说出:提案是在等待时间锁到期、处于"Ready"状态等待执行人点击按钮,还是已经执行完成——你就真正理解了"通过后为何迟迟未执行"的原因。
