许多 DeFi 应用程序遵循的治理模式在很大程度上受到了 Compound Finance 实现的启发。尽管目前还没有与创建标准治理接口相关的以太坊改进提案,但大多数 DeFi 治理实现通常遵循相同的一套原则。
归根结底,治理合约的行为往往类似于多重签名钱包,其投票权重由投票者的代币余额决定。
提案(Proposal)本质上是以太坊交易:一个或一组地址,以及一个或一组 calldata。社区(拥有投票权代币的持有者)提出以太坊交易,并根据投票结果,在链上执行该交易,或者在未通过选举时被否决。
对于不在链上执行的操作(例如更改某个软件的法律许可),只需对授予权限的消息进行签名即可。
常用术语
在开始解释合约之前,了解治理合约的技术术语会很有帮助。
提案
每一次投票都始于前面所描述的提案。它始终是一个可以被签名的以太坊交易,即它包含目标地址和 calldata。
为了防止垃圾提案,合约通常会对谁能创建提案设置某种过滤器,通常要求该地址必须持有占治理代币总供应量一定比例的代币。
在底层,提案通常是一个 Solidity 结构体(struct),包含关于其当前状态的标志、已投的票数,以及如果提案通过将要执行哪些交易的信息。
投票
不出所料,投票就是一笔以太坊交易,投票者在其中对提案投赞成或反对票。投票的权重通常由该地址在相关快照(snapshot)时持有的代币数量决定。
法定人数
如果除非 100% 的代币持有者参与投票才能采取行动,那么很可能什么事也做不成,因为只要有一位代币持有者决定不参与,系统就会停滞不前。另一方面,如果选举只需 1% 的选票即可生效,那么不良提案就太容易获得通过了。
为了决定提案的命运,它必须在投票期内达到法定人数门槛(占所有可能选票的百分比)。
投票期
提案不会无限期地等待达到法定人数。否则,治理提案可能会在促使该提案的客观环境发生变化时才被执行。倒计时从提案创建时就开始,如果在规定时间内未达到法定人数,提案就会被否决(defeated)。
排队与执行
如果在投票期结束前,有足够多的赞成票超过了法定人数门槛,那么该提案就被认为已通过。出于安全考虑,在提案成功和实际执行之间通常会有一个时间延迟。
时间锁
不要与投票期混淆,这是提案被批准与实际执行操作之间的时间延迟。
考虑这样一种情况:治理合约中存在一个有争议的提案,如果提案通过,一部分持异议的用户将会撤出流动性。时间锁为他们提供了一个窗口期,让他们在看到投票失败后能够离开。
给用户提供针对不利提案采取行动的机会,可以激励提案者仅提交那些不会引起反抗的提案。
治理的各个阶段
对于治理提案的创建、投票和执行方式,目前没有统一的规范。然而,你可以大致预期它会遵循类似下面这些状态转换的操作:
Pending ⭢ Active ⭢ Defeated ⭢ Canceled
⮑ Succeeded ⭢ Queued ⭢ Executed
⮑----------⮑-------⮑ Expired
以下是 Compound Finance 的治理状态转换流程

https://docs.compound.finance/v2/governance
这是 Uniswap 的流程

