高级概念
Last updated
Last updated
由于 veFXS 合约的工作原理,如果您锁定更多 FXS 或延长锁定时间,您需要使用 VeFxsVotingDelegation 合约再次委托您的投票权重。
要将委托返回给自己,请调用 delegate()
函数,将您的地址作为受托人。 委托也可以通过签名进行。请参见 delegateBySig()
。
当您的 veFXS 锁定到期时,您的余额等于您锁定的 FXS 数量。在 Frax 治理中,一旦您的锁定到期,您的投票权重将变为 0。您需要保持活跃的锁定才能在 Frax 治理中拥有投票权重。
点击“提案”
填入您的交易数据
提交
Frax 治理利用了 ScopeLift 的分数投票: https://github.com/ScopeLift/flexible-voting/blob/master/src/GovernorCountingFractional.sol
这允许用户在赞成/反对/弃权之间分配他们的投票权。它还允许智能合约/保管人根据相对 LP 份额将投票权传递给流动性提供者。
为了使 Safe 正确配置为 frxGov,它必须安装 FraxGuard,设置 FraxGovernorOmega 为签名者,安装 FraxGovernorAlpha 的 TimelockController 作为模块,并将 FraxCompatibilityFallbackHandler 设置为 fallbackHandler。可以通过 Alpha 提案以类似方式将 Safes 暂停,方法是移除配置并将其从允许列表中删除。 FraxGovernorOmega 和 FraxGovernorAlpha 使用 OpenZeppelin Governor 及以下扩展:
GovernorSettings
GovernorVotesQuorumFraction
GovernorCountingFractional
此外,Alpha 使用这些治理扩展:
GovernorTimelockControl
GovernorPreventLateQuorum
查看它们的配置:
以下所有功能必须通过 Alpha 提案调用。
Alpha 和 Omega:
setVotingDelayBlocks()
setVeFxsVotingDelegation()
updateShortCircuitNumerator()
仅限 Omega:
addToSafeAllowlist()
removeFromSafeAllowlist()
addToDelegateCallAllowlist()
removeFromDelegateCallAllowlist()
setSafeVotingPeriod()
请参阅 frxGov 代码库以了解每个功能的解释。
请参阅 Gnosis Safe 代码库以查看 Alpha 控制的 Safe 配置。
完整提案流程
Alpha 与 OpenZeppelin Governor 和 GovernorTimelockControl 完全相同。
创建提案 - propose()
投票 -castVote()
如果失败则不执行任何操作
如果成功
queue()
Wait Timelock's minDelay
execute()
一个所有者使用 Gnosis Safe 发起 DeFi 交易。这会生成一个事务哈希,标识需要由其他 Safe 所有者批准或拒绝的操作。
⅗ 的外部账户(EOA)通过用户界面签署该交易
收集到 3 个签名后,任何人都可以调用fraxGovernorOmega.addTransaction(address teamSafe, TxHashArgs calldata args, bytes calldata signatures)
开始链上治理。团队有动力这样做,因为他们无法在没有 FraxGovernorOmega 批准的情况下执行任何 Gnosis 交易。
veFXS 投票者在提案投票窗口内有 2 天的时间进行投票。
如果在投票窗口内未达到法定人数,或赞成票多于反对票,任何人都可以调用 execute()
。这会在后台调用safe.approveHash()
。它提供了 FraxGovernorOmega 所需的批准,从而允许通过 Gnosis 用户界面执行 Gnosis 交易。
如果达到了法定人数且反对票多于赞成票,任何人都可以调用 fraxGovernorOmega.rejectTransaction (address teamSafe, uint256 nonce)
否决提案。这将导致 FraxGovernorOmega 签署一个具有相同 nonce 的零 ETH 转账 Safe 交易。Safe 所有者可以使用“替换交易”功能在用户界面中签署相同的交易。Safe 所有者可以执行该零 ETH 转账,从而增加 nonce。原始交易将无法执行,因为没有来自 FraxGovernorOmega 的批准,并且 nonce 已经更改,使得原始交易失效。
背景:https://help.safe.global/en/articles/40783-what-are-signed-messages
Gnosis Safes 可以提供智能合约签名。典型机制包含在 Safe 的 CompatibilityFallbackHandler 中,该机制检查所有者是否满足所需的签名数量,然后 Safe 提供其批准。这个机制对于 frxGov 来说并不充分,因为我们希望 Omega 和所有者共同提供批准,或者仅由 Alpha 提供批准。
为了解决这个问题,我们编写了 FraxCompatibilityFallbackHandler,它仅检查 safe.signedMessages(messageHash)
是否被设置。Alpha 和 Omega 都可以使用 SignMessageLib.signMessage()
调用此状态的设置器。
FraxGovernorAlpha 可能被用来创建一个提案,实质上关闭整个 Frax 协议,并将所有协议拥有的流动性归还给 FXS 持有者。我们在 Alpha 上设置了 Timelock 延迟,以应对这种情况。从提案通过到可以执行之间有一天的时间,给予 Frax 用户通过各种流动性池退出协议的机会。
我们还添加了 OpenZeppelin Governor 扩展 GovernorPreventLateQuorum。如果提案在投票期末期达到法定人数,投票期将延长 2 天。这可以阻止恶意用户在最后一刻投票支持恶意提案,为社区在这种情况下提供反应的时间。
我们还创建了 frxEth 赎回队列,以允许用户在恶意行为者获得 51% veFXS 投票权并通过提案无限铸造 frxEth 以试图盗取财库时退出 frxEth。
为了符合 ERC5805 标准,实现合约必须实现多个函数,包括getPastTotalSupply(uint256 timepoint) external view returns (uint256)
。我们在治理合约中使用时间戳,但这个函数是唯一的例外,它必须接受 block.number
。遗憾的是,veFXS.totalSupply(timestamp)
对历史值无效,因此我们必须使用 veFXS.totalSupplyAt(block.number)
。
这也影响法定人数的计算。通常法定人数是根据投票开始的时间戳(快照)计算的。我们通过使 $votingDelayBlocks
值可由治理配置,允许类似功能,从而反映时间戳功能。
代码库
https://github.com/FraxFinance/frax-governance
合约地址
VeFxsVotingDelegation: https://etherscan.io/address/0x6b83c4f3a6729fb7d5e19b720092162df439f567
FraxGovernorAlpha: https://etherscan.io/address/0xe8Ab863E629a05c73D6a23b99d37027E3763156e
FraxGovernorAlphaTimelock: https://etherscan.io/address/0x821794E69d2831975a11f80E8092c682D5Ec8F83
FraxGovernorOmega: https://etherscan.io/address/0x953791D7C5ac8Ce5fb23BBBF88963DA37a95FE7a
FraxCompatibilityFallbackHandler: https://etherscan.io/address/0x3FeFB779d737aCEa272686eA6E174ebF4273F973