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