Governance开发者文档
Compound 协议由 COMP Token 持有者管理和升级,使用三个不同的组件; COMP Token、治理模块(Governor Alpha)和 Timelock。这些合约一起,允许社区通过 cToken 或 Comproller 的管理功能提出、投票和实时更改。提案可以包括调整利率模型,到增加对新资产的支持等改变。
任何授权超过 10 万 COMP Token 的地址都可以提出治理活动,这些活动都是可执行的代码。提案产生后,社区可以在 3 天的投票期内提交投票。如果投票获得多数、且至少 40 万票以上,就会在 Timlock 中排队,2 天后可以实施。
COMP 是一个 ERC-20 代币,允许所有者将投票权委托给任何地址,包括自己的地址。所有者的代币余额会自动调整被委托人的投票权。
将发送者的投票数委托给被委托人。用户每次可以委托给一个地址,被委托人的投票数相当于用户账号的 COMP 代币余额。投票将从当前区块开始进行委托,直到发送者再次委托或者转移其 COMP。
COMP
1 function delegate(address delegatee)
Solidity
1 Comp comp = Comp(0x123...); // contract address
2 comp.delegate(delegateeAddress);
Web3 1.2.6
1 const tx = await comp.methods.delegate(delegateeAddress).send({ from: sender });
Delegate 投票从签名者到被委托人。这种方法与 Delegate 的目的相同,但它可以离线签名参与Compound 治理投票授权。有关如何创建离线签名的更多细节,请查看 EIP-712。
COMP
1 function delegateBySig(address delegateeAddress,uint256 nonce,uint256 expiry,uint256 v,uint256 r,uint256 s);
Solidity
1 Comp comp = Comp(0x123...); // contract address
2 comp.delegateBySig(delegateeAddress, nonce, expiry, v, r, s);
Web3 1.2.6
1 const tx = await comp.methods.delegateBySig(delegateeAddress, nonce, expiry, v, r, s).send({});
获取一个账户当前区块的票数余额。
COMP
1 function getCurrentVotes(address account) returns (uint96)
Solidity
1 Comp comp = Comp(0x123...); // contract address
2 uint votes = comp.getCurrentVotes(0xabc...);
Web3 1.2.6
1 const account = '0x123...'; // contract address
2 const votes = await comp.methods.getCurrentVotes(account).call();
获取一个账户在特定区块上的投票数。传入的区块高度必须是最终确定的区块,否则函数将revert。
COMP
1 function getPriorVotes(address account, uint blockNumber) returns (uint96)
Solidity
1 Comp comp = Comp(0x123...); // contract address
2 uint priorVotes = comp.getPriorVotes(account, blockNumber);
Web3 1.2.6
1 const priorVotes = await comp.methods.getPriorVotes(account, blockNumber).call();
Governor Alpha 是协议的治理模块;它允许超过 10 万 COMP 代币的地址提出修改建议。在提案开始时,手握投票权(通过调用 getpriorvotes 方法)的地址可以在 3 天的投票期内提交投票。如果提取被投了多数,且至少有 40 万票,则会在 Timelock 中排队,2 两天后实施。
Govern Alpha 合约包含一个守卫者地址,由 Compound 团队控制,可以取消提案,或在紧急情况下禁用治理模块。在最初的沙盒期后,守护者可以放弃权利,标志着 COMP 代币持有者开始完全控制。
成功支持一项提案的最低票数要求。
Governor Alpha
1 function quorumVotes() public pure returns (uint)
Solidity
1GovernorAlpha gov = GovernorAlpha(0x123...); // contract address
2 uint quorum = gov.quorumVotes();
Web3 1.2.6
1 const quorum = await gov.methods.quorumVotes().call();
账户创建一个提案所需的最低票数;
Governor Alpha
1 function proposalThreshold() returns (uint)
Solidity
1 GovernorAlpha gov = GovernorAlpha(0x123...); // contract address
2 uint threshold = gov.proposalThreshold();
Web3 1.2.6
1 const threshold = await gov.methods.proposalThreshold().call();
提案中可以包含的最大操作数量。操作是指提案成功并执行时将进行的函数调用。
Governor Alpha
1 function proposalMaxOperations() returns (uint)
Solidity
1 GovernorAlpha gov = GovernorAlpha(0x123...); // contract address
2 uint operations = gov.proposalMaxOperations();
Web3 1.2.6
1 const operations = await gov.methods.proposalMaxOperations().call();
在对一个提案投票前需要等到的以太坊区块数。当创建一个提案时,该值会被添加到当前区块高度上。
Governor Alpha
1function votingDelay() returns (uint)
Solidity
1 GovernorAlpha gov = GovernorAlpha(0x123...); // contract address
2 uint blocks = gov.votingDelay();
Web3 1.2.6
1 const blocks = await gov.methods.votingDelay().call();
以以太坊区块为单位,对提案进行投票的持续时间。
Governor Alpha
1 function votingPeriod() returns (uint)
Solidity
1 GovernorAlpha gov = GovernorAlpha(0x123...); // contract address
2 uint blocks = gov.votingPeriod();
Web3 1.2.6
1 const blocks = await gov.methods.votingPeriod().call();
创建一个提案来改变协议。比如:一个提案能在 Comproller 上设置 cToken 的利率模型或者风险参数。
提案将委托投票人进行投票表决。如果在投票期结束前有足够的支持,提案将被自动颁布。已颁布的提案将在 Compound Timelock 合约中排队并执行。
发送者在紧邻的前一个区块中持有的 COMP 代币必须超过当前的提案阈值(proposalThreshold)。如果阈值是 10 万 COMP 代币,则发送者必须被委托超过所有 COMP 的 1% 才能创建一个提案。提案最多有 10 个操作(基于 proposalMaxOperations() )。
如果提案者当前有待处理或活动中的提案,则他们不能创建另一个提案。不可能在同一个区块中排队两个相同的操作(由于 Timelock 中的限制)。因此一个提案中的操作必须是唯一的,共享一个相同操作的唯一提案必须在不同的区块中排队。
Governor Alpha
1 function propose(address[] memory targets, uint[] memory values, string[] memory signatures, bytes[] memory calldatas, string memory description) returns (uint)
Solidity
1 GovernorAlpha gov = GovernorAlpha(0x123...); // contract address
2 uint proposalId = gov.propose(targets, values, signatures, calldatas, description);
Web3 1.2.6
1const tx = gov.methods.propose(targets, values, signatures, calldatas, description).send({ from: sender });
提案通过后,任何地址可以调用 queue 方法将提案转移到 Timelock 队列中。提案只有在成功通过后,才能被排队。
Governor Alpha
1 function queue(uint proposalId)
Solidity
1 GovernorAlpha gov = GovernorAlpha(0x123...); // contract address
2 gov.queue(proposalId);
Web3 1.2.6
1 const tx = gov.methods.queue(proposalId).send({ from: sender });
在 Timelock 延迟期之后,任何账户都可以调用 execu 方法将提案中的更改应用到目标合约中。这将调用提案中描述的每一个操作。
这个功能是可支付(payable)的,所以 Timelock 合约可以调用提案中选择的可支付功能。例如,A 提案可以 像cETH 一样在市场上添加准备金,设置 cToken 的利率模型,或者在 Comptroller上设置风险参数。
Governor Alpha
1function execute(uint proposalId) payable returns (uint)
Solidity
1 GovernorAlpha gov = GovernorAlpha(0x123...); // contract address
2 gov.execute(proposalId).value(999).gas(999)();
Web3 1.2.6
1 const tx = gov.methods.execute(proposalId).send({ from: sender, value: 1 });
取消尚未执行的提案。除非提案人没有维持创建提案所需的委托量,否则监护人是唯一可以执行取消的人。如果提案人的委托人数没有超过提案的阈值,任何人都可以取消该提案。
Governor Alpha
1 function cancel(uint proposalId)
Solidity
1 GovernorAlpha gov = GovernorAlpha(0x123...); // contract address
2 gov.cancel(proposalId);
Web3 1.2.6
1 const tx = gov.methods.cancel(proposalId).send({ from: sender });
获取所选提案的操作列表。传递一个提案 ID,获取该提案的目标对象、值、签名和调用数据。
Governor Alpha
1 function getActions(uint proposalId) returns (uint proposalId) public view returns (address[] memory targets, uint[] memory values, string[] memory signatures, bytes[] memory calldatas)
Solidity
1 GovernorAlpha gov = GovernorAlpha(0x123...); // contract address
2 uint proposalId = 123;
3 (address[] memory targets, uint[] memory values, string[] memory signatures, bytes[] memory calldatas) = gov.getActions(proposalId);
Web3 1.2.6
1 const {0: targets, 1: values, 2: signatures, 3: calldatas} = gov.methods.getActions(proposalId).call();
获得指定投票者的提案选票。
Governor Alpha
1 function getReceipt(uint proposalId, address voter) returns (Receipt memory)
Solidity
1 GovernorAlpha gov = GovernorAlpha(0x123...); // contract address
2 Receipt ballot = gov.getReceipt(proposalId, voterAddress);
Web3 1.2.6
1 const proposalId = 11;
2 const voterAddress = '0x123...';
3 const result = await gov.methods.getReceipt(proposalId, voterAddress).call();
4 const { hasVoted, support, votes } = result;
获取指定提案的提案状态。返回值 ProposalState 是一个 Governor Alpha 合约中定义的枚举类型。
Governor Alpha
1 function state(uint proposalId) returns (ProposalState)
返回值 : 枚举类型 ProposalState。类型有:Pending(等待中)、Active(活动中)、
Canceled(已取消)、Defeated(已败北)、 Succeeded(已成功)、Queued(已排队)、Expired(已过期)和Executed(已执行)。
Solidity
1 overnorAlpha gov = GovernorAlpha(0x123...); // contract address
2 GovernorAlpha.ProposalState state = gov.state(123);
Web3 1.2.6
1 const proposalStates = ['Pending', 'Active', 'Canceled', 'Defeated', 'Succeeded', 'Queued', 'Expired', 'Executed'];
2 const proposalId = 123;
3 result = await gov.methods.state(proposalId).call();
4 const proposalState = proposalStates[result];
对某项提案进行投票。该账户的表决权重取决于该账户在提案开始生效时的表决权重。
Governor Alpha
1 function castVote(uint proposalId, bool support)
Solidity
1 GovernorAlpha gov = GovernorAlpha(0x123...); // contract address
2 gov.castVote(proposalId, true);
Web3 1.2.6
1 const tx = gov.methods.castVote(proposalId, false).send({ from: sender });
对某项提案进行投票。该账户的投票权重由该账户在该提案状态生效时的投票权重决定。此方法的目的与 "cast vote "相同,但它可以让脱机签名参与 Compound 治理投票。有关如何创建离线签名的详细信息,请查看 EIP-712。
Governor Alpha
1 function castVoteBySig(uint proposalId, bool support, uint8 v, bytes32 r, bytes32 s)
Solidity
1 GovernorAlpha gov = GovernorAlpha(0x123...); // contract address
2 gov.castVoteBySig(proposalId, true, v, r, s);
Web3 1.2.6
1 const tx = await gov.methods.castVoteBySig(proposalId, false, v, r, s).send({});
每个 cToken 合约和 Comptroller 合约都允许 Timelock 地址修改。Timelock 合约可以修改系统参数、逻辑和合约,以 "延迟时间、选择退出 " 的升级模式进行修改。
Timelock 有一个 2 天的最小延迟时间硬性规定,这是治理行动的最小通知时间。每项拟采取的治理行动,都会在公告后至少 2 天内公布。重大升级,如变更风险系统等,可能会有 14 天的延迟时间。
时间锁由治理模块控制;待定和已完成的治理行动可以在时间锁仪表板上监控。
Comptroller 合约指定了一个能够禁用协议功能的暂停守护者地址。暂停守护者只有在出现不可预见的漏洞时才会使用,暂停守护者只有一种能力:禁用一组选定的功能。Mint、Borrow、Borrow、Transfer 和 Liquidate。暂停守护者不能解除一个动作,也不能阻止用户调用赎回、偿还借款以平仓和退出协议。
目前,Compound 团队控制了暂停守护者的地址。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!