From d528dab582f5f3b78cc391825748b70822415f9c Mon Sep 17 00:00:00 2001 From: bengtlofgren Date: Mon, 26 Jun 2023 14:05:57 +0200 Subject: [PATCH] improved pgf specs --- .vscode/settings.json | 5 + .../pages/economics/public-goods-funding.mdx | 210 +----------------- .../economics/public-goods-funding/_meta.json | 7 + .../becoming-a-steward.mdx | 64 ++++++ .../public-goods-funding/electing.mdx | 77 +++++++ .../public-goods-funding/funding.mdx | 53 +++++ .../public-goods-stewards.mdx | 14 ++ .../public-goods-funding/storage.mdx | 31 +++ 8 files changed, 252 insertions(+), 209 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 packages/specs/pages/economics/public-goods-funding/_meta.json create mode 100644 packages/specs/pages/economics/public-goods-funding/becoming-a-steward.mdx create mode 100644 packages/specs/pages/economics/public-goods-funding/electing.mdx create mode 100644 packages/specs/pages/economics/public-goods-funding/funding.mdx create mode 100644 packages/specs/pages/economics/public-goods-funding/public-goods-stewards.mdx create mode 100644 packages/specs/pages/economics/public-goods-funding/storage.mdx diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..d4e48660 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "[markdown]": { + "editor.wordWrap": "on" + } +} \ No newline at end of file diff --git a/packages/specs/pages/economics/public-goods-funding.mdx b/packages/specs/pages/economics/public-goods-funding.mdx index 707c57bf..62a75533 100644 --- a/packages/specs/pages/economics/public-goods-funding.mdx +++ b/packages/specs/pages/economics/public-goods-funding.mdx @@ -1,6 +1,6 @@ import { Callout } from 'nextra-theme-docs' -# PGF specs +# Public Goods Funding ## Motivation @@ -46,211 +46,3 @@ _Meta public goods_ covers funding for any good that increases the production or - External public goods _External public goods_ covers funding for public goods explicitly external to the Namada and Namada ecosystem, including carbon sequestration, independent journalism, direct cash transfers, legal advocacy, etc. Possible funding forms could include direct purchase of tokenised assets such as carbon credits, direct cash transfers (e.g. GiveDirectly), institutional funding (e.g. Wikileaks), and similar. - -## The public goods stewards - -The funding of public goods on Namada will be conducted through a structure we call "public goods stewards". - -Each steward is elected by governance through separate governance proposals. Each steward will be responsible for covering a specific area of public goods, which they describe during their election. Stewards can then "propose" funding of various public goods, which will pass by default. However, Governance retains the power to veto any proposal, which would result in the Steward being removed from the set of stewards. - -## Voting for the stewards - -### What is a Steward (technically)? -All valid PGF stewards will be established multisignature account addresses. These must be created by the intended parties (which may very well be just one person, but could be more) that wish to represent the steward entity. For example, if David Alice and Bob wish to represent the combined steward DAB, they may do so as a common entity. But likewise, Alice can create her own 1-out-of-1 multisig that to just represent herself. - - -### Becoming a Steward -The first step towards becoming a Steward is to instantiate a multisignature account. This is done through the CLI. - -In order to propose candidacy as a PGF Steward, the steward must initiate a custom governance proposal. At the cost of deposited NAM, the governance proposal is broadcast on-chain and governance is able to vote on whether the steward-applicant will be accepted or not. Together with this proposal, the applicant is encouraged to provide a motivational statement as to why they should be entrusted with the responsibility of proposing public goods candidates. This will also include a commitment to at least one of the categories of public goods funding that social consensus has established (or propose their own category, which would inherently introduce a new category into social consensus, should the proposal be accepted). - -Nominating oneself as a PGF steward may be done at any time. - - -### Losing stewardship status - -There are 3 ways that a Steward be removed from the steward set: - -1. Resign as a steward -2. Have a failed funding proposal -3. Become voted out through a governance proposal - -Resigning as a Steward is straight-forward. A simple CLI is implemented to allow for this so that the established account representing the Steward loses their priveleges as a PG Steward. - -If a steward's PGF proposal receives a significant number of `Nay` votes ($\frac{2}{3}$ as a fraction of voting-power), they will be removed from the steward set. It is likely that there would only be such wide-speread disagreement if the proposal was misaligned with the users the stewards is attempting to cater to. This is described in more detail under [its section](#proposing-funding). - -Finally, the steward can be "voted-out" from its responsibility through a custom governance proposal similar to the one used to elect the steward in the first place! - -#### "Voting-out" the Steward - -In the same way that a steward can be voted in by Namada governance through a custom proposal, the equal and opposite force exists. Hence, any governance member (validator or delegate), is able to initiate a vote (for the relevant cost) in order to remove an arbitrary number of current PGF stewards. If this proposal passes, it signals that the Steward(s) has/have not fulfilled their duty to the public, which the stewards are meant to serve (hence the name). - -### Initiating the vote - -Before a new PGF steward can either be elected or removed, a governance proposal that specifies this objective must pass. The voting on this proposal is handled by the governance proposal type `StewardProposal`, which is a custom proposal type. - - -The struct of `StewardProposal` is constructed as follows, and is explained in more detail in the [governance specs](../base-ledger/governance.md) - -```rust -struct StewardProposal{ - id: u64 - content: Vec, - author: Address, - r#type: PGFSteward, - votingStartEpoch: Epoch, - votingEndEpoch: Epoch, - graceEpoch: Epoch, -} -``` - - In order for a new PGF steward to be elected (or removed), $\frac{2}{3}$ of validating power must vote on the `StewardProposal` and more than half of the votes must be in favor. If more than half of the votes are against the proposal, the steward set is kept the same, and the proposer of the proposal loses their escrowed funds. - - -See the example below for more detail, as it may serve as the best medium for explaining the mechanism. - -### Voting for stewards -After the `StewardProposal` has been submitted, and once the steward's address has been constructed and broadcasted, the steward address can be voted on by governance participants. All voting must occur between `votingStartEpoch` and `votingEndEpoch`. - - -The vote for a new steward nomination will be constructed as follows: - - -Each participant submits a vote through governance: -```rust -struct OnChainVote { - id: u64, - voter: Address, - yay: proposalVote, -} -``` - -Where the proposalVote is simply an enum dictating whether the voter voted `Yay` or `Nay` to the proposed candidate change. - - -#### Dealing with ties -In the rare occurance of a tie, the steward retains membership by default. - - -### Electing stewards - -Once the decision has been made on whether to elect (or remove) the intended steward, the established address corresponding to the multisig is added to (removed from) the `PGF` internal address. - -### Example - -The below example hopefully demonstrates the mechanism more clearly. - - -The governance set consists of Alice, Bob, Charlie, Dave, and Elsa. Each member has 20% voting power. - -The current PGF stewards are Dave and Elsa. - -- At epoch 42, Bob and Charlie decide to put themselves forward as a joint PGF Steward. They construct a multisig with address `0xBobCharlieMultisig`. -- At epoch 42, Bob proposes his and Charlie's candidacy through a `StewardProposal`: - -```rust -struct StewardProposal{ - id: 2 - content: Vec<32,54,01,24,13,37>, // (Just the byte representation of the content (description) of the proposal) - author: 0xCharlie, - r#type: StewardProposal, - votingStartEpoch: Epoch(45), - votingEndEpoch: Epoch(54), - graceEpoch: Epoch(57), -} -``` - -This proposal proposes the candidate 0xBobCharlieMultisig as a Steward. - -- At epoch 49, Alice submits the vote: - -```rust -struct OnChainVote { - id: 2, - voter: 0xalice, - yay: proposalVote, -} -``` -Where the proposalVote is simply the enum `Yay` with an empty memo field. - -- At epoch 49, Bob and Elsa submit an identical transaction. - -- At epoch 50, Dave votes `Nay` on the proposal. - -- At epoch 54, the voting period ends and the votes are tallied. Since 80% > 66% of the voting power voted on this proposal (everyone except Charlie, who forgot to vote on her own proposal), the intitial condition is passed and the Proposal is active. Further, because out of the total votes, most were `Yay`, (75% > 50% threshold), the new Steward consisting of Bob and Charlie will be added to the Steward set. - -- At epoch 57, Bob and Charlie have the effective power to propose Public Goods Funding transactions (that may or may not be vetoed). - - -## Mechanism - -Once elected and instantiated, PGF stewards will then unilaterally be able to sign transactions that propose either RPGF or CPGF funding. The PGF stewards as a whole will have an "allowance" to spend up to the `PGF` internal address's balance. - -### Proposing Funding -In order to propose funding, any steward will be able to propose a PGFProposal through governance. Only stewards will be valid authors of these proposals. There will be a minimum voting period set specifically for these types of proposals and can be changed by Governance. - -This governance proposal will be such that it **passes** by default **unless** the following conditions are met: - -Conditions to veto a PGF proposal: -1. Out of the votes that voted for the proposal, more than $50\%$ voted `Nay` on the proposal -2. At least $\frac{1}{3}$ of voting power voted on the proposal. - - Further, if at least $\frac{2}{3}$ of voting power voted `Nay` on the proposal, and the proposal was rejected, the Steward is removed from the set of stewards. - - -The PGF stewards should be able to propose both retroactive and continuous public funding transactions. Retroactive public funding transactions are straightforward and implement no additional logic to a normal transfer. - -However, for continuous PGF (cPGF), the stewards should be able to submit a one time transaction which indicates the recipient addresses that should be eligble for receiveing cPGF. - -The following data is attached to the PGF transaction and will allow the stewards to represent the projects they wish to be continously funded. Each tuple represent the address of the recipient and the respective amount of NAM that the recipient will receive every epoch. - -```rust -struct cPgfRecipients { - recipients: HashSet<(Address, u64)> -} -``` -The mechanism for these transfers will be implemented in `finalize-block.rs`, which will send the addresses their respective amounts each end-of-epoch. -Further, the following transactions: -- add (recipient, amount) to cPgfRecipients (inserts the pair into the hashset above) -- remove recipient from cPgfRecipients (removes the address and corresponding amount pair from the hashset above) - should be added in order to ease the management of cPGF recipients. - -```rust -impl addRecipient for cPgfRecipients - -impl remRecipient for cPgfRecipients -``` - -## PGF stewards incentives - -Being a PGF steward is (should be) hard work. Stewards must invest their time in crafting proposals, being in touch with the opinions of the Namada community, and taking the risks associated with being voted out. In order to incentivise this effort, Namada allocates a set amount of NAM inflation that is directed towards the stewards. This parameter is set by governance and is included in genesis by default. That allocation is then allocated to each steward (more stewards = more total funding). - -## Addresses -Governance adds 1 internal address: - -`PGF` internal address - -The internal address VP will hold the allowance of 10% inflation of NAM. This funding will be allocated to the internal address at the start of each epoch. It is important to note that it is this internal address which holds the funds, rather than any of the stewards' multisigs. - - -The stewards should be able to propose the burning of funds, but this hopefully should not require additional functionality beyond what currently exists. - -### VP checks - -The VP must check that the steward's spending does not exceed the balance of the VP (in aggregate). - -The VP must also check that the any spending is only done by the active PGF stewards. - -## Storage - -### Storage keys - -Each recipient will be listed under this storage space (for cPGF) -- `/PGFAddress/cPGF_recipients/Address = Amount` -- `/PGFAddress/active_stewards/address = Address` -### Struct - -```rust -struct Stewards { - addresses: Vec
, -} -``` diff --git a/packages/specs/pages/economics/public-goods-funding/_meta.json b/packages/specs/pages/economics/public-goods-funding/_meta.json new file mode 100644 index 00000000..93e7e458 --- /dev/null +++ b/packages/specs/pages/economics/public-goods-funding/_meta.json @@ -0,0 +1,7 @@ +{ + "public-goods-stewards" : "Public Goods Stewards", + "becoming-a-steward" : "Becoming a steward", + "electing" : "Electing the stewards", + "funding" : "Mechanism for funding", + "storage" : "Storage" +} \ No newline at end of file diff --git a/packages/specs/pages/economics/public-goods-funding/becoming-a-steward.mdx b/packages/specs/pages/economics/public-goods-funding/becoming-a-steward.mdx new file mode 100644 index 00000000..b945a166 --- /dev/null +++ b/packages/specs/pages/economics/public-goods-funding/becoming-a-steward.mdx @@ -0,0 +1,64 @@ +import { Callout } from 'nextra-theme-docs' + +# Becoming a steward +The first step towards becoming a Steward is to instantiate a multisignature account. + +In order to propose candidacy as a PGF Steward, the steward must initiate a custom governance proposal. At the cost +of deposited NAM, the governance proposal is broadcast on-chain and governance is able to vote on whether the steward-applicant +will be accepted or not. Together with this proposal, the applicant is encouraged to provide a motivational statement as to why +they should be entrusted with the responsibility of proposing public goods candidates. This will also include a commitment to at +least one of the categories of public goods funding that social consensus has established (or propose their own category, which +would inherently introduce a new category into social consensus, should the proposal be accepted). + +Nominating oneself as a PGF steward may be done at any time. + + +## Losing stewardship status + +There are 3 ways that a Steward may be removed from the steward set: + +1. Resign as a steward +2. Have a failed funding proposal +3. Become voted out through a governance proposal + +Resigning as a Steward is straight-forward. A simple interface is implemented to allow for the established account +representing the Steward to lose their priveleges as a PGF Steward. + +If a steward's PGF proposal receives a significant number of `Nay` votes ($\frac{2}{3}$ as a fraction of voting-power), +they will be removed from the steward set. It is likely that there would only be such wide-speread disagreement if the +proposal was misaligned with the users the stewards is attempting to cater to. This is described in more detail under +[its section](#proposing-funding). + +Finally, the steward can be "voted-out" from its responsibility through a custom governance proposal similar to the one +used to elect the steward in the first place! + +### "Voting-out" the steward + +In the same way that a steward can be voted in by Namada governance through a custom proposal, the equal and opposite force exists. +Hence, any governance member (validator or delegate), is able to initiate a vote (for the relevant cost) in order to remove an arbitrary +number of current PGF stewards. If this proposal passes, it signals that the Steward(s) has/have not fulfilled their duty to the public, +which the stewards are meant to serve (hence the name). + +## Initiating the vote + +Before a new PGF steward can either be elected or removed, a governance proposal that specifies this objective must pass. The voting on this proposal is handled by the governance proposal type `StewardProposal`, which is a custom proposal type. + + +The struct of `StewardProposal` is constructed as follows, and is explained in more detail in the [governance specs](../base-ledger/governance.md) + +```rust +struct StewardProposal{ + id: u64 + content: Vec, + author: Address, + r#type: PGFSteward, + votingStartEpoch: Epoch, + votingEndEpoch: Epoch, + graceEpoch: Epoch, +} +``` + + In order for a new PGF steward to be elected (or removed), $\frac{2}{3}$ of validating power must vote on the `StewardProposal` and more than half of the votes must be in favor. If more than half of the votes are against the proposal, the steward set is kept the same, and the proposer of the proposal loses their escrowed funds. + + +See the example below for more detail, as it may serve as the best medium for explaining the mechanism. \ No newline at end of file diff --git a/packages/specs/pages/economics/public-goods-funding/electing.mdx b/packages/specs/pages/economics/public-goods-funding/electing.mdx new file mode 100644 index 00000000..ade173f6 --- /dev/null +++ b/packages/specs/pages/economics/public-goods-funding/electing.mdx @@ -0,0 +1,77 @@ +import { Callout } from 'nextra-theme-docs' + +# Electing the stewards + +## Voting for the stewards + +After the `StewardProposal` has been submitted, and once the steward's address has been constructed and broadcasted, the steward address can be voted on by governance participants. All voting must occur between `votingStartEpoch` and `votingEndEpoch`. + + +The vote for a new steward nomination will be constructed as follows: + + +Each participant submits a vote through governance: +```rust +struct OnChainVote { + id: u64, + voter: Address, + yay: proposalVote, +} +``` + +Where the proposalVote is simply an enum dictating whether the voter voted `Yay` or `Nay` to the proposed candidate change. + + +#### Dealing with ties +In the rare occurance of a tie, the steward retains membership by default. + + +## Electing stewards + +Once the decision has been made on whether to elect (or remove) the intended steward, the established address corresponding to the multisig is added to (removed from) the `PGF` internal address. + +### Example + +The below example hopefully demonstrates the mechanism more clearly. + + +The governance set consists of Alice, Bob, Charlie, Dave, and Elsa. Each member has 20% voting power. + +The current PGF stewards are Dave and Elsa. + +- At epoch 42, Bob and Charlie decide to put themselves forward as a joint PGF Steward. They construct a multisig with address `0xBobCharlieMultisig`. +- At epoch 42, Bob proposes his and Charlie's candidacy through a `StewardProposal`: + +```rust +struct StewardProposal{ + id: 2 + content: Vec<32,54,01,24,13,37>, // (Just the byte representation of the content (description) of the proposal) + author: 0xCharlie, + r#type: StewardProposal, + votingStartEpoch: Epoch(45), + votingEndEpoch: Epoch(54), + graceEpoch: Epoch(57), +} +``` + +This proposal proposes the candidate 0xBobCharlieMultisig as a Steward. + +- At epoch 49, Alice submits the vote: + +```rust +struct OnChainVote { + id: 2, + voter: 0xalice, + yay: proposalVote, +} +``` +Where the proposalVote is simply the enum `Yay` with an empty memo field. + +- At epoch 49, Bob and Elsa submit an identical transaction. + +- At epoch 50, Dave votes `Nay` on the proposal. + +- At epoch 54, the voting period ends and the votes are tallied. Since 80% > 66% of the voting power voted on this proposal (everyone except Charlie, who forgot to vote on her own proposal), the intitial condition is passed and the Proposal is active. Further, because out of the total votes, most were `Yay`, (75% > 50% threshold), the new Steward consisting of Bob and Charlie will be added to the Steward set. + +- At epoch 57, Bob and Charlie have the effective power to propose Public Goods Funding transactions (that may or may not be vetoed). + diff --git a/packages/specs/pages/economics/public-goods-funding/funding.mdx b/packages/specs/pages/economics/public-goods-funding/funding.mdx new file mode 100644 index 00000000..5bd5b32a --- /dev/null +++ b/packages/specs/pages/economics/public-goods-funding/funding.mdx @@ -0,0 +1,53 @@ +import { Callout } from 'nextra-theme-docs' + +# Mechanism + +Once elected and instantiated, PGF stewards will then unilaterally be able to sign transactions that propose either RPGF or CPGF funding. The PGF stewards as a whole will have an "allowance" to spend up to the `PGF` internal address's balance. + +## Proposing Funding +In order to propose funding, any steward will be able to propose a PGFProposal through governance. Only stewards will be valid authors of these proposals. There will be a minimum voting period set specifically for these types of proposals and can be changed by Governance. + +This governance proposal will be such that it **passes** by default **unless** the following conditions are met: + +Conditions to veto a PGF proposal: +1. Out of the votes that voted for the proposal, more than $50\%$ voted `Nay` on the proposal +2. At least $\frac{1}{3}$ of voting power voted on the proposal. + - Further, if at least $\frac{2}{3}$ of voting power voted `Nay` on the proposal, and the proposal was rejected, the Steward is removed from the set of stewards. + + +The PGF stewards should be able to propose both retroactive and continuous public funding transactions. Retroactive public funding transactions are straightforward and implement no additional logic to a normal transfer. + +However, for continuous PGF (cPGF), the stewards should be able to submit a one time transaction which indicates the recipient addresses that should be eligble for receiveing cPGF. + +The following data is attached to the PGF transaction and will allow the stewards to represent the projects they wish to be continously funded. Each tuple represent the address of the recipient and the respective amount of NAM that the recipient will receive every epoch. + +```rust +struct cPgfRecipients { + recipients: HashSet<(Address, u64)> +} +``` +The mechanism for these transfers will be implemented in `finalize-block.rs`, which will send the addresses their respective amounts each end-of-epoch. +Further, the following transactions: +- add (recipient, amount) to cPgfRecipients (inserts the pair into the hashset above) +- remove recipient from cPgfRecipients (removes the address and corresponding amount pair from the hashset above) + should be added in order to ease the management of cPGF recipients. + +```rust +impl addRecipient for cPgfRecipients + +impl remRecipient for cPgfRecipients +``` + +## PGF stewards incentives + +Being a PGF steward is (should be) hard work. Stewards must invest their time in crafting proposals, being in touch with the opinions of the Namada community, and taking the risks associated with being voted out. +In order to incentivise this effort, Namada allocates a set amount of NAM inflation that is directed towards the stewards. + +This inflation is allocated towards the PGF internal address, in which each steward account has control over their respective share of the funds. +The inflation is "streamed" to the PGF internal address, in an identical manner to how the cPGF is streamed to the recipients (i.e end of each epoch). +The Steward account can then unilaterally (within the rules of a multisig transaction) either: + - Set up a "stream of income" to another account (e.g a personal account) + - Transfer collected funds in a lump sum transaction + +The parameter of inflation income is set by governance and is included in genesis by default. +That allocation is then allocated to each steward (more stewards = more total funding). diff --git a/packages/specs/pages/economics/public-goods-funding/public-goods-stewards.mdx b/packages/specs/pages/economics/public-goods-funding/public-goods-stewards.mdx new file mode 100644 index 00000000..bcd8a3dc --- /dev/null +++ b/packages/specs/pages/economics/public-goods-funding/public-goods-stewards.mdx @@ -0,0 +1,14 @@ +# The public goods stewards + +The funding of public goods on Namada is conducted through a structure we call "public goods stewards". + +Each steward is elected by governance through separate governance proposals. Each steward is responsible +for covering a specific area of public goods, which they describe during their election. Stewards can then "propose" +funding of various public goods, which passes by default. However, Governance retains the power to veto any proposal, +which would result in the Steward being removed from the set of stewards. + +## What is a Steward (technically)? +All valid PGF stewards are established multisignature account addresses. These must be created by the parties +(which may very well be just one person, but could be more) that wish to represent the steward entity. For example, if +David Alice and Bob wish to represent the combined steward DAB, they may do so as a common entity. But likewise, Alice +can create her own 1-out-of-1 multisig that to just represent herself. \ No newline at end of file diff --git a/packages/specs/pages/economics/public-goods-funding/storage.mdx b/packages/specs/pages/economics/public-goods-funding/storage.mdx new file mode 100644 index 00000000..504f41c9 --- /dev/null +++ b/packages/specs/pages/economics/public-goods-funding/storage.mdx @@ -0,0 +1,31 @@ +# Stewards in storage + +## Addresses +Governance adds 1 internal address: + +`PGF` internal address + +The internal address VP will hold the allowance of 10% inflation of NAM. This funding is allocated to the internal address at the start of each epoch. It is important to note that it is this internal address which holds the funds, rather than any of the stewards' multisigs. + +The stewards should be able to propose the burning of funds, but this hopefully should not require additional functionality beyond what currently exists. + +### VP checks + +The VP must check that the steward's spending does not exceed the balance of the VP (in aggregate). + +The VP must also check that any spending is only done by the active PGF stewards. + +## Storage + +### Storage keys + +Each recipient will be listed under this storage space (for cPGF) +- `/PGFAddress/cPGF_recipients/Address = Amount` +- `/PGFAddress/active_stewards/address = Address` +### Struct + +```rust +struct Stewards { + addresses: Vec
, +} +``` \ No newline at end of file