diff --git a/README.md b/README.md index 9a679eb..968e0a7 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,17 @@ The comments in that file explain what each variable is for and when they're nee - `just deploy` - deploy and verify payload on mainnet - Run `just -l` or see the [`justfile`](https://github.com/llamaxyz/llama/blob/main/justfile) for other commands such as dry runs. +## Testnet deployment + +| Name | Sepolia | +| ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- | +|_Factory_| +| LlamaTokenVotingFactory | [0x6A97643633eafEEC00b7Ec4CE84269203645aaBC](https://sepolia.etherscan.io/address/0x6A97643633eafEEC00b7Ec4CE84269203645aaBC) | +|_Governor_| +| LlamaTokenGovernor (logic contract) | [0x0A01C701013E6d6F1c1759457324303Bf25CC7E3](https://sepolia.etherscan.io/address/0x0A01C701013E6d6F1c1759457324303Bf25CC7E3) | +|_Token Adapters_| +| LlamaTokenAdapterVotesTimestamp (logic contract) | [0x8CCe1b824EfF3A7966348528B6951A84eC0541A5](https://sepolia.etherscan.io/address/0x8CCe1b824EfF3A7966348528B6951A84eC0541A5) | + ## Smart contract reference Run the following command to generate smart contract reference documentation from our NatSpec comments and serve those static files locally: diff --git a/foundry.toml b/foundry.toml index 5865046..371ec3b 100644 --- a/foundry.toml +++ b/foundry.toml @@ -11,7 +11,7 @@ fuzz = { runs = 5000 } invariant = { runs = 1000, depth = 100 } optimizer = true - optimizer_runs = 10_000_000 + optimizer_runs = 19_000 via_ir = false [rpc_endpoints] diff --git a/script/DeployLlamaTokenVotingFactory.s.sol b/script/DeployLlamaTokenVotingFactory.s.sol index 12180a3..3707714 100644 --- a/script/DeployLlamaTokenVotingFactory.s.sol +++ b/script/DeployLlamaTokenVotingFactory.s.sol @@ -4,15 +4,13 @@ pragma solidity 0.8.23; import {Script} from "forge-std/Script.sol"; import {DeployUtils} from "script/DeployUtils.sol"; -import {LlamaTokenActionCreator} from "src/token-voting/LlamaTokenActionCreator.sol"; -import {LlamaTokenCaster} from "src/token-voting/LlamaTokenCaster.sol"; +import {LlamaTokenGovernor} from "src/token-voting/LlamaTokenGovernor.sol"; import {LlamaTokenVotingFactory} from "src/token-voting/LlamaTokenVotingFactory.sol"; import {LlamaTokenAdapterVotesTimestamp} from "src/token-voting/token-adapters/LlamaTokenAdapterVotesTimestamp.sol"; contract DeployLlamaTokenVotingFactory is Script { // Logic contracts. - LlamaTokenActionCreator llamaTokenActionCreatorLogic; - LlamaTokenCaster llamaTokenCasterLogic; + LlamaTokenGovernor llamaTokenGovernorLogic; LlamaTokenAdapterVotesTimestamp llamaTokenAdapterTimestampLogic; // Factory contracts. @@ -24,17 +22,11 @@ contract DeployLlamaTokenVotingFactory is Script { ); vm.broadcast(); - llamaTokenActionCreatorLogic = new LlamaTokenActionCreator(); - DeployUtils.print( - string.concat(" LlamaTokenActionCreatorLogic: ", vm.toString(address(llamaTokenActionCreatorLogic))) - ); - - vm.broadcast(); - llamaTokenCasterLogic = new LlamaTokenCaster(); - DeployUtils.print(string.concat(" LlamaTokenCasterLogic: ", vm.toString(address(llamaTokenCasterLogic)))); + llamaTokenGovernorLogic = new LlamaTokenGovernor(); + DeployUtils.print(string.concat(" LlamaTokenGovernorLogic: ", vm.toString(address(llamaTokenGovernorLogic)))); vm.broadcast(); - tokenVotingFactory = new LlamaTokenVotingFactory(llamaTokenActionCreatorLogic, llamaTokenCasterLogic); + tokenVotingFactory = new LlamaTokenVotingFactory(llamaTokenGovernorLogic); DeployUtils.print(string.concat(" LlamaTokenVotingFactory: ", vm.toString(address(tokenVotingFactory)))); vm.broadcast(); diff --git a/script/DeployLlamaTokenVotingModule.s.sol b/script/DeployLlamaTokenVotingModule.s.sol index 5876969..a52a071 100644 --- a/script/DeployLlamaTokenVotingModule.s.sol +++ b/script/DeployLlamaTokenVotingModule.s.sol @@ -8,8 +8,7 @@ import {DeployUtils} from "script/DeployUtils.sol"; import {ILlamaCore} from "src/interfaces/ILlamaCore.sol"; import {CasterConfig, LlamaTokenVotingConfig} from "src/lib/Structs.sol"; import {ILlamaTokenAdapter} from "src/token-voting/interfaces/ILlamaTokenAdapter.sol"; -import {LlamaTokenActionCreator} from "src/token-voting/LlamaTokenActionCreator.sol"; -import {LlamaTokenCaster} from "src/token-voting/LlamaTokenCaster.sol"; +import {LlamaTokenGovernor} from "src/token-voting/LlamaTokenGovernor.sol"; import {LlamaTokenVotingFactory} from "src/token-voting/LlamaTokenVotingFactory.sol"; import {DeployUtils} from "script/DeployUtils.sol"; @@ -36,17 +35,15 @@ contract DeployLlamaTokenVotingModule is Script { ILlamaTokenAdapter(jsonInput.readAddress(".tokenAdapterLogic")), DeployUtils.readTokenAdapter(jsonInput), abi.decode(jsonInput.parseRaw(".nonce"), (uint256)), - abi.decode(jsonInput.parseRaw(".actionCreatorRole"), (uint8)), - abi.decode(jsonInput.parseRaw(".casterRole"), (uint8)), + abi.decode(jsonInput.parseRaw(".governorRole"), (uint8)), abi.decode(jsonInput.parseRaw(".creationThreshold"), (uint256)), casterConfig ); vm.broadcast(deployer); - (LlamaTokenActionCreator actionCreator, LlamaTokenCaster caster) = factory.deploy(config); + LlamaTokenGovernor governor = factory.deploy(config); DeployUtils.print("Successfully deployed a new Llama token voting module"); - DeployUtils.print(string.concat(" LlamaTokenActionCreator: ", vm.toString(address(actionCreator)))); - DeployUtils.print(string.concat(" LlamaTokenCaster: ", vm.toString(address(caster)))); + DeployUtils.print(string.concat(" LlamaTokenGovernor: ", vm.toString(address(governor)))); } } diff --git a/script/input/11155111/tokenVotingModuleConfig.json b/script/input/11155111/tokenVotingModuleConfig.json index 31eaad1..995e021 100644 --- a/script/input/11155111/tokenVotingModuleConfig.json +++ b/script/input/11155111/tokenVotingModuleConfig.json @@ -1,12 +1,11 @@ { "comment": "This is an example token voting module deployment on Sepolia.", - "factory": "0x2997f4D6899DC91dE9Ae0FcD98b49CA88b8Fc85e", + "factory": "0x6A97643633eafEEC00b7Ec4CE84269203645aaBC", "llamaCore": "0xc68046794327490F953EA15522367FFBA0b64f86", - "tokenAdapterLogic": "0x88D63b8c5F8C3e95743F1d26Df8aDd0669614278", + "tokenAdapterLogic": "0x8CCe1b824EfF3A7966348528B6951A84eC0541A5", "tokenAddress": "0xf44d44a54440F22e5DC5adb7efA3233645f04007", "nonce": 0, - "actionCreatorRole": 0, - "casterRole": 0, + "governorRole": 0, "creationThreshold": 10000e18, "casterConfig": { "voteQuorumPct": 2000, diff --git a/src/lib/Structs.sol b/src/lib/Structs.sol index 08aaabb..37cb6f6 100644 --- a/src/lib/Structs.sol +++ b/src/lib/Structs.sol @@ -36,27 +36,6 @@ struct Action { uint96 totalDisapprovals; // The total quantity of policyholder disapprovals. } -/// @dev Configuration of a new Llama token voting module. -struct LlamaTokenVotingConfig { - ILlamaCore llamaCore; // The address of the Llama core. - ILlamaTokenAdapter tokenAdapterLogic; // The logic contract of the token adapter. - bytes adapterConfig; // The configuration of the token adapter. - uint256 nonce; // The nonce to be used in the salt of the deterministic deployment. - uint8 actionCreatorRole; // The role required by the `LlamaTokenActionCreator` to create an action. - uint8 casterRole; // The role required by the `LlamaTokenCaster` to cast approvals and disapprovals. - uint256 creationThreshold; // The number of tokens required to create an action. - CasterConfig casterConfig; // The quorum and period data for the `LlamaTokenCaster`. -} - -/// @dev Quorum and period data for token voting caster contracts. -struct CasterConfig { - uint16 voteQuorumPct; - uint16 vetoQuorumPct; - uint16 delayPeriodPct; - uint16 castingPeriodPct; - uint16 submissionPeriodPct; -} - /// @dev Data that represents a permission. struct PermissionData { address target; // Contract being called by an action. @@ -98,3 +77,23 @@ struct LlamaPolicyConfig { string color; // The primary color of the SVG representation of the instance's policy (e.g. #00FF00). string logo; // The SVG string representing the logo for the deployed Llama instance's NFT. } + +/// @dev Configuration of a new Llama token voting module. +struct LlamaTokenVotingConfig { + ILlamaCore llamaCore; // The address of the Llama core. + ILlamaTokenAdapter tokenAdapterLogic; // The logic contract of the token adapter. + bytes adapterConfig; // The configuration of the token adapter. + uint256 nonce; // The nonce to be used in the salt of the deterministic deployment. + uint8 governorRole; // The role required by the `LlamaTokenGovernor` to create actions and cast on them. + uint256 creationThreshold; // The number of tokens required to create an action. + CasterConfig casterConfig; // The quorum and period data for the `LlamaTokenGovernor`. +} + +/// @dev Quorum and period data for token voting caster contracts. +struct CasterConfig { + uint16 voteQuorumPct; + uint16 vetoQuorumPct; + uint16 delayPeriodPct; + uint16 castingPeriodPct; + uint16 submissionPeriodPct; +} diff --git a/src/token-voting/LlamaTokenActionCreator.sol b/src/token-voting/LlamaTokenActionCreator.sol deleted file mode 100644 index a212062..0000000 --- a/src/token-voting/LlamaTokenActionCreator.sol +++ /dev/null @@ -1,352 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.23; - -import {Initializable} from "@openzeppelin/proxy/utils/Initializable.sol"; - -import {ILlamaCore} from "src/interfaces/ILlamaCore.sol"; -import {ILlamaStrategy} from "src/interfaces/ILlamaStrategy.sol"; -import {ILlamaTokenAdapter} from "src/token-voting/interfaces/ILlamaTokenAdapter.sol"; -import {Action, ActionInfo} from "src/lib/Structs.sol"; -import {LlamaUtils} from "src/lib/LlamaUtils.sol"; - -/// @title LlamaTokenActionCreator -/// @author Llama (devsdosomething@llama.xyz) -/// @notice This contract lets holders of a given governance token create actions if they have -/// sufficient token balance. -/// @dev This contract is deployed by `LlamaTokenVotingFactory`. Anyone can deploy this contract using the factory, but -/// it must hold a Policy from the specified `LlamaCore` instance to actually be able to create an action. The -/// instance's policy encodes what actions this contract is allowed to create, and attempting to create an action that -/// is not allowed by the policy will result in a revert. -contract LlamaTokenActionCreator is Initializable { - // ======================== - // ======== Errors ======== - // ======================== - - /// @dev Thrown when a user tries to create an action but does not have enough tokens. - error InsufficientBalance(uint256 balance); - - /// @dev Thrown when an invalid `creationThreshold` is passed to the constructor. - error InvalidCreationThreshold(); - - /// @dev Thrown when an invalid `llamaCore` address is passed to the constructor. - error InvalidLlamaCoreAddress(); - - /// @dev The recovered signer does not match the expected token holder. - error InvalidSignature(); - - /// @dev Thrown when a `token` with an invalid totaly supply is passed to the constructor. - error InvalidTotalSupply(); - - /// @dev Thrown when a user tries to cancel an action but they are not the action creator. - error OnlyActionCreator(); - - /// @dev Thrown when an address other than the `LlamaExecutor` tries to call a function. - error OnlyLlamaExecutor(); - - /// @dev Thrown when an invalid `role` is passed to the constructor. - error RoleNotInitialized(uint8 role); - - // ======================== - // ======== Events ======== - // ======================== - - /// @dev Emitted when an action is canceled. - event ActionCanceled(uint256 id, address indexed creator); - - /// @dev Emitted when an action is created. - event ActionCreated(uint256 id, address indexed creator); - - /// @dev Emitted when the default number of tokens required to create an action is changed. - event ActionThresholdSet(uint256 newThreshold); - - // ================================================= - // ======== Constants and Storage Variables ======== - // ================================================= - - /// @dev EIP-712 base typehash. - bytes32 internal constant EIP712_DOMAIN_TYPEHASH = - keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); - - /// @dev EIP-712 createAction typehash. - bytes32 internal constant CREATE_ACTION_TYPEHASH = keccak256( - "CreateAction(address tokenHolder,address strategy,address target,uint256 value,bytes data,string description,uint256 nonce)" - ); - - /// @dev EIP-712 cancelAction typehash. - bytes32 internal constant CANCEL_ACTION_TYPEHASH = keccak256( - "CancelAction(address tokenHolder,ActionInfo actionInfo,uint256 nonce)ActionInfo(uint256 id,address creator,uint8 creatorRole,address strategy,address target,uint256 value,bytes data)" - ); - - /// @dev EIP-712 actionInfo typehash. - bytes32 internal constant ACTION_INFO_TYPEHASH = keccak256( - "ActionInfo(uint256 id,address creator,uint8 creatorRole,address strategy,address target,uint256 value,bytes data)" - ); - - /// @notice The core contract for this Llama instance. - ILlamaCore public llamaCore; - - /// @notice The contract that manages the timepoints for this token voting module. - ILlamaTokenAdapter public tokenAdapter; - - /// @notice The default number of tokens required to create an action. - uint256 public creationThreshold; - - /// @notice The role used by this contract to cast approvals and disapprovals. - /// @dev This role is expected to have the permissions to create appropriate actions. - uint8 public role; - - /// @notice The address of the tokenholder that created the action. - mapping(uint256 => address) public actionCreators; - - /// @notice Mapping of token holder to function selectors to current nonces for EIP-712 signatures. - /// @dev This is used to prevent replay attacks by incrementing the nonce for each operation (`createAction` and - /// `cancelAction`) signed by the token holder. - mapping(address tokenHolder => mapping(bytes4 selector => uint256 currentNonce)) public nonces; - - // ================================ - // ======== Initialization ======== - // ================================ - - /// @dev This contract is deployed as a minimal proxy from the factory's `deploy` function. The - /// `_disableInitializers` locks the implementation (logic) contract, preventing any future initialization of it. - constructor() { - _disableInitializers(); - } - - /// @notice Initializes a new `LlamaTokenActionCreator` clone. - /// @dev This function is called by the `deploy` function in the `LlamaTokenVotingFactory` contract. - /// The `initializer` modifier ensures that this function can be invoked at most once. - /// @param _llamaCore The `LlamaCore` contract for this Llama instance. - /// @param _tokenAdapter The token adapter that manages the clock, timepoints, past votes and past supply for this - /// token voting module. - /// @param _role The role used by this contract to cast approvals and disapprovals. - /// @param _creationThreshold The default number of tokens required to create an action. This must - /// be in the same decimals as the token. For example, if the token has 18 decimals and you want a - /// creation threshold of 1000 tokens, pass in 1000e18. - function initialize(ILlamaCore _llamaCore, ILlamaTokenAdapter _tokenAdapter, uint8 _role, uint256 _creationThreshold) - external - initializer - { - if (_llamaCore.actionsCount() < 0) revert InvalidLlamaCoreAddress(); - if (_role > _llamaCore.policy().numRoles()) revert RoleNotInitialized(_role); - - llamaCore = _llamaCore; - tokenAdapter = _tokenAdapter; - role = _role; - _setActionThreshold(_creationThreshold); - } - - // =========================================== - // ======== External and Public Logic ======== - // =========================================== - - // -------- Action Lifecycle Management -------- - - /// @notice Creates an action. - /// @dev Use `""` for `description` if there is no description. - /// @param strategy The strategy contract that will determine how the action is executed. - /// @param target The contract called when the action is executed. - /// @param value The value in wei to be sent when the action is executed. - /// @param data Data to be called on the target when the action is executed. - /// @param description A human readable description of the action and the changes it will enact. - /// @return actionId Action ID of the newly created action. - function createAction( - ILlamaStrategy strategy, - address target, - uint256 value, - bytes calldata data, - string calldata description - ) external returns (uint256 actionId) { - return _createAction(msg.sender, strategy, target, value, data, description); - } - - /// @notice Creates an action via an off-chain signature. The creator needs to have sufficient token balance that is - /// greater than or equal to the creation threshold. - /// @dev Use `""` for `description` if there is no description. - /// @param tokenHolder The tokenHolder that signed the message. - /// @param strategy The strategy contract that will determine how the action is executed. - /// @param target The contract called when the action is executed. - /// @param value The value in wei to be sent when the action is executed. - /// @param data Data to be called on the target when the action is executed. - /// @param description A human readable description of the action and the changes it will enact. - /// @param v ECDSA signature component: Parity of the `y` coordinate of point `R` - /// @param r ECDSA signature component: x-coordinate of `R` - /// @param s ECDSA signature component: `s` value of the signature - /// @return actionId Action ID of the newly created action. - function createActionBySig( - address tokenHolder, - ILlamaStrategy strategy, - address target, - uint256 value, - bytes calldata data, - string calldata description, - uint8 v, - bytes32 r, - bytes32 s - ) external returns (uint256 actionId) { - bytes32 digest = _getCreateActionTypedDataHash(tokenHolder, strategy, target, value, data, description); - address signer = ecrecover(digest, v, r, s); - if (signer == address(0) || signer != tokenHolder) revert InvalidSignature(); - actionId = _createAction(signer, strategy, target, value, data, description); - } - - /// @notice Cancels an action. - /// @param actionInfo The action to cancel. - /// @dev Relies on the validation checks in `LlamaCore.cancelAction()`. - function cancelAction(ActionInfo calldata actionInfo) external { - _cancelAction(msg.sender, actionInfo); - } - - /// @notice Cancels an action by its `actionInfo` struct via an off-chain signature. - /// @dev Rules for cancelation are defined by the strategy. - /// @param policyholder The policyholder that signed the message. - /// @param actionInfo Data required to create an action. - /// @param v ECDSA signature component: Parity of the `y` coordinate of point `R` - /// @param r ECDSA signature component: x-coordinate of `R` - /// @param s ECDSA signature component: `s` value of the signature - function cancelActionBySig(address policyholder, ActionInfo calldata actionInfo, uint8 v, bytes32 r, bytes32 s) - external - { - bytes32 digest = _getCancelActionTypedDataHash(policyholder, actionInfo); - address signer = ecrecover(digest, v, r, s); - if (signer == address(0) || signer != policyholder) revert InvalidSignature(); - _cancelAction(signer, actionInfo); - } - - // -------- Instance Management -------- - - /// @notice Sets the default number of tokens required to create an action. - /// @param _creationThreshold The number of tokens required to create an action. - /// @dev This must be in the same decimals as the token. - function setActionThreshold(uint256 _creationThreshold) external { - if (msg.sender != address(llamaCore.executor())) revert OnlyLlamaExecutor(); - _setActionThreshold(_creationThreshold); - } - - // -------- User Nonce Management -------- - - /// @notice Increments the caller's nonce for the given `selector`. This is useful for revoking - /// signatures that have not been used yet. - /// @param selector The function selector to increment the nonce for. - function incrementNonce(bytes4 selector) external { - // Safety: Can never overflow a uint256 by incrementing. - nonces[msg.sender][selector] = LlamaUtils.uncheckedIncrement(nonces[msg.sender][selector]); - } - - // ================================ - // ======== Internal Logic ======== - // ================================ - - /// @dev Creates an action. The creator needs to have sufficient token balance. - function _createAction( - address tokenHolder, - ILlamaStrategy strategy, - address target, - uint256 value, - bytes calldata data, - string calldata description - ) internal returns (uint256 actionId) { - // Reverts if clock or CLOCK_MODE() has changed - tokenAdapter.checkIfInconsistentClock(); - - uint256 balance = tokenAdapter.getPastVotes(tokenHolder, tokenAdapter.clock() - 1); - if (balance < creationThreshold) revert InsufficientBalance(balance); - - actionId = llamaCore.createAction(role, strategy, target, value, data, description); - actionCreators[actionId] = tokenHolder; - emit ActionCreated(actionId, tokenHolder); - } - - /// @dev Cancels an action by its `actionInfo` struct. Only the action creator can cancel. - function _cancelAction(address creator, ActionInfo calldata actionInfo) internal { - if (creator != actionCreators[actionInfo.id]) revert OnlyActionCreator(); - llamaCore.cancelAction(actionInfo); - emit ActionCanceled(actionInfo.id, creator); - } - - /// @dev Sets the default number of tokens required to create an action. - function _setActionThreshold(uint256 _creationThreshold) internal { - uint256 totalSupply = tokenAdapter.getPastTotalSupply(tokenAdapter.clock() - 1); - if (totalSupply == 0) revert InvalidTotalSupply(); - if (_creationThreshold > totalSupply) revert InvalidCreationThreshold(); - creationThreshold = _creationThreshold; - emit ActionThresholdSet(_creationThreshold); - } - - /// @dev Returns the current nonce for a given tokenHolder and selector, and increments it. Used to prevent - /// replay attacks. - function _useNonce(address tokenHolder, bytes4 selector) internal returns (uint256 nonce) { - nonce = nonces[tokenHolder][selector]; - nonces[tokenHolder][selector] = LlamaUtils.uncheckedIncrement(nonce); - } - - // -------- EIP-712 Getters -------- - - /// @dev Returns the EIP-712 domain separator. - function _getDomainHash() internal view returns (bytes32) { - return keccak256( - abi.encode( - EIP712_DOMAIN_TYPEHASH, keccak256(bytes(llamaCore.name())), keccak256(bytes("1")), block.chainid, address(this) - ) - ); - } - - /// @dev Returns the hash of the ABI-encoded EIP-712 message for the `CreateAction` domain, which can be used to - /// recover the signer. - function _getCreateActionTypedDataHash( - address tokenHolder, - ILlamaStrategy strategy, - address target, - uint256 value, - bytes calldata data, - string calldata description - ) internal returns (bytes32) { - // Calculating and storing nonce in memory and using that below, instead of calculating in place to prevent stack - // too deep error. - uint256 nonce = _useNonce(tokenHolder, msg.sig); - - bytes32 createActionHash = keccak256( - abi.encode( - CREATE_ACTION_TYPEHASH, - tokenHolder, - address(strategy), - target, - value, - keccak256(data), - keccak256(bytes(description)), - nonce - ) - ); - - return keccak256(abi.encodePacked("\x19\x01", _getDomainHash(), createActionHash)); - } - - /// @dev Returns the hash of the ABI-encoded EIP-712 message for the `CancelAction` domain, which can be used to - /// recover the signer. - function _getCancelActionTypedDataHash(address tokenHolder, ActionInfo calldata actionInfo) - internal - returns (bytes32) - { - bytes32 cancelActionHash = keccak256( - abi.encode(CANCEL_ACTION_TYPEHASH, tokenHolder, _getActionInfoHash(actionInfo), _useNonce(tokenHolder, msg.sig)) - ); - - return keccak256(abi.encodePacked("\x19\x01", _getDomainHash(), cancelActionHash)); - } - - /// @dev Returns the hash of `actionInfo`. - function _getActionInfoHash(ActionInfo calldata actionInfo) internal pure returns (bytes32) { - return keccak256( - abi.encode( - ACTION_INFO_TYPEHASH, - actionInfo.id, - actionInfo.creator, - actionInfo.creatorRole, - address(actionInfo.strategy), - actionInfo.target, - actionInfo.value, - keccak256(actionInfo.data) - ) - ); - } -} diff --git a/src/token-voting/LlamaTokenCaster.sol b/src/token-voting/LlamaTokenGovernor.sol similarity index 73% rename from src/token-voting/LlamaTokenCaster.sol rename to src/token-voting/LlamaTokenGovernor.sol index a95cf0a..8e6d916 100644 --- a/src/token-voting/LlamaTokenCaster.sol +++ b/src/token-voting/LlamaTokenGovernor.sol @@ -5,23 +5,21 @@ import {Initializable} from "@openzeppelin/proxy/utils/Initializable.sol"; import {FixedPointMathLib} from "@solmate/utils/FixedPointMathLib.sol"; import {ILlamaCore} from "src/interfaces/ILlamaCore.sol"; +import {ILlamaStrategy} from "src/interfaces/ILlamaStrategy.sol"; import {ILlamaTokenAdapter} from "src/token-voting/interfaces/ILlamaTokenAdapter.sol"; import {ActionState, VoteType} from "src/lib/Enums.sol"; -import {CasterConfig} from "src/lib/Structs.sol"; +import {Action, ActionInfo, CasterConfig} from "src/lib/Structs.sol"; import {LlamaUtils} from "src/lib/LlamaUtils.sol"; import {PeriodPctCheckpoints} from "src/lib/PeriodPctCheckpoints.sol"; import {QuorumCheckpoints} from "src/lib/QuorumCheckpoints.sol"; -import {Action, ActionInfo} from "src/lib/Structs.sol"; -/// @title LlamaTokenCaster +/// @title LlamaTokenGovernor /// @author Llama (devsdosomething@llama.xyz) -/// @notice This contract lets holders of a given governance token collectively cast an approval or -/// disapproval on created actions. +/// @notice This contract lets holders of a given governance token create actions if they have a +/// sufficient token balance and collectively cast an approval or disapproval on created actions. /// @dev This contract is deployed by `LlamaTokenVotingFactory`. Anyone can deploy this contract using the factory, but -/// it must hold a Policy from the specified `LlamaCore` instance to actually be able to cast on an action. This -/// contract does not verify that it holds the correct policy when voting and relies on `LlamaCore` to -/// verify that during submission. -contract LlamaTokenCaster is Initializable { +/// it must hold a Policy from the specified `LlamaCore` instance to actually be able to create and cast on an action. +contract LlamaTokenGovernor is Initializable { using PeriodPctCheckpoints for PeriodPctCheckpoints.History; using QuorumCheckpoints for QuorumCheckpoints.History; // ========================= @@ -40,9 +38,9 @@ contract LlamaTokenCaster is Initializable { mapping(address tokenholder => bool) castVeto; // True if tokenholder casted a veto, false otherwise. } - // ======================== - // ======== Errors ======== - // ======================== + // ====================================== + // ======== Errors and Modifiers ======== + // ====================================== /// @dev Thrown when a user tries to submit (dis)approval but the casting period has not ended. error CastingPeriodNotOver(); @@ -59,6 +57,9 @@ contract LlamaTokenCaster is Initializable { /// @dev Thrown when a user tries to cast a vote or veto but the against surpasses for. error ForDoesNotSurpassAgainst(uint256 castsFor, uint256 castsAgainst); + /// @dev Thrown when a user tries to create an action but does not have enough tokens. + error InsufficientBalance(uint256 balance); + /// @dev Thrown when a user tries to submit an approval but there are not enough votes. error InsufficientVotes(uint256 votes, uint256 threshold); @@ -66,6 +67,9 @@ contract LlamaTokenCaster is Initializable { /// @param current The current state of the action. error InvalidActionState(ActionState current); + /// @dev Thrown when an invalid `creationThreshold` is passed to the constructor. + error InvalidCreationThreshold(); + /// @dev The indices would result in `Panic: Index Out of Bounds`. /// @dev Thrown when the `end` index is greater than array length or when the `start` index is greater than the `end` /// index. @@ -86,12 +90,18 @@ contract LlamaTokenCaster is Initializable { /// @dev Thrown when an invalid `support` value is used when casting. error InvalidSupport(uint8 support); + /// @dev Thrown when a `token` with an invalid totaly supply is passed to the constructor. + error InvalidTotalSupply(); + /// @dev Thrown when an invalid `vetoQuorumPct` is passed to the constructor. error InvalidVetoQuorumPct(uint16 vetoQuorumPct); /// @dev Thrown when an invalid `voteQuorumPct` is passed to the constructor. error InvalidVoteQuorumPct(uint16 voteQuorumPct); + /// @dev Thrown when a user tries to cancel an action but they are not the action creator. + error OnlyActionCreator(); + /// @dev Thrown when an address other than the `LlamaExecutor` tries to call a function. error OnlyLlamaExecutor(); @@ -101,10 +111,25 @@ contract LlamaTokenCaster is Initializable { /// @dev Thrown when a user tries to submit (dis)approval but the submission period has ended. error SubmissionPeriodOver(); + /// @dev Checks that the caller is the Llama Executor and reverts if not. + modifier onlyLlama() { + if (msg.sender != address(llamaCore.executor())) revert OnlyLlamaExecutor(); + _; + } + // ======================== // ======== Events ======== // ======================== + /// @dev Emitted when an action is canceled. + event ActionCanceled(uint256 id, address indexed creator); + + /// @dev Emitted when an action is created. + event ActionCreated(uint256 id, address indexed creator); + + /// @dev Emitted when the default number of tokens required to create an action is changed. + event ActionThresholdSet(uint256 newThreshold); + /// @dev Emitted when a cast approval is submitted to the `LlamaCore` contract. event ApprovalSubmitted( uint256 id, address indexed caller, uint256 weightFor, uint256 weightAgainst, uint256 weightAbstain @@ -135,6 +160,16 @@ contract LlamaTokenCaster is Initializable { bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); + /// @dev EIP-712 createAction typehash. + bytes32 internal constant CREATE_ACTION_TYPEHASH = keccak256( + "CreateAction(address tokenHolder,address strategy,address target,uint256 value,bytes data,string description,uint256 nonce)" + ); + + /// @dev EIP-712 cancelAction typehash. + bytes32 internal constant CANCEL_ACTION_TYPEHASH = keccak256( + "CancelAction(address tokenHolder,ActionInfo actionInfo,uint256 nonce)ActionInfo(uint256 id,address creator,uint8 creatorRole,address strategy,address target,uint256 value,bytes data)" + ); + /// @notice EIP-712 castVote typehash. bytes32 internal constant CAST_VOTE_TYPEHASH = keccak256( "CastVote(address tokenHolder,ActionInfo actionInfo,uint8 support,string reason,uint256 nonce)ActionInfo(uint256 id,address creator,uint8 creatorRole,address strategy,address target,uint256 value,bytes data)" @@ -156,25 +191,31 @@ contract LlamaTokenCaster is Initializable { /// @notice The core contract for this Llama instance. ILlamaCore public llamaCore; + /// @notice The contract that manages the timepoints for this token voting module. + ILlamaTokenAdapter public tokenAdapter; + + /// @notice The role used by this contract to create actions and cast approvals and disapprovals. + /// @dev This role is expected to have the ability to create actions and force approve and disapprove actions. + uint8 public role; + + /// @notice The number of tokens required to create an action. + uint256 public creationThreshold; + /// @dev The quorum checkpoints for this token voting module. QuorumCheckpoints.History internal quorumCheckpoints; /// @dev The period pct checkpoints for this token voting module. PeriodPctCheckpoints.History internal periodPctsCheckpoint; - /// @notice The contract that manages the timepoints for this token voting module. - ILlamaTokenAdapter public tokenAdapter; - - /// @notice The role used by this contract to cast approvals and disapprovals. - /// @dev This role is expected to have the ability to force approve and disapprove actions. - uint8 public role; + /// @notice The address of the tokenholder that created the action. + mapping(uint256 => address) public actionCreators; /// @notice Mapping from action ID to the status of existing casts. mapping(uint256 actionId => CastData) public casts; /// @notice Mapping of tokenholders to function selectors to current nonces for EIP-712 signatures. - /// @dev This is used to prevent replay attacks by incrementing the nonce for each operation (`castVote` and - /// `castVeto`) signed by the tokenholders. + /// @dev This is used to prevent replay attacks by incrementing the nonce for each operation (`castVote`, + /// `createAction`, `cancelAction`, and `castVeto`) signed by the tokenholders. mapping(address tokenholders => mapping(bytes4 selector => uint256 currentNonce)) public nonces; // ================================ @@ -187,18 +228,22 @@ contract LlamaTokenCaster is Initializable { _disableInitializers(); } - /// @notice Initializes a new `LlamaTokenCaster` clone. + /// @notice Initializes a new `LlamaTokenGovernor clone. /// @dev This function is called by the `deploy` function in the `LlamaTokenVotingFactory` contract. /// The `initializer` modifier ensures that this function can be invoked at most once. /// @param _llamaCore The `LlamaCore` contract for this Llama instance. /// @param _tokenAdapter The token adapter that manages the clock, timepoints, past votes and past supply for this /// token voting module. - /// @param _role The role used by this contract to cast approvals and disapprovals. + /// @param _role The role used by this contract to create actions and cast approvals and disapprovals. + /// @param _creationThreshold The default number of tokens required to create an action. This must + /// be in the same decimals as the token. For example, if the token has 18 decimals and you want a + /// creation threshold of 1000 tokens, pass in 1000e18. /// @param casterConfig Contains the quorum and period pct values to initialize the contract with. function initialize( ILlamaCore _llamaCore, ILlamaTokenAdapter _tokenAdapter, uint8 _role, + uint256 _creationThreshold, CasterConfig memory casterConfig ) external initializer { if (_llamaCore.actionsCount() < 0) revert InvalidLlamaCoreAddress(); @@ -207,6 +252,7 @@ contract LlamaTokenCaster is Initializable { llamaCore = _llamaCore; tokenAdapter = _tokenAdapter; role = _role; + _setActionThreshold(_creationThreshold); _setQuorumPct(casterConfig.voteQuorumPct, casterConfig.vetoQuorumPct); _setPeriodPct(casterConfig.delayPeriodPct, casterConfig.castingPeriodPct, casterConfig.submissionPeriodPct); } @@ -215,7 +261,80 @@ contract LlamaTokenCaster is Initializable { // ======== External and Public Logic ======== // =========================================== - // -------- Action Lifecycle Management -------- + // -------- Action Creation Lifecycle Management -------- + + /// @notice Creates an action. + /// @dev Use `""` for `description` if there is no description. + /// @param strategy The strategy contract that will determine how the action is executed. + /// @param target The contract called when the action is executed. + /// @param value The value in wei to be sent when the action is executed. + /// @param data Data to be called on the target when the action is executed. + /// @param description A human readable description of the action and the changes it will enact. + /// @return actionId Action ID of the newly created action. + function createAction( + ILlamaStrategy strategy, + address target, + uint256 value, + bytes calldata data, + string calldata description + ) external returns (uint256 actionId) { + return _createAction(msg.sender, strategy, target, value, data, description); + } + + /// @notice Creates an action via an off-chain signature. The creator needs to have sufficient token balance that is + /// greater than or equal to the creation threshold. + /// @dev Use `""` for `description` if there is no description. + /// @param tokenHolder The tokenHolder that signed the message. + /// @param strategy The strategy contract that will determine how the action is executed. + /// @param target The contract called when the action is executed. + /// @param value The value in wei to be sent when the action is executed. + /// @param data Data to be called on the target when the action is executed. + /// @param description A human readable description of the action and the changes it will enact. + /// @param v ECDSA signature component: Parity of the `y` coordinate of point `R` + /// @param r ECDSA signature component: x-coordinate of `R` + /// @param s ECDSA signature component: `s` value of the signature + /// @return actionId Action ID of the newly created action. + function createActionBySig( + address tokenHolder, + ILlamaStrategy strategy, + address target, + uint256 value, + bytes calldata data, + string calldata description, + uint8 v, + bytes32 r, + bytes32 s + ) external returns (uint256 actionId) { + bytes32 digest = _getCreateActionTypedDataHash(tokenHolder, strategy, target, value, data, description); + address signer = ecrecover(digest, v, r, s); + if (signer == address(0) || signer != tokenHolder) revert InvalidSignature(); + actionId = _createAction(signer, strategy, target, value, data, description); + } + + /// @notice Cancels an action. + /// @param actionInfo The action to cancel. + /// @dev Relies on the validation checks in `LlamaCore.cancelAction()`. + function cancelAction(ActionInfo calldata actionInfo) external { + _cancelAction(msg.sender, actionInfo); + } + + /// @notice Cancels an action by its `actionInfo` struct via an off-chain signature. + /// @dev Rules for cancelation are defined by the strategy. + /// @param policyholder The policyholder that signed the message. + /// @param actionInfo Data required to create an action. + /// @param v ECDSA signature component: Parity of the `y` coordinate of point `R` + /// @param r ECDSA signature component: x-coordinate of `R` + /// @param s ECDSA signature component: `s` value of the signature + function cancelActionBySig(address policyholder, ActionInfo calldata actionInfo, uint8 v, bytes32 r, bytes32 s) + external + { + bytes32 digest = _getCancelActionTypedDataHash(policyholder, actionInfo); + address signer = ecrecover(digest, v, r, s); + if (signer == address(0) || signer != policyholder) revert InvalidSignature(); + _cancelAction(signer, actionInfo); + } + + // -------- Action Casting Lifecycle Management -------- /// @notice How tokenholders add their support of the approval of an action with a reason. /// @dev Use `""` for `reason` if there is no reason. @@ -392,11 +511,17 @@ contract LlamaTokenCaster is Initializable { // -------- Instance Management -------- + /// @notice Sets the default number of tokens required to create an action. + /// @param _creationThreshold The number of tokens required to create an action. + /// @dev This must be in the same decimals as the token. + function setActionThreshold(uint256 _creationThreshold) external onlyLlama { + _setActionThreshold(_creationThreshold); + } + /// @notice Sets the voting quorum and vetoing quorum. /// @param _voteQuorumPct The minimum % of votes required to submit an approval to `LlamaCore`. /// @param _vetoQuorumPct The minimum % of vetoes required to submit a disapproval to `LlamaCore`. - function setQuorumPct(uint16 _voteQuorumPct, uint16 _vetoQuorumPct) external { - if (msg.sender != llamaCore.executor()) revert OnlyLlamaExecutor(); + function setQuorumPct(uint16 _voteQuorumPct, uint16 _vetoQuorumPct) external onlyLlama { _setQuorumPct(_voteQuorumPct, _vetoQuorumPct); } @@ -404,8 +529,10 @@ contract LlamaTokenCaster is Initializable { /// @param _delayPeriodPct The % of the total period that must pass before voting can begin. /// @param _castingPeriodPct The % of the total period that voting can occur. /// @param _submissionPeriodPct The % of the total period withing which the (dis)approval must be submitted. - function setPeriodPct(uint16 _delayPeriodPct, uint16 _castingPeriodPct, uint16 _submissionPeriodPct) external { - if (msg.sender != llamaCore.executor()) revert OnlyLlamaExecutor(); + function setPeriodPct(uint16 _delayPeriodPct, uint16 _castingPeriodPct, uint16 _submissionPeriodPct) + external + onlyLlama + { _setPeriodPct(_delayPeriodPct, _castingPeriodPct, _submissionPeriodPct); } @@ -496,6 +623,37 @@ contract LlamaTokenCaster is Initializable { // ======== Internal Logic ======== // ================================ + // -------- Action Creation Internal Functions -------- + + /// @dev Creates an action. The creator needs to have sufficient token balance. + function _createAction( + address tokenHolder, + ILlamaStrategy strategy, + address target, + uint256 value, + bytes calldata data, + string calldata description + ) internal returns (uint256 actionId) { + // Reverts if clock or CLOCK_MODE() has changed + tokenAdapter.checkIfInconsistentClock(); + + uint256 balance = tokenAdapter.getPastVotes(tokenHolder, tokenAdapter.clock() - 1); + if (balance < creationThreshold) revert InsufficientBalance(balance); + + actionId = llamaCore.createAction(role, strategy, target, value, data, description); + actionCreators[actionId] = tokenHolder; + emit ActionCreated(actionId, tokenHolder); + } + + /// @dev Cancels an action by its `actionInfo` struct. Only the action creator can cancel. + function _cancelAction(address creator, ActionInfo calldata actionInfo) internal { + if (creator != actionCreators[actionInfo.id]) revert OnlyActionCreator(); + llamaCore.cancelAction(actionInfo); + emit ActionCanceled(actionInfo.id, creator); + } + + // -------- Action Casting Internal Functions -------- + /// @dev How token holders add their support of the approval of an action with a reason. function _castVote(address caster, ActionInfo calldata actionInfo, uint8 support, string calldata reason) internal @@ -504,8 +662,10 @@ contract LlamaTokenCaster is Initializable { Action memory action = llamaCore.getAction(actionInfo.id); uint256 checkpointTime = action.creationTime - 1; + CastData storage castData = casts[actionInfo.id]; + actionInfo.strategy.checkIfApprovalEnabled(actionInfo, address(this), role); // Reverts if not allowed. - if (casts[actionInfo.id].castVote[caster]) revert DuplicateCast(); + if (castData.castVote[caster]) revert DuplicateCast(); _preCastAssertions(actionInfo, support, ActionState.Active, checkpointTime); uint256 delayPeriodEndTime; @@ -527,8 +687,6 @@ contract LlamaTokenCaster is Initializable { uint128 weight = LlamaUtils.toUint128(tokenAdapter.getPastVotes(caster, tokenAdapter.timestampToTimepoint(delayPeriodEndTime))); - CastData storage castData = casts[actionInfo.id]; - if (support == uint8(VoteType.Against)) castData.votesAgainst = _newCastCount(castData.votesAgainst, weight); else if (support == uint8(VoteType.For)) castData.votesFor = _newCastCount(castData.votesFor, weight); else if (support == uint8(VoteType.Abstain)) castData.votesAbstain = _newCastCount(castData.votesAbstain, weight); @@ -546,8 +704,10 @@ contract LlamaTokenCaster is Initializable { Action memory action = llamaCore.getAction(actionInfo.id); uint256 checkpointTime = action.creationTime - 1; + CastData storage castData = casts[actionInfo.id]; + actionInfo.strategy.checkIfDisapprovalEnabled(actionInfo, address(this), role); // Reverts if not allowed. - if (casts[actionInfo.id].castVeto[caster]) revert DuplicateCast(); + if (castData.castVeto[caster]) revert DuplicateCast(); _preCastAssertions(actionInfo, support, ActionState.Queued, checkpointTime); uint256 delayPeriodEndTime; @@ -570,8 +730,6 @@ contract LlamaTokenCaster is Initializable { uint128 weight = LlamaUtils.toUint128(tokenAdapter.getPastVotes(caster, tokenAdapter.timestampToTimepoint(delayPeriodEndTime))); - CastData storage castData = casts[actionInfo.id]; - if (support == uint8(VoteType.Against)) castData.vetoesAgainst = _newCastCount(castData.vetoesAgainst, weight); else if (support == uint8(VoteType.For)) castData.vetoesFor = _newCastCount(castData.vetoesFor, weight); else if (support == uint8(VoteType.Abstain)) castData.vetoesAbstain = _newCastCount(castData.vetoesAbstain, weight); @@ -606,6 +764,17 @@ contract LlamaTokenCaster is Initializable { return currentCount + weight; } + // -------- Instance Management Internal Functions -------- + + /// @dev Sets the default number of tokens required to create an action. + function _setActionThreshold(uint256 _creationThreshold) internal { + uint256 totalSupply = tokenAdapter.getPastTotalSupply(tokenAdapter.clock() - 1); + if (totalSupply == 0) revert InvalidTotalSupply(); + if (_creationThreshold > totalSupply) revert InvalidCreationThreshold(); + creationThreshold = _creationThreshold; + emit ActionThresholdSet(_creationThreshold); + } + /// @dev Sets the voting quorum and vetoing quorum. function _setQuorumPct(uint16 _voteQuorumPct, uint16 _vetoQuorumPct) internal { if (_voteQuorumPct > ONE_HUNDRED_IN_BPS || _voteQuorumPct <= 0) revert InvalidVoteQuorumPct(_voteQuorumPct); @@ -623,11 +792,13 @@ contract LlamaTokenCaster is Initializable { emit PeriodPctSet(_delayPeriodPct, _castingPeriodPct, _submissionPeriodPct); } - /// @dev Returns the current nonce for a given tokenholder and selector, and increments it. Used to prevent + // -------- User Nonce Management Internal Functions -------- + + /// @dev Returns the current nonce for a given tokenHolder and selector, and increments it. Used to prevent /// replay attacks. - function _useNonce(address tokenholder, bytes4 selector) internal returns (uint256 nonce) { - nonce = nonces[tokenholder][selector]; - nonces[tokenholder][selector] = LlamaUtils.uncheckedIncrement(nonce); + function _useNonce(address tokenHolder, bytes4 selector) internal returns (uint256 nonce) { + nonce = nonces[tokenHolder][selector]; + nonces[tokenHolder][selector] = LlamaUtils.uncheckedIncrement(nonce); } // -------- EIP-712 Getters -------- @@ -641,6 +812,49 @@ contract LlamaTokenCaster is Initializable { ); } + /// @dev Returns the hash of the ABI-encoded EIP-712 message for the `CreateAction` domain, which can be used to + /// recover the signer. + function _getCreateActionTypedDataHash( + address tokenHolder, + ILlamaStrategy strategy, + address target, + uint256 value, + bytes calldata data, + string calldata description + ) internal returns (bytes32) { + // Calculating and storing nonce in memory and using that below, instead of calculating in place to prevent stack + // too deep error. + uint256 nonce = _useNonce(tokenHolder, msg.sig); + + bytes32 createActionHash = keccak256( + abi.encode( + CREATE_ACTION_TYPEHASH, + tokenHolder, + address(strategy), + target, + value, + keccak256(data), + keccak256(bytes(description)), + nonce + ) + ); + + return keccak256(abi.encodePacked("\x19\x01", _getDomainHash(), createActionHash)); + } + + /// @dev Returns the hash of the ABI-encoded EIP-712 message for the `CancelAction` domain, which can be used to + /// recover the signer. + function _getCancelActionTypedDataHash(address tokenHolder, ActionInfo calldata actionInfo) + internal + returns (bytes32) + { + bytes32 cancelActionHash = keccak256( + abi.encode(CANCEL_ACTION_TYPEHASH, tokenHolder, _getActionInfoHash(actionInfo), _useNonce(tokenHolder, msg.sig)) + ); + + return keccak256(abi.encodePacked("\x19\x01", _getDomainHash(), cancelActionHash)); + } + /// @dev Returns the hash of the ABI-encoded EIP-712 message for the `CastApproval` domain, which can be used to /// recover the signer. function _getCastVoteTypedDataHash( diff --git a/src/token-voting/LlamaTokenVotingFactory.sol b/src/token-voting/LlamaTokenVotingFactory.sol index 437cd09..3c9d90a 100644 --- a/src/token-voting/LlamaTokenVotingFactory.sol +++ b/src/token-voting/LlamaTokenVotingFactory.sol @@ -6,8 +6,7 @@ import {Clones} from "@openzeppelin/proxy/Clones.sol"; import {ILlamaCore} from "src/interfaces/ILlamaCore.sol"; import {CasterConfig, LlamaTokenVotingConfig} from "src/lib/Structs.sol"; import {ILlamaTokenAdapter} from "src/token-voting/interfaces/ILlamaTokenAdapter.sol"; -import {LlamaTokenActionCreator} from "src/token-voting/LlamaTokenActionCreator.sol"; -import {LlamaTokenCaster} from "src/token-voting/LlamaTokenCaster.sol"; +import {LlamaTokenGovernor} from "src/token-voting/LlamaTokenGovernor.sol"; /// @title LlamaTokenVotingFactory /// @author Llama (devsdosomething@llama.xyz) @@ -32,10 +31,8 @@ contract LlamaTokenVotingFactory { ILlamaTokenAdapter tokenAdapterLogic, ILlamaTokenAdapter tokenAdapter, uint256 nonce, - uint8 actionCreatorRole, - uint8 casterRole, - LlamaTokenActionCreator llamaTokenActionCreator, - LlamaTokenCaster llamaTokenCaster, + uint8 governorRole, + LlamaTokenGovernor llamaTokenGovernor, uint256 chainId ); @@ -43,26 +40,18 @@ contract LlamaTokenVotingFactory { // ======== Constants and Storage Variables ======== // ================================================= - /// @notice The Token Action Creator implementation (logic) contract. - LlamaTokenActionCreator public immutable LLAMA_TOKEN_ACTION_CREATOR_LOGIC; + /// @notice The Token Governor implementation (logic) contract. + LlamaTokenGovernor public immutable LLAMA_TOKEN_GOVERNOR_LOGIC; - /// @notice The Token Caster implementation (logic) contract. - LlamaTokenCaster public immutable LLAMA_TOKEN_CASTER_LOGIC; - - /// @dev Set the logic contracts used to deploy Token Voting modules. - constructor(LlamaTokenActionCreator LlamaTokenActionCreatorLogic, LlamaTokenCaster LlamaTokenCasterLogic) { - LLAMA_TOKEN_ACTION_CREATOR_LOGIC = LlamaTokenActionCreatorLogic; - LLAMA_TOKEN_CASTER_LOGIC = LlamaTokenCasterLogic; + /// @dev Set the logic contract used to deploy Token Voting modules. + constructor(LlamaTokenGovernor llamaTokenGovernorLogic) { + LLAMA_TOKEN_GOVERNOR_LOGIC = llamaTokenGovernorLogic; } /// @notice Deploys a new Llama token voting module. /// @param tokenVotingConfig The configuration of the new Llama token voting module. - /// @return actionCreator The address of the `LlamaTokenActionCreator` of the deployed token voting module. - /// @return caster The address of the `LlamaTokenCaster` of the deployed token voting module. - function deploy(LlamaTokenVotingConfig memory tokenVotingConfig) - external - returns (LlamaTokenActionCreator actionCreator, LlamaTokenCaster caster) - { + /// @return governor The address of the `LlamaTokenGovernor` (the deployed token voting module). + function deploy(LlamaTokenVotingConfig memory tokenVotingConfig) external returns (LlamaTokenGovernor governor) { bytes32 salt = keccak256( abi.encodePacked( msg.sender, address(tokenVotingConfig.llamaCore), tokenVotingConfig.adapterConfig, tokenVotingConfig.nonce @@ -78,25 +67,17 @@ contract LlamaTokenVotingFactory { if (address(tokenAdapter.token()) == address(0)) revert InvalidTokenAdapterConfig(); if (tokenAdapter.timestampToTimepoint(block.timestamp) == 0) revert InvalidTokenAdapterConfig(); if (tokenAdapter.clock() == 0) revert InvalidTokenAdapterConfig(); - // Reverts if clock is inconsistent tokenAdapter.checkIfInconsistentClock(); - // Deploy and initialize `LlamaTokenActionCreator` contract - actionCreator = LlamaTokenActionCreator(Clones.cloneDeterministic(address(LLAMA_TOKEN_ACTION_CREATOR_LOGIC), salt)); - - actionCreator.initialize( + // Deploy and initialize `LlamaTokenGovernor` contract + governor = LlamaTokenGovernor(Clones.cloneDeterministic(address(LLAMA_TOKEN_GOVERNOR_LOGIC), salt)); + governor.initialize( tokenVotingConfig.llamaCore, tokenAdapter, - tokenVotingConfig.actionCreatorRole, - tokenVotingConfig.creationThreshold - ); - - // Deploy and initialize `LlamaTokenCaster` contract - caster = LlamaTokenCaster(Clones.cloneDeterministic(address(LLAMA_TOKEN_CASTER_LOGIC), salt)); - - caster.initialize( - tokenVotingConfig.llamaCore, tokenAdapter, tokenVotingConfig.casterRole, tokenVotingConfig.casterConfig + tokenVotingConfig.governorRole, + tokenVotingConfig.creationThreshold, + tokenVotingConfig.casterConfig ); emit LlamaTokenVotingInstanceCreated( @@ -106,10 +87,8 @@ contract LlamaTokenVotingFactory { tokenVotingConfig.tokenAdapterLogic, tokenAdapter, tokenVotingConfig.nonce, - tokenVotingConfig.actionCreatorRole, - tokenVotingConfig.casterRole, - actionCreator, - caster, + tokenVotingConfig.governorRole, + governor, block.chainid ); } diff --git a/test/token-voting/LlamaTokenVotingFactory.t.sol b/test/token-voting/LlamaTokenVotingFactory.t.sol index 6135b56..aee0f34 100644 --- a/test/token-voting/LlamaTokenVotingFactory.t.sol +++ b/test/token-voting/LlamaTokenVotingFactory.t.sol @@ -12,8 +12,7 @@ import {ILlamaCore} from "src/interfaces/ILlamaCore.sol"; import {ILlamaPolicy} from "src/interfaces/ILlamaPolicy.sol"; import {ILlamaTokenAdapter} from "src/token-voting/interfaces/ILlamaTokenAdapter.sol"; import {LlamaTokenAdapterVotesTimestamp} from "src/token-voting/token-adapters/LlamaTokenAdapterVotesTimestamp.sol"; -import {LlamaTokenActionCreator} from "src/token-voting/LlamaTokenActionCreator.sol"; -import {LlamaTokenCaster} from "src/token-voting/LlamaTokenCaster.sol"; +import {LlamaTokenGovernor} from "src/token-voting/LlamaTokenGovernor.sol"; import {LlamaTokenVotingFactory} from "src/token-voting/LlamaTokenVotingFactory.sol"; contract LlamaTokenVotingFactoryTest is LlamaTokenVotingTestSetup { @@ -24,10 +23,8 @@ contract LlamaTokenVotingFactoryTest is LlamaTokenVotingTestSetup { ILlamaTokenAdapter tokenAdapterLogic, ILlamaTokenAdapter tokenAdapter, uint256 nonce, - uint8 actionCreatorRole, - uint8 casterRole, - LlamaTokenActionCreator llamaTokenActionCreator, - LlamaTokenCaster llamaTokenCaster, + uint8 governorRole, + LlamaTokenGovernor llamaTokenGovernor, uint256 chainId ); event ActionThresholdSet(uint256 newThreshold); @@ -48,12 +45,8 @@ contract LlamaTokenVotingFactoryTest is LlamaTokenVotingTestSetup { } contract Constructor is LlamaTokenVotingFactoryTest { - function test_SetsLlamaERC20TokenActionCreatorLogicAddress() public { - assertEq(address(tokenVotingFactory.LLAMA_TOKEN_ACTION_CREATOR_LOGIC()), address(llamaTokenActionCreatorLogic)); - } - - function test_SetsLlamaERC20TokenCasterLogicAddress() public { - assertEq(address(tokenVotingFactory.LLAMA_TOKEN_CASTER_LOGIC()), address(llamaTokenCasterLogic)); + function test_SetsLlamaERC20TokenGovernorLogicAddress() public { + assertEq(address(tokenVotingFactory.LLAMA_TOKEN_GOVERNOR_LOGIC()), address(llamaTokenGovernorLogic)); } } @@ -87,8 +80,7 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest { llamaTokenAdapterTimestampLogic, adapterConfig, 0, - tokenVotingActionCreatorRole, - tokenVotingCasterRole, + tokenVotingGovernorRole, ERC20_CREATION_THRESHOLD, defaultCasterConfig ); @@ -100,16 +92,9 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest { bytes32 salt = keccak256(abi.encodePacked(address(EXECUTOR), address(CORE), adapterConfig, uint256(0))); // Compute addresses of ERC20 Token Voting Module - LlamaTokenActionCreator llamaERC20TokenActionCreator = LlamaTokenActionCreator( - Clones.predictDeterministicAddress( - address(llamaTokenActionCreatorLogic), - salt, - address(tokenVotingFactory) // deployer - ) - ); - LlamaTokenCaster llamaERC20TokenCaster = LlamaTokenCaster( + LlamaTokenGovernor llamaERC20TokenGovernor = LlamaTokenGovernor( Clones.predictDeterministicAddress( - address(llamaTokenCasterLogic), + address(llamaTokenGovernorLogic), salt, address(tokenVotingFactory) // deployer ) @@ -137,24 +122,20 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest { llamaTokenAdapterTimestampLogic, llamaERC20TokenAdapter, 0, - tokenVotingActionCreatorRole, - tokenVotingCasterRole, - llamaERC20TokenActionCreator, - llamaERC20TokenCaster, + tokenVotingGovernorRole, + llamaERC20TokenGovernor, block.chainid ); CORE.executeAction(actionInfo); assertEq(address(llamaERC20TokenAdapter.token()), address(erc20VotesToken)); - assertEq(address(llamaERC20TokenActionCreator.llamaCore()), address(CORE)); - (uint16 voteQuorumPct, uint16 vetoQuorumPct) = llamaERC20TokenCaster.getQuorum(); + assertEq(address(llamaERC20TokenGovernor.llamaCore()), address(CORE)); + (uint16 voteQuorumPct, uint16 vetoQuorumPct) = llamaERC20TokenGovernor.getQuorum(); assertEq(ERC20_VOTE_QUORUM_PCT, voteQuorumPct); assertEq(ERC20_VETO_QUORUM_PCT, vetoQuorumPct); - assertEq(llamaERC20TokenActionCreator.role(), tokenVotingActionCreatorRole); - assertEq(llamaERC20TokenActionCreator.creationThreshold(), ERC20_CREATION_THRESHOLD); + assertEq(llamaERC20TokenGovernor.role(), tokenVotingGovernorRole); + assertEq(llamaERC20TokenGovernor.creationThreshold(), ERC20_CREATION_THRESHOLD); assertEq(address(llamaERC20TokenAdapter.token()), address(erc20VotesToken)); - assertEq(address(llamaERC20TokenCaster.llamaCore()), address(CORE)); - assertEq(llamaERC20TokenCaster.role(), tokenVotingCasterRole); } function test_CanDeployERC721TokenVotingModule() public { @@ -164,8 +145,7 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest { llamaTokenAdapterTimestampLogic, adapterConfig, 0, - tokenVotingActionCreatorRole, - tokenVotingCasterRole, + tokenVotingGovernorRole, ERC721_CREATION_THRESHOLD, defaultCasterConfig ); @@ -177,16 +157,9 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest { bytes32 salt = keccak256(abi.encodePacked(address(EXECUTOR), address(CORE), adapterConfig, uint256(0))); // Compute addresses of ERC721 Token Voting Module - LlamaTokenActionCreator llamaERC721TokenActionCreator = LlamaTokenActionCreator( + LlamaTokenGovernor llamaERC721TokenGovernor = LlamaTokenGovernor( Clones.predictDeterministicAddress( - address(llamaTokenActionCreatorLogic), - salt, - address(tokenVotingFactory) // deployer - ) - ); - LlamaTokenCaster llamaERC721TokenCaster = LlamaTokenCaster( - Clones.predictDeterministicAddress( - address(llamaTokenCasterLogic), + address(llamaTokenGovernorLogic), salt, address(tokenVotingFactory) // deployer ) @@ -214,24 +187,20 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest { llamaTokenAdapterTimestampLogic, llamaERC721TokenAdapter, 0, - tokenVotingActionCreatorRole, - tokenVotingCasterRole, - llamaERC721TokenActionCreator, - llamaERC721TokenCaster, + tokenVotingGovernorRole, + llamaERC721TokenGovernor, block.chainid ); CORE.executeAction(actionInfo); assertEq(address(llamaERC721TokenAdapter.token()), address(erc721VotesToken)); - assertEq(address(llamaERC721TokenActionCreator.llamaCore()), address(CORE)); - (uint16 voteQuorumPct, uint16 vetoQuorumPct) = llamaERC721TokenCaster.getQuorum(); + assertEq(address(llamaERC721TokenGovernor.llamaCore()), address(CORE)); + (uint16 voteQuorumPct, uint16 vetoQuorumPct) = llamaERC721TokenGovernor.getQuorum(); assertEq(ERC721_VOTE_QUORUM_PCT, voteQuorumPct); assertEq(ERC721_VETO_QUORUM_PCT, vetoQuorumPct); - assertEq(llamaERC721TokenActionCreator.role(), tokenVotingActionCreatorRole); - assertEq(llamaERC721TokenActionCreator.creationThreshold(), ERC721_CREATION_THRESHOLD); + assertEq(llamaERC721TokenGovernor.role(), tokenVotingGovernorRole); + assertEq(llamaERC721TokenGovernor.creationThreshold(), ERC721_CREATION_THRESHOLD); assertEq(address(llamaERC721TokenAdapter.token()), address(erc721VotesToken)); - assertEq(address(llamaERC721TokenCaster.llamaCore()), address(CORE)); - assertEq(llamaERC721TokenCaster.role(), tokenVotingCasterRole); } function test_CanBeDeployedByAnyone(address randomCaller) public { @@ -241,17 +210,9 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest { bytes memory adapterConfig = abi.encode(LlamaTokenAdapterVotesTimestamp.Config(address(erc20VotesToken))); bytes32 salt = keccak256(abi.encodePacked(randomCaller, address(CORE), adapterConfig, uint256(0))); - LlamaTokenActionCreator llamaERC20TokenActionCreator = LlamaTokenActionCreator( - Clones.predictDeterministicAddress( - address(llamaTokenActionCreatorLogic), - salt, - address(tokenVotingFactory) // deployer - ) - ); - - LlamaTokenCaster llamaERC20TokenCaster = LlamaTokenCaster( + LlamaTokenGovernor llamaERC20TokenGovernor = LlamaTokenGovernor( Clones.predictDeterministicAddress( - address(llamaTokenCasterLogic), + address(llamaTokenGovernorLogic), salt, address(tokenVotingFactory) // deployer ) @@ -278,10 +239,8 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest { llamaTokenAdapterTimestampLogic, llamaERC20TokenAdapter, 0, - tokenVotingActionCreatorRole, - tokenVotingCasterRole, - llamaERC20TokenActionCreator, - llamaERC20TokenCaster, + tokenVotingGovernorRole, + llamaERC20TokenGovernor, block.chainid ); @@ -290,8 +249,7 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest { llamaTokenAdapterTimestampLogic, adapterConfig, 0, - tokenVotingActionCreatorRole, - tokenVotingCasterRole, + tokenVotingGovernorRole, ERC20_CREATION_THRESHOLD, defaultCasterConfig ); @@ -300,15 +258,13 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest { tokenVotingFactory.deploy(config); assertEq(address(llamaERC20TokenAdapter.token()), address(erc20VotesToken)); - assertEq(address(llamaERC20TokenActionCreator.llamaCore()), address(CORE)); - (uint16 voteQuorumPct, uint16 vetoQuorumPct) = llamaERC20TokenCaster.getQuorum(); + assertEq(address(llamaERC20TokenGovernor.llamaCore()), address(CORE)); + (uint16 voteQuorumPct, uint16 vetoQuorumPct) = llamaERC20TokenGovernor.getQuorum(); assertEq(ERC20_VOTE_QUORUM_PCT, voteQuorumPct); assertEq(ERC20_VETO_QUORUM_PCT, vetoQuorumPct); - assertEq(llamaERC20TokenActionCreator.role(), tokenVotingActionCreatorRole); - assertEq(llamaERC20TokenActionCreator.creationThreshold(), ERC20_CREATION_THRESHOLD); + assertEq(llamaERC20TokenGovernor.role(), tokenVotingGovernorRole); + assertEq(llamaERC20TokenGovernor.creationThreshold(), ERC20_CREATION_THRESHOLD); assertEq(address(llamaERC20TokenAdapter.token()), address(erc20VotesToken)); - assertEq(address(llamaERC20TokenCaster.llamaCore()), address(CORE)); - assertEq(llamaERC20TokenCaster.role(), tokenVotingCasterRole); } function test_CanBeDeployedMoreThanOnceBySameDeployer() public { @@ -322,8 +278,7 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest { llamaTokenAdapterTimestampLogic, adapterConfig, 0, - tokenVotingActionCreatorRole, - tokenVotingCasterRole, + tokenVotingGovernorRole, ERC20_CREATION_THRESHOLD, defaultCasterConfig ); @@ -336,16 +291,9 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest { bytes32 salt = keccak256(abi.encodePacked(address(EXECUTOR), address(CORE), adapterConfig, uint256(0))); // Compute addresses of ERC20 Token Voting Module - LlamaTokenActionCreator llamaERC20TokenActionCreator = LlamaTokenActionCreator( - Clones.predictDeterministicAddress( - address(llamaTokenActionCreatorLogic), - salt, - address(tokenVotingFactory) // deployer - ) - ); - LlamaTokenCaster llamaERC20TokenCaster = LlamaTokenCaster( + LlamaTokenGovernor llamaERC20TokenGovernor = LlamaTokenGovernor( Clones.predictDeterministicAddress( - address(llamaTokenCasterLogic), + address(llamaTokenGovernorLogic), salt, address(tokenVotingFactory) // deployer ) @@ -367,10 +315,8 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest { llamaTokenAdapterTimestampLogic, llamaERC20TokenAdapter, 0, - tokenVotingActionCreatorRole, - tokenVotingCasterRole, - llamaERC20TokenActionCreator, - llamaERC20TokenCaster, + tokenVotingGovernorRole, + llamaERC20TokenGovernor, block.chainid ); CORE.executeAction(actionInfo); @@ -385,8 +331,7 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest { llamaTokenAdapterTimestampLogic, adapterConfig, 1, - tokenVotingActionCreatorRole, - tokenVotingCasterRole, + tokenVotingGovernorRole, ERC20_CREATION_THRESHOLD, defaultCasterConfig ); @@ -399,16 +344,9 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest { salt = keccak256(abi.encodePacked(address(EXECUTOR), address(CORE), adapterConfig, uint256(1))); // Compute addresses of ERC20 Token Voting Module - llamaERC20TokenActionCreator = LlamaTokenActionCreator( - Clones.predictDeterministicAddress( - address(llamaTokenActionCreatorLogic), - salt, // salt - address(tokenVotingFactory) // deployer - ) - ); - llamaERC20TokenCaster = LlamaTokenCaster( + llamaERC20TokenGovernor = LlamaTokenGovernor( Clones.predictDeterministicAddress( - address(llamaTokenCasterLogic), + address(llamaTokenGovernorLogic), salt, // salt address(tokenVotingFactory) // deployer ) @@ -430,10 +368,8 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest { llamaTokenAdapterTimestampLogic, llamaERC20TokenAdapter, 1, - tokenVotingActionCreatorRole, - tokenVotingCasterRole, - llamaERC20TokenActionCreator, - llamaERC20TokenCaster, + tokenVotingGovernorRole, + llamaERC20TokenGovernor, block.chainid ); CORE.executeAction(actionInfo); diff --git a/test/token-voting/LlamaTokenVotingTestSetup.sol b/test/token-voting/LlamaTokenVotingTestSetup.sol index f2c1eb6..dd6d1f0 100644 --- a/test/token-voting/LlamaTokenVotingTestSetup.sol +++ b/test/token-voting/LlamaTokenVotingTestSetup.sol @@ -16,8 +16,7 @@ import {ILlamaRelativeStrategyBase} from "src/interfaces/ILlamaRelativeStrategyB import {ILlamaStrategy} from "src/interfaces/ILlamaStrategy.sol"; import {RoleDescription} from "src/lib/UDVTs.sol"; import {LlamaTokenAdapterVotesTimestamp} from "src/token-voting/token-adapters/LlamaTokenAdapterVotesTimestamp.sol"; -import {LlamaTokenActionCreator} from "src/token-voting/LlamaTokenActionCreator.sol"; -import {LlamaTokenCaster} from "src/token-voting/LlamaTokenCaster.sol"; +import {LlamaTokenGovernor} from "src/token-voting/LlamaTokenGovernor.sol"; contract LlamaTokenVotingTestSetup is LlamaPeripheryTestSetup, DeployLlamaTokenVotingFactory { // Percentages @@ -48,8 +47,7 @@ contract LlamaTokenVotingTestSetup is LlamaPeripheryTestSetup, DeployLlamaTokenV CasterConfig public defaultCasterConfig; // Token Voting Roles - uint8 tokenVotingActionCreatorRole; - uint8 tokenVotingCasterRole; + uint8 tokenVotingGovernorRole; uint8 madeUpRole; // Token holders. @@ -93,10 +91,8 @@ contract LlamaTokenVotingTestSetup is LlamaPeripheryTestSetup, DeployLlamaTokenV // Initialize required roles. vm.startPrank(address(EXECUTOR)); - POLICY.initializeRole(RoleDescription.wrap("Token Voting Action Creator Role")); - tokenVotingActionCreatorRole = POLICY.numRoles(); - POLICY.initializeRole(RoleDescription.wrap("Token Voting Caster Role")); - tokenVotingCasterRole = POLICY.numRoles(); + POLICY.initializeRole(RoleDescription.wrap("Token Voting Governor Role")); + tokenVotingGovernorRole = POLICY.numRoles(); POLICY.initializeRole(RoleDescription.wrap("Made Up Role")); madeUpRole = POLICY.numRoles(); vm.stopPrank(); @@ -106,76 +102,66 @@ contract LlamaTokenVotingTestSetup is LlamaPeripheryTestSetup, DeployLlamaTokenV // ======== Helpers ======== // ========================= - function _deployERC20TokenVotingModuleAndSetRole() internal returns (LlamaTokenActionCreator, LlamaTokenCaster) { + function _deployERC20TokenVotingModuleAndSetRole() internal returns (LlamaTokenGovernor) { bytes memory adapterConfig = abi.encode(LlamaTokenAdapterVotesTimestamp.Config(address(erc20VotesToken))); LlamaTokenVotingConfig memory config = LlamaTokenVotingConfig( CORE, llamaTokenAdapterTimestampLogic, adapterConfig, 0, - tokenVotingActionCreatorRole, - tokenVotingCasterRole, + tokenVotingGovernorRole, ERC20_CREATION_THRESHOLD, defaultCasterConfig ); vm.startPrank(address(EXECUTOR)); // Deploy Token Voting Module - (LlamaTokenActionCreator llamaERC20TokenActionCreator, LlamaTokenCaster llamaERC20TokenCaster) = - tokenVotingFactory.deploy(config); + (LlamaTokenGovernor llamaERC20TokenGovernor) = tokenVotingFactory.deploy(config); // Assign roles to Token Voting Modules POLICY.setRoleHolder( - tokenVotingActionCreatorRole, address(llamaERC20TokenActionCreator), DEFAULT_ROLE_QTY, DEFAULT_ROLE_EXPIRATION - ); - POLICY.setRoleHolder( - tokenVotingCasterRole, address(llamaERC20TokenCaster), DEFAULT_ROLE_QTY, DEFAULT_ROLE_EXPIRATION + tokenVotingGovernorRole, address(llamaERC20TokenGovernor), DEFAULT_ROLE_QTY, DEFAULT_ROLE_EXPIRATION ); vm.stopPrank(); - return (LlamaTokenActionCreator(llamaERC20TokenActionCreator), LlamaTokenCaster(llamaERC20TokenCaster)); + return LlamaTokenGovernor(llamaERC20TokenGovernor); } - function _deployERC721TokenVotingModuleAndSetRole() internal returns (LlamaTokenActionCreator, LlamaTokenCaster) { + function _deployERC721TokenVotingModuleAndSetRole() internal returns (LlamaTokenGovernor) { bytes memory adapterConfig = abi.encode(LlamaTokenAdapterVotesTimestamp.Config(address(erc721VotesToken))); LlamaTokenVotingConfig memory config = LlamaTokenVotingConfig( CORE, llamaTokenAdapterTimestampLogic, adapterConfig, 0, - tokenVotingActionCreatorRole, - tokenVotingCasterRole, + tokenVotingGovernorRole, ERC721_CREATION_THRESHOLD, defaultCasterConfig ); vm.startPrank(address(EXECUTOR)); // Deploy Token Voting Module - (LlamaTokenActionCreator llamaERC721TokenActionCreator, LlamaTokenCaster llamaERC721TokenCaster) = - tokenVotingFactory.deploy(config); + (LlamaTokenGovernor llamaERC721TokenGovernor) = tokenVotingFactory.deploy(config); // Assign roles to Token Voting Modules POLICY.setRoleHolder( - tokenVotingActionCreatorRole, address(llamaERC721TokenActionCreator), DEFAULT_ROLE_QTY, DEFAULT_ROLE_EXPIRATION - ); - POLICY.setRoleHolder( - tokenVotingCasterRole, address(llamaERC721TokenCaster), DEFAULT_ROLE_QTY, DEFAULT_ROLE_EXPIRATION + tokenVotingGovernorRole, address(llamaERC721TokenGovernor), DEFAULT_ROLE_QTY, DEFAULT_ROLE_EXPIRATION ); vm.stopPrank(); - return (LlamaTokenActionCreator(llamaERC721TokenActionCreator), LlamaTokenCaster(llamaERC721TokenCaster)); + return LlamaTokenGovernor(llamaERC721TokenGovernor); } - function _setRolePermissionToLlamaTokenActionCreator() internal { - // Assign permission for `MockProtocol.pause` to the LlamaTokenActionCreator. + function _setRolePermissionToLlamaTokenGovernor() internal { + // Assign permission for `MockProtocol.pause` to the LlamaTokenGovernor. vm.prank(address(EXECUTOR)); POLICY.setRolePermission( - tokenVotingActionCreatorRole, + tokenVotingGovernorRole, ILlamaPolicy.PermissionData(address(mockProtocol), PAUSE_SELECTOR, address(STRATEGY)), true ); vm.stopPrank(); } - function _deployRelativeQuantityQuorumAndSetRolePermissionToCoreTeam(uint8 _tokenVotingCasterRole) + function _deployRelativeQuantityQuorumAndSetRolePermissionToCoreTeam(uint8 _tokenVotingGovernorRole) internal returns (ILlamaStrategy newStrategy) { @@ -188,8 +174,8 @@ contract LlamaTokenVotingTestSetup is LlamaPeripheryTestSetup, DeployLlamaTokenV isFixedLengthApprovalPeriod: false, minApprovalPct: ONE_HUNDRED_IN_BPS, minDisapprovalPct: ONE_HUNDRED_IN_BPS, - approvalRole: _tokenVotingCasterRole, - disapprovalRole: _tokenVotingCasterRole, + approvalRole: _tokenVotingGovernorRole, + disapprovalRole: _tokenVotingGovernorRole, forceApprovalRoles: forceRoles, forceDisapprovalRoles: forceRoles }); diff --git a/test/token-voting/LlamaERC20TokenActionCreator.t.sol b/test/token-voting/llama-token-governor/erc-20/LlamaTokenGovernorActionCreation.t.sol similarity index 69% rename from test/token-voting/LlamaERC20TokenActionCreator.t.sol rename to test/token-voting/llama-token-governor/erc-20/LlamaTokenGovernorActionCreation.t.sol index b7f7a9d..eb82a81 100644 --- a/test/token-voting/LlamaERC20TokenActionCreator.t.sol +++ b/test/token-voting/llama-token-governor/erc-20/LlamaTokenGovernorActionCreation.t.sol @@ -9,14 +9,14 @@ import {LlamaCoreSigUtils} from "test/utils/LlamaCoreSigUtils.sol"; import {ILlamaCore} from "src/interfaces/ILlamaCore.sol"; import {ActionState} from "src/lib/Enums.sol"; import {Action, ActionInfo} from "src/lib/Structs.sol"; -import {LlamaTokenActionCreator} from "src/token-voting/LlamaTokenActionCreator.sol"; +import {LlamaTokenGovernor} from "src/token-voting/LlamaTokenGovernor.sol"; -contract LlamaERC20TokenActionCreatorTest is LlamaTokenVotingTestSetup, LlamaCoreSigUtils { +contract LlamaTokenGovernorActionCreation is LlamaTokenVotingTestSetup, LlamaCoreSigUtils { event ActionCreated(uint256 id, address indexed creator); event ActionCanceled(uint256 id, address indexed creator); event ActionThresholdSet(uint256 newThreshold); - LlamaTokenActionCreator llamaERC20TokenActionCreator; + LlamaTokenGovernor llamaERC20TokenGovernor; function setUp() public virtual override { LlamaTokenVotingTestSetup.setUp(); @@ -29,7 +29,7 @@ contract LlamaERC20TokenActionCreatorTest is LlamaTokenVotingTestSetup, LlamaCor mineBlock(); // Deploy ERC20 Token Voting Module. - (llamaERC20TokenActionCreator,) = _deployERC20TokenVotingModuleAndSetRole(); + llamaERC20TokenGovernor = _deployERC20TokenVotingModuleAndSetRole(); // Setting ERC20TokenHolderActionCreator's EIP-712 Domain Hash setDomainHash( @@ -37,22 +37,22 @@ contract LlamaERC20TokenActionCreatorTest is LlamaTokenVotingTestSetup, LlamaCor name: CORE.name(), version: "1", chainId: block.chainid, - verifyingContract: address(llamaERC20TokenActionCreator) + verifyingContract: address(llamaERC20TokenGovernor) }) ); } } -// contract Constructor is LlamaERC20TokenActionCreatorTest { +// contract Constructor is LlamaTokenGovernorActionCreation { // function test_RevertsIf_InvalidLlamaCore() public { -// // With invalid LlamaCore instance, LlamaTokenActionCreator.InvalidLlamaCoreAddress is unreachable +// // With invalid LlamaCore instance, LlamaTokenGovernor.InvalidLlamaCoreAddress is unreachable // vm.expectRevert(); -// new LlamaTokenActionCreator(erc20VotesToken, ILlamaCore(makeAddr("invalid-llama-core")), uint256(0)); +// new LlamaTokenGovernor(erc20VotesToken, ILlamaCore(makeAddr("invalid-llama-core")), uint256(0)); // } // function test_RevertsIf_InvalidTokenAddress() public { // vm.expectRevert(); // will EvmError: Revert vecause totalSupply fn does not exist -// new LlamaTokenActionCreator(ERC20Votes(makeAddr("invalid-erc20VotesToken")), CORE, uint256(0)); +// new LlamaTokenGovernor(ERC20Votes(makeAddr("invalid-erc20VotesToken")), CORE, uint256(0)); // } // function test_RevertsIf_CreationThresholdExceedsTotalSupply() public { @@ -61,8 +61,8 @@ contract LlamaERC20TokenActionCreatorTest is LlamaTokenVotingTestSetup, LlamaCor // vm.warp(block.timestamp + 1); -// vm.expectRevert(LlamaTokenActionCreator.InvalidCreationThreshold.selector); -// new LlamaTokenActionCreator(erc20VotesToken, CORE, 17_000_000_000_000_000_000_000_000); +// vm.expectRevert(LlamaTokenGovernor.InvalidCreationThreshold.selector); +// new LlamaTokenGovernor(erc20VotesToken, CORE, 17_000_000_000_000_000_000_000_000); // } // function test_ProperlySetsConstructorArguments() public { @@ -72,17 +72,17 @@ contract LlamaERC20TokenActionCreatorTest is LlamaTokenVotingTestSetup, LlamaCor // vm.warp(block.timestamp + 1); -// LlamaTokenActionCreator llamaERC20TokenActionCreator = new -// LlamaTokenActionCreator(erc20VotesToken, +// LlamaTokenGovernor llamaERC20TokenGovernor = new +// LlamaTokenGovernor(erc20VotesToken, // CORE, // threshold); -// assertEq(address(llamaERC20TokenActionCreator.TOKEN()), address(erc20VotesToken)); -// assertEq(address(llamaERC20TokenActionCreator.LLAMA_CORE()), address(CORE)); -// assertEq(llamaERC20TokenActionCreator.creationThreshold(), threshold); +// assertEq(address(llamaERC20TokenGovernor.TOKEN()), address(erc20VotesToken)); +// assertEq(address(llamaERC20TokenGovernor.LLAMA_CORE()), address(CORE)); +// assertEq(llamaERC20TokenGovernor.creationThreshold(), threshold); // } // } -contract CreateAction is LlamaERC20TokenActionCreatorTest { +contract CreateAction is LlamaTokenGovernorActionCreation { bytes data = abi.encodeCall(mockProtocol.pause, (true)); function test_RevertsIf_InsufficientBalance() public { @@ -92,12 +92,12 @@ contract CreateAction is LlamaERC20TokenActionCreatorTest { mineBlock(); - vm.expectRevert(abi.encodeWithSelector(LlamaTokenActionCreator.InsufficientBalance.selector, 0)); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.InsufficientBalance.selector, 0)); vm.prank(notTokenHolder); - llamaERC20TokenActionCreator.createAction(STRATEGY, address(mockProtocol), 0, data, ""); + llamaERC20TokenGovernor.createAction(STRATEGY, address(mockProtocol), 0, data, ""); } - function test_RevertsIf_LlamaTokenActionCreatorDoesNotHavePermission() public { + function test_RevertsIf_LlamaTokenGovernorDoesNotHavePermission() public { erc20VotesToken.mint(tokenHolder1, ERC20_CREATION_THRESHOLD); vm.prank(tokenHolder1); erc20VotesToken.delegate(tokenHolder1); @@ -106,12 +106,12 @@ contract CreateAction is LlamaERC20TokenActionCreatorTest { vm.expectRevert(ILlamaCore.PolicyholderDoesNotHavePermission.selector); vm.prank(tokenHolder1); - llamaERC20TokenActionCreator.createAction(STRATEGY, address(mockProtocol), 0, data, ""); + llamaERC20TokenGovernor.createAction(STRATEGY, address(mockProtocol), 0, data, ""); } function test_ProperlyCreatesAction() public { - // Assigns Permission to LlamaTokenActionCreator. - _setRolePermissionToLlamaTokenActionCreator(); + // Assigns Permission to LlamaTokenGovernor. + _setRolePermissionToLlamaTokenGovernor(); // Mint tokens to tokenholder so that they can create action. erc20VotesToken.mint(tokenHolder1, ERC20_CREATION_THRESHOLD); @@ -126,7 +126,7 @@ contract CreateAction is LlamaERC20TokenActionCreatorTest { vm.expectEmit(); emit ActionCreated(actionCount, address(tokenHolder1)); vm.prank(tokenHolder1); - uint256 actionId = llamaERC20TokenActionCreator.createAction(STRATEGY, address(mockProtocol), 0, data, ""); + uint256 actionId = llamaERC20TokenGovernor.createAction(STRATEGY, address(mockProtocol), 0, data, ""); Action memory action = CORE.getAction(actionId); assertEq(actionId, actionCount); @@ -134,12 +134,12 @@ contract CreateAction is LlamaERC20TokenActionCreatorTest { } } -contract CreateActionBySig is LlamaERC20TokenActionCreatorTest { +contract CreateActionBySig is LlamaTokenGovernorActionCreation { function setUp() public virtual override { - LlamaERC20TokenActionCreatorTest.setUp(); + LlamaTokenGovernorActionCreation.setUp(); - // Assigns Permission to LlamaTokenActionCreator. - _setRolePermissionToLlamaTokenActionCreator(); + // Assigns Permission to LlamaTokenGovernor. + _setRolePermissionToLlamaTokenGovernor(); // Mint tokens to tokenholder so that they can create action. erc20VotesToken.mint(tokenHolder1, ERC20_CREATION_THRESHOLD); @@ -173,7 +173,7 @@ contract CreateActionBySig is LlamaERC20TokenActionCreatorTest { } function createActionBySig(uint8 v, bytes32 r, bytes32 s) internal returns (uint256 actionId) { - actionId = llamaERC20TokenActionCreator.createActionBySig( + actionId = llamaERC20TokenGovernor.createActionBySig( tokenHolder1, STRATEGY, address(mockProtocol), 0, abi.encodeCall(mockProtocol.pause, (true)), "", v, r, s ); } @@ -203,7 +203,7 @@ contract CreateActionBySig is LlamaERC20TokenActionCreatorTest { vm.expectEmit(); emit ActionCreated(actionCount, tokenHolder1); - uint256 actionId = llamaERC20TokenActionCreator.createActionBySig( + uint256 actionId = llamaERC20TokenGovernor.createActionBySig( tokenHolder1, STRATEGY, address(mockProtocol), @@ -223,9 +223,9 @@ contract CreateActionBySig is LlamaERC20TokenActionCreatorTest { function test_CheckNonceIncrements() public { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(tokenHolder1PrivateKey); - assertEq(llamaERC20TokenActionCreator.nonces(tokenHolder1, LlamaTokenActionCreator.createActionBySig.selector), 0); + assertEq(llamaERC20TokenGovernor.nonces(tokenHolder1, LlamaTokenGovernor.createActionBySig.selector), 0); createActionBySig(v, r, s); - assertEq(llamaERC20TokenActionCreator.nonces(tokenHolder1, LlamaTokenActionCreator.createActionBySig.selector), 1); + assertEq(llamaERC20TokenGovernor.nonces(tokenHolder1, LlamaTokenGovernor.createActionBySig.selector), 1); } function test_OperationCannotBeReplayed() public { @@ -233,7 +233,7 @@ contract CreateActionBySig is LlamaERC20TokenActionCreatorTest { createActionBySig(v, r, s); // Invalid Signature error since the recovered signer address during the second call is not the same as // policyholder since nonce has increased. - vm.expectRevert(LlamaTokenActionCreator.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); createActionBySig(v, r, s); } @@ -242,7 +242,7 @@ contract CreateActionBySig is LlamaERC20TokenActionCreatorTest { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(randomSignerPrivateKey); // Invalid Signature error since the recovered signer address is not the same as the policyholder passed in as // parameter. - vm.expectRevert(LlamaTokenActionCreator.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); createActionBySig(v, r, s); } @@ -250,7 +250,7 @@ contract CreateActionBySig is LlamaERC20TokenActionCreatorTest { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(tokenHolder1PrivateKey); // Invalid Signature error since the recovered signer address is zero address due to invalid signature values // (v,r,s). - vm.expectRevert(LlamaTokenActionCreator.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); createActionBySig((v + 1), r, s); } @@ -258,24 +258,24 @@ contract CreateActionBySig is LlamaERC20TokenActionCreatorTest { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(tokenHolder1PrivateKey); vm.prank(tokenHolder1); - llamaERC20TokenActionCreator.incrementNonce(LlamaTokenActionCreator.createActionBySig.selector); + llamaERC20TokenGovernor.incrementNonce(LlamaTokenGovernor.createActionBySig.selector); // Invalid Signature error since the recovered signer address during the call is not the same as policyholder // since nonce has increased. - vm.expectRevert(LlamaTokenActionCreator.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); createActionBySig(v, r, s); } } -contract CancelAction is LlamaERC20TokenActionCreatorTest { +contract CancelAction is LlamaTokenGovernorActionCreation { uint256 actionId; ActionInfo actionInfo; function setUp() public virtual override { - LlamaERC20TokenActionCreatorTest.setUp(); + LlamaTokenGovernorActionCreation.setUp(); - // Assigns Permission to LlamaTokenActionCreator. - _setRolePermissionToLlamaTokenActionCreator(); + // Assigns Permission to LlamaTokenGovernor. + _setRolePermissionToLlamaTokenGovernor(); // Mint tokens to tokenholder so that they can create action. erc20VotesToken.mint(tokenHolder1, ERC20_CREATION_THRESHOLD); @@ -288,16 +288,10 @@ contract CancelAction is LlamaERC20TokenActionCreatorTest { bytes memory data = abi.encodeCall(mockProtocol.pause, (true)); vm.prank(tokenHolder1); - actionId = llamaERC20TokenActionCreator.createAction(STRATEGY, address(mockProtocol), 0, data, ""); + actionId = llamaERC20TokenGovernor.createAction(STRATEGY, address(mockProtocol), 0, data, ""); actionInfo = ActionInfo( - actionId, - address(llamaERC20TokenActionCreator), - tokenVotingActionCreatorRole, - STRATEGY, - address(mockProtocol), - 0, - data + actionId, address(llamaERC20TokenGovernor), tokenVotingGovernorRole, STRATEGY, address(mockProtocol), 0, data ); } @@ -305,26 +299,26 @@ contract CancelAction is LlamaERC20TokenActionCreatorTest { vm.expectEmit(); emit ActionCanceled(actionId, tokenHolder1); vm.prank(tokenHolder1); - llamaERC20TokenActionCreator.cancelAction(actionInfo); + llamaERC20TokenGovernor.cancelAction(actionInfo); } function test_RevertsIf_CallerIsNotActionCreator(address notCreator) public { vm.assume(notCreator != tokenHolder1); - vm.expectRevert(LlamaTokenActionCreator.OnlyActionCreator.selector); + vm.expectRevert(LlamaTokenGovernor.OnlyActionCreator.selector); vm.prank(notCreator); - llamaERC20TokenActionCreator.cancelAction(actionInfo); + llamaERC20TokenGovernor.cancelAction(actionInfo); } } -contract CancelActionBySig is LlamaERC20TokenActionCreatorTest { +contract CancelActionBySig is LlamaTokenGovernorActionCreation { uint256 actionId; ActionInfo actionInfo; function setUp() public virtual override { - LlamaERC20TokenActionCreatorTest.setUp(); + LlamaTokenGovernorActionCreation.setUp(); - // Assigns Permission to LlamaTokenActionCreator. - _setRolePermissionToLlamaTokenActionCreator(); + // Assigns Permission to LlamaTokenGovernor. + _setRolePermissionToLlamaTokenGovernor(); // Mint tokens to tokenholder so that they can create action. erc20VotesToken.mint(tokenHolder1, ERC20_CREATION_THRESHOLD); @@ -337,16 +331,10 @@ contract CancelActionBySig is LlamaERC20TokenActionCreatorTest { bytes memory data = abi.encodeCall(mockProtocol.pause, (true)); vm.prank(tokenHolder1); - actionId = llamaERC20TokenActionCreator.createAction(STRATEGY, address(mockProtocol), 0, data, ""); + actionId = llamaERC20TokenGovernor.createAction(STRATEGY, address(mockProtocol), 0, data, ""); actionInfo = ActionInfo( - actionId, - address(llamaERC20TokenActionCreator), - tokenVotingActionCreatorRole, - STRATEGY, - address(mockProtocol), - 0, - data + actionId, address(llamaERC20TokenGovernor), tokenVotingGovernorRole, STRATEGY, address(mockProtocol), 0, data ); } @@ -358,14 +346,14 @@ contract CancelActionBySig is LlamaERC20TokenActionCreatorTest { LlamaCoreSigUtils.CancelAction memory cancelAction = LlamaCoreSigUtils.CancelAction({ tokenHolder: tokenHolder1, actionInfo: _actionInfo, - nonce: llamaERC20TokenActionCreator.nonces(tokenHolder1, LlamaTokenActionCreator.cancelActionBySig.selector) + nonce: llamaERC20TokenGovernor.nonces(tokenHolder1, LlamaTokenGovernor.cancelActionBySig.selector) }); bytes32 digest = getCancelActionTypedDataHash(cancelAction); (v, r, s) = vm.sign(privateKey, digest); } function cancelActionBySig(ActionInfo memory _actionInfo, uint8 v, bytes32 r, bytes32 s) internal { - llamaERC20TokenActionCreator.cancelActionBySig(tokenHolder1, _actionInfo, v, r, s); + llamaERC20TokenGovernor.cancelActionBySig(tokenHolder1, _actionInfo, v, r, s); } function test_CancelActionBySig() public { @@ -383,9 +371,9 @@ contract CancelActionBySig is LlamaERC20TokenActionCreatorTest { function test_CheckNonceIncrements() public { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(actionInfo, tokenHolder1PrivateKey); - assertEq(llamaERC20TokenActionCreator.nonces(tokenHolder1, LlamaTokenActionCreator.cancelActionBySig.selector), 0); + assertEq(llamaERC20TokenGovernor.nonces(tokenHolder1, LlamaTokenGovernor.cancelActionBySig.selector), 0); cancelActionBySig(actionInfo, v, r, s); - assertEq(llamaERC20TokenActionCreator.nonces(tokenHolder1, LlamaTokenActionCreator.cancelActionBySig.selector), 1); + assertEq(llamaERC20TokenGovernor.nonces(tokenHolder1, LlamaTokenGovernor.cancelActionBySig.selector), 1); } function test_OperationCannotBeReplayed() public { @@ -393,7 +381,7 @@ contract CancelActionBySig is LlamaERC20TokenActionCreatorTest { cancelActionBySig(actionInfo, v, r, s); // Invalid Signature error since the recovered signer address during the second call is not the same as policyholder // since nonce has increased. - vm.expectRevert(LlamaTokenActionCreator.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); cancelActionBySig(actionInfo, v, r, s); } @@ -402,7 +390,7 @@ contract CancelActionBySig is LlamaERC20TokenActionCreatorTest { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(actionInfo, randomSignerPrivateKey); // Invalid Signature error since the recovered signer address is not the same as the policyholder passed in as // parameter. - vm.expectRevert(LlamaTokenActionCreator.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); cancelActionBySig(actionInfo, v, r, s); } @@ -410,7 +398,7 @@ contract CancelActionBySig is LlamaERC20TokenActionCreatorTest { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(actionInfo, tokenHolder1PrivateKey); // Invalid Signature error since the recovered signer address is zero address due to invalid signature values // (v,r,s). - vm.expectRevert(LlamaTokenActionCreator.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); cancelActionBySig(actionInfo, (v + 1), r, s); } @@ -418,42 +406,42 @@ contract CancelActionBySig is LlamaERC20TokenActionCreatorTest { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(actionInfo, tokenHolder1PrivateKey); vm.prank(tokenHolder1); - llamaERC20TokenActionCreator.incrementNonce(LlamaTokenActionCreator.cancelActionBySig.selector); + llamaERC20TokenGovernor.incrementNonce(LlamaTokenGovernor.cancelActionBySig.selector); // Invalid Signature error since the recovered signer address during the call is not the same as policyholder // since nonce has increased. - vm.expectRevert(LlamaTokenActionCreator.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); cancelActionBySig(actionInfo, v, r, s); } } -contract SetActionThreshold is LlamaERC20TokenActionCreatorTest { +contract SetActionThreshold is LlamaTokenGovernorActionCreation { function testFuzz_SetsCreationThreshold(uint256 threshold) public { threshold = bound(threshold, 0, erc20VotesToken.getPastTotalSupply(block.timestamp - 1)); - assertEq(llamaERC20TokenActionCreator.creationThreshold(), ERC20_CREATION_THRESHOLD); + assertEq(llamaERC20TokenGovernor.creationThreshold(), ERC20_CREATION_THRESHOLD); vm.expectEmit(); emit ActionThresholdSet(threshold); vm.prank(address(EXECUTOR)); - llamaERC20TokenActionCreator.setActionThreshold(threshold); + llamaERC20TokenGovernor.setActionThreshold(threshold); - assertEq(llamaERC20TokenActionCreator.creationThreshold(), threshold); + assertEq(llamaERC20TokenGovernor.creationThreshold(), threshold); } function testFuzz_RevertsIf_CreationThresholdExceedsTotalSupply(uint256 threshold) public { vm.assume(threshold > erc20VotesToken.getPastTotalSupply(block.timestamp - 1)); - vm.expectRevert(LlamaTokenActionCreator.InvalidCreationThreshold.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidCreationThreshold.selector); vm.prank(address(EXECUTOR)); - llamaERC20TokenActionCreator.setActionThreshold(threshold); + llamaERC20TokenGovernor.setActionThreshold(threshold); } function testFuzz_RevertsIf_CalledByNotLlamaExecutor(address notLlamaExecutor) public { vm.assume(notLlamaExecutor != address(EXECUTOR)); - vm.expectRevert(LlamaTokenActionCreator.OnlyLlamaExecutor.selector); + vm.expectRevert(LlamaTokenGovernor.OnlyLlamaExecutor.selector); vm.prank(notLlamaExecutor); - llamaERC20TokenActionCreator.setActionThreshold(ERC20_CREATION_THRESHOLD); + llamaERC20TokenGovernor.setActionThreshold(ERC20_CREATION_THRESHOLD); } } diff --git a/test/token-voting/LlamaERC20TokenCaster.t.sol b/test/token-voting/llama-token-governor/erc-20/LlamaTokenGovernorCasting.t.sol similarity index 71% rename from test/token-voting/LlamaERC20TokenCaster.t.sol rename to test/token-voting/llama-token-governor/erc-20/LlamaTokenGovernorCasting.t.sol index 47adbc2..b7ddbdc 100644 --- a/test/token-voting/LlamaERC20TokenCaster.t.sol +++ b/test/token-voting/llama-token-governor/erc-20/LlamaTokenGovernorCasting.t.sol @@ -15,9 +15,9 @@ import {ILlamaRelativeStrategyBase} from "src/interfaces/ILlamaRelativeStrategyB import {ILlamaStrategy} from "src/interfaces/ILlamaStrategy.sol"; import {LlamaTokenAdapterVotesTimestamp} from "src/token-voting/token-adapters/LlamaTokenAdapterVotesTimestamp.sol"; import {ILlamaTokenAdapter} from "src/token-voting/interfaces/ILlamaTokenAdapter.sol"; -import {LlamaTokenCaster} from "src/token-voting/LlamaTokenCaster.sol"; +import {LlamaTokenGovernor} from "src/token-voting/LlamaTokenGovernor.sol"; -contract LlamaERC20TokenCasterTest is LlamaTokenVotingTestSetup, LlamaCoreSigUtils { +contract LlamaTokenGovernorCasting is LlamaTokenVotingTestSetup, LlamaCoreSigUtils { event VoteCast(uint256 id, address indexed tokenholder, uint8 indexed support, uint256 weight, string reason); event ApprovalSubmitted( uint256 id, address indexed caller, uint256 weightFor, uint256 weightAgainst, uint256 weightAbstain @@ -31,7 +31,7 @@ contract LlamaERC20TokenCasterTest is LlamaTokenVotingTestSetup, LlamaCoreSigUti ActionInfo actionInfo; uint256 actionCreationTime; - LlamaTokenCaster llamaERC20TokenCaster; + LlamaTokenGovernor llamaERC20TokenGovernor; ILlamaStrategy tokenVotingStrategy; function setUp() public virtual override { @@ -55,43 +55,43 @@ contract LlamaERC20TokenCasterTest is LlamaTokenVotingTestSetup, LlamaCoreSigUti mineBlock(); // Deploy ERC20 Token Voting Module. - (, llamaERC20TokenCaster) = _deployERC20TokenVotingModuleAndSetRole(); + llamaERC20TokenGovernor = _deployERC20TokenVotingModuleAndSetRole(); // Mine block so that Token Voting Caster Role will have supply during action creation (due to past timestamp check) mineBlock(); - tokenVotingStrategy = _deployRelativeQuantityQuorumAndSetRolePermissionToCoreTeam(tokenVotingCasterRole); + tokenVotingStrategy = _deployRelativeQuantityQuorumAndSetRolePermissionToCoreTeam(tokenVotingGovernorRole); actionInfo = _createActionWithTokenVotingStrategy(tokenVotingStrategy); Action memory action = CORE.getAction(actionInfo.id); actionCreationTime = action.creationTime; - // Setting LlamaTokenCaster's EIP-712 Domain Hash + // Setting LlamaTokenGovernor's EIP-712 Domain Hash setDomainHash( LlamaCoreSigUtils.EIP712Domain({ name: CORE.name(), version: "1", chainId: block.chainid, - verifyingContract: address(llamaERC20TokenCaster) + verifyingContract: address(llamaERC20TokenGovernor) }) ); } function castVotesFor() public { vm.prank(tokenHolder1); - llamaERC20TokenCaster.castVote(actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVote(actionInfo, uint8(VoteType.For), ""); vm.prank(tokenHolder2); - llamaERC20TokenCaster.castVote(actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVote(actionInfo, uint8(VoteType.For), ""); vm.prank(tokenHolder3); - llamaERC20TokenCaster.castVote(actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVote(actionInfo, uint8(VoteType.For), ""); } function castVetosFor() public { vm.prank(tokenHolder1); - llamaERC20TokenCaster.castVeto(actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVeto(actionInfo, uint8(VoteType.For), ""); vm.prank(tokenHolder2); - llamaERC20TokenCaster.castVeto(actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVeto(actionInfo, uint8(VoteType.For), ""); vm.prank(tokenHolder3); - llamaERC20TokenCaster.castVeto(actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVeto(actionInfo, uint8(VoteType.For), ""); } function createTimestampTokenAdapter(address token, uint256 nonce) public returns (ILlamaTokenAdapter tokenAdapter) { @@ -104,48 +104,48 @@ contract LlamaERC20TokenCasterTest is LlamaTokenVotingTestSetup, LlamaCoreSigUti } } -contract CastVote is LlamaERC20TokenCasterTest { +contract CastVote is LlamaTokenGovernorCasting { function setUp() public virtual override { - LlamaERC20TokenCasterTest.setUp(); + LlamaTokenGovernorCasting.setUp(); _skipVotingDelay(actionInfo); } function test_RevertsIf_NotPastVotingDelay() public { vm.warp(block.timestamp - 1); - vm.expectRevert(LlamaTokenCaster.DelayPeriodNotOver.selector); - llamaERC20TokenCaster.castVote(actionInfo, uint8(VoteType.For), ""); + vm.expectRevert(LlamaTokenGovernor.DelayPeriodNotOver.selector); + llamaERC20TokenGovernor.castVote(actionInfo, uint8(VoteType.For), ""); } function test_RevertsIf_ActionInfoMismatch(ActionInfo memory notActionInfo) public { vm.assume(notActionInfo.id != actionInfo.id); vm.expectRevert(); - llamaERC20TokenCaster.castVote(notActionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVote(notActionInfo, uint8(VoteType.For), ""); } function test_RevertsIf_ApprovalNotEnabled() public { - LlamaTokenCaster casterWithWrongRole = LlamaTokenCaster( + LlamaTokenGovernor casterWithWrongRole = LlamaTokenGovernor( Clones.cloneDeterministic( - address(llamaTokenCasterLogic), keccak256(abi.encodePacked(address(erc20VotesToken), msg.sender)) + address(llamaTokenGovernorLogic), keccak256(abi.encodePacked(address(erc20VotesToken), msg.sender)) ) ); ILlamaTokenAdapter tokenAdapter = createTimestampTokenAdapter(address(erc20VotesToken), 0); - casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, defaultCasterConfig); + casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, 0, defaultCasterConfig); - vm.expectRevert(abi.encodeWithSelector(ILlamaRelativeStrategyBase.InvalidRole.selector, tokenVotingCasterRole)); + vm.expectRevert(abi.encodeWithSelector(ILlamaRelativeStrategyBase.InvalidRole.selector, tokenVotingGovernorRole)); casterWithWrongRole.castVote(actionInfo, uint8(VoteType.For), ""); } function test_RevertsIf_ActionNotActive() public { vm.warp(actionCreationTime + APPROVAL_PERIOD + 1); - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.InvalidActionState.selector, ActionState.Failed)); - llamaERC20TokenCaster.castVote(actionInfo, uint8(VoteType.For), ""); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.InvalidActionState.selector, ActionState.Failed)); + llamaERC20TokenGovernor.castVote(actionInfo, uint8(VoteType.For), ""); } function test_RevertsIf_RoleHasBeenRevokedBeforeActionCreation() public { // Revoking Caster role from Token Holder Caster and assigning it to a random address so that Role has supply. vm.startPrank(address(EXECUTOR)); - POLICY.setRoleHolder(tokenVotingCasterRole, address(llamaERC20TokenCaster), 0, 0); - POLICY.setRoleHolder(tokenVotingCasterRole, address(0xdeadbeef), DEFAULT_ROLE_QTY, DEFAULT_ROLE_EXPIRATION); + POLICY.setRoleHolder(tokenVotingGovernorRole, address(llamaERC20TokenGovernor), 0, 0); + POLICY.setRoleHolder(tokenVotingGovernorRole, address(0xdeadbeef), DEFAULT_ROLE_QTY, DEFAULT_ROLE_EXPIRATION); vm.stopPrank(); // Mine block so that the revoke will be effective @@ -158,35 +158,35 @@ contract CastVote is LlamaERC20TokenCasterTest { vm.warp(action.creationTime + ((APPROVAL_PERIOD * ONE_QUARTER_IN_BPS) / ONE_HUNDRED_IN_BPS) + 1); vm.startPrank(tokenHolder1); - vm.expectRevert(LlamaTokenCaster.InvalidPolicyholder.selector); - llamaERC20TokenCaster.castVote(_actionInfo, uint8(VoteType.For), ""); + vm.expectRevert(LlamaTokenGovernor.InvalidPolicyholder.selector); + llamaERC20TokenGovernor.castVote(_actionInfo, uint8(VoteType.For), ""); } function test_RevertsIf_AlreadyCastedVote() public { vm.startPrank(tokenHolder1); - llamaERC20TokenCaster.castVote(actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVote(actionInfo, uint8(VoteType.For), ""); - vm.expectRevert(LlamaTokenCaster.DuplicateCast.selector); - llamaERC20TokenCaster.castVote(actionInfo, uint8(VoteType.For), ""); + vm.expectRevert(LlamaTokenGovernor.DuplicateCast.selector); + llamaERC20TokenGovernor.castVote(actionInfo, uint8(VoteType.For), ""); } function test_RevertsIf_InvalidSupport() public { - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.InvalidSupport.selector, uint8(3))); - llamaERC20TokenCaster.castVote(actionInfo, 3, ""); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.InvalidSupport.selector, uint8(3))); + llamaERC20TokenGovernor.castVote(actionInfo, 3, ""); } function test_RevertsIf_CastingPeriodOver() public { uint256 delayPeriodEndTime = actionCreationTime + ((APPROVAL_PERIOD * ONE_QUARTER_IN_BPS) / ONE_HUNDRED_IN_BPS); uint256 castingPeriodEndTime = delayPeriodEndTime + ((APPROVAL_PERIOD * TWO_QUARTERS_IN_BPS) / ONE_HUNDRED_IN_BPS); vm.warp(castingPeriodEndTime + 1); - vm.expectRevert(LlamaTokenCaster.CastingPeriodOver.selector); - llamaERC20TokenCaster.castVote(actionInfo, uint8(VoteType.For), ""); + vm.expectRevert(LlamaTokenGovernor.CastingPeriodOver.selector); + llamaERC20TokenGovernor.castVote(actionInfo, uint8(VoteType.For), ""); } function test_CanCastWithWeightZero() public { vm.expectEmit(); emit VoteCast(actionInfo.id, address(this), uint8(VoteType.For), 0, ""); - llamaERC20TokenCaster.castVote(actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVote(actionInfo, uint8(VoteType.For), ""); } function test_CanCastWhenCountisMax() public { @@ -201,18 +201,18 @@ contract CastVote is LlamaERC20TokenCasterTest { mineBlock(); // Casting vote with weight type(uint128).max. Count should now be type(uint128).max. vm.prank(address(0xdeadbeef)); - llamaERC20TokenCaster.castVote(actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVote(actionInfo, uint8(VoteType.For), ""); - (uint128 votesFor,,,,,) = llamaERC20TokenCaster.casts(actionInfo.id); + (uint128 votesFor,,,,,) = llamaERC20TokenGovernor.casts(actionInfo.id); assertEq(votesFor, type(uint128).max); // Can still cast even if count is max. vm.expectEmit(); emit VoteCast(actionInfo.id, tokenHolder1, uint8(VoteType.For), ERC20_CREATION_THRESHOLD / 2, ""); vm.prank(tokenHolder1); - llamaERC20TokenCaster.castVote(actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVote(actionInfo, uint8(VoteType.For), ""); - (votesFor,,,,,) = llamaERC20TokenCaster.casts(actionInfo.id); + (votesFor,,,,,) = llamaERC20TokenGovernor.casts(actionInfo.id); assertEq(votesFor, type(uint128).max); } @@ -223,7 +223,7 @@ contract CastVote is LlamaERC20TokenCasterTest { actionInfo.id, tokenHolder1, support, erc20VotesToken.getPastVotes(tokenHolder1, block.timestamp - 1), "" ); vm.prank(tokenHolder1); - uint128 weight = llamaERC20TokenCaster.castVote(actionInfo, support, ""); + uint128 weight = llamaERC20TokenGovernor.castVote(actionInfo, support, ""); assertEq(weight, erc20VotesToken.getPastVotes(tokenHolder1, block.timestamp - 1)); } @@ -237,7 +237,7 @@ contract CastVote is LlamaERC20TokenCasterTest { "reason" ); vm.prank(tokenHolder1); - llamaERC20TokenCaster.castVote(actionInfo, uint8(VoteType.For), "reason"); + llamaERC20TokenGovernor.castVote(actionInfo, uint8(VoteType.For), "reason"); } function test_GetsWeightAtDelayPeriodTimestamp() public { @@ -250,15 +250,15 @@ contract CastVote is LlamaERC20TokenCasterTest { // However tokenholder1 is able to vote with the weight they had at delayPeriodEndTime vm.expectEmit(); emit VoteCast(actionInfo.id, tokenHolder1, 1, ERC20_CREATION_THRESHOLD / 2, ""); - uint128 weight = llamaERC20TokenCaster.castVote(actionInfo, 1, ""); + uint128 weight = llamaERC20TokenGovernor.castVote(actionInfo, 1, ""); assertEq(weight, ERC20_CREATION_THRESHOLD / 2); vm.stopPrank(); } } -contract CastVoteBySig is LlamaERC20TokenCasterTest { +contract CastVoteBySig is LlamaTokenGovernorCasting { function setUp() public virtual override { - LlamaERC20TokenCasterTest.setUp(); + LlamaTokenGovernorCasting.setUp(); _skipVotingDelay(actionInfo); } @@ -279,7 +279,7 @@ contract CastVoteBySig is LlamaERC20TokenCasterTest { } function castVoteBySig(ActionInfo memory _actionInfo, uint8 support, uint8 v, bytes32 r, bytes32 s) internal { - llamaERC20TokenCaster.castVoteBySig(tokenHolder1, _actionInfo, support, "", v, r, s); + llamaERC20TokenGovernor.castVoteBySig(tokenHolder1, _actionInfo, support, "", v, r, s); } function test_CastsVoteBySig() public { @@ -300,9 +300,9 @@ contract CastVoteBySig is LlamaERC20TokenCasterTest { function test_CheckNonceIncrements() public { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(actionInfo, tokenHolder1PrivateKey); - assertEq(llamaERC20TokenCaster.nonces(tokenHolder1, LlamaTokenCaster.castVoteBySig.selector), 0); + assertEq(llamaERC20TokenGovernor.nonces(tokenHolder1, LlamaTokenGovernor.castVoteBySig.selector), 0); castVoteBySig(actionInfo, uint8(VoteType.For), v, r, s); - assertEq(llamaERC20TokenCaster.nonces(tokenHolder1, LlamaTokenCaster.castVoteBySig.selector), 1); + assertEq(llamaERC20TokenGovernor.nonces(tokenHolder1, LlamaTokenGovernor.castVoteBySig.selector), 1); } function test_OperationCannotBeReplayed() public { @@ -310,7 +310,7 @@ contract CastVoteBySig is LlamaERC20TokenCasterTest { castVoteBySig(actionInfo, uint8(VoteType.For), v, r, s); // Invalid Signature error since the recovered signer address during the second call is not the same as // erc20VotesTokenholder since nonce has increased. - vm.expectRevert(LlamaTokenCaster.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); castVoteBySig(actionInfo, uint8(VoteType.For), v, r, s); } @@ -319,7 +319,7 @@ contract CastVoteBySig is LlamaERC20TokenCasterTest { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(actionInfo, randomSignerPrivateKey); // Invalid Signature error since the recovered signer address is not the same as the erc20VotesTokenholder passed // in as parameter. - vm.expectRevert(LlamaTokenCaster.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); castVoteBySig(actionInfo, uint8(VoteType.For), v, r, s); } @@ -327,7 +327,7 @@ contract CastVoteBySig is LlamaERC20TokenCasterTest { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(actionInfo, tokenHolder1PrivateKey); // Invalid Signature error since the recovered signer address is zero address due to invalid signature values // (v,r,s). - vm.expectRevert(LlamaTokenCaster.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); castVoteBySig(actionInfo, uint8(VoteType.For), (v + 1), r, s); } @@ -335,18 +335,18 @@ contract CastVoteBySig is LlamaERC20TokenCasterTest { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(actionInfo, tokenHolder1PrivateKey); vm.prank(tokenHolder1); - llamaERC20TokenCaster.incrementNonce(LlamaTokenCaster.castVoteBySig.selector); + llamaERC20TokenGovernor.incrementNonce(LlamaTokenGovernor.castVoteBySig.selector); // Invalid Signature error since the recovered signer address during the call is not the same as // erc20VotesTokenholder since nonce has increased. - vm.expectRevert(LlamaTokenCaster.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); castVoteBySig(actionInfo, uint8(VoteType.For), v, r, s); } } -contract CastVeto is LlamaERC20TokenCasterTest { +contract CastVeto is LlamaTokenGovernorCasting { function setUp() public virtual override { - LlamaERC20TokenCasterTest.setUp(); + LlamaTokenGovernorCasting.setUp(); _skipVotingDelay(actionInfo); castVotesFor(); @@ -355,32 +355,32 @@ contract CastVeto is LlamaERC20TokenCasterTest { uint256 castingPeriodEndTime = delayPeriodEndTime + ((APPROVAL_PERIOD * TWO_QUARTERS_IN_BPS) / ONE_HUNDRED_IN_BPS); vm.warp(castingPeriodEndTime + 1); - llamaERC20TokenCaster.submitApproval(actionInfo); + llamaERC20TokenGovernor.submitApproval(actionInfo); _skipVetoDelay(actionInfo); } function test_RevertsIf_NotPastVotingDelay() public { vm.warp(block.timestamp - 1); - vm.expectRevert(LlamaTokenCaster.DelayPeriodNotOver.selector); - llamaERC20TokenCaster.castVeto(actionInfo, uint8(VoteType.For), ""); + vm.expectRevert(LlamaTokenGovernor.DelayPeriodNotOver.selector); + llamaERC20TokenGovernor.castVeto(actionInfo, uint8(VoteType.For), ""); } function test_RevertsIf_ActionInfoMismatch(ActionInfo memory notActionInfo) public { vm.assume(notActionInfo.id != actionInfo.id); vm.expectRevert(); - llamaERC20TokenCaster.castVeto(notActionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVeto(notActionInfo, uint8(VoteType.For), ""); } function test_RevertsIf_DisapprovalNotEnabled() public { - LlamaTokenCaster casterWithWrongRole = LlamaTokenCaster( + LlamaTokenGovernor casterWithWrongRole = LlamaTokenGovernor( Clones.cloneDeterministic( - address(llamaTokenCasterLogic), keccak256(abi.encodePacked(address(erc20VotesToken), msg.sender)) + address(llamaTokenGovernorLogic), keccak256(abi.encodePacked(address(erc20VotesToken), msg.sender)) ) ); ILlamaTokenAdapter tokenAdapter = createTimestampTokenAdapter(address(erc20VotesToken), 0); - casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, defaultCasterConfig); + casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, 0, defaultCasterConfig); - vm.expectRevert(abi.encodeWithSelector(ILlamaRelativeStrategyBase.InvalidRole.selector, tokenVotingCasterRole)); + vm.expectRevert(abi.encodeWithSelector(ILlamaRelativeStrategyBase.InvalidRole.selector, tokenVotingGovernorRole)); casterWithWrongRole.castVeto(actionInfo, uint8(VoteType.For), ""); } @@ -391,21 +391,21 @@ contract CastVeto is LlamaERC20TokenCasterTest { ActionInfo memory _actionInfo = ActionInfo(actionId, coreTeam1, CORE_TEAM_ROLE, tokenVotingStrategy, address(mockProtocol), 0, data); // Currently at actionCreationTime which is Active state. - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.InvalidActionState.selector, ActionState.Active)); - llamaERC20TokenCaster.castVeto(_actionInfo, uint8(VoteType.For), ""); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.InvalidActionState.selector, ActionState.Active)); + llamaERC20TokenGovernor.castVeto(_actionInfo, uint8(VoteType.For), ""); } function test_RevertsIf_AlreadyCastedVote() public { vm.startPrank(tokenHolder1); - llamaERC20TokenCaster.castVeto(actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVeto(actionInfo, uint8(VoteType.For), ""); - vm.expectRevert(LlamaTokenCaster.DuplicateCast.selector); - llamaERC20TokenCaster.castVeto(actionInfo, uint8(VoteType.For), ""); + vm.expectRevert(LlamaTokenGovernor.DuplicateCast.selector); + llamaERC20TokenGovernor.castVeto(actionInfo, uint8(VoteType.For), ""); } function test_RevertsIf_InvalidSupport() public { - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.InvalidSupport.selector, uint8(3))); - llamaERC20TokenCaster.castVeto(actionInfo, 3, ""); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.InvalidSupport.selector, uint8(3))); + llamaERC20TokenGovernor.castVeto(actionInfo, 3, ""); } function test_RevertsIf_CastingPeriodOver() public { @@ -414,14 +414,14 @@ contract CastVeto is LlamaERC20TokenCasterTest { (action.minExecutionTime - QUEUING_PERIOD) + ((QUEUING_PERIOD * ONE_QUARTER_IN_BPS) / ONE_HUNDRED_IN_BPS); uint256 castingPeriodEndTime = delayPeriodEndTime + ((QUEUING_PERIOD * TWO_QUARTERS_IN_BPS) / ONE_HUNDRED_IN_BPS); vm.warp(castingPeriodEndTime + 1); - vm.expectRevert(LlamaTokenCaster.CastingPeriodOver.selector); - llamaERC20TokenCaster.castVeto(actionInfo, uint8(VoteType.For), ""); + vm.expectRevert(LlamaTokenGovernor.CastingPeriodOver.selector); + llamaERC20TokenGovernor.castVeto(actionInfo, uint8(VoteType.For), ""); } function test_CanCastWithWeightZero() public { vm.expectEmit(); emit VetoCast(actionInfo.id, address(this), uint8(VoteType.For), 0, ""); - llamaERC20TokenCaster.castVeto(actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVeto(actionInfo, uint8(VoteType.For), ""); } function test_CanCastWhenCountisMax() public { @@ -437,18 +437,18 @@ contract CastVeto is LlamaERC20TokenCasterTest { mineBlock(); // Casting vote with weight type(uint128).max. Count should now be type(uint128).max. vm.prank(address(0xdeadbeef)); - llamaERC20TokenCaster.castVeto(actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVeto(actionInfo, uint8(VoteType.For), ""); - (,,, uint128 vetoesFor,,) = llamaERC20TokenCaster.casts(actionInfo.id); + (,,, uint128 vetoesFor,,) = llamaERC20TokenGovernor.casts(actionInfo.id); assertEq(vetoesFor, type(uint128).max); // Can still cast even if count is max. vm.expectEmit(); emit VetoCast(actionInfo.id, tokenHolder1, uint8(VoteType.For), ERC20_CREATION_THRESHOLD / 2, ""); vm.prank(tokenHolder1); - llamaERC20TokenCaster.castVeto(actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVeto(actionInfo, uint8(VoteType.For), ""); - (,,, vetoesFor,,) = llamaERC20TokenCaster.casts(actionInfo.id); + (,,, vetoesFor,,) = llamaERC20TokenGovernor.casts(actionInfo.id); assertEq(vetoesFor, type(uint128).max); } @@ -459,7 +459,7 @@ contract CastVeto is LlamaERC20TokenCasterTest { actionInfo.id, tokenHolder1, support, erc20VotesToken.getPastVotes(tokenHolder1, block.timestamp - 1), "" ); vm.prank(tokenHolder1); - uint128 weight = llamaERC20TokenCaster.castVeto(actionInfo, support, ""); + uint128 weight = llamaERC20TokenGovernor.castVeto(actionInfo, support, ""); assertEq(weight, erc20VotesToken.getPastVotes(tokenHolder1, block.timestamp - 1)); } @@ -473,7 +473,7 @@ contract CastVeto is LlamaERC20TokenCasterTest { "reason" ); vm.prank(tokenHolder1); - llamaERC20TokenCaster.castVeto(actionInfo, uint8(VoteType.For), "reason"); + llamaERC20TokenGovernor.castVeto(actionInfo, uint8(VoteType.For), "reason"); } function test_GetsWeightAtDelayPeriodTimestamp() public { @@ -486,15 +486,15 @@ contract CastVeto is LlamaERC20TokenCasterTest { // However tokenholder1 is able to vote with the weight they had at delayPeriodEndTime vm.expectEmit(); emit VetoCast(actionInfo.id, tokenHolder1, 1, ERC20_CREATION_THRESHOLD / 2, ""); - uint128 weight = llamaERC20TokenCaster.castVeto(actionInfo, 1, ""); + uint128 weight = llamaERC20TokenGovernor.castVeto(actionInfo, 1, ""); assertEq(weight, ERC20_CREATION_THRESHOLD / 2); vm.stopPrank(); } } -contract CastVetoBySig is LlamaERC20TokenCasterTest { +contract CastVetoBySig is LlamaTokenGovernorCasting { function setUp() public virtual override { - LlamaERC20TokenCasterTest.setUp(); + LlamaTokenGovernorCasting.setUp(); _skipVotingDelay(actionInfo); castVotesFor(); @@ -503,7 +503,7 @@ contract CastVetoBySig is LlamaERC20TokenCasterTest { uint256 castingPeriodEndTime = delayPeriodEndTime + ((APPROVAL_PERIOD * TWO_QUARTERS_IN_BPS) / ONE_HUNDRED_IN_BPS); vm.warp(castingPeriodEndTime + 1); - llamaERC20TokenCaster.submitApproval(actionInfo); + llamaERC20TokenGovernor.submitApproval(actionInfo); _skipVetoDelay(actionInfo); } @@ -524,7 +524,7 @@ contract CastVetoBySig is LlamaERC20TokenCasterTest { } function castVetoBySig(ActionInfo memory _actionInfo, uint8 v, bytes32 r, bytes32 s) internal { - llamaERC20TokenCaster.castVetoBySig(tokenHolder1, _actionInfo, uint8(VoteType.For), "", v, r, s); + llamaERC20TokenGovernor.castVetoBySig(tokenHolder1, _actionInfo, uint8(VoteType.For), "", v, r, s); } function test_CastsVetoBySig() public { @@ -548,9 +548,9 @@ contract CastVetoBySig is LlamaERC20TokenCasterTest { function test_CheckNonceIncrements() public { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(actionInfo, tokenHolder1PrivateKey); - assertEq(llamaERC20TokenCaster.nonces(tokenHolder1, LlamaTokenCaster.castVetoBySig.selector), 0); + assertEq(llamaERC20TokenGovernor.nonces(tokenHolder1, LlamaTokenGovernor.castVetoBySig.selector), 0); castVetoBySig(actionInfo, v, r, s); - assertEq(llamaERC20TokenCaster.nonces(tokenHolder1, LlamaTokenCaster.castVetoBySig.selector), 1); + assertEq(llamaERC20TokenGovernor.nonces(tokenHolder1, LlamaTokenGovernor.castVetoBySig.selector), 1); } function test_OperationCannotBeReplayed() public { @@ -559,7 +559,7 @@ contract CastVetoBySig is LlamaERC20TokenCasterTest { // Invalid Signature error since the recovered signer address during the second call is not the same as // erc20VotesTokenholder // since nonce has increased. - vm.expectRevert(LlamaTokenCaster.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); castVetoBySig(actionInfo, v, r, s); } @@ -569,7 +569,7 @@ contract CastVetoBySig is LlamaERC20TokenCasterTest { // Invalid Signature error since the recovered signer address during the second call is not the same as // erc20VotesTokenholder // since nonce has increased. - vm.expectRevert(LlamaTokenCaster.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); castVetoBySig(actionInfo, v, r, s); } @@ -577,7 +577,7 @@ contract CastVetoBySig is LlamaERC20TokenCasterTest { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(actionInfo, tokenHolder1PrivateKey); // Invalid Signature error since the recovered signer address is zero address due to invalid signature values // (v,r,s). - vm.expectRevert(LlamaTokenCaster.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); castVetoBySig(actionInfo, (v + 1), r, s); } @@ -585,11 +585,11 @@ contract CastVetoBySig is LlamaERC20TokenCasterTest { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(actionInfo, tokenHolder1PrivateKey); vm.prank(tokenHolder1); - llamaERC20TokenCaster.incrementNonce(LlamaTokenCaster.castVetoBySig.selector); + llamaERC20TokenGovernor.incrementNonce(LlamaTokenGovernor.castVetoBySig.selector); // Invalid Signature error since the recovered signer address during the second call is not the same as policyholder // since nonce has increased. - vm.expectRevert(LlamaTokenCaster.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); castVetoBySig(actionInfo, v, r, s); } @@ -610,7 +610,7 @@ contract CastVetoBySig is LlamaERC20TokenCasterTest { // Second disapproval. vm.prank(tokenHolder2); - llamaERC20TokenCaster.castVeto(actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVeto(actionInfo, uint8(VoteType.For), ""); Action memory action = CORE.getAction(actionInfo.id); uint256 delayPeriodEndTime = @@ -618,7 +618,7 @@ contract CastVetoBySig is LlamaERC20TokenCasterTest { uint256 castingPeriodEndTime = delayPeriodEndTime + ((QUEUING_PERIOD * TWO_QUARTERS_IN_BPS) / ONE_HUNDRED_IN_BPS); vm.warp(castingPeriodEndTime + 1); - llamaERC20TokenCaster.submitDisapproval(actionInfo); + llamaERC20TokenGovernor.submitDisapproval(actionInfo); // Assertions. ActionState state = ActionState(CORE.getActionState(actionInfo)); @@ -629,9 +629,9 @@ contract CastVetoBySig is LlamaERC20TokenCasterTest { } } -contract SubmitApprovals is LlamaERC20TokenCasterTest { +contract SubmitApprovals is LlamaTokenGovernorCasting { function setUp() public virtual override { - LlamaERC20TokenCasterTest.setUp(); + LlamaTokenGovernorCasting.setUp(); _skipVotingDelay(actionInfo); castVotesFor(); @@ -644,23 +644,23 @@ contract SubmitApprovals is LlamaERC20TokenCasterTest { function test_RevertsIf_ActionInfoMismatch(ActionInfo memory notActionInfo) public { vm.assume(notActionInfo.id != actionInfo.id); vm.expectRevert(); - llamaERC20TokenCaster.submitApproval(notActionInfo); + llamaERC20TokenGovernor.submitApproval(notActionInfo); } function test_RevertsIf_AlreadySubmittedApproval() public { vm.startPrank(tokenHolder1); - llamaERC20TokenCaster.submitApproval(actionInfo); + llamaERC20TokenGovernor.submitApproval(actionInfo); // This should revert since the underlying Action has transitioned to Queued state. Otherwise it would have reverted // due to `LlamaCore.DuplicateCast() error`. vm.expectRevert(abi.encodeWithSelector(ILlamaCore.InvalidActionState.selector, ActionState.Queued)); - llamaERC20TokenCaster.submitApproval(actionInfo); + llamaERC20TokenGovernor.submitApproval(actionInfo); } function test_RevertsIf_SubmissionPeriodOver() public { vm.warp(actionCreationTime + APPROVAL_PERIOD + 1); - vm.expectRevert(LlamaTokenCaster.SubmissionPeriodOver.selector); - llamaERC20TokenCaster.submitApproval(actionInfo); + vm.expectRevert(LlamaTokenGovernor.SubmissionPeriodOver.selector); + llamaERC20TokenGovernor.submitApproval(actionInfo); } function test_RevertsIf_InsufficientVotes() public { @@ -669,14 +669,14 @@ contract SubmitApprovals is LlamaERC20TokenCasterTest { uint256 delayPeriodEndTime = action.creationTime + ((APPROVAL_PERIOD * ONE_QUARTER_IN_BPS) / ONE_HUNDRED_IN_BPS); uint256 castingPeriodEndTime = delayPeriodEndTime + ((APPROVAL_PERIOD * TWO_QUARTERS_IN_BPS) / ONE_HUNDRED_IN_BPS); vm.warp(castingPeriodEndTime + 1); - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.InsufficientVotes.selector, 0, 75_000e18)); - llamaERC20TokenCaster.submitApproval(_actionInfo); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.InsufficientVotes.selector, 0, 75_000e18)); + llamaERC20TokenGovernor.submitApproval(_actionInfo); } function test_RevertsIf_CastingPeriodNotOver() public { vm.warp(block.timestamp - 1); - vm.expectRevert(LlamaTokenCaster.CastingPeriodNotOver.selector); - llamaERC20TokenCaster.submitApproval(actionInfo); + vm.expectRevert(LlamaTokenGovernor.CastingPeriodNotOver.selector); + llamaERC20TokenGovernor.submitApproval(actionInfo); } function test_RevertsIf_ForDoesNotSurpassAgainst() public { @@ -689,27 +689,29 @@ contract SubmitApprovals is LlamaERC20TokenCasterTest { vm.warp(delayPeriodEndTime + 1); vm.prank(tokenHolder1); - llamaERC20TokenCaster.castVote(_actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVote(_actionInfo, uint8(VoteType.For), ""); vm.prank(tokenHolder2); - llamaERC20TokenCaster.castVote(_actionInfo, uint8(VoteType.Against), ""); + llamaERC20TokenGovernor.castVote(_actionInfo, uint8(VoteType.Against), ""); vm.prank(tokenHolder3); - llamaERC20TokenCaster.castVote(_actionInfo, uint8(VoteType.Against), ""); + llamaERC20TokenGovernor.castVote(_actionInfo, uint8(VoteType.Against), ""); vm.warp(castingPeriodEndTime + 1); - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.ForDoesNotSurpassAgainst.selector, 250_000e18, 500_000e18)); - llamaERC20TokenCaster.submitApproval(_actionInfo); + vm.expectRevert( + abi.encodeWithSelector(LlamaTokenGovernor.ForDoesNotSurpassAgainst.selector, 250_000e18, 500_000e18) + ); + llamaERC20TokenGovernor.submitApproval(_actionInfo); } function test_SubmitsApprovalsCorrectly() public { vm.expectEmit(); emit ApprovalSubmitted(actionInfo.id, address(this), 750_000e18, 0, 0); - llamaERC20TokenCaster.submitApproval(actionInfo); + llamaERC20TokenGovernor.submitApproval(actionInfo); } } -contract SubmitDisapprovals is LlamaERC20TokenCasterTest { +contract SubmitDisapprovals is LlamaTokenGovernorCasting { function setUp() public virtual override { - LlamaERC20TokenCasterTest.setUp(); + LlamaTokenGovernorCasting.setUp(); _skipVotingDelay(actionInfo); castVotesFor(); @@ -718,7 +720,7 @@ contract SubmitDisapprovals is LlamaERC20TokenCasterTest { uint256 castingPeriodEndTime = delayPeriodEndTime + ((APPROVAL_PERIOD * TWO_QUARTERS_IN_BPS) / ONE_HUNDRED_IN_BPS); vm.warp(castingPeriodEndTime + 1); - llamaERC20TokenCaster.submitApproval(actionInfo); + llamaERC20TokenGovernor.submitApproval(actionInfo); _skipVetoDelay(actionInfo); castVetosFor(); @@ -733,24 +735,24 @@ contract SubmitDisapprovals is LlamaERC20TokenCasterTest { function test_RevertsIf_ActionInfoMismatch(ActionInfo memory notActionInfo) public { vm.assume(notActionInfo.id != actionInfo.id); vm.expectRevert(); - llamaERC20TokenCaster.submitDisapproval(notActionInfo); + llamaERC20TokenGovernor.submitDisapproval(notActionInfo); } function test_RevertsIf_AlreadySubmittedDisapproval() public { vm.startPrank(tokenHolder1); - llamaERC20TokenCaster.submitDisapproval(actionInfo); + llamaERC20TokenGovernor.submitDisapproval(actionInfo); // This should revert since the underlying Action has transitioned to Failed state. Otherwise it would have reverted // due to `LlamaCore.DuplicateCast() error`. vm.expectRevert(abi.encodeWithSelector(ILlamaCore.InvalidActionState.selector, ActionState.Failed)); - llamaERC20TokenCaster.submitDisapproval(actionInfo); + llamaERC20TokenGovernor.submitDisapproval(actionInfo); } function test_RevertsIf_SubmissionPeriodOver() public { Action memory action = CORE.getAction(actionInfo.id); vm.warp(action.minExecutionTime); - vm.expectRevert(LlamaTokenCaster.SubmissionPeriodOver.selector); - llamaERC20TokenCaster.submitDisapproval(actionInfo); + vm.expectRevert(LlamaTokenGovernor.SubmissionPeriodOver.selector); + llamaERC20TokenGovernor.submitDisapproval(actionInfo); } function test_RevertsIf_InsufficientDisapprovals() public { @@ -763,14 +765,14 @@ contract SubmitDisapprovals is LlamaERC20TokenCasterTest { vm.warp(delayPeriodEndTime + 1); vm.prank(tokenHolder1); - llamaERC20TokenCaster.castVote(_actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVote(_actionInfo, uint8(VoteType.For), ""); vm.prank(tokenHolder2); - llamaERC20TokenCaster.castVote(_actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVote(_actionInfo, uint8(VoteType.For), ""); vm.prank(tokenHolder3); - llamaERC20TokenCaster.castVote(_actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVote(_actionInfo, uint8(VoteType.For), ""); vm.warp(castingPeriodEndTime + 1); - llamaERC20TokenCaster.submitApproval(_actionInfo); + llamaERC20TokenGovernor.submitApproval(_actionInfo); action = CORE.getAction(_actionInfo.id); @@ -778,14 +780,14 @@ contract SubmitDisapprovals is LlamaERC20TokenCasterTest { (action.minExecutionTime - QUEUING_PERIOD) + ((QUEUING_PERIOD * ONE_QUARTER_IN_BPS) / ONE_HUNDRED_IN_BPS); castingPeriodEndTime = delayPeriodEndTime + ((QUEUING_PERIOD * TWO_QUARTERS_IN_BPS) / ONE_HUNDRED_IN_BPS); vm.warp(castingPeriodEndTime + 1); - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.InsufficientVotes.selector, 0, 75_000e18)); - llamaERC20TokenCaster.submitDisapproval(_actionInfo); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.InsufficientVotes.selector, 0, 75_000e18)); + llamaERC20TokenGovernor.submitDisapproval(_actionInfo); } function test_RevertsIf_CastingPeriodNotOver() public { vm.warp(block.timestamp - 1); - vm.expectRevert(LlamaTokenCaster.CastingPeriodNotOver.selector); - llamaERC20TokenCaster.submitDisapproval(actionInfo); + vm.expectRevert(LlamaTokenGovernor.CastingPeriodNotOver.selector); + llamaERC20TokenGovernor.submitDisapproval(actionInfo); } function test_RevertsIf_ForDoesNotSurpassAgainst() public { @@ -798,14 +800,14 @@ contract SubmitDisapprovals is LlamaERC20TokenCasterTest { vm.warp(delayPeriodEndTime + 1); vm.prank(tokenHolder1); - llamaERC20TokenCaster.castVote(_actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVote(_actionInfo, uint8(VoteType.For), ""); vm.prank(tokenHolder2); - llamaERC20TokenCaster.castVote(_actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVote(_actionInfo, uint8(VoteType.For), ""); vm.prank(tokenHolder3); - llamaERC20TokenCaster.castVote(_actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVote(_actionInfo, uint8(VoteType.For), ""); vm.warp(castingPeriodEndTime + 1); - llamaERC20TokenCaster.submitApproval(_actionInfo); + llamaERC20TokenGovernor.submitApproval(_actionInfo); action = CORE.getAction(_actionInfo.id); @@ -816,42 +818,44 @@ contract SubmitDisapprovals is LlamaERC20TokenCasterTest { vm.warp(delayPeriodEndTime + 1); vm.prank(tokenHolder1); - llamaERC20TokenCaster.castVeto(_actionInfo, uint8(VoteType.For), ""); + llamaERC20TokenGovernor.castVeto(_actionInfo, uint8(VoteType.For), ""); vm.prank(tokenHolder2); - llamaERC20TokenCaster.castVeto(_actionInfo, uint8(VoteType.Against), ""); + llamaERC20TokenGovernor.castVeto(_actionInfo, uint8(VoteType.Against), ""); vm.prank(tokenHolder3); - llamaERC20TokenCaster.castVeto(_actionInfo, uint8(VoteType.Against), ""); + llamaERC20TokenGovernor.castVeto(_actionInfo, uint8(VoteType.Against), ""); vm.warp(castingPeriodEndTime + 1); - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.ForDoesNotSurpassAgainst.selector, 250_000e18, 500_000e18)); - llamaERC20TokenCaster.submitDisapproval(_actionInfo); + vm.expectRevert( + abi.encodeWithSelector(LlamaTokenGovernor.ForDoesNotSurpassAgainst.selector, 250_000e18, 500_000e18) + ); + llamaERC20TokenGovernor.submitDisapproval(_actionInfo); } function test_SubmitsDisapprovalsCorrectly() public { vm.expectEmit(); emit DisapprovalSubmitted(actionInfo.id, address(this), 750_000e18, 0, 0); - llamaERC20TokenCaster.submitDisapproval(actionInfo); + llamaERC20TokenGovernor.submitDisapproval(actionInfo); } } -contract SetQuorumPct is LlamaERC20TokenCasterTest { +contract SetQuorumPct is LlamaTokenGovernorCasting { function test_RevertsIf_NotLlamaExecutor(address notLlamaExecutor) public { vm.assume(notLlamaExecutor != address(EXECUTOR)); - vm.expectRevert(LlamaTokenCaster.OnlyLlamaExecutor.selector); + vm.expectRevert(LlamaTokenGovernor.OnlyLlamaExecutor.selector); vm.prank(notLlamaExecutor); - llamaERC20TokenCaster.setQuorumPct(ERC20_VOTE_QUORUM_PCT, ERC20_VETO_QUORUM_PCT); + llamaERC20TokenGovernor.setQuorumPct(ERC20_VOTE_QUORUM_PCT, ERC20_VETO_QUORUM_PCT); } function test_RevertsIf_InvalidQuorumPct() public { vm.startPrank(address(EXECUTOR)); - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.InvalidVetoQuorumPct.selector, uint256(0))); - llamaERC20TokenCaster.setQuorumPct(ERC20_VOTE_QUORUM_PCT, 0); - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.InvalidVoteQuorumPct.selector, uint256(0))); - llamaERC20TokenCaster.setQuorumPct(0, ERC20_VETO_QUORUM_PCT); - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.InvalidVetoQuorumPct.selector, uint256(10_001))); - llamaERC20TokenCaster.setQuorumPct(ERC20_VOTE_QUORUM_PCT, 10_001); - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.InvalidVoteQuorumPct.selector, uint256(10_001))); - llamaERC20TokenCaster.setQuorumPct(10_001, ERC20_VETO_QUORUM_PCT); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.InvalidVetoQuorumPct.selector, uint256(0))); + llamaERC20TokenGovernor.setQuorumPct(ERC20_VOTE_QUORUM_PCT, 0); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.InvalidVoteQuorumPct.selector, uint256(0))); + llamaERC20TokenGovernor.setQuorumPct(0, ERC20_VETO_QUORUM_PCT); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.InvalidVetoQuorumPct.selector, uint256(10_001))); + llamaERC20TokenGovernor.setQuorumPct(ERC20_VOTE_QUORUM_PCT, 10_001); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.InvalidVoteQuorumPct.selector, uint256(10_001))); + llamaERC20TokenGovernor.setQuorumPct(10_001, ERC20_VETO_QUORUM_PCT); vm.stopPrank(); } @@ -861,16 +865,16 @@ contract SetQuorumPct is LlamaERC20TokenCasterTest { vm.expectEmit(); emit QuorumPctSet(_voteQuorum, _vetoQuorum); vm.prank(address(EXECUTOR)); - llamaERC20TokenCaster.setQuorumPct(_voteQuorum, _vetoQuorum); + llamaERC20TokenGovernor.setQuorumPct(_voteQuorum, _vetoQuorum); } } -contract SetPeriodPct is LlamaERC20TokenCasterTest { +contract SetPeriodPct is LlamaTokenGovernorCasting { function test_RevertsIf_NotLlamaExecutor(address notLlamaExecutor) public { vm.assume(notLlamaExecutor != address(EXECUTOR)); - vm.expectRevert(LlamaTokenCaster.OnlyLlamaExecutor.selector); + vm.expectRevert(LlamaTokenGovernor.OnlyLlamaExecutor.selector); vm.prank(notLlamaExecutor); - llamaERC20TokenCaster.setPeriodPct( + llamaERC20TokenGovernor.setPeriodPct( uint16(ONE_QUARTER_IN_BPS), uint16(TWO_QUARTERS_IN_BPS), uint16(ONE_QUARTER_IN_BPS) ); } @@ -879,24 +883,24 @@ contract SetPeriodPct is LlamaERC20TokenCasterTest { vm.startPrank(address(EXECUTOR)); vm.expectRevert( abi.encodeWithSelector( - LlamaTokenCaster.InvalidPeriodPcts.selector, + LlamaTokenGovernor.InvalidPeriodPcts.selector, uint16(ONE_QUARTER_IN_BPS), uint16(TWO_QUARTERS_IN_BPS), uint16(ONE_QUARTER_IN_BPS) + 1 ) ); - llamaERC20TokenCaster.setPeriodPct( + llamaERC20TokenGovernor.setPeriodPct( uint16(ONE_QUARTER_IN_BPS), uint16(TWO_QUARTERS_IN_BPS), uint16(ONE_QUARTER_IN_BPS) + 1 ); vm.expectRevert( abi.encodeWithSelector( - LlamaTokenCaster.InvalidPeriodPcts.selector, + LlamaTokenGovernor.InvalidPeriodPcts.selector, uint16(ONE_QUARTER_IN_BPS), uint16(TWO_QUARTERS_IN_BPS), uint16(ONE_QUARTER_IN_BPS) - 1 ) ); - llamaERC20TokenCaster.setPeriodPct( + llamaERC20TokenGovernor.setPeriodPct( uint16(ONE_QUARTER_IN_BPS), uint16(TWO_QUARTERS_IN_BPS), uint16(ONE_QUARTER_IN_BPS) - 1 ); vm.stopPrank(); @@ -906,15 +910,15 @@ contract SetPeriodPct is LlamaERC20TokenCasterTest { vm.expectEmit(); emit PeriodPctSet(uint16(ONE_QUARTER_IN_BPS), uint16(TWO_QUARTERS_IN_BPS), uint16(ONE_QUARTER_IN_BPS)); vm.prank(address(EXECUTOR)); - llamaERC20TokenCaster.setPeriodPct( + llamaERC20TokenGovernor.setPeriodPct( uint16(ONE_QUARTER_IN_BPS), uint16(TWO_QUARTERS_IN_BPS), uint16(ONE_QUARTER_IN_BPS) ); } } -contract CastData is LlamaERC20TokenCasterTest { +contract CastData is LlamaTokenGovernorCasting { function setUp() public virtual override { - LlamaERC20TokenCasterTest.setUp(); + LlamaTokenGovernorCasting.setUp(); _skipVotingDelay(actionInfo); castVotesFor(); @@ -923,7 +927,7 @@ contract CastData is LlamaERC20TokenCasterTest { uint256 castingPeriodEndTime = delayPeriodEndTime + ((APPROVAL_PERIOD * TWO_QUARTERS_IN_BPS) / ONE_HUNDRED_IN_BPS); vm.warp(castingPeriodEndTime + 1); - llamaERC20TokenCaster.submitApproval(actionInfo); + llamaERC20TokenGovernor.submitApproval(actionInfo); _skipVetoDelay(actionInfo); castVetosFor(); @@ -934,7 +938,7 @@ contract CastData is LlamaERC20TokenCasterTest { castingPeriodEndTime = delayPeriodEndTime + ((QUEUING_PERIOD * TWO_QUARTERS_IN_BPS) / ONE_HUNDRED_IN_BPS); vm.warp(castingPeriodEndTime + 1); - llamaERC20TokenCaster.submitDisapproval(actionInfo); + llamaERC20TokenGovernor.submitDisapproval(actionInfo); } function test_CanGetCastData() public { @@ -945,7 +949,7 @@ contract CastData is LlamaERC20TokenCasterTest { uint128 vetoesFor, uint128 vetoesAbstain, uint128 vetoesAgainst - ) = llamaERC20TokenCaster.casts(actionInfo.id); + ) = llamaERC20TokenGovernor.casts(actionInfo.id); assertEq(votesFor, (ERC20_CREATION_THRESHOLD / 2) * 3); assertEq(votesAbstain, 0); assertEq(votesAgainst, 0); @@ -953,13 +957,13 @@ contract CastData is LlamaERC20TokenCasterTest { assertEq(vetoesAbstain, 0); assertEq(vetoesAgainst, 0); - assertTrue(llamaERC20TokenCaster.hasTokenHolderCast(actionInfo.id, tokenHolder1, true)); - assertTrue(llamaERC20TokenCaster.hasTokenHolderCast(actionInfo.id, tokenHolder2, true)); - assertTrue(llamaERC20TokenCaster.hasTokenHolderCast(actionInfo.id, tokenHolder3, true)); - assertFalse(llamaERC20TokenCaster.hasTokenHolderCast(actionInfo.id, notTokenHolder, true)); - assertTrue(llamaERC20TokenCaster.hasTokenHolderCast(actionInfo.id, tokenHolder1, false)); - assertTrue(llamaERC20TokenCaster.hasTokenHolderCast(actionInfo.id, tokenHolder2, false)); - assertTrue(llamaERC20TokenCaster.hasTokenHolderCast(actionInfo.id, tokenHolder3, false)); - assertFalse(llamaERC20TokenCaster.hasTokenHolderCast(actionInfo.id, notTokenHolder, false)); + assertTrue(llamaERC20TokenGovernor.hasTokenHolderCast(actionInfo.id, tokenHolder1, true)); + assertTrue(llamaERC20TokenGovernor.hasTokenHolderCast(actionInfo.id, tokenHolder2, true)); + assertTrue(llamaERC20TokenGovernor.hasTokenHolderCast(actionInfo.id, tokenHolder3, true)); + assertFalse(llamaERC20TokenGovernor.hasTokenHolderCast(actionInfo.id, notTokenHolder, true)); + assertTrue(llamaERC20TokenGovernor.hasTokenHolderCast(actionInfo.id, tokenHolder1, false)); + assertTrue(llamaERC20TokenGovernor.hasTokenHolderCast(actionInfo.id, tokenHolder2, false)); + assertTrue(llamaERC20TokenGovernor.hasTokenHolderCast(actionInfo.id, tokenHolder3, false)); + assertFalse(llamaERC20TokenGovernor.hasTokenHolderCast(actionInfo.id, notTokenHolder, false)); } } diff --git a/test/token-voting/LlamaERC721TokenActionCreator.t.sol b/test/token-voting/llama-token-governor/erc-721/LlamaTokenGovernorActionCreation.t.sol similarity index 69% rename from test/token-voting/LlamaERC721TokenActionCreator.t.sol rename to test/token-voting/llama-token-governor/erc-721/LlamaTokenGovernorActionCreation.t.sol index bb8d5d6..2c07fc5 100644 --- a/test/token-voting/LlamaERC721TokenActionCreator.t.sol +++ b/test/token-voting/llama-token-governor/erc-721/LlamaTokenGovernorActionCreation.t.sol @@ -9,14 +9,14 @@ import {LlamaCoreSigUtils} from "test/utils/LlamaCoreSigUtils.sol"; import {ILlamaCore} from "src/interfaces/ILlamaCore.sol"; import {ActionState} from "src/lib/Enums.sol"; import {Action, ActionInfo} from "src/lib/Structs.sol"; -import {LlamaTokenActionCreator} from "src/token-voting/LlamaTokenActionCreator.sol"; +import {LlamaTokenGovernor} from "src/token-voting/LlamaTokenGovernor.sol"; -contract LlamaERC721TokenActionCreatorTest is LlamaTokenVotingTestSetup, LlamaCoreSigUtils { +contract LlamaERC721TokenGovernorActionCreationTest is LlamaTokenVotingTestSetup, LlamaCoreSigUtils { event ActionCreated(uint256 id, address indexed creator); event ActionCanceled(uint256 id, address indexed creator); event ActionThresholdSet(uint256 newThreshold); - LlamaTokenActionCreator llamaERC721TokenActionCreator; + LlamaTokenGovernor llamaERC721TokenGovernor; function setUp() public virtual override { LlamaTokenVotingTestSetup.setUp(); @@ -29,7 +29,7 @@ contract LlamaERC721TokenActionCreatorTest is LlamaTokenVotingTestSetup, LlamaCo mineBlock(); // Deploy ERC20 Token Voting Module. - (llamaERC721TokenActionCreator,) = _deployERC721TokenVotingModuleAndSetRole(); + llamaERC721TokenGovernor = _deployERC721TokenVotingModuleAndSetRole(); // Setting ERC20TokenHolderActionCreator's EIP-712 Domain Hash setDomainHash( @@ -37,23 +37,23 @@ contract LlamaERC721TokenActionCreatorTest is LlamaTokenVotingTestSetup, LlamaCo name: CORE.name(), version: "1", chainId: block.chainid, - verifyingContract: address(llamaERC721TokenActionCreator) + verifyingContract: address(llamaERC721TokenGovernor) }) ); } } -// contract Constructor is LlamaERC721TokenActionCreatorTest { +// contract Constructor is LlamaERC721TokenGovernorActionCreationTest { // function test_RevertsIf_InvalidLlamaCore() public { -// // With invalid LlamaCore instance, LlamaTokenActionCreator.InvalidLlamaCoreAddress is unreachable +// // With invalid LlamaCore instance, LlamaTokenGovernor.InvalidLlamaCoreAddress is unreachable // vm.expectRevert(); -// new LlamaTokenActionCreator(erc721VotesToken, ILlamaCore(makeAddr("invalid-llama-core")), +// new LlamaTokenGovernor(erc721VotesToken, ILlamaCore(makeAddr("invalid-llama-core")), // uint256(0)); // } // function test_RevertsIf_InvalidTokenAddress() public { // vm.expectRevert(); // will EvmError: Revert vecause totalSupply fn does not exist -// new LlamaTokenActionCreator(ERC20Votes(makeAddr("invalid-erc721VotesToken")), CORE, uint256(0)); +// new LlamaTokenGovernor(ERC20Votes(makeAddr("invalid-erc721VotesToken")), CORE, uint256(0)); // } // function test_RevertsIf_CreationThresholdExceedsTotalSupply() public { @@ -62,8 +62,8 @@ contract LlamaERC721TokenActionCreatorTest is LlamaTokenVotingTestSetup, LlamaCo // vm.warp(block.timestamp + 1); -// vm.expectRevert(LlamaTokenActionCreator.InvalidCreationThreshold.selector); -// new LlamaTokenActionCreator(erc721VotesToken, CORE, 17_000_000_000_000_000_000_000_000); +// vm.expectRevert(LlamaTokenGovernor.InvalidCreationThreshold.selector); +// new LlamaTokenGovernor(erc721VotesToken, CORE, 17_000_000_000_000_000_000_000_000); // } // function test_ProperlySetsConstructorArguments() public { @@ -73,17 +73,17 @@ contract LlamaERC721TokenActionCreatorTest is LlamaTokenVotingTestSetup, LlamaCo // vm.warp(block.timestamp + 1); -// LlamaTokenActionCreator llamaERC721TokenActionCreator = new -// LlamaTokenActionCreator(erc721VotesToken, +// LlamaTokenGovernor llamaERC721TokenGovernor = new +// LlamaTokenGovernor(erc721VotesToken, // CORE, // threshold); -// assertEq(address(llamaERC721TokenActionCreator.TOKEN()), address(erc721VotesToken)); -// assertEq(address(llamaERC721TokenActionCreator.LLAMA_CORE()), address(CORE)); -// assertEq(llamaERC721TokenActionCreator.creationThreshold(), threshold); +// assertEq(address(llamaERC721TokenGovernor.TOKEN()), address(erc721VotesToken)); +// assertEq(address(llamaERC721TokenGovernor.LLAMA_CORE()), address(CORE)); +// assertEq(llamaERC721TokenGovernor.creationThreshold(), threshold); // } // } -contract CreateAction is LlamaERC721TokenActionCreatorTest { +contract CreateAction is LlamaERC721TokenGovernorActionCreationTest { bytes data = abi.encodeCall(mockProtocol.pause, (true)); function test_RevertsIf_InsufficientBalance() public { @@ -93,12 +93,12 @@ contract CreateAction is LlamaERC721TokenActionCreatorTest { mineBlock(); - vm.expectRevert(abi.encodeWithSelector(LlamaTokenActionCreator.InsufficientBalance.selector, 0)); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.InsufficientBalance.selector, 0)); vm.prank(notTokenHolder); - llamaERC721TokenActionCreator.createAction(STRATEGY, address(mockProtocol), 0, data, ""); + llamaERC721TokenGovernor.createAction(STRATEGY, address(mockProtocol), 0, data, ""); } - function test_RevertsIf_LlamaTokenActionCreatorDoesNotHavePermission() public { + function test_RevertsIf_LlamaTokenGovernorDoesNotHavePermission() public { erc721VotesToken.mint(tokenHolder1, ERC721_CREATION_THRESHOLD); vm.prank(tokenHolder1); erc721VotesToken.delegate(tokenHolder1); @@ -107,12 +107,12 @@ contract CreateAction is LlamaERC721TokenActionCreatorTest { vm.expectRevert(ILlamaCore.PolicyholderDoesNotHavePermission.selector); vm.prank(tokenHolder1); - llamaERC721TokenActionCreator.createAction(STRATEGY, address(mockProtocol), 0, data, ""); + llamaERC721TokenGovernor.createAction(STRATEGY, address(mockProtocol), 0, data, ""); } function test_ProperlyCreatesAction() public { - // Assigns Permission to LlamaTokenActionCreator. - _setRolePermissionToLlamaTokenActionCreator(); + // Assigns Permission to LlamaTokenGovernor. + _setRolePermissionToLlamaTokenGovernor(); // Mint tokens to tokenholder so that they can create action. erc721VotesToken.mint(tokenHolder1, ERC721_CREATION_THRESHOLD); @@ -127,7 +127,7 @@ contract CreateAction is LlamaERC721TokenActionCreatorTest { vm.expectEmit(); emit ActionCreated(actionCount, address(tokenHolder1)); vm.prank(tokenHolder1); - uint256 actionId = llamaERC721TokenActionCreator.createAction(STRATEGY, address(mockProtocol), 0, data, ""); + uint256 actionId = llamaERC721TokenGovernor.createAction(STRATEGY, address(mockProtocol), 0, data, ""); Action memory action = CORE.getAction(actionId); assertEq(actionId, actionCount); @@ -135,12 +135,12 @@ contract CreateAction is LlamaERC721TokenActionCreatorTest { } } -contract CreateActionBySig is LlamaERC721TokenActionCreatorTest { +contract CreateActionBySig is LlamaERC721TokenGovernorActionCreationTest { function setUp() public virtual override { - LlamaERC721TokenActionCreatorTest.setUp(); + LlamaERC721TokenGovernorActionCreationTest.setUp(); - // Assigns Permission to LlamaTokenActionCreator. - _setRolePermissionToLlamaTokenActionCreator(); + // Assigns Permission to LlamaTokenGovernor. + _setRolePermissionToLlamaTokenGovernor(); // Mint tokens to tokenholder so that they can create action. erc721VotesToken.mint(tokenHolder1, ERC721_CREATION_THRESHOLD); @@ -174,7 +174,7 @@ contract CreateActionBySig is LlamaERC721TokenActionCreatorTest { } function createActionBySig(uint8 v, bytes32 r, bytes32 s) internal returns (uint256 actionId) { - actionId = llamaERC721TokenActionCreator.createActionBySig( + actionId = llamaERC721TokenGovernor.createActionBySig( tokenHolder1, STRATEGY, address(mockProtocol), 0, abi.encodeCall(mockProtocol.pause, (true)), "", v, r, s ); } @@ -204,7 +204,7 @@ contract CreateActionBySig is LlamaERC721TokenActionCreatorTest { vm.expectEmit(); emit ActionCreated(actionCount, tokenHolder1); - uint256 actionId = llamaERC721TokenActionCreator.createActionBySig( + uint256 actionId = llamaERC721TokenGovernor.createActionBySig( tokenHolder1, STRATEGY, address(mockProtocol), @@ -224,9 +224,9 @@ contract CreateActionBySig is LlamaERC721TokenActionCreatorTest { function test_CheckNonceIncrements() public { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(tokenHolder1PrivateKey); - assertEq(llamaERC721TokenActionCreator.nonces(tokenHolder1, LlamaTokenActionCreator.createActionBySig.selector), 0); + assertEq(llamaERC721TokenGovernor.nonces(tokenHolder1, LlamaTokenGovernor.createActionBySig.selector), 0); createActionBySig(v, r, s); - assertEq(llamaERC721TokenActionCreator.nonces(tokenHolder1, LlamaTokenActionCreator.createActionBySig.selector), 1); + assertEq(llamaERC721TokenGovernor.nonces(tokenHolder1, LlamaTokenGovernor.createActionBySig.selector), 1); } function test_OperationCannotBeReplayed() public { @@ -234,7 +234,7 @@ contract CreateActionBySig is LlamaERC721TokenActionCreatorTest { createActionBySig(v, r, s); // Invalid Signature error since the recovered signer address during the second call is not the same as // policyholder since nonce has increased. - vm.expectRevert(LlamaTokenActionCreator.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); createActionBySig(v, r, s); } @@ -243,7 +243,7 @@ contract CreateActionBySig is LlamaERC721TokenActionCreatorTest { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(randomSignerPrivateKey); // Invalid Signature error since the recovered signer address is not the same as the policyholder passed in as // parameter. - vm.expectRevert(LlamaTokenActionCreator.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); createActionBySig(v, r, s); } @@ -251,7 +251,7 @@ contract CreateActionBySig is LlamaERC721TokenActionCreatorTest { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(tokenHolder1PrivateKey); // Invalid Signature error since the recovered signer address is zero address due to invalid signature values // (v,r,s). - vm.expectRevert(LlamaTokenActionCreator.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); createActionBySig((v + 1), r, s); } @@ -259,24 +259,24 @@ contract CreateActionBySig is LlamaERC721TokenActionCreatorTest { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(tokenHolder1PrivateKey); vm.prank(tokenHolder1); - llamaERC721TokenActionCreator.incrementNonce(LlamaTokenActionCreator.createActionBySig.selector); + llamaERC721TokenGovernor.incrementNonce(LlamaTokenGovernor.createActionBySig.selector); // Invalid Signature error since the recovered signer address during the call is not the same as policyholder // since nonce has increased. - vm.expectRevert(LlamaTokenActionCreator.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); createActionBySig(v, r, s); } } -contract CancelAction is LlamaERC721TokenActionCreatorTest { +contract CancelAction is LlamaERC721TokenGovernorActionCreationTest { uint256 actionId; ActionInfo actionInfo; function setUp() public virtual override { - LlamaERC721TokenActionCreatorTest.setUp(); + LlamaERC721TokenGovernorActionCreationTest.setUp(); - // Assigns Permission to LlamaTokenActionCreator. - _setRolePermissionToLlamaTokenActionCreator(); + // Assigns Permission to LlamaTokenGovernor. + _setRolePermissionToLlamaTokenGovernor(); // Mint tokens to tokenholder so that they can create action. erc721VotesToken.mint(tokenHolder1, ERC721_CREATION_THRESHOLD); @@ -289,16 +289,10 @@ contract CancelAction is LlamaERC721TokenActionCreatorTest { bytes memory data = abi.encodeCall(mockProtocol.pause, (true)); vm.prank(tokenHolder1); - actionId = llamaERC721TokenActionCreator.createAction(STRATEGY, address(mockProtocol), 0, data, ""); + actionId = llamaERC721TokenGovernor.createAction(STRATEGY, address(mockProtocol), 0, data, ""); actionInfo = ActionInfo( - actionId, - address(llamaERC721TokenActionCreator), - tokenVotingActionCreatorRole, - STRATEGY, - address(mockProtocol), - 0, - data + actionId, address(llamaERC721TokenGovernor), tokenVotingGovernorRole, STRATEGY, address(mockProtocol), 0, data ); } @@ -306,26 +300,26 @@ contract CancelAction is LlamaERC721TokenActionCreatorTest { vm.expectEmit(); emit ActionCanceled(actionId, tokenHolder1); vm.prank(tokenHolder1); - llamaERC721TokenActionCreator.cancelAction(actionInfo); + llamaERC721TokenGovernor.cancelAction(actionInfo); } function test_RevertsIf_CallerIsNotActionCreator(address notCreator) public { vm.assume(notCreator != tokenHolder1); - vm.expectRevert(LlamaTokenActionCreator.OnlyActionCreator.selector); + vm.expectRevert(LlamaTokenGovernor.OnlyActionCreator.selector); vm.prank(notCreator); - llamaERC721TokenActionCreator.cancelAction(actionInfo); + llamaERC721TokenGovernor.cancelAction(actionInfo); } } -contract CancelActionBySig is LlamaERC721TokenActionCreatorTest { +contract CancelActionBySig is LlamaERC721TokenGovernorActionCreationTest { uint256 actionId; ActionInfo actionInfo; function setUp() public virtual override { - LlamaERC721TokenActionCreatorTest.setUp(); + LlamaERC721TokenGovernorActionCreationTest.setUp(); - // Assigns Permission to LlamaTokenActionCreator. - _setRolePermissionToLlamaTokenActionCreator(); + // Assigns Permission to LlamaTokenGovernor. + _setRolePermissionToLlamaTokenGovernor(); // Mint tokens to tokenholder so that they can create action. erc721VotesToken.mint(tokenHolder1, ERC721_CREATION_THRESHOLD); @@ -338,16 +332,10 @@ contract CancelActionBySig is LlamaERC721TokenActionCreatorTest { bytes memory data = abi.encodeCall(mockProtocol.pause, (true)); vm.prank(tokenHolder1); - actionId = llamaERC721TokenActionCreator.createAction(STRATEGY, address(mockProtocol), 0, data, ""); + actionId = llamaERC721TokenGovernor.createAction(STRATEGY, address(mockProtocol), 0, data, ""); actionInfo = ActionInfo( - actionId, - address(llamaERC721TokenActionCreator), - tokenVotingActionCreatorRole, - STRATEGY, - address(mockProtocol), - 0, - data + actionId, address(llamaERC721TokenGovernor), tokenVotingGovernorRole, STRATEGY, address(mockProtocol), 0, data ); } @@ -359,14 +347,14 @@ contract CancelActionBySig is LlamaERC721TokenActionCreatorTest { LlamaCoreSigUtils.CancelAction memory cancelAction = LlamaCoreSigUtils.CancelAction({ tokenHolder: tokenHolder1, actionInfo: _actionInfo, - nonce: llamaERC721TokenActionCreator.nonces(tokenHolder1, LlamaTokenActionCreator.cancelActionBySig.selector) + nonce: llamaERC721TokenGovernor.nonces(tokenHolder1, LlamaTokenGovernor.cancelActionBySig.selector) }); bytes32 digest = getCancelActionTypedDataHash(cancelAction); (v, r, s) = vm.sign(privateKey, digest); } function cancelActionBySig(ActionInfo memory _actionInfo, uint8 v, bytes32 r, bytes32 s) internal { - llamaERC721TokenActionCreator.cancelActionBySig(tokenHolder1, _actionInfo, v, r, s); + llamaERC721TokenGovernor.cancelActionBySig(tokenHolder1, _actionInfo, v, r, s); } function test_CancelActionBySig() public { @@ -384,9 +372,9 @@ contract CancelActionBySig is LlamaERC721TokenActionCreatorTest { function test_CheckNonceIncrements() public { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(actionInfo, tokenHolder1PrivateKey); - assertEq(llamaERC721TokenActionCreator.nonces(tokenHolder1, LlamaTokenActionCreator.cancelActionBySig.selector), 0); + assertEq(llamaERC721TokenGovernor.nonces(tokenHolder1, LlamaTokenGovernor.cancelActionBySig.selector), 0); cancelActionBySig(actionInfo, v, r, s); - assertEq(llamaERC721TokenActionCreator.nonces(tokenHolder1, LlamaTokenActionCreator.cancelActionBySig.selector), 1); + assertEq(llamaERC721TokenGovernor.nonces(tokenHolder1, LlamaTokenGovernor.cancelActionBySig.selector), 1); } function test_OperationCannotBeReplayed() public { @@ -394,7 +382,7 @@ contract CancelActionBySig is LlamaERC721TokenActionCreatorTest { cancelActionBySig(actionInfo, v, r, s); // Invalid Signature error since the recovered signer address during the second call is not the same as policyholder // since nonce has increased. - vm.expectRevert(LlamaTokenActionCreator.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); cancelActionBySig(actionInfo, v, r, s); } @@ -403,7 +391,7 @@ contract CancelActionBySig is LlamaERC721TokenActionCreatorTest { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(actionInfo, randomSignerPrivateKey); // Invalid Signature error since the recovered signer address is not the same as the policyholder passed in as // parameter. - vm.expectRevert(LlamaTokenActionCreator.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); cancelActionBySig(actionInfo, v, r, s); } @@ -411,7 +399,7 @@ contract CancelActionBySig is LlamaERC721TokenActionCreatorTest { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(actionInfo, tokenHolder1PrivateKey); // Invalid Signature error since the recovered signer address is zero address due to invalid signature values // (v,r,s). - vm.expectRevert(LlamaTokenActionCreator.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); cancelActionBySig(actionInfo, (v + 1), r, s); } @@ -419,42 +407,42 @@ contract CancelActionBySig is LlamaERC721TokenActionCreatorTest { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(actionInfo, tokenHolder1PrivateKey); vm.prank(tokenHolder1); - llamaERC721TokenActionCreator.incrementNonce(LlamaTokenActionCreator.cancelActionBySig.selector); + llamaERC721TokenGovernor.incrementNonce(LlamaTokenGovernor.cancelActionBySig.selector); // Invalid Signature error since the recovered signer address during the call is not the same as policyholder // since nonce has increased. - vm.expectRevert(LlamaTokenActionCreator.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); cancelActionBySig(actionInfo, v, r, s); } } -contract SetActionThreshold is LlamaERC721TokenActionCreatorTest { +contract SetActionThreshold is LlamaERC721TokenGovernorActionCreationTest { function testFuzz_SetsCreationThreshold(uint256 threshold) public { threshold = bound(threshold, 0, erc721VotesToken.getPastTotalSupply(block.timestamp - 1)); - assertEq(llamaERC721TokenActionCreator.creationThreshold(), ERC721_CREATION_THRESHOLD); + assertEq(llamaERC721TokenGovernor.creationThreshold(), ERC721_CREATION_THRESHOLD); vm.expectEmit(); emit ActionThresholdSet(threshold); vm.prank(address(EXECUTOR)); - llamaERC721TokenActionCreator.setActionThreshold(threshold); + llamaERC721TokenGovernor.setActionThreshold(threshold); - assertEq(llamaERC721TokenActionCreator.creationThreshold(), threshold); + assertEq(llamaERC721TokenGovernor.creationThreshold(), threshold); } function testFuzz_RevertsIf_CreationThresholdExceedsTotalSupply(uint256 threshold) public { vm.assume(threshold > erc721VotesToken.getPastTotalSupply(block.timestamp - 1)); - vm.expectRevert(LlamaTokenActionCreator.InvalidCreationThreshold.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidCreationThreshold.selector); vm.prank(address(EXECUTOR)); - llamaERC721TokenActionCreator.setActionThreshold(threshold); + llamaERC721TokenGovernor.setActionThreshold(threshold); } function testFuzz_RevertsIf_CalledByNotLlamaExecutor(address notLlamaExecutor) public { vm.assume(notLlamaExecutor != address(EXECUTOR)); - vm.expectRevert(LlamaTokenActionCreator.OnlyLlamaExecutor.selector); + vm.expectRevert(LlamaTokenGovernor.OnlyLlamaExecutor.selector); vm.prank(notLlamaExecutor); - llamaERC721TokenActionCreator.setActionThreshold(ERC721_CREATION_THRESHOLD); + llamaERC721TokenGovernor.setActionThreshold(ERC721_CREATION_THRESHOLD); } } diff --git a/test/token-voting/LlamaERC721TokenCaster.t.sol b/test/token-voting/llama-token-governor/erc-721/LlamaTokenGovernorCasting.t.sol similarity index 70% rename from test/token-voting/LlamaERC721TokenCaster.t.sol rename to test/token-voting/llama-token-governor/erc-721/LlamaTokenGovernorCasting.t.sol index 081f9d5..cc048b4 100644 --- a/test/token-voting/LlamaERC721TokenCaster.t.sol +++ b/test/token-voting/llama-token-governor/erc-721/LlamaTokenGovernorCasting.t.sol @@ -15,9 +15,9 @@ import {ILlamaRelativeStrategyBase} from "src/interfaces/ILlamaRelativeStrategyB import {ILlamaStrategy} from "src/interfaces/ILlamaStrategy.sol"; import {ILlamaTokenAdapter} from "src/token-voting/interfaces/ILlamaTokenAdapter.sol"; import {LlamaTokenAdapterVotesTimestamp} from "src/token-voting/token-adapters/LlamaTokenAdapterVotesTimestamp.sol"; -import {LlamaTokenCaster} from "src/token-voting/LlamaTokenCaster.sol"; +import {LlamaTokenGovernor} from "src/token-voting/LlamaTokenGovernor.sol"; -contract LlamaERC721TokenCasterTest is LlamaTokenVotingTestSetup, LlamaCoreSigUtils { +contract LlamaTokenGovernorCastingTest is LlamaTokenVotingTestSetup, LlamaCoreSigUtils { event VoteCast(uint256 id, address indexed tokenholder, uint8 indexed support, uint256 weight, string reason); event ApprovalSubmitted( uint256 id, address indexed caller, uint256 weightFor, uint256 weightAgainst, uint256 weightAbstain @@ -32,7 +32,7 @@ contract LlamaERC721TokenCasterTest is LlamaTokenVotingTestSetup, LlamaCoreSigUt ActionInfo actionInfo; uint256 actionCreationTime; uint256 minExecutionTime; - LlamaTokenCaster llamaERC721TokenCaster; + LlamaTokenGovernor llamaERC721TokenGovernor; ILlamaStrategy tokenVotingStrategy; function setUp() public virtual override { @@ -56,44 +56,44 @@ contract LlamaERC721TokenCasterTest is LlamaTokenVotingTestSetup, LlamaCoreSigUt mineBlock(); // Deploy ERC721 Token Voting Module. - (, llamaERC721TokenCaster) = _deployERC721TokenVotingModuleAndSetRole(); + llamaERC721TokenGovernor = _deployERC721TokenVotingModuleAndSetRole(); // Mine block so that Token Voting Caster Role will have supply during action creation (due to past timestamp check) mineBlock(); - tokenVotingStrategy = _deployRelativeQuantityQuorumAndSetRolePermissionToCoreTeam(tokenVotingCasterRole); + tokenVotingStrategy = _deployRelativeQuantityQuorumAndSetRolePermissionToCoreTeam(tokenVotingGovernorRole); actionInfo = _createActionWithTokenVotingStrategy(tokenVotingStrategy); Action memory action = CORE.getAction(actionInfo.id); actionCreationTime = action.creationTime; minExecutionTime = action.minExecutionTime; - // Setting LlamaTokenCaster's EIP-712 Domain Hash + // Setting LlamaTokenGovernor's EIP-712 Domain Hash setDomainHash( LlamaCoreSigUtils.EIP712Domain({ name: CORE.name(), version: "1", chainId: block.chainid, - verifyingContract: address(llamaERC721TokenCaster) + verifyingContract: address(llamaERC721TokenGovernor) }) ); } function castVotesFor() public { vm.prank(tokenHolder1); - llamaERC721TokenCaster.castVote(actionInfo, uint8(VoteType.For), ""); + llamaERC721TokenGovernor.castVote(actionInfo, uint8(VoteType.For), ""); vm.prank(tokenHolder2); - llamaERC721TokenCaster.castVote(actionInfo, uint8(VoteType.For), ""); + llamaERC721TokenGovernor.castVote(actionInfo, uint8(VoteType.For), ""); vm.prank(tokenHolder3); - llamaERC721TokenCaster.castVote(actionInfo, uint8(VoteType.For), ""); + llamaERC721TokenGovernor.castVote(actionInfo, uint8(VoteType.For), ""); } function castVetosFor() public { vm.prank(tokenHolder1); - llamaERC721TokenCaster.castVeto(actionInfo, uint8(VoteType.For), ""); + llamaERC721TokenGovernor.castVeto(actionInfo, uint8(VoteType.For), ""); vm.prank(tokenHolder2); - llamaERC721TokenCaster.castVeto(actionInfo, uint8(VoteType.For), ""); + llamaERC721TokenGovernor.castVeto(actionInfo, uint8(VoteType.For), ""); vm.prank(tokenHolder3); - llamaERC721TokenCaster.castVeto(actionInfo, uint8(VoteType.For), ""); + llamaERC721TokenGovernor.castVeto(actionInfo, uint8(VoteType.For), ""); } function createTimestampTokenAdapter(address token, uint256 nonce) public returns (ILlamaTokenAdapter tokenAdapter) { @@ -106,50 +106,50 @@ contract LlamaERC721TokenCasterTest is LlamaTokenVotingTestSetup, LlamaCoreSigUt } } -contract CastVote is LlamaERC721TokenCasterTest { +contract CastVote is LlamaTokenGovernorCastingTest { function setUp() public virtual override { - LlamaERC721TokenCasterTest.setUp(); + LlamaTokenGovernorCastingTest.setUp(); _skipVotingDelay(actionInfo); } function test_RevertsIf_NotPastVotingDelay() public { vm.warp(block.timestamp - 1); - vm.expectRevert(LlamaTokenCaster.DelayPeriodNotOver.selector); - llamaERC721TokenCaster.castVote(actionInfo, uint8(VoteType.For), ""); + vm.expectRevert(LlamaTokenGovernor.DelayPeriodNotOver.selector); + llamaERC721TokenGovernor.castVote(actionInfo, uint8(VoteType.For), ""); } function test_RevertsIf_ActionInfoMismatch(ActionInfo memory notActionInfo) public { vm.assume(notActionInfo.id != actionInfo.id); vm.expectRevert(); - llamaERC721TokenCaster.castVote(notActionInfo, uint8(VoteType.For), ""); + llamaERC721TokenGovernor.castVote(notActionInfo, uint8(VoteType.For), ""); } function test_RevertsIf_ApprovalNotEnabled() public { ILlamaTokenAdapter tokenAdapter = createTimestampTokenAdapter(address(erc721VotesToken), 0); - LlamaTokenCaster casterWithWrongRole = LlamaTokenCaster( + LlamaTokenGovernor casterWithWrongRole = LlamaTokenGovernor( Clones.cloneDeterministic( - address(llamaTokenCasterLogic), keccak256(abi.encodePacked(address(erc721VotesToken), msg.sender)) + address(llamaTokenGovernorLogic), keccak256(abi.encodePacked(address(erc721VotesToken), msg.sender)) ) ); - casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, defaultCasterConfig); + casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, 0, defaultCasterConfig); - vm.expectRevert(abi.encodeWithSelector(ILlamaRelativeStrategyBase.InvalidRole.selector, tokenVotingCasterRole)); + vm.expectRevert(abi.encodeWithSelector(ILlamaRelativeStrategyBase.InvalidRole.selector, tokenVotingGovernorRole)); casterWithWrongRole.castVote(actionInfo, uint8(VoteType.For), ""); } function test_RevertsIf_ActionNotActive() public { vm.warp(actionCreationTime + APPROVAL_PERIOD + 1); - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.InvalidActionState.selector, ActionState.Failed)); - llamaERC721TokenCaster.castVote(actionInfo, uint8(VoteType.For), ""); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.InvalidActionState.selector, ActionState.Failed)); + llamaERC721TokenGovernor.castVote(actionInfo, uint8(VoteType.For), ""); } function test_RevertsIf_RoleHasBeenRevokedBeforeActionCreation() public { // Revoking Caster role from Token Holder Caster and assigning it to a random address so that Role has supply. vm.startPrank(address(EXECUTOR)); - POLICY.setRoleHolder(tokenVotingCasterRole, address(llamaERC721TokenCaster), 0, 0); - POLICY.setRoleHolder(tokenVotingCasterRole, address(0xdeadbeef), DEFAULT_ROLE_QTY, DEFAULT_ROLE_EXPIRATION); + POLICY.setRoleHolder(tokenVotingGovernorRole, address(llamaERC721TokenGovernor), 0, 0); + POLICY.setRoleHolder(tokenVotingGovernorRole, address(0xdeadbeef), DEFAULT_ROLE_QTY, DEFAULT_ROLE_EXPIRATION); vm.stopPrank(); // Mine block so that the revoke will be effective @@ -162,35 +162,35 @@ contract CastVote is LlamaERC721TokenCasterTest { vm.warp(action.creationTime + ((APPROVAL_PERIOD * ONE_QUARTER_IN_BPS) / ONE_HUNDRED_IN_BPS) + 1); vm.startPrank(tokenHolder1); - vm.expectRevert(LlamaTokenCaster.InvalidPolicyholder.selector); - llamaERC721TokenCaster.castVote(_actionInfo, uint8(VoteType.For), ""); + vm.expectRevert(LlamaTokenGovernor.InvalidPolicyholder.selector); + llamaERC721TokenGovernor.castVote(_actionInfo, uint8(VoteType.For), ""); } function test_RevertsIf_AlreadyCastedVote() public { vm.startPrank(tokenHolder1); - llamaERC721TokenCaster.castVote(actionInfo, uint8(VoteType.For), ""); + llamaERC721TokenGovernor.castVote(actionInfo, uint8(VoteType.For), ""); - vm.expectRevert(LlamaTokenCaster.DuplicateCast.selector); - llamaERC721TokenCaster.castVote(actionInfo, uint8(VoteType.For), ""); + vm.expectRevert(LlamaTokenGovernor.DuplicateCast.selector); + llamaERC721TokenGovernor.castVote(actionInfo, uint8(VoteType.For), ""); } function test_RevertsIf_InvalidSupport() public { - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.InvalidSupport.selector, uint8(3))); - llamaERC721TokenCaster.castVote(actionInfo, 3, ""); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.InvalidSupport.selector, uint8(3))); + llamaERC721TokenGovernor.castVote(actionInfo, 3, ""); } function test_RevertsIf_CastingPeriodOver() public { uint256 delayPeriodEndTime = actionCreationTime + ((APPROVAL_PERIOD * ONE_QUARTER_IN_BPS) / ONE_HUNDRED_IN_BPS); uint256 castingPeriodEndTime = delayPeriodEndTime + ((APPROVAL_PERIOD * TWO_QUARTERS_IN_BPS) / ONE_HUNDRED_IN_BPS); vm.warp(castingPeriodEndTime + 1); - vm.expectRevert(LlamaTokenCaster.CastingPeriodOver.selector); - llamaERC721TokenCaster.castVote(actionInfo, uint8(VoteType.For), ""); + vm.expectRevert(LlamaTokenGovernor.CastingPeriodOver.selector); + llamaERC721TokenGovernor.castVote(actionInfo, uint8(VoteType.For), ""); } function test_CanCastWithWeightZero() public { vm.expectEmit(); emit VoteCast(actionInfo.id, address(this), uint8(VoteType.For), 0, ""); - llamaERC721TokenCaster.castVote(actionInfo, uint8(VoteType.For), ""); + llamaERC721TokenGovernor.castVote(actionInfo, uint8(VoteType.For), ""); } function test_CastsVoteCorrectly(uint8 support) public { @@ -200,7 +200,7 @@ contract CastVote is LlamaERC721TokenCasterTest { actionInfo.id, tokenHolder1, support, erc721VotesToken.getPastVotes(tokenHolder1, block.timestamp - 1), "" ); vm.prank(tokenHolder1); - uint128 weight = llamaERC721TokenCaster.castVote(actionInfo, support, ""); + uint128 weight = llamaERC721TokenGovernor.castVote(actionInfo, support, ""); assertEq(weight, erc721VotesToken.getPastVotes(tokenHolder1, block.timestamp - 1)); } @@ -214,7 +214,7 @@ contract CastVote is LlamaERC721TokenCasterTest { "reason" ); vm.prank(tokenHolder1); - llamaERC721TokenCaster.castVote(actionInfo, uint8(VoteType.For), "reason"); + llamaERC721TokenGovernor.castVote(actionInfo, uint8(VoteType.For), "reason"); } function test_GetsWeightAtDelayPeriodTimestamp() public { @@ -227,15 +227,15 @@ contract CastVote is LlamaERC721TokenCasterTest { // However tokenholder1 is able to vote with the weight they had at delayPeriodEndTime vm.expectEmit(); emit VoteCast(actionInfo.id, tokenHolder1, 1, 1, ""); - uint128 weight = llamaERC721TokenCaster.castVote(actionInfo, 1, ""); + uint128 weight = llamaERC721TokenGovernor.castVote(actionInfo, 1, ""); assertEq(weight, 1); vm.stopPrank(); } } -contract CastVoteBySig is LlamaERC721TokenCasterTest { +contract CastVoteBySig is LlamaTokenGovernorCastingTest { function setUp() public virtual override { - LlamaERC721TokenCasterTest.setUp(); + LlamaTokenGovernorCastingTest.setUp(); _skipVotingDelay(actionInfo); } @@ -256,7 +256,7 @@ contract CastVoteBySig is LlamaERC721TokenCasterTest { } function castVoteBySig(ActionInfo memory _actionInfo, uint8 support, uint8 v, bytes32 r, bytes32 s) internal { - llamaERC721TokenCaster.castVoteBySig(tokenHolder1, _actionInfo, support, "", v, r, s); + llamaERC721TokenGovernor.castVoteBySig(tokenHolder1, _actionInfo, support, "", v, r, s); } function test_CastsVoteBySig() public { @@ -277,9 +277,9 @@ contract CastVoteBySig is LlamaERC721TokenCasterTest { function test_CheckNonceIncrements() public { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(actionInfo, tokenHolder1PrivateKey); - assertEq(llamaERC721TokenCaster.nonces(tokenHolder1, LlamaTokenCaster.castVoteBySig.selector), 0); + assertEq(llamaERC721TokenGovernor.nonces(tokenHolder1, LlamaTokenGovernor.castVoteBySig.selector), 0); castVoteBySig(actionInfo, uint8(VoteType.For), v, r, s); - assertEq(llamaERC721TokenCaster.nonces(tokenHolder1, LlamaTokenCaster.castVoteBySig.selector), 1); + assertEq(llamaERC721TokenGovernor.nonces(tokenHolder1, LlamaTokenGovernor.castVoteBySig.selector), 1); } function test_OperationCannotBeReplayed() public { @@ -287,7 +287,7 @@ contract CastVoteBySig is LlamaERC721TokenCasterTest { castVoteBySig(actionInfo, uint8(VoteType.For), v, r, s); // Invalid Signature error since the recovered signer address during the second call is not the same as // erc721VotesTokenholder since nonce has increased. - vm.expectRevert(LlamaTokenCaster.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); castVoteBySig(actionInfo, uint8(VoteType.For), v, r, s); } @@ -296,7 +296,7 @@ contract CastVoteBySig is LlamaERC721TokenCasterTest { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(actionInfo, randomSignerPrivateKey); // Invalid Signature error since the recovered signer address is not the same as the erc721VotesTokenholder passed // in as parameter. - vm.expectRevert(LlamaTokenCaster.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); castVoteBySig(actionInfo, uint8(VoteType.For), v, r, s); } @@ -304,7 +304,7 @@ contract CastVoteBySig is LlamaERC721TokenCasterTest { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(actionInfo, tokenHolder1PrivateKey); // Invalid Signature error since the recovered signer address is zero address due to invalid signature values // (v,r,s). - vm.expectRevert(LlamaTokenCaster.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); castVoteBySig(actionInfo, uint8(VoteType.For), (v + 1), r, s); } @@ -312,18 +312,18 @@ contract CastVoteBySig is LlamaERC721TokenCasterTest { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(actionInfo, tokenHolder1PrivateKey); vm.prank(tokenHolder1); - llamaERC721TokenCaster.incrementNonce(LlamaTokenCaster.castVoteBySig.selector); + llamaERC721TokenGovernor.incrementNonce(LlamaTokenGovernor.castVoteBySig.selector); // Invalid Signature error since the recovered signer address during the call is not the same as // erc721VotesTokenholder since nonce has increased. - vm.expectRevert(LlamaTokenCaster.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); castVoteBySig(actionInfo, uint8(VoteType.For), v, r, s); } } -contract CastVeto is LlamaERC721TokenCasterTest { +contract CastVeto is LlamaTokenGovernorCastingTest { function setUp() public virtual override { - LlamaERC721TokenCasterTest.setUp(); + LlamaTokenGovernorCastingTest.setUp(); _skipVotingDelay(actionInfo); castVotesFor(); @@ -332,33 +332,33 @@ contract CastVeto is LlamaERC721TokenCasterTest { uint256 castingPeriodEndTime = delayPeriodEndTime + ((APPROVAL_PERIOD * TWO_QUARTERS_IN_BPS) / ONE_HUNDRED_IN_BPS); vm.warp(castingPeriodEndTime + 1); - llamaERC721TokenCaster.submitApproval(actionInfo); + llamaERC721TokenGovernor.submitApproval(actionInfo); _skipVetoDelay(actionInfo); } function test_RevertsIf_NotPastVotingDelay() public { vm.warp(block.timestamp - 1); - vm.expectRevert(LlamaTokenCaster.DelayPeriodNotOver.selector); - llamaERC721TokenCaster.castVeto(actionInfo, uint8(VoteType.For), ""); + vm.expectRevert(LlamaTokenGovernor.DelayPeriodNotOver.selector); + llamaERC721TokenGovernor.castVeto(actionInfo, uint8(VoteType.For), ""); } function test_RevertsIf_ActionInfoMismatch(ActionInfo memory notActionInfo) public { vm.assume(notActionInfo.id != actionInfo.id); vm.expectRevert(); - llamaERC721TokenCaster.castVeto(notActionInfo, uint8(VoteType.For), ""); + llamaERC721TokenGovernor.castVeto(notActionInfo, uint8(VoteType.For), ""); } function test_RevertsIf_DisapprovalNotEnabled() public { ILlamaTokenAdapter tokenAdapter = createTimestampTokenAdapter(address(erc721VotesToken), 0); - LlamaTokenCaster casterWithWrongRole = LlamaTokenCaster( + LlamaTokenGovernor casterWithWrongRole = LlamaTokenGovernor( Clones.cloneDeterministic( - address(llamaTokenCasterLogic), keccak256(abi.encodePacked(address(erc721VotesToken), msg.sender)) + address(llamaTokenGovernorLogic), keccak256(abi.encodePacked(address(erc721VotesToken), msg.sender)) ) ); - casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, defaultCasterConfig); + casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, 0, defaultCasterConfig); - vm.expectRevert(abi.encodeWithSelector(ILlamaRelativeStrategyBase.InvalidRole.selector, tokenVotingCasterRole)); + vm.expectRevert(abi.encodeWithSelector(ILlamaRelativeStrategyBase.InvalidRole.selector, tokenVotingGovernorRole)); casterWithWrongRole.castVeto(actionInfo, uint8(VoteType.For), ""); } @@ -369,21 +369,21 @@ contract CastVeto is LlamaERC721TokenCasterTest { ActionInfo memory _actionInfo = ActionInfo(actionId, coreTeam1, CORE_TEAM_ROLE, tokenVotingStrategy, address(mockProtocol), 0, data); // Currently at actionCreationTime which is Active state. - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.InvalidActionState.selector, ActionState.Active)); - llamaERC721TokenCaster.castVeto(_actionInfo, uint8(VoteType.For), ""); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.InvalidActionState.selector, ActionState.Active)); + llamaERC721TokenGovernor.castVeto(_actionInfo, uint8(VoteType.For), ""); } function test_RevertsIf_AlreadyCastedVote() public { vm.startPrank(tokenHolder1); - llamaERC721TokenCaster.castVeto(actionInfo, uint8(VoteType.For), ""); + llamaERC721TokenGovernor.castVeto(actionInfo, uint8(VoteType.For), ""); - vm.expectRevert(LlamaTokenCaster.DuplicateCast.selector); - llamaERC721TokenCaster.castVeto(actionInfo, uint8(VoteType.For), ""); + vm.expectRevert(LlamaTokenGovernor.DuplicateCast.selector); + llamaERC721TokenGovernor.castVeto(actionInfo, uint8(VoteType.For), ""); } function test_RevertsIf_InvalidSupport() public { - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.InvalidSupport.selector, uint8(3))); - llamaERC721TokenCaster.castVeto(actionInfo, 3, ""); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.InvalidSupport.selector, uint8(3))); + llamaERC721TokenGovernor.castVeto(actionInfo, 3, ""); } function test_RevertsIf_CastingPeriodOver() public { @@ -392,14 +392,14 @@ contract CastVeto is LlamaERC721TokenCasterTest { (action.minExecutionTime - QUEUING_PERIOD) + ((QUEUING_PERIOD * ONE_QUARTER_IN_BPS) / ONE_HUNDRED_IN_BPS); uint256 castingPeriodEndTime = delayPeriodEndTime + ((QUEUING_PERIOD * TWO_QUARTERS_IN_BPS) / ONE_HUNDRED_IN_BPS); vm.warp(castingPeriodEndTime + 1); - vm.expectRevert(LlamaTokenCaster.CastingPeriodOver.selector); - llamaERC721TokenCaster.castVeto(actionInfo, uint8(VoteType.For), ""); + vm.expectRevert(LlamaTokenGovernor.CastingPeriodOver.selector); + llamaERC721TokenGovernor.castVeto(actionInfo, uint8(VoteType.For), ""); } function test_CanCastWithWeightZero() public { vm.expectEmit(); emit VetoCast(actionInfo.id, address(this), uint8(VoteType.For), 0, ""); - llamaERC721TokenCaster.castVeto(actionInfo, uint8(VoteType.For), ""); + llamaERC721TokenGovernor.castVeto(actionInfo, uint8(VoteType.For), ""); } function test_CastsVetoCorrectly(uint8 support) public { @@ -409,7 +409,7 @@ contract CastVeto is LlamaERC721TokenCasterTest { actionInfo.id, tokenHolder1, support, erc721VotesToken.getPastVotes(tokenHolder1, block.timestamp - 1), "" ); vm.prank(tokenHolder1); - uint128 weight = llamaERC721TokenCaster.castVeto(actionInfo, support, ""); + uint128 weight = llamaERC721TokenGovernor.castVeto(actionInfo, support, ""); assertEq(weight, erc721VotesToken.getPastVotes(tokenHolder1, block.timestamp - 1)); } @@ -423,7 +423,7 @@ contract CastVeto is LlamaERC721TokenCasterTest { "reason" ); vm.prank(tokenHolder1); - llamaERC721TokenCaster.castVeto(actionInfo, uint8(VoteType.For), "reason"); + llamaERC721TokenGovernor.castVeto(actionInfo, uint8(VoteType.For), "reason"); } function test_GetsWeightAtDelayPeriodTimestamp() public { @@ -436,15 +436,15 @@ contract CastVeto is LlamaERC721TokenCasterTest { // However tokenholder1 is able to vote with the weight they had at delayPeriodEndTime vm.expectEmit(); emit VetoCast(actionInfo.id, tokenHolder1, 1, 1, ""); - uint128 weight = llamaERC721TokenCaster.castVeto(actionInfo, 1, ""); + uint128 weight = llamaERC721TokenGovernor.castVeto(actionInfo, 1, ""); assertEq(weight, 1); vm.stopPrank(); } } -contract CastVetoBySig is LlamaERC721TokenCasterTest { +contract CastVetoBySig is LlamaTokenGovernorCastingTest { function setUp() public virtual override { - LlamaERC721TokenCasterTest.setUp(); + LlamaTokenGovernorCastingTest.setUp(); _skipVotingDelay(actionInfo); castVotesFor(); @@ -453,7 +453,7 @@ contract CastVetoBySig is LlamaERC721TokenCasterTest { uint256 castingPeriodEndTime = delayPeriodEndTime + ((APPROVAL_PERIOD * TWO_QUARTERS_IN_BPS) / ONE_HUNDRED_IN_BPS); vm.warp(castingPeriodEndTime + 1); - llamaERC721TokenCaster.submitApproval(actionInfo); + llamaERC721TokenGovernor.submitApproval(actionInfo); _skipVetoDelay(actionInfo); } @@ -474,7 +474,7 @@ contract CastVetoBySig is LlamaERC721TokenCasterTest { } function castVetoBySig(ActionInfo memory _actionInfo, uint8 v, bytes32 r, bytes32 s) internal { - llamaERC721TokenCaster.castVetoBySig(tokenHolder1, _actionInfo, uint8(VoteType.For), "", v, r, s); + llamaERC721TokenGovernor.castVetoBySig(tokenHolder1, _actionInfo, uint8(VoteType.For), "", v, r, s); } function test_CastsVetoBySig() public { @@ -498,9 +498,9 @@ contract CastVetoBySig is LlamaERC721TokenCasterTest { function test_CheckNonceIncrements() public { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(actionInfo, tokenHolder1PrivateKey); - assertEq(llamaERC721TokenCaster.nonces(tokenHolder1, LlamaTokenCaster.castVetoBySig.selector), 0); + assertEq(llamaERC721TokenGovernor.nonces(tokenHolder1, LlamaTokenGovernor.castVetoBySig.selector), 0); castVetoBySig(actionInfo, v, r, s); - assertEq(llamaERC721TokenCaster.nonces(tokenHolder1, LlamaTokenCaster.castVetoBySig.selector), 1); + assertEq(llamaERC721TokenGovernor.nonces(tokenHolder1, LlamaTokenGovernor.castVetoBySig.selector), 1); } function test_OperationCannotBeReplayed() public { @@ -509,7 +509,7 @@ contract CastVetoBySig is LlamaERC721TokenCasterTest { // Invalid Signature error since the recovered signer address during the second call is not the same as // erc721VotesTokenholder // since nonce has increased. - vm.expectRevert(LlamaTokenCaster.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); castVetoBySig(actionInfo, v, r, s); } @@ -519,7 +519,7 @@ contract CastVetoBySig is LlamaERC721TokenCasterTest { // Invalid Signature error since the recovered signer address during the second call is not the same as // erc721VotesTokenholder // since nonce has increased. - vm.expectRevert(LlamaTokenCaster.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); castVetoBySig(actionInfo, v, r, s); } @@ -527,7 +527,7 @@ contract CastVetoBySig is LlamaERC721TokenCasterTest { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(actionInfo, tokenHolder1PrivateKey); // Invalid Signature error since the recovered signer address is zero address due to invalid signature values // (v,r,s). - vm.expectRevert(LlamaTokenCaster.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); castVetoBySig(actionInfo, (v + 1), r, s); } @@ -535,11 +535,11 @@ contract CastVetoBySig is LlamaERC721TokenCasterTest { (uint8 v, bytes32 r, bytes32 s) = createOffchainSignature(actionInfo, tokenHolder1PrivateKey); vm.prank(tokenHolder1); - llamaERC721TokenCaster.incrementNonce(LlamaTokenCaster.castVetoBySig.selector); + llamaERC721TokenGovernor.incrementNonce(LlamaTokenGovernor.castVetoBySig.selector); // Invalid Signature error since the recovered signer address during the second call is not the same as policyholder // since nonce has increased. - vm.expectRevert(LlamaTokenCaster.InvalidSignature.selector); + vm.expectRevert(LlamaTokenGovernor.InvalidSignature.selector); castVetoBySig(actionInfo, v, r, s); } @@ -560,7 +560,7 @@ contract CastVetoBySig is LlamaERC721TokenCasterTest { // Second disapproval. vm.prank(tokenHolder2); - llamaERC721TokenCaster.castVeto(actionInfo, uint8(VoteType.For), ""); + llamaERC721TokenGovernor.castVeto(actionInfo, uint8(VoteType.For), ""); Action memory action = CORE.getAction(actionInfo.id); uint256 delayPeriodEndTime = @@ -568,7 +568,7 @@ contract CastVetoBySig is LlamaERC721TokenCasterTest { uint256 castingPeriodEndTime = delayPeriodEndTime + ((QUEUING_PERIOD * TWO_QUARTERS_IN_BPS) / ONE_HUNDRED_IN_BPS); vm.warp(castingPeriodEndTime + 1); - llamaERC721TokenCaster.submitDisapproval(actionInfo); + llamaERC721TokenGovernor.submitDisapproval(actionInfo); // Assertions. ActionState state = ActionState(CORE.getActionState(actionInfo)); @@ -579,9 +579,9 @@ contract CastVetoBySig is LlamaERC721TokenCasterTest { } } -contract SubmitApprovals is LlamaERC721TokenCasterTest { +contract SubmitApprovals is LlamaTokenGovernorCastingTest { function setUp() public virtual override { - LlamaERC721TokenCasterTest.setUp(); + LlamaTokenGovernorCastingTest.setUp(); _skipVotingDelay(actionInfo); castVotesFor(); @@ -594,23 +594,23 @@ contract SubmitApprovals is LlamaERC721TokenCasterTest { function test_RevertsIf_ActionInfoMismatch(ActionInfo memory notActionInfo) public { vm.assume(notActionInfo.id != actionInfo.id); vm.expectRevert(); - llamaERC721TokenCaster.submitApproval(notActionInfo); + llamaERC721TokenGovernor.submitApproval(notActionInfo); } function test_RevertsIf_AlreadySubmittedApproval() public { vm.startPrank(tokenHolder1); - llamaERC721TokenCaster.submitApproval(actionInfo); + llamaERC721TokenGovernor.submitApproval(actionInfo); // This should revert since the underlying Action has transitioned to Queued state. Otherwise it would have reverted // due to `LlamaCore.DuplicateCast() error`. vm.expectRevert(abi.encodeWithSelector(ILlamaCore.InvalidActionState.selector, ActionState.Queued)); - llamaERC721TokenCaster.submitApproval(actionInfo); + llamaERC721TokenGovernor.submitApproval(actionInfo); } function test_RevertsIf_SubmissionPeriodOver() public { vm.warp(actionCreationTime + APPROVAL_PERIOD + 1); - vm.expectRevert(LlamaTokenCaster.SubmissionPeriodOver.selector); - llamaERC721TokenCaster.submitApproval(actionInfo); + vm.expectRevert(LlamaTokenGovernor.SubmissionPeriodOver.selector); + llamaERC721TokenGovernor.submitApproval(actionInfo); } function test_RevertsIf_InsufficientVotes() public { @@ -619,14 +619,14 @@ contract SubmitApprovals is LlamaERC721TokenCasterTest { uint256 delayPeriodEndTime = action.creationTime + ((APPROVAL_PERIOD * ONE_QUARTER_IN_BPS) / ONE_HUNDRED_IN_BPS); uint256 castingPeriodEndTime = delayPeriodEndTime + ((APPROVAL_PERIOD * TWO_QUARTERS_IN_BPS) / ONE_HUNDRED_IN_BPS); vm.warp(castingPeriodEndTime + 1); - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.InsufficientVotes.selector, 0, 1)); - llamaERC721TokenCaster.submitApproval(_actionInfo); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.InsufficientVotes.selector, 0, 1)); + llamaERC721TokenGovernor.submitApproval(_actionInfo); } function test_RevertsIf_CastingPeriodNotOver() public { vm.warp(block.timestamp - 1); - vm.expectRevert(LlamaTokenCaster.CastingPeriodNotOver.selector); - llamaERC721TokenCaster.submitApproval(actionInfo); + vm.expectRevert(LlamaTokenGovernor.CastingPeriodNotOver.selector); + llamaERC721TokenGovernor.submitApproval(actionInfo); } function test_RevertsIf_ForDoesNotSurpassAgainst() public { @@ -639,27 +639,27 @@ contract SubmitApprovals is LlamaERC721TokenCasterTest { vm.warp(delayPeriodEndTime + 1); vm.prank(tokenHolder1); - llamaERC721TokenCaster.castVote(_actionInfo, uint8(VoteType.For), ""); + llamaERC721TokenGovernor.castVote(_actionInfo, uint8(VoteType.For), ""); vm.prank(tokenHolder2); - llamaERC721TokenCaster.castVote(_actionInfo, uint8(VoteType.Against), ""); + llamaERC721TokenGovernor.castVote(_actionInfo, uint8(VoteType.Against), ""); vm.prank(tokenHolder3); - llamaERC721TokenCaster.castVote(_actionInfo, uint8(VoteType.Against), ""); + llamaERC721TokenGovernor.castVote(_actionInfo, uint8(VoteType.Against), ""); vm.warp(castingPeriodEndTime + 1); - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.ForDoesNotSurpassAgainst.selector, 1, 2)); - llamaERC721TokenCaster.submitApproval(_actionInfo); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.ForDoesNotSurpassAgainst.selector, 1, 2)); + llamaERC721TokenGovernor.submitApproval(_actionInfo); } function test_SubmitsApprovalsCorrectly() public { vm.expectEmit(); emit ApprovalSubmitted(actionInfo.id, address(this), 3, 0, 0); - llamaERC721TokenCaster.submitApproval(actionInfo); + llamaERC721TokenGovernor.submitApproval(actionInfo); } } -contract SubmitDisapprovals is LlamaERC721TokenCasterTest { +contract SubmitDisapprovals is LlamaTokenGovernorCastingTest { function setUp() public virtual override { - LlamaERC721TokenCasterTest.setUp(); + LlamaTokenGovernorCastingTest.setUp(); _skipVotingDelay(actionInfo); castVotesFor(); @@ -668,7 +668,7 @@ contract SubmitDisapprovals is LlamaERC721TokenCasterTest { uint256 castingPeriodEndTime = delayPeriodEndTime + ((APPROVAL_PERIOD * TWO_QUARTERS_IN_BPS) / ONE_HUNDRED_IN_BPS); vm.warp(castingPeriodEndTime + 1); - llamaERC721TokenCaster.submitApproval(actionInfo); + llamaERC721TokenGovernor.submitApproval(actionInfo); _skipVetoDelay(actionInfo); castVetosFor(); @@ -683,24 +683,24 @@ contract SubmitDisapprovals is LlamaERC721TokenCasterTest { function test_RevertsIf_ActionInfoMismatch(ActionInfo memory notActionInfo) public { vm.assume(notActionInfo.id != actionInfo.id); vm.expectRevert(); - llamaERC721TokenCaster.submitDisapproval(notActionInfo); + llamaERC721TokenGovernor.submitDisapproval(notActionInfo); } function test_RevertsIf_AlreadySubmittedDisapproval() public { vm.startPrank(tokenHolder1); - llamaERC721TokenCaster.submitDisapproval(actionInfo); + llamaERC721TokenGovernor.submitDisapproval(actionInfo); // This should revert since the underlying Action has transitioned to Failed state. Otherwise it would have reverted // due to `LlamaCore.DuplicateCast() error`. vm.expectRevert(abi.encodeWithSelector(ILlamaCore.InvalidActionState.selector, ActionState.Failed)); - llamaERC721TokenCaster.submitDisapproval(actionInfo); + llamaERC721TokenGovernor.submitDisapproval(actionInfo); } function test_RevertsIf_SubmissionPeriodOver() public { Action memory action = CORE.getAction(actionInfo.id); vm.warp(action.minExecutionTime); - vm.expectRevert(LlamaTokenCaster.SubmissionPeriodOver.selector); - llamaERC721TokenCaster.submitDisapproval(actionInfo); + vm.expectRevert(LlamaTokenGovernor.SubmissionPeriodOver.selector); + llamaERC721TokenGovernor.submitDisapproval(actionInfo); } function test_RevertsIf_InsufficientDisapprovals() public { @@ -713,14 +713,14 @@ contract SubmitDisapprovals is LlamaERC721TokenCasterTest { vm.warp(delayPeriodEndTime + 1); vm.prank(tokenHolder1); - llamaERC721TokenCaster.castVote(_actionInfo, uint8(VoteType.For), ""); + llamaERC721TokenGovernor.castVote(_actionInfo, uint8(VoteType.For), ""); vm.prank(tokenHolder2); - llamaERC721TokenCaster.castVote(_actionInfo, uint8(VoteType.For), ""); + llamaERC721TokenGovernor.castVote(_actionInfo, uint8(VoteType.For), ""); vm.prank(tokenHolder3); - llamaERC721TokenCaster.castVote(_actionInfo, uint8(VoteType.For), ""); + llamaERC721TokenGovernor.castVote(_actionInfo, uint8(VoteType.For), ""); vm.warp(castingPeriodEndTime + 1); - llamaERC721TokenCaster.submitApproval(_actionInfo); + llamaERC721TokenGovernor.submitApproval(_actionInfo); action = CORE.getAction(_actionInfo.id); @@ -728,14 +728,14 @@ contract SubmitDisapprovals is LlamaERC721TokenCasterTest { (action.minExecutionTime - QUEUING_PERIOD) + ((QUEUING_PERIOD * ONE_QUARTER_IN_BPS) / ONE_HUNDRED_IN_BPS); castingPeriodEndTime = delayPeriodEndTime + ((QUEUING_PERIOD * TWO_QUARTERS_IN_BPS) / ONE_HUNDRED_IN_BPS); vm.warp(castingPeriodEndTime + 1); - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.InsufficientVotes.selector, 0, 1)); - llamaERC721TokenCaster.submitDisapproval(_actionInfo); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.InsufficientVotes.selector, 0, 1)); + llamaERC721TokenGovernor.submitDisapproval(_actionInfo); } function test_RevertsIf_CastingPeriodNotOver() public { vm.warp(block.timestamp - 1); - vm.expectRevert(LlamaTokenCaster.CastingPeriodNotOver.selector); - llamaERC721TokenCaster.submitDisapproval(actionInfo); + vm.expectRevert(LlamaTokenGovernor.CastingPeriodNotOver.selector); + llamaERC721TokenGovernor.submitDisapproval(actionInfo); } function test_RevertsIf_ForDoesNotSurpassAgainst() public { @@ -748,14 +748,14 @@ contract SubmitDisapprovals is LlamaERC721TokenCasterTest { vm.warp(delayPeriodEndTime + 1); vm.prank(tokenHolder1); - llamaERC721TokenCaster.castVote(_actionInfo, uint8(VoteType.For), ""); + llamaERC721TokenGovernor.castVote(_actionInfo, uint8(VoteType.For), ""); vm.prank(tokenHolder2); - llamaERC721TokenCaster.castVote(_actionInfo, uint8(VoteType.For), ""); + llamaERC721TokenGovernor.castVote(_actionInfo, uint8(VoteType.For), ""); vm.prank(tokenHolder3); - llamaERC721TokenCaster.castVote(_actionInfo, uint8(VoteType.For), ""); + llamaERC721TokenGovernor.castVote(_actionInfo, uint8(VoteType.For), ""); vm.warp(castingPeriodEndTime + 1); - llamaERC721TokenCaster.submitApproval(_actionInfo); + llamaERC721TokenGovernor.submitApproval(_actionInfo); action = CORE.getAction(_actionInfo.id); @@ -766,42 +766,42 @@ contract SubmitDisapprovals is LlamaERC721TokenCasterTest { vm.warp(delayPeriodEndTime + 1); vm.prank(tokenHolder1); - llamaERC721TokenCaster.castVeto(_actionInfo, uint8(VoteType.For), ""); + llamaERC721TokenGovernor.castVeto(_actionInfo, uint8(VoteType.For), ""); vm.prank(tokenHolder2); - llamaERC721TokenCaster.castVeto(_actionInfo, uint8(VoteType.Against), ""); + llamaERC721TokenGovernor.castVeto(_actionInfo, uint8(VoteType.Against), ""); vm.prank(tokenHolder3); - llamaERC721TokenCaster.castVeto(_actionInfo, uint8(VoteType.Against), ""); + llamaERC721TokenGovernor.castVeto(_actionInfo, uint8(VoteType.Against), ""); vm.warp(castingPeriodEndTime + 1); - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.ForDoesNotSurpassAgainst.selector, 1, 2)); - llamaERC721TokenCaster.submitDisapproval(_actionInfo); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.ForDoesNotSurpassAgainst.selector, 1, 2)); + llamaERC721TokenGovernor.submitDisapproval(_actionInfo); } function test_SubmitsDisapprovalsCorrectly() public { vm.expectEmit(); emit DisapprovalSubmitted(actionInfo.id, address(this), 3, 0, 0); - llamaERC721TokenCaster.submitDisapproval(actionInfo); + llamaERC721TokenGovernor.submitDisapproval(actionInfo); } } -contract SetQuorumPct is LlamaERC721TokenCasterTest { +contract SetQuorumPct is LlamaTokenGovernorCastingTest { function test_RevertsIf_NotLlamaExecutor(address notLlamaExecutor) public { vm.assume(notLlamaExecutor != address(EXECUTOR)); - vm.expectRevert(LlamaTokenCaster.OnlyLlamaExecutor.selector); + vm.expectRevert(LlamaTokenGovernor.OnlyLlamaExecutor.selector); vm.prank(notLlamaExecutor); - llamaERC721TokenCaster.setQuorumPct(ERC721_VOTE_QUORUM_PCT, ERC721_VETO_QUORUM_PCT); + llamaERC721TokenGovernor.setQuorumPct(ERC721_VOTE_QUORUM_PCT, ERC721_VETO_QUORUM_PCT); } function test_RevertsIf_InvalidQuorumPct() public { vm.startPrank(address(EXECUTOR)); - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.InvalidVetoQuorumPct.selector, uint256(0))); - llamaERC721TokenCaster.setQuorumPct(ERC721_VOTE_QUORUM_PCT, 0); - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.InvalidVoteQuorumPct.selector, uint256(0))); - llamaERC721TokenCaster.setQuorumPct(0, ERC721_VETO_QUORUM_PCT); - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.InvalidVetoQuorumPct.selector, uint256(10_001))); - llamaERC721TokenCaster.setQuorumPct(ERC721_VOTE_QUORUM_PCT, 10_001); - vm.expectRevert(abi.encodeWithSelector(LlamaTokenCaster.InvalidVoteQuorumPct.selector, uint256(10_001))); - llamaERC721TokenCaster.setQuorumPct(10_001, ERC721_VETO_QUORUM_PCT); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.InvalidVetoQuorumPct.selector, uint256(0))); + llamaERC721TokenGovernor.setQuorumPct(ERC721_VOTE_QUORUM_PCT, 0); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.InvalidVoteQuorumPct.selector, uint256(0))); + llamaERC721TokenGovernor.setQuorumPct(0, ERC721_VETO_QUORUM_PCT); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.InvalidVetoQuorumPct.selector, uint256(10_001))); + llamaERC721TokenGovernor.setQuorumPct(ERC721_VOTE_QUORUM_PCT, 10_001); + vm.expectRevert(abi.encodeWithSelector(LlamaTokenGovernor.InvalidVoteQuorumPct.selector, uint256(10_001))); + llamaERC721TokenGovernor.setQuorumPct(10_001, ERC721_VETO_QUORUM_PCT); vm.stopPrank(); } @@ -811,16 +811,16 @@ contract SetQuorumPct is LlamaERC721TokenCasterTest { vm.expectEmit(); emit QuorumPctSet(_voteQuorum, _vetoQuorum); vm.prank(address(EXECUTOR)); - llamaERC721TokenCaster.setQuorumPct(_voteQuorum, _vetoQuorum); + llamaERC721TokenGovernor.setQuorumPct(_voteQuorum, _vetoQuorum); } } -contract SetPeriodPct is LlamaERC721TokenCasterTest { +contract SetPeriodPct is LlamaTokenGovernorCastingTest { function test_RevertsIf_NotLlamaExecutor(address notLlamaExecutor) public { vm.assume(notLlamaExecutor != address(EXECUTOR)); - vm.expectRevert(LlamaTokenCaster.OnlyLlamaExecutor.selector); + vm.expectRevert(LlamaTokenGovernor.OnlyLlamaExecutor.selector); vm.prank(notLlamaExecutor); - llamaERC721TokenCaster.setPeriodPct( + llamaERC721TokenGovernor.setPeriodPct( uint16(ONE_QUARTER_IN_BPS), uint16(TWO_QUARTERS_IN_BPS), uint16(ONE_QUARTER_IN_BPS) ); } @@ -829,24 +829,24 @@ contract SetPeriodPct is LlamaERC721TokenCasterTest { vm.startPrank(address(EXECUTOR)); vm.expectRevert( abi.encodeWithSelector( - LlamaTokenCaster.InvalidPeriodPcts.selector, + LlamaTokenGovernor.InvalidPeriodPcts.selector, uint16(ONE_QUARTER_IN_BPS), uint16(TWO_QUARTERS_IN_BPS), uint16(ONE_QUARTER_IN_BPS) + 1 ) ); - llamaERC721TokenCaster.setPeriodPct( + llamaERC721TokenGovernor.setPeriodPct( uint16(ONE_QUARTER_IN_BPS), uint16(TWO_QUARTERS_IN_BPS), uint16(ONE_QUARTER_IN_BPS) + 1 ); vm.expectRevert( abi.encodeWithSelector( - LlamaTokenCaster.InvalidPeriodPcts.selector, + LlamaTokenGovernor.InvalidPeriodPcts.selector, uint16(ONE_QUARTER_IN_BPS), uint16(TWO_QUARTERS_IN_BPS), uint16(ONE_QUARTER_IN_BPS) - 1 ) ); - llamaERC721TokenCaster.setPeriodPct( + llamaERC721TokenGovernor.setPeriodPct( uint16(ONE_QUARTER_IN_BPS), uint16(TWO_QUARTERS_IN_BPS), uint16(ONE_QUARTER_IN_BPS) - 1 ); vm.stopPrank(); @@ -856,15 +856,15 @@ contract SetPeriodPct is LlamaERC721TokenCasterTest { vm.expectEmit(); emit PeriodPctSet(uint16(ONE_QUARTER_IN_BPS), uint16(TWO_QUARTERS_IN_BPS), uint16(ONE_QUARTER_IN_BPS)); vm.prank(address(EXECUTOR)); - llamaERC721TokenCaster.setPeriodPct( + llamaERC721TokenGovernor.setPeriodPct( uint16(ONE_QUARTER_IN_BPS), uint16(TWO_QUARTERS_IN_BPS), uint16(ONE_QUARTER_IN_BPS) ); } } -contract CastData is LlamaERC721TokenCasterTest { +contract CastData is LlamaTokenGovernorCastingTest { function setUp() public virtual override { - LlamaERC721TokenCasterTest.setUp(); + LlamaTokenGovernorCastingTest.setUp(); _skipVotingDelay(actionInfo); castVotesFor(); @@ -873,7 +873,7 @@ contract CastData is LlamaERC721TokenCasterTest { uint256 castingPeriodEndTime = delayPeriodEndTime + ((APPROVAL_PERIOD * TWO_QUARTERS_IN_BPS) / ONE_HUNDRED_IN_BPS); vm.warp(castingPeriodEndTime + 1); - llamaERC721TokenCaster.submitApproval(actionInfo); + llamaERC721TokenGovernor.submitApproval(actionInfo); _skipVetoDelay(actionInfo); castVetosFor(); @@ -884,7 +884,7 @@ contract CastData is LlamaERC721TokenCasterTest { castingPeriodEndTime = delayPeriodEndTime + ((QUEUING_PERIOD * TWO_QUARTERS_IN_BPS) / ONE_HUNDRED_IN_BPS); vm.warp(castingPeriodEndTime + 1); - llamaERC721TokenCaster.submitDisapproval(actionInfo); + llamaERC721TokenGovernor.submitDisapproval(actionInfo); } function test_CanGetCastData() public { @@ -895,7 +895,7 @@ contract CastData is LlamaERC721TokenCasterTest { uint128 vetoesFor, uint128 vetoesAbstain, uint128 vetoesAgainst - ) = llamaERC721TokenCaster.casts(actionInfo.id); + ) = llamaERC721TokenGovernor.casts(actionInfo.id); assertEq(votesFor, 3); assertEq(votesAbstain, 0); assertEq(votesAgainst, 0); @@ -903,13 +903,13 @@ contract CastData is LlamaERC721TokenCasterTest { assertEq(vetoesAbstain, 0); assertEq(vetoesAgainst, 0); - assertTrue(llamaERC721TokenCaster.hasTokenHolderCast(actionInfo.id, tokenHolder1, true)); - assertTrue(llamaERC721TokenCaster.hasTokenHolderCast(actionInfo.id, tokenHolder2, true)); - assertTrue(llamaERC721TokenCaster.hasTokenHolderCast(actionInfo.id, tokenHolder3, true)); - assertFalse(llamaERC721TokenCaster.hasTokenHolderCast(actionInfo.id, notTokenHolder, true)); - assertTrue(llamaERC721TokenCaster.hasTokenHolderCast(actionInfo.id, tokenHolder1, false)); - assertTrue(llamaERC721TokenCaster.hasTokenHolderCast(actionInfo.id, tokenHolder2, false)); - assertTrue(llamaERC721TokenCaster.hasTokenHolderCast(actionInfo.id, tokenHolder3, false)); - assertFalse(llamaERC721TokenCaster.hasTokenHolderCast(actionInfo.id, notTokenHolder, false)); + assertTrue(llamaERC721TokenGovernor.hasTokenHolderCast(actionInfo.id, tokenHolder1, true)); + assertTrue(llamaERC721TokenGovernor.hasTokenHolderCast(actionInfo.id, tokenHolder2, true)); + assertTrue(llamaERC721TokenGovernor.hasTokenHolderCast(actionInfo.id, tokenHolder3, true)); + assertFalse(llamaERC721TokenGovernor.hasTokenHolderCast(actionInfo.id, notTokenHolder, true)); + assertTrue(llamaERC721TokenGovernor.hasTokenHolderCast(actionInfo.id, tokenHolder1, false)); + assertTrue(llamaERC721TokenGovernor.hasTokenHolderCast(actionInfo.id, tokenHolder2, false)); + assertTrue(llamaERC721TokenGovernor.hasTokenHolderCast(actionInfo.id, tokenHolder3, false)); + assertFalse(llamaERC721TokenGovernor.hasTokenHolderCast(actionInfo.id, notTokenHolder, false)); } }