On-chain Vote: Recurring Spend for Committee Budgets

Hello, pDAO!

So far we’ve relied on the team to execute funding for both management committees (IMC, GMC). We now have the ability to vote on these directly, as well as the ability to make scheduled periodic payouts. In addition to testnet, this has been trialed by the IMC on mainnet through bootstrap. Now that pDAO on-chain governance is active, we should take advantage of it to remove that blocker from the team giving up some power.

Given that RPIP-10 specifies that “MCs SHALL be fully re-selected between 10-14 months from their last full selection”, the suggestion is to base the schedule on the latest allowed timing, i.e. vote in payouts up to the latest possible reward period the committee will have to be replaced by. If the MC changes sooner, the funding will still be correct for the new incoming MC and existing payment contracts can also be modified through another vote if needed.

The last selection for the GMC ended 2024-11-10, so we want to capture all payouts before 2026-01-10. This would mean 13 payouts.

The last selection for the IMC ended 2024-06-09, so we want to capture all payouts before 2025-08-09. This would mean 8 periods.

Proposed GMC Payment Contract

_contractName: GMC (2025-01)
_recipientAddress: 0x6efD08303F42EDb68F2D6464BCdCA0824e1C813a
_amountPerPeriod: 4702424536260456958231 (4,702.42 RPL)
_periodLength: 2419200
_startTime: 1734586539
_numPeriods: 13

Proposed IMC Payment Contract

_contractName: IMC (2025-01)
_recipientAddress: 0xb867EA3bBC909954d737019FEf5AB25dFDb38CB9
_amountPerPeriod: 11361813617781227549820 (11,361.81 RPL)
_periodLength: 2419200
_startTime: 1734586539
_numPeriods: 8

Full explanation of contract parameters

_contractName
Just need something that is identifiable and can be typed in easily when claiming. Committee name plus date of the first claim seems like a reasonable choice.

_recipientAddress
Multisig addresses are in RPIP-36.

_amountPerPeriod
This one is a bit tricky. Payment contracts are set up to support a fixed amount of RPL per claim throughout their validity, but committee compensation is a share of inflation. The idea is to calculate the appropriate inflation share for the entire contract duration and then divide by the number of periods to get the correct total. The calculation was done with the following Python script:

def calculate_inflation(initial_supply: int, days: int) -> int:
    supply = initial_supply

    for _ in range(days):
        supply *= 1000133680617113500
        supply //= 10**18

    return supply - initial_supply

def main():
    rpl_supply = 20988203069190289903554721 - 78407971276658331933618
    rpl_supply += calculate_inflation(rpl_supply, 27)

    imc_periods = 8
    imc_inflation = calculate_inflation(rpl_supply, imc_periods * 28)
    imc_payout = imc_inflation * 285 * 500 // (imc_periods * 10**6)
    print(f"IMC: {imc_payout}")

    gmc_periods = 13
    gmc_inflation = calculate_inflation(rpl_supply, gmc_periods * 28)
    gmc_payout = gmc_inflation * 285 * 205 // (gmc_periods * 10**6)
    print(f"GMC: {gmc_payout}")

if __name__ == '__main__':
    main()

It prints

IMC: 11361813617781227549820
GMC: 4702424536260456958231

The hardcoded constants are based on the following:

The inflation share calculation is based on the 28.5% pDAO share (RPIP-25) and the 50% IMC / 20.5% GMC shares (RPIP-10) within that. The script also takes into account the idiosyncrasy that snapshot rewards are actually based on the day before, hence taking one period’s inflation off the supply and adding 27 days of inflation back on.

_periodLength
This is just the number of seconds in a reward period: 28 * 24 * 60 * 60 = 2419200.

_startTime
The first payout is _periodLength after _startTime, so this should be the start of the current reward period rather than the end. https://etherscan.io/address/0xEE4d2A71cF479e0D3d0c3c2C923dbfEB57E73111#readContract#F4 shows 1734586539, which matches the last snapshot.

_numPeriods
This is discussed in the main post. 13 for GMC and 8 for IMC.

2 Likes

Apologies for opening the poll immediately, but this needs to be submitted within roughly 4 days to make it in time for the next reward period. This is because on-chain votes take a total of three weeks:

  • 1 week of delay for vote tree challenges
  • 1 week of phase 1 voting (delegates and self-votes)
  • 1 week to override delegates

If the consensus is strong (say 70%), it probably makes sense to submit. If not, we’ll have to wait another period and will have lots of time for the poll.

  • Support moving to on-chain vote now
  • Oppose moving to on-chain vote now - ask team to manually do one more period and work on scheduling all subsequent periods
  • Oppose moving to on-chain vote for a different reason
  • Undecided
0 voters
1 Like

Thanks @haloooloolo for putting that together. Since this is just executing something previously voted in (and it’s cancelable if things change), I’m happy to go ahead ASAP.

I reviewed the parameters (especially _amountPerPeriod) and looks like we’re matching (there’s a minimal amount of rounding error, probably on my end, which amount to less than a billionth of an RPL, so deffo close enough).

Val's double checks the calculation

Parameters we need:

_contractName

  • choices seem clear and unambiguous
  • GMC (2025-01)
  • IMC (2025-01)

_recipientAddress

  • Multisig addresses are in RPIP-36 (and also in my Safe app)
  • GMC 0x6efD08303F42EDb68F2D6464BCdCA0824e1C813a
  • IMC 0xb867EA3bBC909954d737019FEf5AB25dFDb38CB9

On to _amountPerPeriod, which is the tough one.

  • I’m doibg this a bit differently form Halo, which is good for checking. First I look at actual amounts transferred to pDAO treasury: https://dune.com/queries/1264376
  • period_31_transfer=22343.284949727202292854
  • period_30_transfer=22259.814647920560318926
  • Get rate of increase per period period_mult=period_31_transfer/period_30_transfer=1.003749820163684
  • _amountPerPeriod=mc_share*sum([period_31_transfer*period_mult**i for i in range(1, 1+num_periods)])/num_periods
    • For the GMC, mc_share=.205 and num_periods=13. We get _amountPerPeriod = 4702.424536260458
    • For the IMC, mc_share=.5 and num_periods=8. We get _amountPerPeriod = 11361.81361778123

_periodLength

  • We’d like to align this with reward periods, so simply the number of seconds in 28 days. 28*24*60*60=2419200

_startTime

_numPeriods was discussed earlier. 13 for GMC and 8 for IMC.

2 Likes

The GMC is working through some things and we’d prefer this waited for another round. Very glad halooo is thinking about it and doing the prep work, though.

7 Likes

Vote deferred. Here are the updated parameters if we’re targeting period 33.

_contractName: GMC (2025-02)
_recipientAddress: 0x6efD08303F42EDb68F2D6464BCdCA0824e1C813a
_amountPerPeriod: 4711164165008686816503 (4,711 RPL)
_periodLength: 2419200
_startTime: 1737005739
_numPeriods: 12

_contractName: IMC (2025-02)
_recipientAddress: 0xb867EA3bBC909954d737019FEf5AB25dFDb38CB9
_amountPerPeriod: 11382996402453215228030 (11,383 RPL)
_periodLength: 2419200
_startTime: 1737005739
_numPeriods: 7

Will check back in a few weeks with another poll.

2 Likes

This will take another period to sort out due to On-chain Quorum & Initialization POAP.

Confirmed initialised vote power is now 100%. Well done @haloooloolo for sorting that out.

Initialised vote power: 86133.31411969055, which is 100% vote power.

I can get @kane to adjust the quorum to 15% this week to match snapshot.

5 Likes