-
Notifications
You must be signed in to change notification settings - Fork 5
/
LlamaRelativeUniqueHolderQuorum.sol
64 lines (55 loc) · 2.71 KB
/
LlamaRelativeUniqueHolderQuorum.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
import {ILlamaStrategy} from "src/interfaces/ILlamaStrategy.sol";
import {ActionInfo} from "src/lib/Structs.sol";
import {LlamaCore} from "src/LlamaCore.sol";
import {LlamaRelativeStrategyBase} from "src/strategies/relative/LlamaRelativeStrategyBase.sol";
/// @title Llama Relative Unique Holder Quorum Strategy
/// @author Llama (devsdosomething@llama.xyz)
/// @notice This is a Llama strategy which has the following properties:
/// - Approval/disapproval thresholds are specified as percentages of total supply.
/// - Action creators are allowed to cast approvals or disapprovals on their own actions within this strategy.
/// - The approval and disapproval role holder supplies are saved at action creation time and used to calculate that
/// action's quorum.
/// - Policyholders with the corresponding approval or disapproval role have a cast weight of 1.
contract LlamaRelativeUniqueHolderQuorum is LlamaRelativeStrategyBase {
// -------- When Casting Approval --------
/// @inheritdoc ILlamaStrategy
function getApprovalQuantityAt(address policyholder, uint8 role, uint256 timestamp)
external
view
override
returns (uint96)
{
if (role != approvalRole && !forceApprovalRole[role]) return 0;
uint96 quantity = policy.getPastQuantity(policyholder, role, timestamp);
if (quantity == 0) return 0;
return forceApprovalRole[role] ? type(uint96).max : 1;
}
// -------- When Casting Disapproval --------
/// @inheritdoc ILlamaStrategy
function getDisapprovalQuantityAt(address policyholder, uint8 role, uint256 timestamp)
external
view
override
returns (uint96)
{
if (role != disapprovalRole && !forceDisapprovalRole[role]) return 0;
uint96 quantity = policy.getPastQuantity(policyholder, role, timestamp);
if (quantity == 0) return 0;
return forceDisapprovalRole[role] ? type(uint96).max : 1;
}
// -------- At Action Creation and When Determining Action State --------
/// @inheritdoc LlamaRelativeStrategyBase
function getApprovalSupply(ActionInfo calldata actionInfo) public view override returns (uint96) {
uint256 creationTime = llamaCore.getAction(actionInfo.id).creationTime;
if (creationTime == 0) revert InvalidActionInfo();
return policy.getPastRoleSupplyAsNumberOfHolders(approvalRole, creationTime - 1);
}
/// @inheritdoc LlamaRelativeStrategyBase
function getDisapprovalSupply(ActionInfo calldata actionInfo) public view override returns (uint96) {
uint256 creationTime = llamaCore.getAction(actionInfo.id).creationTime;
if (creationTime == 0) revert InvalidActionInfo();
return policy.getPastRoleSupplyAsNumberOfHolders(disapprovalRole, creationTime - 1);
}
}