详解Compound治理

你也许知道很多的 DEFI 项目是参考Compound的链上治理方式,本文来看看一下 Compound的去中心化治理是底层是如何运行的

去中心化借贷项目 Compound 发行的COMP代币。目前的市值当前大约是 20亿美元,该代币已经积累了巨大的价值。但COMP的实际效用是什么?

其实COMP是一个治理代币。Compound作为一个完全去中心化的系统(或者至少是在走向它的路上),基于COMP实现了一个去中心化的治理机制。同样的机制,在SushiSwap治理中也被复制和使用。

但它是怎么详细工作的呢?

什么是Compound治理?

在上层来看,治理也是一套简单的智能合约。它们允许以去中心化的方式从治理核心合约内调用任何其他智能合约的任何数据。在Compound中,核心合约被设定为其他Compound协议合约的管理者。这意味着核心合约将能够调用各种管理功能,如添加新的市场,改变参数,甚至升级合约本身。

COMP代币持有者可以投票。COMP被分配给系统中的积极参与者,确保使用Compound的人能够决定Compound的未来。

升级功能是最强大的。Compound使用的是典型的代理升级模式,所以通过允许治理合约进行升级,简直可以改变一切,包括治理机制本身。

治理机制遵循一个严格的过程:创建提案、对提案进行投票以及执行前的两天时间限制。

Governance Diagram

治理实践

由于治理系统对Compound来说是一直在线及持续的,你可以在各个不同的地方看到这个系统在真正地发挥作用。

治理智能合约一瞥

