Address Contract Verified
Address
0x119FbeeDD4F4f4298Fb59B720d5654442b81ae2c
Balance
0 ETH
Nonce
1
Code Size
3836 bytes
Creator
0xF2f1ACbe...40BB at tx 0x63c6feae...b072c3
Indexed Transactions
0 (1 on-chain, <1% indexed)
Contract Bytecode
3836 bytes
0x608060405234801561000f575f80fd5b5060043610610163575f3560e01c8063abf306a8116100c7578063d7d1c1c01161007d578063f294bd9211610063578063f294bd9214610332578063f52c93c514610359578063fbfa77cf14610361575f80fd5b8063d7d1c1c0146102f8578063e94bb2231461030b575f80fd5b8063b3d0c202116100ad578063b3d0c202146102c8578063b4d87a12146102d2578063d48d8423146102e5575f80fd5b8063abf306a814610281578063af63a3e1146102a1575f80fd5b80635548917f1161011c5780638eaa6ac0116101025780638eaa6ac01461024757806391ddadf41461025a5780639662ac5814610279575f80fd5b80635548917f146101f95780638df3227f14610220575f80fd5b80632595f8cf1161014c5780632595f8cf146101945780634bf5d7e9146101b75780634d6d7441146101cc575f80fd5b806307a0033014610167578063246c53081461017c575b5f80fd5b61017a610175366004610b41565b610388565b005b6213c6805b6040519081526020015b60405180910390f35b6101a76101a2366004610ba9565b61042a565b604051901515815260200161018b565b6101bf610514565b60405161018b9190610bf1565b6101d4610523565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161018b565b6101d47f0000000000000000000000003414922ff6edf6aacadb6ab4f2533089144625c481565b6101d47f000000000000000000000000a0dafaeea4a1d44534e1b9227e19cae6358b80fe81565b610181610255366004610c5b565b6105b1565b61026261061f565b60405165ffffffffffff909116815260200161018b565b6101d4610631565b61029461028f366004610c72565b61069b565b60405161018b9190610cb1565b6101d47f000000000000000000000000f6de7fde6f7a8947b94973053b580e754360d2f981565b63661bd350610181565b61017a6102e0366004610d18565b610796565b61017a6102f3366004610d18565b61086b565b6101a7610306366004610d18565b61093f565b6101d47f0000000000000000000000009fff4be0003d0716f37f8d2574e89f1a5d0745c881565b6101d47f000000000000000000000000988567fe094570cce1ffda29d1f2d842b70492be81565b6101d46109e0565b6101d47f000000000000000000000000d7298f620b0f752cf41bd818a16c756d9dcaa34f81565b610390610a4a565b805f806103e9856040517f56414c55450000000000000000000000000000000000000000000000000000006020820152602581018290525f90604501604051602081830303815290604052805190602001209050919050565b81526020019081526020015f20819055827f40d4a420f99fca87993b89b3251153e5ffb22d82a70bf764d19ba9f0621d653560405160405180910390a35050565b5f805b828110156105075760015f806104e38888888781811061044f5761044f610d46565b90506020020160208101906104649190610d73565b6040517f494e5f4c495354000000000000000000000000000000000000000000000000006020820152602781018390527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606083901b1660478201525f90605b0160405160208183030381529060405280519060200120905092915050565b81526020019081526020015f2054146104ff575f91505061050d565b60010161042d565b50600190505b9392505050565b606061051e610af9565b905090565b5f7f0000000000000000000000009fff4be0003d0716f37f8d2574e89f1a5d0745c873ffffffffffffffffffffffffffffffffffffffff1663585e78af6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561058d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061051e9190610d8e565b5f805f61060a846040517f56414c55450000000000000000000000000000000000000000000000000000006020820152602581018290525f90604501604051602081830303815290604052805190602001209050919050565b81526020019081526020015f20549050919050565b5f610628610b19565b61ffff16905090565b5f7f000000000000000000000000f6de7fde6f7a8947b94973053b580e754360d2f973ffffffffffffffffffffffffffffffffffffffff1663585e78af6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561058d573d5f803e3d5ffd5b60608167ffffffffffffffff8111156106b6576106b6610da9565b6040519080825280602002602001820160405280156106df578160200160208202803683370190505b5090505f5b8281101561078f575f8061075c86868581811061070357610703610d46565b905060200201356040517f56414c55450000000000000000000000000000000000000000000000000000006020820152602581018290525f90604501604051602081830303815290604052805190602001209050919050565b81526020019081526020015f205482828151811061077c5761077c610d46565b60209081029190910101526001016106e4565b5092915050565b61079e610a4a565b604080517f494e5f4c49535400000000000000000000000000000000000000000000000000602080830191909152602782018590527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085901b1660478301528251808303603b018152605b9092018084528251928201929092205f908152908190529182206001905573ffffffffffffffffffffffffffffffffffffffff83169184917f56573e227f8e2cfaf9c513a7e1586b18527b6f4010b703025003741b6a451ad59190a35050565b610873610a4a565b604080517f494e5f4c49535400000000000000000000000000000000000000000000000000602080830191909152602782018590527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085901b1660478301528251808303603b018152605b9092018084528251928201929092205f9081529081905291822082905573ffffffffffffffffffffffffffffffffffffffff83169184917f72e193b20c528dc6c7ac5d8f5bc4354aa22b592c0fdca040fa926c2ff90534f79190a35050565b5f600181806109c886866040517f494e5f4c495354000000000000000000000000000000000000000000000000006020820152602781018390527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606083901b1660478201525f90605b0160405160208183030381529060405280519060200120905092915050565b81526020019081526020015f20541490505b92915050565b5f7f0000000000000000000000003414922ff6edf6aacadb6ab4f2533089144625c473ffffffffffffffffffffffffffffffffffffffff1663585e78af6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561058d573d5f803e3d5ffd5b610a52610523565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015610ac05750610a906109e0565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b15610af7576040517f72fab01a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60606040518060a0016040528060658152602001610e6260659139905090565b5f6213c680610b2c63661bd35042610e03565b610b369190610e16565b61051e906001610e4e565b5f8060408385031215610b52575f80fd5b50508035926020909101359150565b5f8083601f840112610b71575f80fd5b50813567ffffffffffffffff811115610b88575f80fd5b6020830191508360208260051b8501011115610ba2575f80fd5b9250929050565b5f805f60408486031215610bbb575f80fd5b83359250602084013567ffffffffffffffff811115610bd8575f80fd5b610be486828701610b61565b9497909650939450505050565b5f602080835283518060208501525f5b81811015610c1d57858101830151858201604001528201610c01565b505f6040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b5f60208284031215610c6b575f80fd5b5035919050565b5f8060208385031215610c83575f80fd5b823567ffffffffffffffff811115610c99575f80fd5b610ca585828601610b61565b90969095509350505050565b602080825282518282018190525f9190848201906040850190845b81811015610ce857835183529284019291840191600101610ccc565b50909695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610d15575f80fd5b50565b5f8060408385031215610d29575f80fd5b823591506020830135610d3b81610cf4565b809150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f60208284031215610d83575f80fd5b813561050d81610cf4565b5f60208284031215610d9e575f80fd5b815161050d81610cf4565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b818103818111156109da576109da610dd6565b5f82610e49577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b808201808211156109da576109da610dd656fe6d6f64653d65706f63682665706f6368556e6465726c79696e67536f757263653d626c6f636b54696d657374616d702665706f63685374617274696e6754696d657374616d703d313731333039393630302665706f6368506572696f643d31323936303030a26469706673582212200a0c0a55c2e0eb0c25754573a708b569ab026719b289cbf421f59aa7286248d664736f6c63430008170033
Verified Source Code Full Match
Compiler: v0.8.23+commit.f704f362
EVM: shanghai
Optimization: Yes (999999 runs)
Registrar.sol 201 lines
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.23;
import { IEmergencyGovernorDeployer } from "./interfaces/IEmergencyGovernorDeployer.sol";
import { IERC6372 } from "./abstract/interfaces/IERC6372.sol";
import { IPowerTokenDeployer } from "./interfaces/IPowerTokenDeployer.sol";
import { IRegistrar } from "./interfaces/IRegistrar.sol";
import { IStandardGovernorDeployer } from "./interfaces/IStandardGovernorDeployer.sol";
import { IZeroGovernor } from "./interfaces/IZeroGovernor.sol";
import { PureEpochs } from "./libs/PureEpochs.sol";
/*
████████╗████████╗ ██████╗ ██████╗ ███████╗ ██████╗ ██╗███████╗████████╗██████╗ █████╗ ██████╗
╚══██╔══╝╚══██╔══╝██╔════╝ ██╔══██╗██╔════╝██╔════╝ ██║██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██╔══██╗
██║ ██║ ██║ ███╗ ██████╔╝█████╗ ██║ ███╗██║███████╗ ██║ ██████╔╝███████║██████╔╝
██║ ██║ ██║ ██║ ██╔══██╗██╔══╝ ██║ ██║██║╚════██║ ██║ ██╔══██╗██╔══██║██╔══██╗
██║ ██║ ╚██████╔╝ ██║ ██║███████╗╚██████╔╝██║███████║ ██║ ██║ ██║██║ ██║██║ ██║
╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝
*/
/**
* @title A book of record of TTG-specific contracts and arbitrary key-value pairs and lists.
* @author M^0 Labs
*/
contract Registrar is IRegistrar {
/* ============ Variables ============ */
/// @inheritdoc IRegistrar
address public immutable emergencyGovernorDeployer;
/// @inheritdoc IRegistrar
address public immutable powerTokenDeployer;
/// @inheritdoc IRegistrar
address public immutable standardGovernorDeployer;
/// @inheritdoc IRegistrar
address public immutable vault;
/// @inheritdoc IRegistrar
address public immutable zeroGovernor;
/// @inheritdoc IRegistrar
address public immutable zeroToken;
/// @dev A mapping of keys to values.
mapping(bytes32 key => bytes32 value) internal _valueAt;
/* ============ Modifiers ============ */
/// @dev Revert if the caller is not the Standard Governor nor the Emergency Governor.
modifier onlyStandardOrEmergencyGovernor() {
_revertIfNotStandardOrEmergencyGovernor();
_;
}
/* ============ Constructor ============ */
/**
* @notice Constructs a new Registrar contract.
* @param zeroGovernor_ The address of the ZeroGovernor contract.
*/
constructor(address zeroGovernor_) {
if ((zeroGovernor = zeroGovernor_) == address(0)) revert InvalidZeroGovernorAddress();
IZeroGovernor zeroGovernorInstance_ = IZeroGovernor(zeroGovernor_);
if ((emergencyGovernorDeployer = zeroGovernorInstance_.emergencyGovernorDeployer()) == address(0))
revert InvalidEmergencyGovernorDeployerAddress();
if ((powerTokenDeployer = zeroGovernorInstance_.powerTokenDeployer()) == address(0))
revert InvalidPowerTokenDeployerAddress();
address standardGovernorDeployer_ = standardGovernorDeployer = zeroGovernorInstance_.standardGovernorDeployer();
if (standardGovernorDeployer_ == address(0)) revert InvalidStandardGovernorDeployerAddress();
if ((zeroToken = zeroGovernorInstance_.voteToken()) == address(0)) revert InvalidVoteTokenAddress();
if ((vault = IStandardGovernorDeployer(standardGovernorDeployer_).vault()) == address(0))
revert InvalidVaultAddress();
}
/* ============ Interactive Functions ============ */
/// @inheritdoc IRegistrar
function addToList(bytes32 list_, address account_) external onlyStandardOrEmergencyGovernor {
_valueAt[_getIsInListKey(list_, account_)] = bytes32(uint256(1));
emit AddressAddedToList(list_, account_);
}
/// @inheritdoc IRegistrar
function removeFromList(bytes32 list_, address account_) external onlyStandardOrEmergencyGovernor {
delete _valueAt[_getIsInListKey(list_, account_)];
emit AddressRemovedFromList(list_, account_);
}
/// @inheritdoc IRegistrar
function setKey(bytes32 key_, bytes32 value_) external onlyStandardOrEmergencyGovernor {
emit KeySet(key_, _valueAt[_getValueKey(key_)] = value_);
}
/* ============ View/Pure Functions ============ */
/// @inheritdoc IERC6372
function clock() external view returns (uint48) {
return PureEpochs.currentEpoch();
}
/// @inheritdoc IRegistrar
function get(bytes32 key_) external view returns (bytes32) {
return _valueAt[_getValueKey(key_)];
}
/// @inheritdoc IRegistrar
function get(bytes32[] calldata keys_) external view returns (bytes32[] memory values_) {
values_ = new bytes32[](keys_.length);
for (uint256 index_; index_ < keys_.length; ++index_) {
values_[index_] = _valueAt[_getValueKey(keys_[index_])];
}
}
/// @inheritdoc IRegistrar
function listContains(bytes32 list_, address account_) external view returns (bool) {
return _valueAt[_getIsInListKey(list_, account_)] == bytes32(uint256(1));
}
/// @inheritdoc IRegistrar
function listContains(bytes32 list_, address[] calldata accounts_) external view returns (bool) {
for (uint256 index_; index_ < accounts_.length; ++index_) {
if (_valueAt[_getIsInListKey(list_, accounts_[index_])] != bytes32(uint256(1))) return false;
}
return true;
}
/// @inheritdoc IRegistrar
function powerToken() external view returns (address) {
return IPowerTokenDeployer(powerTokenDeployer).lastDeploy();
}
/// @inheritdoc IERC6372
function CLOCK_MODE() external pure returns (string memory) {
return PureEpochs.clockMode();
}
/// @inheritdoc IRegistrar
function clockStartingTimestamp() external pure returns (uint256) {
return PureEpochs.STARTING_TIMESTAMP;
}
/// @inheritdoc IRegistrar
function clockPeriod() external pure returns (uint256) {
return PureEpochs.EPOCH_PERIOD;
}
/// @inheritdoc IRegistrar
function emergencyGovernor() public view returns (address) {
return IEmergencyGovernorDeployer(emergencyGovernorDeployer).lastDeploy();
}
/// @inheritdoc IRegistrar
function standardGovernor() public view returns (address) {
return IStandardGovernorDeployer(standardGovernorDeployer).lastDeploy();
}
/* ============ Internal View/Pure Functions ============ */
/// @dev Reverts if the caller is not the Standard Governor nor the Emergency Governor.
function _revertIfNotStandardOrEmergencyGovernor() internal view {
if (msg.sender != standardGovernor() && msg.sender != emergencyGovernor()) {
revert NotStandardOrEmergencyGovernor();
}
}
/**
* @dev Returns the key used to store the value of `key_`.
* @param key_ The key of the value.
* @return The key used to store the value of `key_`.
*/
function _getValueKey(bytes32 key_) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("VALUE", key_));
}
/**
* @dev Returns the key used to store whether `account_` is in `list_`.
* @param list_ The list of addresses.
* @param account_ The address of the account.
* @return The key used to store whether `account_` is in `list_`.
*/
function _getIsInListKey(bytes32 list_, address account_) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("IN_LIST", list_, account_));
}
}
PureEpochs.sol 34 lines
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.23;
/**
* @notice Defines epochs as periods away from STARTING_TIMESTAMP timestamp.
* @author M^0 Labs
* @dev Provides a `uint16` epoch clock value.
*/
library PureEpochs {
/* ============ Variables ============ */
/// @notice The timestamp of the start of Epoch 1.
uint40 internal constant STARTING_TIMESTAMP = 1713099600;
/// @notice The approximate target of seconds an epoch should endure.
uint40 internal constant EPOCH_PERIOD = 1296000;
/* ============ Internal View/Pure Functions ============ */
/// @dev Returns the current epoch number.
function currentEpoch() internal view returns (uint16) {
return uint16(((block.timestamp - STARTING_TIMESTAMP) / EPOCH_PERIOD) + 1);
}
/// @dev Returns the remaining time in the current epoch.
function timeRemainingInCurrentEpoch() internal view returns (uint40) {
return STARTING_TIMESTAMP + (currentEpoch() * EPOCH_PERIOD) - uint40(block.timestamp);
}
function clockMode() internal pure returns (string memory) {
return "mode=epoch&epochUnderlyingSource=blockTimestamp&epochStartingTimestamp=1713099600&epochPeriod=1296000";
}
}
IDeployer.sol 18 lines
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.23;
/**
* @title A Deterministic deployer of contracts using CREATE.
* @author M^0 Labs
*/
interface IDeployer {
/// @notice Returns the nonce used to pre deterministically compute the address of the next deployed contract.
function nonce() external view returns (uint256);
/// @notice Returns the address of the last contract deployed by this contract.
function lastDeploy() external view returns (address);
/// @notice Returns the address of the next contract this contract will deploy.
function nextDeploy() external view returns (address);
}
IRegistrar.sol 145 lines
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.23;
import { IERC6372 } from "../abstract/interfaces/IERC6372.sol";
/**
* @title A book of record of TTG-specific contracts and arbitrary key-value pairs and lists.
* @author M^0 Labs
*/
interface IRegistrar is IERC6372 {
/* ============ Events ============ */
/**
* @notice Emitted when `account` is added to `list`.
* @param list The key for the list.
* @param account The address of the added account.
*/
event AddressAddedToList(bytes32 indexed list, address indexed account);
/**
* @notice Emitted when `account` is removed from `list`.
* @param list The key for the list.
* @param account The address of the removed account.
*/
event AddressRemovedFromList(bytes32 indexed list, address indexed account);
/**
* @notice Emitted when `key` is set to `value`.
* @param key The key.
* @param value The value.
*/
event KeySet(bytes32 indexed key, bytes32 indexed value);
/* ============ Custom Errors ============ */
/// @notice Revert message when the Emergency Governor Deployer retrieved in the constructor is address(0).
error InvalidEmergencyGovernorDeployerAddress();
/// @notice Revert message when the Power Token Deployer retrieved in the constructor is address(0).
error InvalidPowerTokenDeployerAddress();
/// @notice Revert message when the Standard Governor Deployer retrieved in the constructor is address(0).
error InvalidStandardGovernorDeployerAddress();
/// @notice Revert message when the Vault retrieved in the constructor is address(0).
error InvalidVaultAddress();
/// @notice Revert message when the Vote Token retrieved in the constructor is address(0).
error InvalidVoteTokenAddress();
/// @notice Revert message when the Zero Governor specified in the constructor is address(0).
error InvalidZeroGovernorAddress();
/// @notice Revert message when the caller is not the Standard Governor nor the Emergency Governor.
error NotStandardOrEmergencyGovernor();
/* ============ Interactive Functions ============ */
/**
* @notice Adds `account` to `list`.
* @param list The key for some list.
* @param account The address of some account to be added.
*/
function addToList(bytes32 list, address account) external;
/**
* @notice Removes `account` from `list`.
* @param list The key for some list.
* @param account The address of some account to be removed.
*/
function removeFromList(bytes32 list, address account) external;
/**
* @notice Sets `key` to `value`.
* @param key Some key.
* @param value Some value.
*/
function setKey(bytes32 key, bytes32 value) external;
/* ============ View/Pure Functions ============ */
/// @notice Returns the starting timestamp of Epoch 1.
function clockStartingTimestamp() external pure returns (uint256);
/// @notice Returns the period/duration, in seconds, of an epoch.
function clockPeriod() external pure returns (uint256);
/**
* @notice Returns the value of `key`.
* @param key Some key.
* @return Some value.
*/
function get(bytes32 key) external view returns (bytes32);
/**
* @notice Returns the values of `keys` respectively.
* @param keys Some keys.
* @return Some values.
*/
function get(bytes32[] calldata keys) external view returns (bytes32[] memory);
/**
* @notice Returns whether `list` contains `account`.
* @param list The key for some list.
* @param account The address of some account.
* @return Whether `list` contains `account`.
*/
function listContains(bytes32 list, address account) external view returns (bool);
/**
* @notice Returns whether `list` contains all specified accounts.
* @param list The key for some list.
* @param accounts An array of addressed of some accounts.
* @return Whether `list` contains all specified accounts.
*/
function listContains(bytes32 list, address[] calldata accounts) external view returns (bool);
/// @notice Returns the address of the Emergency Governor.
function emergencyGovernor() external view returns (address);
/// @notice Returns the address of the Emergency Governor Deployer.
function emergencyGovernorDeployer() external view returns (address);
/// @notice Returns the address of the Power Token.
function powerToken() external view returns (address);
/// @notice Returns the address of the Power Token Deployer.
function powerTokenDeployer() external view returns (address);
/// @notice Returns the address of the Standard Governor.
function standardGovernor() external view returns (address);
/// @notice Returns the address of the Standard Governor Deployer.
function standardGovernorDeployer() external view returns (address);
/// @notice Returns the address of the Vault.
function vault() external view returns (address);
/// @notice Returns the address of the Zero Governor.
function zeroGovernor() external view returns (address);
/// @notice Returns the address of the Zero Token.
function zeroToken() external view returns (address);
}
IZeroGovernor.sol 127 lines
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.23;
import { IThresholdGovernor } from "../abstract/interfaces/IThresholdGovernor.sol";
/**
* @title An instance of a ThresholdGovernor with a unique and limited set of possible proposals.
* @author M^0 Labs
*/
interface IZeroGovernor is IThresholdGovernor {
/* ============ Events ============ */
/**
* @notice Emitted upon contract deployment, once the set of allowed cash tokens is finalized.
* @param allowedCashTokens An array of addressed that are allowed as cash tokens.
*/
event AllowedCashTokensSet(address[] allowedCashTokens);
/**
* @notice Emitted upon a Reset, resulting in a new Standard Governor, Emergency Governor, and Power Token.
* @param bootstrapToken The address of token (Zero Token or old Power Token), that bootstraps the reset.
* @param standardGovernor The address of the new Standard Governor.
* @param emergencyGovernor The address of the new Emergency Governor.
* @param powerToken The address of the new Power Token.
*/
event ResetExecuted(
address indexed bootstrapToken,
address standardGovernor,
address emergencyGovernor,
address powerToken
);
/* ============ Custom Errors ============ */
/// @notice Revert message when the Cash Token specified is not in the allowed set.
error InvalidCashToken();
/// @notice Revert message when the Cash Token specified in the constructor is address(0).
error InvalidCashTokenAddress();
/// @notice Revert message when the Emergency Governor Deployer specified in the constructor is address(0).
error InvalidEmergencyGovernorDeployerAddress();
/// @notice Revert message when the Power Token Deployer specified in the constructor is address(0).
error InvalidPowerTokenDeployerAddress();
/// @notice Revert message when the Standard Governor Deployer specified in the constructor is address(0).
error InvalidStandardGovernorDeployerAddress();
/// @notice Revert message when the set of allowed cash tokens specified in the constructor is empty.
error NoAllowedCashTokens();
/**
* @notice Revert message when the address of the deployed Power Token differs fro what was expected.
* @param expected The expected address of the deployed Power Token.
* @param deployed The actual address of the deployed Power Token.
*/
error UnexpectedPowerTokenDeployed(address expected, address deployed);
/**
* @notice Revert message when the address of the deployed Standard Governor differs fro what was expected.
* @param expected The expected address of the deployed Standard Governor.
* @param deployed The actual address of the deployed Standard Governor.
*/
error UnexpectedStandardGovernorDeployed(address expected, address deployed);
/* ============ Proposal Functions ============ */
/**
* @notice One of the valid proposals. Reset the Standard Governor, Emergency Governor, and Power Token to the
* Power Token holders. This would be used by Zero Token holders in the event that inflation is soon to
* result in Power Token overflowing, and/or there is a loss of faith in the state of either the Standard
* Governor or Emergency Governor.
*/
function resetToPowerHolders() external;
/**
* @notice One of the valid proposals. Reset the Standard Governor, Emergency Governor, and Power Token to the
* ZeroToken holders. This would be used by Zero Token holders if they no longer have faith in the current
* set of PowerToken holders and/or the state of either the Standard Governor or Emergency Governor.
*/
function resetToZeroHolders() external;
/**
* @notice One of the valid proposals. Sets the Cash Token of the system.
* @param newCashToken The address of the new cash token.
* @param newProposalFee The amount of cash token required onwards to create Standard Governor proposals.
*/
function setCashToken(address newCashToken, uint256 newProposalFee) external;
/**
* @notice One of the valid proposals. Sets the threshold ratio for Emergency Governor proposals.
* @param newThresholdRatio The new threshold ratio.
*/
function setEmergencyProposalThresholdRatio(uint16 newThresholdRatio) external;
/**
* @notice One of the valid proposals. Sets the threshold ratio for this governor's proposals.
* @param newThresholdRatio The new threshold ratio.
*/
function setZeroProposalThresholdRatio(uint16 newThresholdRatio) external;
/* ============ View/Pure Functions ============ */
/**
* @notice Returns whether `token` is an allowed Cash Token of the system, as a parameter in setCashToken proposal.
* @param token The address of some token.
* @return Whether `token` is an allowed Cash Token.
*/
function isAllowedCashToken(address token) external view returns (bool);
/// @notice Returns the address of the Emergency Governor.
function emergencyGovernor() external view returns (address);
/// @notice Returns the address of the Emergency Governor Deployer.
function emergencyGovernorDeployer() external view returns (address);
/// @notice Returns the address of the Power Token Deployer.
function powerTokenDeployer() external view returns (address);
/// @notice Returns the address of the Standard Governor.
function standardGovernor() external view returns (address);
/// @notice Returns the address of the Standard Governor Deployer.
function standardGovernorDeployer() external view returns (address);
}
IERC6372.sol 16 lines
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.23;
/**
* @title Contract clock properties.
* @author M^0 Labs
* @dev The interface as defined by EIP-6372: https://eips.ethereum.org/EIPS/eip-6372
*/
interface IERC6372 {
/// @notice Returns a machine-readable string description of the clock the contract is operating on.
function CLOCK_MODE() external view returns (string memory);
/// @notice Returns the current timepoint according to the mode the contract is operating on.
function clock() external view returns (uint48);
}
IERC712.sol 39 lines
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.23;
/**
* @title Typed structured data hashing and signing via EIP-712.
* @author M^0 Labs
* @dev The interface as defined by EIP-712: https://eips.ethereum.org/EIPS/eip-712
*/
interface IERC712 {
/* ============ Custom Errors ============ */
/// @notice Revert message when an invalid signature is detected.
error InvalidSignature();
/// @notice Revert message when a signature with invalid length is detected.
error InvalidSignatureLength();
/// @notice Revert message when the S portion of a signature is invalid.
error InvalidSignatureS();
/// @notice Revert message when the V portion of a signature is invalid.
error InvalidSignatureV();
/**
* @notice Revert message when a signature is being used beyond its deadline (i.e. expiry).
* @param deadline The deadline of the signature.
* @param timestamp The current timestamp.
*/
error SignatureExpired(uint256 deadline, uint256 timestamp);
/// @notice Revert message when a recovered signer does not match the account being purported to have signed.
error SignerMismatch();
/* ============ View/Pure Functions ============ */
/// @notice Returns the EIP712 domain separator used in the encoding of a signed digest.
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
IGovernor.sol 306 lines
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.23;
import { IERC712 } from "../../../lib/common/src/interfaces/IERC712.sol";
import { IERC6372 } from "./IERC6372.sol";
/**
* @title Minimal OpenZeppelin-style, Tally-compatible governor.
* @author M^0 Labs
*/
interface IGovernor is IERC6372, IERC712 {
/* ============ Enums ============ */
/**
* @notice Proposal state.
* @param Pending The proposal has been created, but the vote has not started yet.
* @param Active The proposal is currently in the voting period.
* @param Canceled The proposal has been canceled.
* @param Defeated The proposal has been defeated.
* @param Succeeded The proposal has succeeded.
* @param Queued The proposal has been queued.
* @param Expired The proposal has expired.
* @param Executed The proposal has been executed.
*/
enum ProposalState {
Pending,
Active,
Canceled, // never used by TTG.
Defeated,
Succeeded,
Queued, // never used by TTG.
Expired,
Executed
}
/* ============ Events ============ */
/**
* @notice Emitted when a proposal has been created.
* @param proposalId The unique identifier for the proposal.
* @param proposer The address of the account that created the proposal.
* @param targets An array of addresses that will be called upon the execution.
* @param values An array of ETH amounts that will be sent to each respective target upon execution.
* @param signatures Empty string array required to be compatible with OZ governor contract.
* @param callDatas An array of call data used to call each respective target upon execution.
* @param voteStart The first clock value when voting on the proposal is allowed.
* @param voteEnd The last clock value when voting on the proposal is allowed.
* @param description The string of the description of the proposal.
*/
event ProposalCreated(
uint256 proposalId,
address proposer,
address[] targets,
uint256[] values,
string[] signatures,
bytes[] callDatas,
uint256 voteStart,
uint256 voteEnd,
string description
);
/**
* @notice Emitted when a proposal has been executed.
* @param proposalId The unique identifier for the proposal.
*/
event ProposalExecuted(uint256 proposalId);
/**
* @notice Emitted when a vote for a proposal with id `proposalId` has been cast by `voter`.
* @param voter The address of the account that has casted their vote.
* @param proposalId The unique identifier for the proposal.
* @param support The type of support that has been cast for the proposal.
* @param weight The number of votes cast.
* @param reason The string of the reason `voter` has cast their vote, if any.
*/
event VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason);
/* ============ Interactive Functions ============ */
/**
* @notice Allows the caller to cast a vote on a proposal with id `proposalId`.
* @param proposalId The unique identifier for the proposal.
* @param support The type of support to cast for the proposal.
* @return weight The number of votes cast.
*/
function castVote(uint256 proposalId, uint8 support) external returns (uint256 weight);
/**
* @notice Allows a signer to cast a vote on a proposal with id `proposalId` via an ECDSA secp256k1 signature.
* @param proposalId The unique identifier for the proposal.
* @param support The type of support to cast for the proposal.
* @param v An ECDSA secp256k1 signature parameter.
* @param r An ECDSA secp256k1 signature parameter.
* @param s An ECDSA secp256k1 signature parameter.
* @return weight The number of votes cast.
*/
function castVoteBySig(
uint256 proposalId,
uint8 support,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint256 weight);
/**
* @notice Allows `voter` to cast a vote on a proposal with id `proposalId` via an arbitrary signature.
* @param voter The address of the account that casting their vote, and purported to have signed.
* @param proposalId The unique identifier for the proposal.
* @param support The type of support to cast for the proposal.
* @param signature An arbitrary signature.
* @return weight The number of votes cast.
*/
function castVoteBySig(
address voter,
uint256 proposalId,
uint8 support,
bytes memory signature
) external returns (uint256 weight);
/**
* @notice Allows the caller to cast a vote with reason on a proposal with id `proposalId`.
* @param proposalId The unique identifier for the proposal.
* @param support The type of support to cast for the proposal.
* @param reason The reason for which the caller casts their vote, if any.
* @return weight The number of votes cast.
*/
function castVoteWithReason(
uint256 proposalId,
uint8 support,
string calldata reason
) external returns (uint256 weight);
/**
* @notice Allows a signer to cast a vote with reason on a proposal with id `proposalId`
* via an ECDSA secp256k1 signature.
* @param proposalId The unique identifier for the proposal.
* @param support The type of support to cast for the proposal.
* @param reason The reason for which the caller casts their vote, if any.
* @param v An ECDSA secp256k1 signature parameter.
* @param r An ECDSA secp256k1 signature parameter.
* @param s An ECDSA secp256k1 signature parameter.
* @return weight The number of votes cast.
*/
function castVoteWithReasonBySig(
uint256 proposalId,
uint8 support,
string calldata reason,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint256 weight);
/**
* @notice Allows `voter` to cast a vote with reason on a proposal with id `proposalId` via an arbitrary signature.
* @param voter The address of the account that casting their vote, and purported to have signed.
* @param proposalId The unique identifier for the proposal.
* @param support The type of support to cast for the proposal.
* @param reason The reason for which the caller casts their vote, if any.
* @param signature An arbitrary signature.
* @return weight The number of votes cast.
*/
function castVoteWithReasonBySig(
address voter,
uint256 proposalId,
uint8 support,
string calldata reason,
bytes memory signature
) external returns (uint256 weight);
/**
* @notice Allows the caller to execute a proposal.
* @param targets An array of addresses that will be called upon the execution.
* @param values An array of ETH amounts that will be sent to each respective target upon execution.
* @param callDatas An array of call data used to call each respective target upon execution.
* @param descriptionHash The hash of the string of the description of the proposal.
* @return proposalId The unique identifier for the proposal.
*/
function execute(
address[] memory targets,
uint256[] memory values,
bytes[] memory callDatas,
bytes32 descriptionHash
) external payable returns (uint256 proposalId);
/**
* @notice Allows the caller to create a proposal.
* @param targets An array of addresses that will be called upon the execution.
* @param values An array of ETH amounts that will be sent to each respective target upon execution.
* @param callDatas An array of call data used to call each respective target upon execution.
* @param description The string of the description of the proposal.
* @return proposalId The unique identifier for the proposal.
*/
function propose(
address[] memory targets,
uint256[] memory values,
bytes[] memory callDatas,
string memory description
) external returns (uint256 proposalId);
/* ============ View/Pure Functions ============ */
/**
* @notice module:voting
* @dev A description of the possible "support" values for castVote and the way these votes are counted, meant to
* be consumed by UIs to show correct vote options and interpret the results. The string is a URL-encoded
* sequence of key-value pairs that each describe one aspect, for example `support=for,against&quorum=for`.
* The string can be decoded by the standard URLSearchParams JavaScript class.
*/
function COUNTING_MODE() external view returns (string memory);
/**
* @notice Returns the voting power of `account` at clock value `timepoint`.
* @param account The address of the account with voting power.
* @param timepoint The point in time, according to the clock mode the contract is operating on.
* @return The voting power of `account` at `timepoint`.
*/
function getVotes(address account, uint256 timepoint) external view returns (uint256);
/**
* @notice Returns the unique identifier for the proposal if it were created at this exact moment.
* @param targets An array of addresses that will be called upon the execution.
* @param values An array of ETH amounts that will be sent to each respective target upon execution.
* @param callDatas An array of call data used to call each respective target upon execution.
* @param descriptionHash The hash of the string of the description of the proposal.
* @return The unique identifier for the proposal.
*/
function hashProposal(
address[] memory targets,
uint256[] memory values,
bytes[] memory callDatas,
bytes32 descriptionHash
) external view returns (uint256);
/**
* @notice Returns whether `account` has voted on the proposal with identifier `proposalId`.
* @param proposalId The unique identifier for the proposal.
* @param account The address of some account.
* @return Whether `account` has already voted on the proposal.
*/
function hasVoted(uint256 proposalId, address account) external view returns (bool);
/// @notice Returns the name of the contract.
function name() external view returns (string memory);
/**
* @notice Returns the last clock value when voting on the proposal with identifier `proposalId` is allowed.
* @param proposalId The unique identifier for the proposal.
* @return The last clock value when voting on the proposal is allowed.
*/
function proposalDeadline(uint256 proposalId) external view returns (uint256);
/**
* @notice Returns the account that created the proposal with identifier `proposalId`.
* @param proposalId The unique identifier for the proposal.
* @return The address of the account that created the proposal.
*/
function proposalProposer(uint256 proposalId) external view returns (address);
/**
* @notice Returns the clock value used to retrieve voting power to vote on proposal with identifier `proposalId`.
* @param proposalId The unique identifier for the proposal.
* @return The clock value used to retrieve voting power.
*/
function proposalSnapshot(uint256 proposalId) external view returns (uint256);
/// @notice Returns the required voting power an account needs to create a proposal.
function proposalThreshold() external view returns (uint256);
/**
* @notice Returns the vote support totals for the proposal with identifier `proposalId`.
* @param proposalId The unique identifier for the proposal.
* @return noVotes The amount of votes cast against the proposal.
* @return yesVotes The amount of votes cast for the proposal.
* @return abstainVotes The amount of votes cast in abstention the proposal.
*/
function proposalVotes(
uint256 proposalId
) external view returns (uint256 noVotes, uint256 yesVotes, uint256 abstainVotes);
/// @notice Returns the minimum number of eligible (COUNTING_MODE) votes for a proposal to succeed.
function quorum() external view returns (uint256);
/**
* @notice Returns the state of a proposal with identifier `proposalId`.
* @param proposalId The unique identifier for the proposal.
* @return The state of the proposal.
*/
function state(uint256 proposalId) external view returns (ProposalState);
/// @notice Returns the EIP-5805 token contact used for determine voting power and total supplies.
function token() external view returns (address);
/// @notice Returns the number of clock values that must elapse before voting begins for a newly created proposal.
function votingDelay() external view returns (uint256);
/// @notice Returns the number of clock values between the vote start and vote end.
function votingPeriod() external view returns (uint256);
/// @notice Returns the EIP712 typehash used in the encoding of the digest for `castVoteBySig` function.
function BALLOT_TYPEHASH() external pure returns (bytes32);
/// @notice Returns the EIP712 typehash used in the encoding of the digest for `castVoteWithReasonBySig` function.
function BALLOT_WITH_REASON_TYPEHASH() external pure returns (bytes32);
}
IPowerTokenDeployer.sol 42 lines
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.23;
import { IDeployer } from "./IDeployer.sol";
/**
* @title A Deterministic deployer of Power Token contracts using CREATE.
* @author M^0 Labs
*/
interface IPowerTokenDeployer is IDeployer {
/* ============ Custom Errors ============ */
/// @notice Revert message when the Vault specified in the constructor is address(0).
error InvalidVaultAddress();
/// @notice Revert message when the Zero Governor specified in the constructor is address(0).
error InvalidZeroGovernorAddress();
/// @notice Revert message when the caller is not the Zero Governor.
error NotZeroGovernor();
/* ============ Interactive Functions ============ */
/**
* @notice Deploys a new instance of a Power Token.
* @dev Callable only by the Zero Governor.
* @param bootstrapToken The address of some token to bootstrap from.
* @param standardGovernor The address of some Standard Governor.
* @param cashToken The address of some Cash Token.
* @return The address of the deployed Emergency Governor.
*/
function deploy(address bootstrapToken, address standardGovernor, address cashToken) external returns (address);
/* ============ View/Pure Functions ============ */
/// @notice Returns the address of the Vault.
function vault() external view returns (address);
/// @notice Returns the address of the Zero Governor.
function zeroGovernor() external view returns (address);
}
IBatchGovernor.sol 241 lines
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.23;
import { IGovernor } from "./IGovernor.sol";
/**
* @title Extension for Governor with specialized strict proposal parameters, vote batching, and an epoch clock.
* @author M^0 Labs
*/
interface IBatchGovernor is IGovernor {
/* ============ Enums ============ */
/**
* @notice The type of support to cast for a proposal.
* @param No The voter does not support the proposal.
* @param Yes The voter supports the proposal.
*/
enum VoteType {
No,
Yes
}
/* ============ Custom Errors ============ */
/// @notice Revert message when a voter is trying to vote on a proposal they already voted on.
error AlreadyVoted();
/// @notice Revert message when input arrays do not match in length.
error ArrayLengthMismatch(uint256 length1, uint256 length2);
/// @notice Revert message when the proposal IDs array is empty.
error EmptyProposalIdsArray();
/**
* @notice Revert message when execution of a proposal fails.
* @param data The revert data returned due to the failed execution.
*/
error ExecutionFailed(bytes data);
/// @notice Revert message when a proposal's call data is not specifically supported.
error InvalidCallData();
/// @notice Revert message when a proposal's call data array is not of length 1.
error InvalidCallDatasLength();
/// @notice Revert message when a proposal target is not this governor itself.
error InvalidTarget();
/// @notice Revert message when a proposal's targets array is not of length 1.
error InvalidTargetsLength();
/// @notice Revert message when a proposal value is not 0 ETH.
error InvalidValue();
/// @notice Revert message when a proposal's values array is not of length 1.
error InvalidValuesLength();
/// @notice Revert message when a an invalid vote start is detected.
error InvalidVoteStart();
/// @notice Revert message when the vote token specified in the constructor is address(0).
error InvalidVoteTokenAddress();
/// @notice Revert message when the caller of a governance-controlled function is not this governor itself.
error NotSelf();
/// @notice Revert message when the proposal information provided cannot be executed.
error ProposalCannotBeExecuted();
/// @notice Revert message when the proposal does not exist.
error ProposalDoesNotExist();
/// @notice Revert message when the proposal already exists.
error ProposalExists();
/**
* @notice Revert message when voting on a proposal that is not in an active state (i.e. not collecting votes).
* @param state The current state of the proposal.
*/
error ProposalInactive(ProposalState state);
/// @notice Revert message when voting on a proposal with a zero voting weight.
error ZeroVotingPower();
/* ============ Interactive Functions ============ */
/**
* @notice Allows the caller to cast votes on multiple proposals.
* @param proposalIds The list of unique proposal IDs being voted on.
* @param supportList The list of support type per proposal IDs to cast.
* @return weight The number of votes cast for each proposal (the same for all of them).
*/
function castVotes(uint256[] calldata proposalIds, uint8[] calldata supportList) external returns (uint256 weight);
/**
* @notice Allows a signer to cast votes on multiple proposals via an ECDSA secp256k1 signature.
* @param proposalIds The list of unique proposal IDs being voted on.
* @param supportList The list of support type per proposal IDs to cast.
* @param v An ECDSA secp256k1 signature parameter.
* @param r An ECDSA secp256k1 signature parameter.
* @param s An ECDSA secp256k1 signature parameter.
* @return weight The number of votes cast for each proposal (the same for all of them).
*/
function castVotesBySig(
uint256[] calldata proposalIds,
uint8[] calldata supportList,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint256 weight);
/**
* @notice Allows a signer to cast votes on multiple proposals via an arbitrary signature.
* @param voter The address of the account casting the votes.
* @param proposalIds The list of unique proposal IDs being voted on.
* @param supportList The list of support type per proposal IDs to cast.
* @param signature An arbitrary signature
* @return weight The number of votes cast for each proposal (the same for all of them).
*/
function castVotesBySig(
address voter,
uint256[] calldata proposalIds,
uint8[] calldata supportList,
bytes memory signature
) external returns (uint256 weight);
/**
* @notice Allows the caller to cast votes with reason on multiple proposals.
* @param proposalIds The list of unique proposal IDs being voted on.
* @param supportList The list of support type per proposal IDs to cast.
* @param reasonList The list of reason per proposal IDs to cast.
* @return weight The number of votes cast for each proposal (the same for all of them).
*/
function castVotesWithReason(
uint256[] calldata proposalIds,
uint8[] calldata supportList,
string[] calldata reasonList
) external returns (uint256 weight);
/**
* @notice Allows a signer to cast votes with reason on multiple proposals via an ECDSA secp256k1 signature.
* @param proposalIds The list of unique proposal IDs being voted on.
* @param supportList The list of support type per proposal IDs to cast.
* @param reasonList The list of reason per proposal IDs to cast.
* @param v An ECDSA secp256k1 signature parameter.
* @param r An ECDSA secp256k1 signature parameter.
* @param s An ECDSA secp256k1 signature parameter.
* @return weight The number of votes cast for each proposal (the same for all of them).
*/
function castVotesWithReasonBySig(
uint256[] calldata proposalIds,
uint8[] calldata supportList,
string[] calldata reasonList,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint256 weight);
/**
* @notice Allows a signer to cast votes with reason on multiple proposals via an arbitrary signature.
* @param voter The address of the account casting the votes.
* @param proposalIds The list of unique proposal IDs being voted on.
* @param supportList The list of support type per proposal IDs to cast.
* @param reasonList The list of reason per proposal IDs to cast.
* @param signature An arbitrary signature
* @return weight The number of votes cast for each proposal (the same for all of them).
*/
function castVotesWithReasonBySig(
address voter,
uint256[] calldata proposalIds,
uint8[] calldata supportList,
string[] calldata reasonList,
bytes memory signature
) external returns (uint256 weight);
/* ============ View/Pure Functions ============ */
/**
* @notice Returns the ballot digest to be signed, via EIP-712, given an internal digest (i.e. hash struct).
* @param proposalId The unique proposal ID being voted on.
* @param support The type of support to cast for the proposal.
* @return The digest to be signed.
*/
function getBallotDigest(uint256 proposalId, uint8 support) external view returns (bytes32);
/**
* @notice Returns the ballots digest to be signed, via EIP-712, given an internal digest (i.e. hash struct).
* @param proposalIds The list of unique proposal IDs being voted on.
* @param supportList The list of support type per proposal IDs to cast.
* @return The digest to be signed.
*/
function getBallotsDigest(
uint256[] calldata proposalIds,
uint8[] calldata supportList
) external view returns (bytes32);
/**
* @notice Returns the ballot with reason digest to be signed, via EIP-712,
* given an internal digest (i.e. hash struct).
* @param proposalId The unique proposal ID being voted on.
* @param support The type of support to cast for the proposal.
* @param reason The reason for which the caller casts their vote, if any.
* @return The digest to be signed.
*/
function getBallotWithReasonDigest(
uint256 proposalId,
uint8 support,
string calldata reason
) external view returns (bytes32);
/**
* @notice Returns the ballots with reason digest to be signed, via EIP-712,
* given an internal digest (i.e. hash struct).
* @param proposalIds The list of unique proposal IDs being voted on.
* @param supportList The list of support type per proposal IDs to cast.
* @param reasonList The list of reason per proposal IDs to cast.
* @return The digest to be signed.
*/
function getBallotsWithReasonDigest(
uint256[] calldata proposalIds,
uint8[] calldata supportList,
string[] calldata reasonList
) external view returns (bytes32);
/**
* @notice Returns the unique identifier for the proposal if it were created at this exact moment.
* @param callData The single call data used to call this governor upon execution of a proposal.
* @return The unique identifier for the proposal.
*/
function hashProposal(bytes memory callData) external view returns (uint256);
/// @notice Returns the EIP-5805 token contact used for determine voting power and total supplies.
function voteToken() external view returns (address);
/// @notice Returns the EIP712 typehash used in the encoding of the digest for `castVotesBySig` function.
function BALLOTS_TYPEHASH() external pure returns (bytes32);
/// @notice Returns the EIP712 typehash used in the encoding of the digest for `castVotesWithReasonBySig` function.
function BALLOTS_WITH_REASON_TYPEHASH() external pure returns (bytes32);
}
IStandardGovernorDeployer.sol 61 lines
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.23;
import { IDeployer } from "./IDeployer.sol";
/**
* @title A Deterministic deployer of Standard Governor contracts using CREATE.
* @author M^0 Labs
*/
interface IStandardGovernorDeployer is IDeployer {
/* ============ Custom Errors ============ */
/// @notice Revert message when the Registrar specified in the constructor is address(0).
error InvalidRegistrarAddress();
/// @notice Revert message when the Vault specified in the constructor is address(0).
error InvalidVaultAddress();
/// @notice Revert message when the Zero Governor specified in the constructor is address(0).
error InvalidZeroGovernorAddress();
/// @notice Revert message when the Zero Token specified in the constructor is address(0).
error InvalidZeroTokenAddress();
/// @notice Revert message when the caller is not the Zero Governor.
error NotZeroGovernor();
/* ============ Interactive Functions ============ */
/**
* @notice Deploys a new instance of a Standard Governor.
* @param powerToken The address of some Power Token that will be used by voters.
* @param emergencyGovernor The address of some Emergency Governor.
* @param cashToken The address of some Cash Token.
* @param proposalFee The proposal fee required to create proposals.
* @param maxTotalZeroRewardPerActiveEpoch The maximum amount of Zero Token rewarded per active epoch.
* @return The address of the deployed Standard Governor.
*/
function deploy(
address powerToken,
address emergencyGovernor,
address cashToken,
uint256 proposalFee,
uint256 maxTotalZeroRewardPerActiveEpoch
) external returns (address);
/* ============ View/Pure Functions ============ */
/// @notice Returns the address of the Registrar.
function registrar() external view returns (address);
/// @notice Returns the address of the Vault.
function vault() external view returns (address);
/// @notice Returns the address of the Zero Governor.
function zeroGovernor() external view returns (address);
/// @notice Returns the address of the Zero Token.
function zeroToken() external view returns (address);
}
IEmergencyGovernorDeployer.sol 41 lines
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.23;
import { IDeployer } from "./IDeployer.sol";
/**
* @title A Deterministic deployer of Emergency Governor contracts using CREATE.
* @author M^0 Labs
*/
interface IEmergencyGovernorDeployer is IDeployer {
/* ============ Custom Errors ============ */
/// @notice Revert message when the Registrar specified in the constructor is address(0).
error InvalidRegistrarAddress();
/// @notice Revert message when the Zero Governor specified in the constructor is address(0).
error InvalidZeroGovernorAddress();
/// @notice Revert message when the caller is not the Zero Governor.
error NotZeroGovernor();
/* ============ Interactive Functions ============ */
/**
* @notice Deploys a new instance of an Emergency Governor.
* @param powerToken The address of some Power Token that will be used by voters.
* @param standardGovernor The address of some Standard Governor.
* @param thresholdRatio The threshold ratio to use for proposals.
* @return The address of the deployed Emergency Governor.
*/
function deploy(address powerToken, address standardGovernor, uint16 thresholdRatio) external returns (address);
/* ============ View/Pure Functions ============ */
/// @notice Returns the address of the Registrar.
function registrar() external view returns (address);
/// @notice Returns the address of the Zero Governor.
function zeroGovernor() external view returns (address);
}
IThresholdGovernor.sol 91 lines
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.23;
import { IBatchGovernor } from "./IBatchGovernor.sol";
/**
* @title Extension for BatchGovernor with a threshold ratio used to determine quorum and yes-threshold requirements.
* @author M^0 Labs
*/
interface IThresholdGovernor is IBatchGovernor {
/* ============ Events ============ */
/**
* @notice Emitted when the threshold ratio is set.
* @param thresholdRatio The new threshold ratio.
*/
event ThresholdRatioSet(uint16 thresholdRatio);
/**
* @notice Emitted when the quorum numerator is set.
* @param oldQuorumNumerator The old quorum numerator.
* @param newQuorumNumerator The new quorum numerator.
*/
event QuorumNumeratorUpdated(uint256 oldQuorumNumerator, uint256 newQuorumNumerator);
/* ============ Custom Errors ============ */
/**
* @notice Revert message when trying to set the threshold ratio above 100% or below 2.71%.
* @param thresholdRatio The threshold ratio being set.
* @param minThresholdRatio The minimum allowed threshold ratio.
* @param maxThresholdRatio The maximum allowed threshold ratio.
*/
error InvalidThresholdRatio(uint256 thresholdRatio, uint256 minThresholdRatio, uint256 maxThresholdRatio);
/* ============ View/Pure Functions ============ */
/**
* @notice Returns all data of a proposal with identifier `proposalId`.
* @param proposalId The unique identifier for the proposal.
* @return voteStart The first clock value when voting on the proposal is allowed.
* @return voteEnd The last clock value when voting on the proposal is allowed.
* @return state The state of the proposal.
* @return noVotes The amount of votes cast against the proposal.
* @return yesVotes The amount of votes cast for the proposal.
* @return proposer The address of the account that created the proposal.
* @return quorum The threshold/quorum of yes votes required for the proposal to succeed.
* @return quorumNumerator The threshold/quorum numerator used to calculate the quorum.
*/
function getProposal(
uint256 proposalId
)
external
view
returns (
uint48 voteStart,
uint48 voteEnd,
ProposalState state,
uint256 noVotes,
uint256 yesVotes,
address proposer,
uint256 quorum,
uint16 quorumNumerator
);
/**
* @notice Returns the threshold ratio to be applied to determine the success threshold for a proposal.
* @dev For all intents and purposes, this is the same as `quorumNumerator`.
*/
function thresholdRatio() external view returns (uint16);
/**
* @notice Returns the quorum of yes votes needed for a specific proposal to succeed.
* @param proposalId The unique identifier for the proposal.
* @return The quorum of yes votes needed for the proposal to succeed.
*/
function proposalQuorum(uint256 proposalId) external view returns (uint256);
/**
* @notice Returns the quorum numerator used to determine the quorum for a proposal.
* @dev For all intents and purposes, this is the same as `thresholdRatio`.
*/
function quorumNumerator() external view returns (uint256);
/// @notice Returns the quorum denominator used to determine the quorum for a proposal.
function quorumDenominator() external view returns (uint256);
/// @notice Returns the value used as 100%, to be used to correctly ascertain the threshold ratio.
function ONE() external pure returns (uint256);
}
Read Contract
CLOCK_MODE 0x4bf5d7e9 → string
clock 0x91ddadf4 → uint48
clockPeriod 0x246c5308 → uint256
clockStartingTimestamp 0xb3d0c202 → uint256
emergencyGovernor 0xf52c93c5 → address
emergencyGovernorDeployer 0x5548917f → address
get 0x8eaa6ac0 → bytes32
get 0xabf306a8 → bytes32[]
listContains 0x2595f8cf → bool
listContains 0xd7d1c1c0 → bool
powerToken 0x9662ac58 → address
powerTokenDeployer 0xaf63a3e1 → address
standardGovernor 0x4d6d7441 → address
standardGovernorDeployer 0xe94bb223 → address
vault 0xfbfa77cf → address
zeroGovernor 0x8df3227f → address
zeroToken 0xf294bd92 → address
Write Contract 3 functions
These functions modify contract state and require a wallet transaction to execute.
addToList 0xb4d87a12
bytes32 list_
address account_
removeFromList 0xd48d8423
bytes32 list_
address account_
setKey 0x07a00330
bytes32 key_
bytes32 value_
Recent Transactions
This address has 1 on-chain transactions, but only <1% of the chain is indexed. Transactions will appear as indexing progresses. View on Etherscan →