https://docs.uniswap.org/contracts/v2/reference/Governance/governance-reference
谁有权创建提案(并将其状态转为 Pending)取决于具体协议。一种常见的模式是,持有足够多治理代币的钱包可以创建提案。同样,谁能将状态转换为“Canceled”也取决于协议。对于谁有权执行这些操作,目前没有通用的标准。
当不确定状态转换何时发生时,最好的方法就是直接阅读治理的 Solidity 智能合约。
Governor Alpha 和 Bravo
Compound 对 DeFi 中如何实施治理产生了深远的影响。2021年,Compound 在其原有的治理 智能合约设计 中引入了新功能。这一新设计被称为 Governor Bravo,随后其他 DeFi 协议 也纷纷效仿了这些设计变更。
以下是 Governor Bravo 的新特性:
- 投票者可以明确表示“弃权(abstain)”,而不再局限于只投赞成或反对票
- 治理合约变成了可升级代理模式(upgradeable proxy pattern)
- 投票者可以在投票中添加原因字符串
在 OpenZeppelin 的 Bravo 实现中,可以在投票 结构体 中看到新增的“abstain”字段。
执行治理提案的工作流示例
网站 tally.xyz 提供了一个非常好的界面,展示了治理提案的工作流。
让我们来看看 Uniswap 的第 9 号提案,这是一个成功的提案,旨在为其流动性池添加 1 个基点(basis point)的费率层级。
对于不熟悉 Uniswap 的人来说,每当有交易代币需求的人在流动性提供者创建的池子中执行兑换时,流动性提供者就会赚取一笔手续费。该手续费在资金池创建时确定,但只能从一组固定的费率档位中选择。社区希望增加一个非常小的费率选项,以在与其他代币兑换 DeFi 服务的竞争中保持优势,该提案最终获得了通过。
以下是 tally 对投票和执行过程的可视化。

https://www.tally.xyz/gov/uniswap/proposal/9
该页面应该在很大程度上是不言自明的,但为了方便起见,我们在这里进行简要说明。
这里列出的每一个操作都是链上操作。读者可以点击三点图标控件,在 Etherscan 上查看相应的交易。
这是实际执行提案的交易。https://etherscan.io/tx/0x5c84f89a67237db7500538b81af61ebd827c081302dd73a1c20c8f6efaaf4f3c#eventlog
很明显,FeeAmountEnabled 事件是由位于 0x1f98431c8ad98523631ae4a59f267346ea31f984 的合约触发的,这就是用于创建资金池的 Uniswap 工厂合约。
Tally 便捷地提供了投票者投票决定执行的代码,这也是最终被执行的代码。
治理攻击
以下是黑客成功执行的一些治理攻击示例。
闪电贷攻击
BeanStalk 协议有一个名为 emergencyCommit 的功能,如果有足够多的投票者支持该交易,则可以立即执行。这一设计的初衷是为了在有紧急提案需要强行通过时,绕过时间延迟。攻击者利用了这一点,通过借入闪电贷获得了足够的投票权,从而绕过时间锁并执行了一条抽干协议资金的指令。
低价攻击
如果代币的价格足够低,那么攻击者就能以极低的经济成本获得足够的选票,从而通过他们想要的任何提案。那些协议中锁定的资产量相对于治理代币市值很大的协议,尤其容易受到这种攻击。这一攻击曾针对 True Seniorage Dollar 发生,攻击者投票为自己铸造了数十亿枚稳定币,然后在另一个去中心化交易所将它们抛售。由于治理代币的市值相对较低,发生 51% 攻击的几率不容忽视。
社交或政治攻击
正如任何民主制度一样,选票可以在一定程度上受到社会化操纵。全副武装的攻击者精心策划的协作行动可以推动不良提案的执行。
改进空间
尚未有定论表明本文描述的当前 DeFi 治理模式实际上就是最优方式。Vitalik Buterin 曾 抨击 当前的做法,认为这通常对小散投票者不利。他在自己的 博客文章 中提出了解决方案。其中一个获得了一定关注度的解决方案是,按持有量的平方根来计算投票权重,这也叫作“二次方投票”。目前仍有一个未解决的问题:攻击者可以将他们的持仓分散到多个地址中,以避免其选票被平方根函数降权。
设置治理的工具
对于那些希望建立具有链上治理的 DAO 的人,以下是一些资源,可以避免从头开始编写合约。
- https://wizard.openzeppelin.com/#governor
- https://www.tally.xyz/developers
- https://docs.alchemy.com/docs/how-to-create-a-dao-governance-token
结论
治理合约是目前公认的模式,供治理代币持有者投票决定要执行哪些以太坊交易。尽管许多项目遵循一种通用模式,但如何以安全且公平的方式进行治理仍然是一个开放的研究课题。
了解更多
查看我们的 区块链训练营 以学习以太坊和 DeFi 开发。
最初发布于 2023 年 2 月 27 日