现在让我们详细研究一下治理合约,包括:

  • 核心治理合约(GovernorAlpha.sol
  • 时间锁合约(Timelock.sol)。
  • 和COMP代币合约本身

GovernorAlpha.sol

核心治理合约为GovernorAlpha,它包含了创建和执行提案的所有逻辑。

propose() - 提案函数

治理的核心是 提按功能。它接收了一个动作列表,每个动作都包括:

  • target: 所执动作作的目标地址。
  • value: 要传递给调用的msg.value
  • signature: 调用的函数签名,例如:transfer(address, amount)
  • calldata: 要传递给函数调用的数据(参数)。
function propose(
    address[] memory targets,
    uint[] memory values,
    string[] memory signatures,
    bytes[] memory calldatas,
    string memory description
) returns (uint)

拥有至少100,000个代币(即≥1%的发行量)的COMP代币持有者,才能添加一个新的提案,每个提案者只能有一个活跃的提案。最后,必须传递一个 描述字符串,其中包含一个人类可读的提案解释描述。

全民投票:在一个提案被添加后,公投开始了。在提案开始时拥有投票权(通过compToken.getPriorVotes函数调用确认)的地址,可以在3天的投票期内提交他们的投票,无论是 同意还是 反对

castVote() - 投票函数

对一个提案进行投票。该账户的投票权重由该账户在提案状态生效时委托给它的投票数决定。

还有一个使用EIP-712离线签名投票的方法。它的思路与我们之前讨论的ERC-20-Permit是一样的,可以参考阅读无需gas代币的ERC20-Permit

function castVote(
    uint proposalId,
    bool support
)
function castVoteBySig(
    uint proposalId,
    bool support,
    uint8 v,
    bytes32 r,
    bytes32 s
)

Governance Meme

queue() - 加入到执行队列

提案公投成功的条件是:

  • 大多数人投票支持该提案
  • 并且至少有400,000张投票,即≥4%的发行量。

在提案成功后,任何地址都可以调用queue方法,将提案移入Timelock队列。

function queue(
    uint proposalId
)

execute() - 执行函数

一旦时间锁定延迟过去,任何人都可以调用执行方法。它将依次运行提案中的每个动作。

function execute(
    uint proposalId
)

对于任何动作(target、value、signature、calldata),都通过这样的方式执行:

bytes memory callData = abi.encodePacked(bytes4(keccak256(bytes(signature))), data);
(bool success,) = target.call.value(value)(callData);

请记住,calldata以函数选择器开始,它是函数签名字符串的哈希值的前四个字节。所以在这里我们只需将结果拼在现有的calldata中,然后在目标地址上进行call调用。

cancel() - 取消提案函数

在极少数情况下,被通过的提案仍然可以被取消。目前,仍然存在一个有权取消任何提案的监护人地址。它目前是由Compound Labs, Inc.自己持有。在未来,这个监护人地址可能会被删除。

如果最初的提议者在加入提案后失去了创建提案所需的COMP代币数量,那么提案也可以被取消。这可以防止有人进行恶意的提案,例如:COMP的价值可能因恶意提案被接受而下降之前立即卖掉他所有的COMP, cancel() 可以防止这样的情况。

function cancel(
    uint proposalId
)

Timelock合约是对提案执行的一个包装。它由以下部分组成:

  • delay(延时):一个提案被接受后,需要等待多少天之后才能被执行。这个时间可以由治理合约改变为2至30天之间。目前设置为2天。
  • 提案执行期限(grace period):在延时到达时间之后,如果超过了grace period期,那么提案将不能再执行,被设置为14天。

CompToken.sol

它除了是一个普通的ERC-20代币,COMP合约还包括相关的治理方法。

delegate()

用户可以将COMP的投票权委托给另外一个地址。被委托人的投票权是他自己的COMP余额+所有委托给他的COMP余额。

就像以前一样,也存在一个delegateBySig,用于EIP-712离线签名投票:

function delegate(
    address delegatee
)

getPriorVotes()

为了获得某个区块号下的投票权,我们可以调用getPriorVotes来检索该值。显然,这只对过去的区块号有效。

function getPriorVotes(
    address account,
    uint blockNumber
) returns (uint96)

Compound自主提案(CAP)

由于创建一个提案需要10万个COMP代币是一个非常高的门槛,毕竟按照目前的COMP价格,这相当于超过1000万美元,所以引入了一个新的机制,称为Compound自主提案(CAP)。这将允许任何拥有100个COMP或更多的人提出一个提案。任何获得100,000票的CAP都可以被添加为常规提案。

你可以在https://app.compound.finance/vote 下看到并投票给自主提案。

JS SDK和API

你还可以通过JS SDK和API直接从Compound找到有用的治理工具。

治理案例

让我们以提案增加UNI的支持 作为例子。你可以在这里找到创建提案的交易。

address[] targets
0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B
0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B
0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B
0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B
0x35A18000230DA775CAc24873d00Ff85BccdeD550
0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B
string[] signatures
_setPriceOracle(address)
_supportMarket(address)
_addCompMarkets(address[])
_setCollateralFactor(address,uint256)
_setReserveFactor(uint256)
_setMarketBorrowCaps(address[],uint256[])
bytes[] calldatas
0x000000000000000000000000922018674c12a7f0d394ebeef9b58f186cde13c1
0x00000000000000000000000035a18000230da775cac24873d00ff85bccded550
0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000035a18000230da775cac24873d00ff85bccded550
0x00000000000000000000000035a18000230da775cac24873d00ff85bccded5500000000000000000000000000000000000000000000000000853a0d2313c0000
0x00000000000000000000000000000000000000000000000002c68af0bb140000
0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000035a18000230da775cac24873d00ff85bccded550000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000001a784379d99db42000000
string description
Add UNI Support This proposal adds [Uniswap](https://etherscan.io/token/0x1f9840a85d5af5bf1d1762f925bdaddc4201f984) as a supported asset
and implements an updated [Open Price Feed](https://compound.finance/docs/prices) view contract that supports cUNI.

[...]

此外,值(msg.value)都被设置为0。一旦提案被接受并随后执行,所有六个动作都被执行。你可以使用Ethtx.info这样的工具来查看交易的细节。

执行Uniswap建议交易

去中心化治理的未来

Compound治理设计简洁,但仍然相当强大。许多项目都采用了同样的机制,或者至少是受其启发。我们去中心化治理在未来肯定会有更大的发展,因为只有真正的还权于民才能够实现真正的去中心化。


本翻译由 Cell Network 赞助支持。

点赞 4
收藏 8
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

1 条评论

请先 登录 后评论
翻译小组
翻译小组
0x9e64...7c84
大家看到好的文章可以在 GitHub 提 Issue: https://github.com/lbc-team/Pioneer/issues 欢迎关注我的 Twitter: https://twitter.com/UpchainDAO