Skip to content
This repository has been archived by the owner on Nov 27, 2024. It is now read-only.

refactor: caster initializes with caster config #70

Merged
merged 27 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/lib/PeriodPctCheckpoints.sol
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ library PeriodPctCheckpoints {
* `timestamp`.
*/
function push(History storage self, uint16 delayPeriodPct, uint16 castingPeriodPct, uint16 submissionPeriodPct) internal {
return _insert(self._checkpoints, LlamaUtils.toUint48(block.timestamp), LlamaUtils.toUint16(delayPeriodPct), LlamaUtils.toUint16(castingPeriodPct), LlamaUtils.toUint16(submissionPeriodPct));
_insert(self._checkpoints, LlamaUtils.toUint48(block.timestamp), LlamaUtils.toUint16(delayPeriodPct), LlamaUtils.toUint16(castingPeriodPct), LlamaUtils.toUint16(submissionPeriodPct));
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/lib/QuorumCheckpoints.sol
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ library QuorumCheckpoints {
* accidentally introducing a bug or breaking change.
*/
function push(History storage self, uint256 vetoQuorumPct, uint256 voteQuorumPct) internal {
return _insert(self._checkpoints, LlamaUtils.toUint48(block.timestamp), LlamaUtils.toUint16(voteQuorumPct), LlamaUtils.toUint16(vetoQuorumPct));
_insert(self._checkpoints, LlamaUtils.toUint48(block.timestamp), LlamaUtils.toUint16(voteQuorumPct), LlamaUtils.toUint16(vetoQuorumPct));
}

/**
Expand Down
9 changes: 9 additions & 0 deletions src/lib/Structs.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ struct Action {
uint96 totalDisapprovals; // The total quantity of policyholder disapprovals.
}

/// @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.
Expand Down
12 changes: 5 additions & 7 deletions src/token-voting/LlamaTokenCaster.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {FixedPointMathLib} from "@solmate/utils/FixedPointMathLib.sol";
import {ILlamaCore} from "src/interfaces/ILlamaCore.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 {LlamaUtils} from "src/lib/LlamaUtils.sol";
import {PeriodPctCheckpoints} from "src/lib/PeriodPctCheckpoints.sol";
import {QuorumCheckpoints} from "src/lib/QuorumCheckpoints.sol";
Expand Down Expand Up @@ -202,24 +203,21 @@ contract LlamaTokenCaster is Initializable {
/// The `initializer` modifier ensures that this function can be invoked at most once.
/// @param _llamaCore The `LlamaCore` contract for this Llama instance.
/// @param _role The role used by this contract to cast approvals and disapprovals.
/// @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`.

/// @param casterConfig Contains the quorum and period pct values to initialize the contract with.
function initialize(
ILlamaCore _llamaCore,
ILlamaTokenAdapter _tokenAdapter,
uint8 _role,
uint16 _voteQuorumPct,
uint16 _vetoQuorumPct
CasterConfig memory casterConfig
) external initializer {
if (_llamaCore.actionsCount() < 0) revert InvalidLlamaCoreAddress();
if (_role > _llamaCore.policy().numRoles()) revert RoleNotInitialized(_role);

llamaCore = _llamaCore;
tokenAdapter = _tokenAdapter;
role = _role;
_setQuorumPct(_voteQuorumPct, _vetoQuorumPct);
_setPeriodPcts(2500, 5000, 2500); // default to 25% delay, 50% casting, 25% submission periods
_setQuorumPct(casterConfig.voteQuorumPct, casterConfig.vetoQuorumPct);
_setPeriodPcts(casterConfig.delayPeriodPct, casterConfig.castingPeriodPct, casterConfig.submissionPeriodPct);
}

// ===========================================
Expand Down
10 changes: 3 additions & 7 deletions src/token-voting/LlamaTokenVotingFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity ^0.8.23;
import {Clones} from "@openzeppelin/proxy/Clones.sol";

import {ILlamaCore} from "src/interfaces/ILlamaCore.sol";
import {CasterConfig} 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";
Expand All @@ -25,8 +26,7 @@ contract LlamaTokenVotingFactory {
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.
uint16 voteQuorumPct; // The minimum percentage of tokens required to approve an action.
uint16 vetoQuorumPct; // The minimum percentage of tokens required to disapprove an action.
CasterConfig casterConfig; // The quorum and period data for the `LlamaTokenCaster`.
}

// ========================
Expand Down Expand Up @@ -112,11 +112,7 @@ contract LlamaTokenVotingFactory {
caster = LlamaTokenCaster(Clones.cloneDeterministic(address(LLAMA_TOKEN_CASTER_LOGIC), salt));

caster.initialize(
tokenVotingConfig.llamaCore,
tokenAdapter,
tokenVotingConfig.casterRole,
tokenVotingConfig.voteQuorumPct,
tokenVotingConfig.vetoQuorumPct
tokenVotingConfig.llamaCore, tokenAdapter, tokenVotingConfig.casterRole, tokenVotingConfig.casterConfig
);

emit LlamaTokenVotingInstanceCreated(
Expand Down
8 changes: 4 additions & 4 deletions test/token-voting/LlamaERC20TokenCaster.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ contract CastVote is LlamaERC20TokenCasterTest {
)
);
ILlamaTokenAdapter tokenAdapter = createTimestampTokenAdapter(address(erc20VotesToken), 0);
casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, ERC20_VOTE_QUORUM_PCT, ERC20_VETO_QUORUM_PCT);
casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, defaultCasterConfig);

vm.expectRevert(abi.encodeWithSelector(ILlamaRelativeStrategyBase.InvalidRole.selector, tokenVotingCasterRole));
casterWithWrongRole.castVote(actionInfo, uint8(VoteType.For), "");
Expand Down Expand Up @@ -341,7 +341,7 @@ contract CastVeto is LlamaERC20TokenCasterTest {
)
);
ILlamaTokenAdapter tokenAdapter = createTimestampTokenAdapter(address(erc20VotesToken), 0);
casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, ERC20_VOTE_QUORUM_PCT, ERC20_VETO_QUORUM_PCT);
casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, defaultCasterConfig);

vm.expectRevert(abi.encodeWithSelector(ILlamaRelativeStrategyBase.InvalidRole.selector, tokenVotingCasterRole));
casterWithWrongRole.castVeto(actionInfo, uint8(VoteType.For), "");
Expand Down Expand Up @@ -602,7 +602,7 @@ contract SubmitApprovals is LlamaERC20TokenCasterTest {
)
);
ILlamaTokenAdapter tokenAdapter = createTimestampTokenAdapter(address(erc20VotesToken), 0);
casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, ERC20_VOTE_QUORUM_PCT, ERC20_VETO_QUORUM_PCT);
casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, defaultCasterConfig);
vm.expectRevert(abi.encodeWithSelector(ILlamaRelativeStrategyBase.InvalidRole.selector, tokenVotingCasterRole));
casterWithWrongRole.submitApproval(actionInfo);
}
Expand Down Expand Up @@ -686,7 +686,7 @@ contract SubmitDisapprovals is LlamaERC20TokenCasterTest {
)
);
ILlamaTokenAdapter tokenAdapter = createTimestampTokenAdapter(address(erc20VotesToken), 0);
casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, ERC20_VOTE_QUORUM_PCT, ERC20_VETO_QUORUM_PCT);
casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, defaultCasterConfig);
vm.expectRevert(abi.encodeWithSelector(ILlamaRelativeStrategyBase.InvalidRole.selector, tokenVotingCasterRole));
casterWithWrongRole.submitDisapproval(actionInfo);
}
Expand Down
8 changes: 4 additions & 4 deletions test/token-voting/LlamaERC721TokenCaster.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ contract CastVote is LlamaERC721TokenCasterTest {
)
);

casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, ERC721_VOTE_QUORUM_PCT, ERC721_VETO_QUORUM_PCT);
casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, defaultCasterConfig);

vm.expectRevert(abi.encodeWithSelector(ILlamaRelativeStrategyBase.InvalidRole.selector, tokenVotingCasterRole));
casterWithWrongRole.castVote(actionInfo, uint8(VoteType.For), "");
Expand Down Expand Up @@ -344,7 +344,7 @@ contract CastVeto is LlamaERC721TokenCasterTest {
address(llamaTokenCasterLogic), keccak256(abi.encodePacked(address(erc721VotesToken), msg.sender))
)
);
casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, ERC721_VOTE_QUORUM_PCT, ERC721_VETO_QUORUM_PCT);
casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, defaultCasterConfig);

vm.expectRevert(abi.encodeWithSelector(ILlamaRelativeStrategyBase.InvalidRole.selector, tokenVotingCasterRole));
casterWithWrongRole.castVeto(actionInfo, uint8(VoteType.For), "");
Expand Down Expand Up @@ -604,7 +604,7 @@ contract SubmitApprovals is LlamaERC721TokenCasterTest {
address(llamaTokenCasterLogic), keccak256(abi.encodePacked(address(erc721VotesToken), msg.sender))
)
);
casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, ERC721_VOTE_QUORUM_PCT, ERC721_VETO_QUORUM_PCT);
casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, defaultCasterConfig);
vm.expectRevert(abi.encodeWithSelector(ILlamaRelativeStrategyBase.InvalidRole.selector, tokenVotingCasterRole));
casterWithWrongRole.submitApproval(actionInfo);
}
Expand Down Expand Up @@ -688,7 +688,7 @@ contract SubmitDisapprovals is LlamaERC721TokenCasterTest {
)
);
ILlamaTokenAdapter tokenAdapter = createTimestampTokenAdapter(address(erc721VotesToken), 0);
casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, ERC721_VOTE_QUORUM_PCT, ERC721_VETO_QUORUM_PCT);
casterWithWrongRole.initialize(CORE, tokenAdapter, madeUpRole, defaultCasterConfig);
vm.expectRevert(abi.encodeWithSelector(ILlamaRelativeStrategyBase.InvalidRole.selector, tokenVotingCasterRole));
casterWithWrongRole.submitDisapproval(actionInfo);
}
Expand Down
17 changes: 6 additions & 11 deletions test/token-voting/LlamaTokenVotingFactory.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {Clones} from "@openzeppelin/proxy/Clones.sol";

import {LlamaTokenVotingTestSetup} from "test/token-voting/LlamaTokenVotingTestSetup.sol";

import {ActionInfo} from "src/lib/Structs.sol";
import {ActionInfo, CasterConfig} from "src/lib/Structs.sol";
import {ILlamaCore} from "src/interfaces/ILlamaCore.sol";
import {ILlamaPolicy} from "src/interfaces/ILlamaPolicy.sol";
import {ILlamaTokenAdapter} from "src/token-voting/interfaces/ILlamaTokenAdapter.sol";
Expand Down Expand Up @@ -89,8 +89,7 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest {
tokenVotingActionCreatorRole,
tokenVotingCasterRole,
ERC20_CREATION_THRESHOLD,
ERC20_VOTE_QUORUM_PCT,
ERC20_VETO_QUORUM_PCT
defaultCasterConfig
);

// Set up action to call `deploy` with the ERC20 token.
Expand Down Expand Up @@ -165,8 +164,7 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest {
tokenVotingActionCreatorRole,
tokenVotingCasterRole,
ERC721_CREATION_THRESHOLD,
ERC721_VOTE_QUORUM_PCT,
ERC721_VETO_QUORUM_PCT
defaultCasterConfig
);

// Set up action to call `deploy` with the ERC721 token.
Expand Down Expand Up @@ -288,8 +286,7 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest {
tokenVotingActionCreatorRole,
tokenVotingCasterRole,
ERC20_CREATION_THRESHOLD,
ERC20_VOTE_QUORUM_PCT,
ERC20_VETO_QUORUM_PCT
defaultCasterConfig
);

vm.prank(randomCaller);
Expand Down Expand Up @@ -321,8 +318,7 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest {
tokenVotingActionCreatorRole,
tokenVotingCasterRole,
ERC20_CREATION_THRESHOLD,
ERC20_VOTE_QUORUM_PCT,
ERC20_VETO_QUORUM_PCT
defaultCasterConfig
);

// Set up action to call `deploy` with the ERC20 token.
Expand Down Expand Up @@ -385,8 +381,7 @@ contract DeployTokenVotingModule is LlamaTokenVotingFactoryTest {
tokenVotingActionCreatorRole,
tokenVotingCasterRole,
ERC20_CREATION_THRESHOLD,
ERC20_VOTE_QUORUM_PCT,
ERC20_VETO_QUORUM_PCT
defaultCasterConfig
);

// Set up action to call `deploy` with the ERC20 token.
Expand Down
18 changes: 13 additions & 5 deletions test/token-voting/LlamaTokenVotingTestSetup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {LlamaPeripheryTestSetup} from "test/LlamaPeripheryTestSetup.sol";

import {DeployLlamaTokenVotingFactory} from "script/DeployLlamaTokenVotingFactory.s.sol";

import {ActionInfo} from "src/lib/Structs.sol";
import {ActionInfo, CasterConfig} from "src/lib/Structs.sol";
import {ILlamaPolicy} from "src/interfaces/ILlamaPolicy.sol";
import {ILlamaRelativeStrategyBase} from "src/interfaces/ILlamaRelativeStrategyBase.sol";
import {ILlamaStrategy} from "src/interfaces/ILlamaStrategy.sol";
Expand Down Expand Up @@ -41,6 +41,8 @@ contract LlamaTokenVotingTestSetup is LlamaPeripheryTestSetup, DeployLlamaTokenV
MockERC20Votes public erc20VotesToken;
MockERC721Votes public erc721VotesToken;

CasterConfig public defaultCasterConfig;

// Token Voting Roles
uint8 tokenVotingActionCreatorRole;
uint8 tokenVotingCasterRole;
Expand Down Expand Up @@ -68,6 +70,14 @@ contract LlamaTokenVotingTestSetup is LlamaPeripheryTestSetup, DeployLlamaTokenV
erc20VotesToken = new MockERC20Votes();
erc721VotesToken = new MockERC721Votes();

defaultCasterConfig = CasterConfig({
voteQuorumPct: ERC20_VOTE_QUORUM_PCT,
vetoQuorumPct: ERC20_VETO_QUORUM_PCT,
delayPeriodPct: uint16(ONE_QUARTER_IN_BPS),
castingPeriodPct: uint16(TWO_QUARTERS_IN_BPS),
submissionPeriodPct: uint16(ONE_QUARTER_IN_BPS)
});

//Deploy

// Setting up tokenholder addresses and private keys.
Expand Down Expand Up @@ -102,8 +112,7 @@ contract LlamaTokenVotingTestSetup is LlamaPeripheryTestSetup, DeployLlamaTokenV
tokenVotingActionCreatorRole,
tokenVotingCasterRole,
ERC20_CREATION_THRESHOLD,
ERC20_VOTE_QUORUM_PCT,
ERC20_VETO_QUORUM_PCT
defaultCasterConfig
);

vm.startPrank(address(EXECUTOR));
Expand Down Expand Up @@ -132,8 +141,7 @@ contract LlamaTokenVotingTestSetup is LlamaPeripheryTestSetup, DeployLlamaTokenV
tokenVotingActionCreatorRole,
tokenVotingCasterRole,
ERC721_CREATION_THRESHOLD,
ERC721_VOTE_QUORUM_PCT,
ERC721_VETO_QUORUM_PCT
defaultCasterConfig
);

vm.startPrank(address(EXECUTOR));
Expand Down
Loading