Mechanism of funding
Once elected and instantiated, PGF stewards will then unilaterally be able to sign transactions that propose either RPGF or CPGF funding. The PGF funding proposals in joint may spend up to the PGF
internal address's balance.
There is also the ability for non-stewards to propose funding, but the voting conditions are different.
Proposing funding as a PGF steward
In order to propose funding, any steward will be able to propose a StewardFundingProposal
through governance, which is a custom proposal.
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 proposal is vetoed.
Conditions to veto a StewardFundingProposal
:
- Out of the votes that voted for the proposal, more than voted
Nay
on the proposal - At least of voting power voted on the proposal.
- Further, if at least of voting-power voted on the proposal, and of the votes on the proposal are
Nay
, the Steward is removed from the set of stewards.
Structuring the proposal
Retroactive PGF (RPGF)
The PGF stewards should be able to propose both retroactive and continuous public funding transactions. Retroactive public goods funding (RPGF) transactions are straightforward and implement no additional logic to a normal transfer. The following data is attached to the PGF transaction and will allow the stewards to represent the projects they wish to be funded retroactively. Each tuple represent the address of the recipient and the respective amount of NAM that the recipient will receive.
struct RPgfRecipients {
recipients: HashSet<(Address, u64)>
}
Continuous PGF (CPGF)
However, for continuous public goods funding (CPGF), the stewards will need to propose changes to the current set of CPGF recipients and amounts they receive.
We define the set of tuples representing the (address of the CPGF recipient, amount of NAM received per epoch) as the CPgfSet
.
We refer to the individual tuple as a CPgfEntry
.
In this manner, any steward can propose a vector of deltas to the current CPgfEntry
s in the CPgfSet
.
These deltas will be attached to the StewardFundingProposal
as follows:
struct CPgfDeltas {
deltas: Vec<(Address, i64)>
}
Note that the amount of NAM received per epoch is represented as an i64
. This means all deltas must be integers.
However, the amount of NAM received per epoch is represented as a u64
in the CPgfEntry
, which means that large negative deltas act as a removal of the recipient from the set.
Applying deltas to the CPgfSet
The CPgfDeltas
will be used to update the CPgfSet
as follows:
- If the address is not in the
CPgfSet
, then the address is added to theCPgfSet
with the corresponding amount. - If the address is in the
CPgfSet
, then the amount is updated by adding the delta to the current amount. - If the delta is negative and the current amount is less than (or equal to) the absolute value of the delta, then the address is removed from the
CPgfSet
.
Mechanism of CPGF
The mechanism for these transfers will be implemented in finalize-block.rs
, which will send the addresses their respective amounts each end-of-epoch.
Edgecase: Total amount of NAM sent to CPgfSet
is greater than the total amount of NAM in the PGF internal address
Because the amount in each CPgfEntry
is not verified, and the absolute value of the PGF internal addresses is unpredictable, it may occur that the total amount of NAM sent to the CPgfSet
in one epoch is greater than the total amount of NAM in the PGF internal address.
In this case, the PGF internal address will be set to zero, and the CPgfSet
will be receive funding accordingly:
The total sum of amounts in the CPgfSet
will be calculated, and the the amount of NAM transferred to a single CPgfEntry
will be proportional to the amount of NAM in the CPgfEntry
relative to the total sum of amounts in the CPgfSet
.
More accurately, it will be calculated as follows:
Applying funding
For blocks of which both RPGF and CPGF funding is to be applied, RPGF is applied first. If there is not enough funds to pay an RPGF proposal, it is rejected. For RPGF proposals that have the same graceEpoch
, the proposal with the lowest proposalId
is applied first.
Proposing funding as a non-PGF steward
There is also the possibility to propose funding as a non-PGF steward. This is done by submitting the custom governance proposal FundingProposal
through governance.
The structure of the proposal is identical to the StewardFundingProposal
except that the author of the proposal is not required to be a PGF steward, and the voting conditions differ.
The proposal will be such that it is rejected by default unless the following conditions are met:
- of voting-power must vote on the
FundingProposal
- More than half of the votes must be in favor of the
FundingProposal
Note that these are the same voting conditions as the StewardProposal