Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improved pgf specs #57

Merged
merged 1 commit into from
Jun 26, 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
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"[markdown]": {
"editor.wordWrap": "on"
}
}
210 changes: 1 addition & 209 deletions packages/specs/pages/economics/public-goods-funding.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Callout } from 'nextra-theme-docs'

# PGF specs
# Public Goods Funding

## Motivation

Expand Down Expand Up @@ -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<u8>,
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.

<Callout type="info" emoji="🧑‍🏫">
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).
</Callout>

## 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<Address>,
}
```
Original file line number Diff line number Diff line change
@@ -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"
}
Original file line number Diff line number Diff line change
@@ -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<u8>,
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.
77 changes: 77 additions & 0 deletions packages/specs/pages/economics/public-goods-funding/electing.mdx
Original file line number Diff line number Diff line change
@@ -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.

<Callout type="info" emoji="🧑‍🏫">
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).
</Callout>
Loading
Loading