Spec: CV Proposal Strategy ---- ### Overview *Provide a brief overview of the strategy and its purpose. Describe the high-level flow of how recipients are registered, allocations, and how tokens are distributed.* Conviction Voting (CV) is a strategy that enables bottom-up governance of a shared pool of funds. The purpose is to allocate community funding more efficiently by making it easier for capable and honest people to get the resources they need to contribute to the community. In CV, the amount of support needed to approve a funding proposal scales with the amount of funding being requested, and the weight of someone's support ("conviction") grows over time as they continue to support a proposal. Proposals are disputable and can be escalated to a judicial system that rules on whether to block funding because the proposal violates the community's shared set of values. Anyone staking tokens in the community's covenant can create a proposal - a deposit is required to create a proposal which is forfeited only if the proposal is disputed and ruled as blocked. There are 3 types of proposals: 1. Funding Proposals 2. Streaming Proposals 3. Signalling Proposals **Funding Proposals** A discrete amount of funding is requested. The amount of conviction needed to pass is determined by the amount of funding requested, as well as the minimum conviction and spending limit set by the community. When a funding proposal reaches enough conviction to pass without being disputed, anyone can execute and all requested funds are distributed. **Streaming Proposals** A stream of funding is requested. The amount of tokens streamed is determined by the amount of conviction staked in the proposal, as well as a minimum conviction for a stream to start and a maximum total streaming amount set by the community. Tokens are wrapped and streamed through Superfluid and recipients receive Super tokens. **Signalling Proposals** No funding is requested - this simply indicates a community's support for an idea, and since conviction needed to pass is a function of total support across all proposals, it can also be used to oppose funding proposals by making it more difficult for them to pass (i.e. an "abstain proposal") To summarize the logic in Allo terms: - Recipients here are treated as Proposal creator, distinct from the beneficiary which the recipient can set as any address. - Proposals are registered if the creator (msg.sender) meets staking and deposit requirements - Proposals can be challenged and sent to Tribunal or Safe to be settled or appealed. - Proposals can be cancelled by the creator (msg.sender) who registered it initially. - Proposals can have a beneficiary address different from the creator (msg.sender). - Anyone can execute a Funding Proposal when conviction surpasses threshold and status /= challenged - Streaming Proposals receive Super Tokens which Recipients can unwrap their accrued balance at any time - Contract has parameters defined at setup that affect calculations: Mininum Conviction, Spending limit, Conviction Growth/Decay Speed, Minimum Streaming Conviction, Max Streaming Spending, Deposit Amount [Config Calculator for reference](https://config.tecommons.org/config/4) #### Contracts that are used by the CVProposal Strategy **CommunityCovenant** contract (1 for each community): - A contract people can stake tokens in and become supporters of the community - IPFS of Covenant text is attached - Contract holds registries of all pools, treasury sources, supporters, tribunals, and council safe connected to that community. >list of proposals challenged with status - this will hold status for all connected Allo strategies? >admin permissions - how to give council safe permissions to edit CV parameters? ## General Specifications ### Recipient Logic Explain the logic for determining how recipients are added to the strategy's pool. This should include how the eligibility of a recipient is determined, the logic for registering eligible recipients, the recipient status workflow (including a list of available statuses such as `None`, `Pending`, `Accepted`, `Rejected`), and the conditions under which status changes. . Specify any custom functions or conditions that will be required. #### Questions to answer - **Recipient eligibility** - What criteria determine the eligibility of a recipient to register in this strategy? Are there any specific requirements or conditions? **A:** **1. Recipient Creator has staked required minimum tokens in CommunityCovenant** **2. Recipient Creator submits required deposit** **3. Deposit can be lost if proposal(recipient) disputed successfully. This lost deposit will be transferred to the CV pool** - Are there any additional custom functions or conditions for verifying recipient eligibility? **A: All required proposal information is submitted:** * **If optional whitelist is selected, check that registerRecipient() sender is included in the whitelist** * **Proposal Type, beneficiary address (except for signalling proposal)** * **amount requested (if funding Proposal)** * **link to proposal discussion.** - **Recipient information** - How does a recipient identify themselves? Is it through an address like msg.sender, do they need an profile registered at the `Registry` contract, or another mechanism? **A: through msg.sender, no profile is needed** - If through the Registry, can the pool creator set a custom registry? **N/A** - Which address is returned by `registerRecipient` and represents the `recipientId`? **A: A proposalID should be returned as uint160 cast to address type, because its enforced to be address or the beneficiary address should be returned** - Can the address that receives the funds be different from the recipient's profile? **A: Yes** - What additional data is needed and passed during the registration process, apart from the recipient's address? **A: - amount fund requested (on chain) - beneficiaryAddress (on chain) - creatorAddress(msg.sender) (emit event for subgraph) - link to discussion - proposal type (funding, streaming signaling)** - **add description(ipfs hash on chain)** - **Registering recipients** - Is the `registerRecipient` function accessible to anyone, or is it restricted to specific roles or addresses? **A: Restricted for specific addresses staked in the CommunityCovenant** - Are there any specific conditions under which the `registerRecipient` function can or cannot be called? - **Require that msg.sender have enough deposit amount** - **Require msg.sender (caller/creatorAddress) isn't zero address** - **Require some description/forum url** - **Amount need be higher than 0 and lower than Spending Limit(set on creation) is defined (eg: 20% of Common Pool)** - **If caller isn't part of registry** - **If this strategy isn't part of a garden allowed strategies** - How does the strategy handle ineligible registrations? Are they automatically rejected, or is there a specific process in place? - **An ineligible registration should be automatically rejected with a msg error** - Does the pool manager need to approve the registration, or is it automatically approved? - If automatically, how? Describe in detail. - **B: Should be approved automatically if all conditions are met (stake and deposit)** - If manually, how? Who needs to approve? **N/A** - Are there any limits on the number of recipients that can be registered? If so, what are those limits and how are they enforced? **A: No, only if that could be make the contracts gas efficient.** - Are multiple registrations for a recipient allowed or just one? **A: Yes, a recipient (proposal) can be created multiple times by the same creator** - What happens in case of a second registration, either in the case of a single registration or multiple registrations? **A: That creates a new proposal (recipient)** - What steps are involved in changing the recipient's status from one state to another? **A: So the proposal can have 4 status:** - **Active** - This is the initial status, also can be after Paused status - conviction is accruing - people can add and remove support from recipient - **Paused** - Happens when recipient is being challenged, or for streaming proposal, paused by creator - Funding Proposal: cannot be executed - Streaming Proposal: token streaming is stopped - **Cancelled** - can no longer add support to a proposal, support can still be removed - For funding Proposal: proposal can never be executed - For streaming proposal: token stream is stopped and can't be restarted - **Executed** - Funds have been distributed (funding proposals only) - Are there any additional functions available to check or modify the recipient's status? **A: We need:** - cancelProposal() that can be called only by the CANCEABLE_ROLE set to creator and Tribunal (slashing creator) - The innner function as \_cancelProposal also can be called after all the staked points voted are withdrawed. - activeProposal() that can be called only by the ACTIVEABLE_ROLE set to creator and Tribunal - ### Allocation Logic Explain the logic for how the strategy will allow eligible allocators to express an opinion about how the pool's funds should be allocated. This should include how allocators are determined to be eligible, the logic for the allocate function, and any special considerations or conditions. #### Questions to answer - **Allocator Eligibility** - How is the eligibility of an allocator determined in this strategy? Is it through a third party, or can anyone allocate? If there are specific roles or addresses allowed to allocate, mention them here. **A: Stake in registry (gardens) and have enough voting points** - Are there any custom functions or conditions for verifying allocator eligibility? If so, describe them and their purpose in determining eligibility. **A: probably isRegistered(address allocator) from registry (gardens) contract** - **Allocate function** - Are there any conditions on when the `allocate` function is callable or not? - Is there an allocation period? - Can an allocator allocate multiple times or just once? Is there any restriction on the number of allocations per allocator? **A:Multiples times, yes we have restrictions based on the voting points in the registry (gardens) contract, that is be capped points based in the type that strategy was defined in the creation, if the tokens staked max is capped to 100 (%) points or is 1-1 tokens-points** - How does the strategy handle ineligible allocators who attempt to allocate? What actions or outcomes are triggered when an ineligible allocator tries to allocate? **A: error message: "you need to support the covenant to vote on this proposal" or "you've used all your votes in other proposals"** - How is the data from allocate calls stored in the strategy? Describe the data structure or mechanism used to track and store the allocate data. What information is important to capture? - In case of allocations that require token donations, are the tokens stored in the strategy or are they sent directly to a specific recipient? If they are stored, who can withdraw funds? - **Proposal deposit stored in strategy contract** - **if proposal disputed and blocked, deposit sent to return address (selected on setup)** - **if proposal is executed or cancelled by creator, deposit is returned to creator.** - Are there any specific rules or conditions for allocations? For example, are there limits on the amount that can be allocated to each recipient or any other constraints that need to be considered? - **Allocation weight is calculated by "CVPoints" which looks at amount of stake in CommunityCovenant and calculates governance weight for that strategy.** - **CVPoints / allocation weight can be distributed between any number of recipients (proposals)** ### Payout Calculation Logic Explain the logic for how the strategy will calculate the pool's final `payout` from the allocations expressed by allocators. This should include any calculation formulas, the shape of the final payouts, and special considerations. #### Questions to answer - What factors determine the payout amount for each recipient? Explain the criteria or calculations used to determine the amount that each recipient should receive from the pool. Provide details on the formula or method used to calculate the payout amount for each recipient. - **Funding Proposal: if proposal passes, beneficiary gets all tokens requested.** - **Streaming Proposal: stream starts when proposal reaches minimum threshold, and increases with more conviction based on these parameters set (https://forum.1hive.org/t/1hive-upgrade-integrating-fluid-proposals/5582/3?u=paul).** - What is the shape of the final payouts? Are they proportional, winner-take-all, etc? - **The beneficiary address gets the whole payout requested from the proposal** - Are there any transfers or other events triggered during the calculation process? - **Streaming Proposals: superfluid stream is created when proposal is created and set to lowest possible stream until minimum threshold is reached.** - Are any additional functions needed to set the final `payout` amounts? Describe any helper functions or steps required. ### Distribution Logic Outline the logic for how the `payout` amounts will be distributed to recipients. Describe any mechanisms in place to prevent double payments. #### Questions to answer - Who is eligible to receive a payout? Specify the criteria or conditions that determine whether a recipient is eligible to receive a distribution from the pool. - **Only the beneficiary address will receive payout after the proposal has passed (Funding and streaming the same)** - Who can call the distribute function? In case there are restrictions, explain why they are needed and who has the authorization to invoke the distribution process. - **The distribute function can be called by anyone but should only work if the CV proposal passed** - Are there any conditions on when the distribute function can be called? Specify any prerequisites or constraints that need to be satisfied before calling the function. - **Funding Proposal: conviction needs to pass threshold** - **Proposal Status needs to be Active** - Are there multiple distributions or just a single distribution? Clarify whether there are multiple rounds of distribution or if it's a one-time distribution process. - **Funding Proposals: One distribution** - **Streaming Proposals: Ongoing distribution handled by Superfluid contract** - How are tokens distributed to recipients in this strategy? Explain the mechanism or steps involved in transferring tokens to the recipients. - Funding Proposals: Direct transfer after the proposal is executed (distributed) - Streaming Proposals: Token is wrapped and with time, the beneficiary is allowed to unwrap more and more tokens from these wrapped tokens pool - Are any third-party services involved in the distribution process? If there are any external dependencies or integrations, provide additional information or relevant links. - **Streaming Proposals: Superfluid** - Are there any mechanisms in place to prevent double payments? Describe any safeguards or mechanisms implemented to ensure that recipients do not receive duplicate or excessive payments. - **Make sure to close proposal as soon as payout is distributed from the funding proposal** ## Developer Specifications ### Data Parameter The following functions may require a data parameter to be passed in. This parameter contains specific information or parameters necessary for the proper execution of the function. Please refer to the descriptions below for each function and provide the required data format or content. - `initialize(uint256 _poolId, bytes memory _data)`: The `_data` parameter should contain the initialization data required for the strategy. Provide the expected format or structure of the data, and specify any important information or parameters that need to be included. - `registerRecipients(bytes memory _data, address _sender)`: The `_data` parameter should contain the data required for recipient registration. Specify the expected format or structure of the data, and provide details on the information or parameters that need to be included. - `allocate(bytes memory _data, address _sender)`: The `_data` parameter should contain the data necessary for the allocation process. Describe the expected format or structure of the data, and specify any important information or parameters that need to be included. - `distribute(address[] memory _recipientIds, bytes memory _data, address _sender)`: The `_data` parameter should contain the data specific to the distribution process. Explain the expected format or structure of the data, and provide details on the information or parameters that need to be included. ### Additional Functions If any custom functions have been introduced as part of the strategy, list and describe them here. Provide information about their purpose, input parameters, return values, and any important considerations for their usage. - **Conviction calculations** - copy / paste calculations from existing CV - **CVpoints / governance weight** - **Dispute proposal + deposit** - **Streaming Proposals / Fluid Proposals** - ceilingBps - max % of pool that can be wrapped - wrapAmount - how many tokens are wrapped when function called - decay - how long streams will take to reach conviction - maxRatio: target % of Common Pool per month distributed - minStake: minimum stake to start receiving funds ### Variables List and explain the important variables used within the strategy. Provide details about their purpose, usage, and any special considerations related to their values or updates. Setup parameters: General - Select Funding, Streaming, and/or Signalling proposals - Deposit amount to create a proposal - Address to receive forfeited deposits Conviction Voting - Minimum Conviction - Conviction Growth - Spending Limit Fluid Proposals - Target % of Pool distributed a month - Minimum Conviction - Decay Tribunal: - Contract Address - Deposit amount to dispute - Days to make a ruling - Default decision for no ruling / abstain ### Additional Considerations If there are any other important considerations or specifications specific to this strategy, mention them here. - Sybil resistance for the CVPoints threshold #### Future Changes