Skip to content

feat: fund the GovDAO multisig with a 5,000 GNOT realm-operation float - #81

Merged
moul merged 1 commit into
mainfrom
feat/fund-govdao-multisig
Sep 11, 2026
Merged

moul merged 1 commit into
mainfrom
feat/fund-govdao-multisig

Conversation

@moul

@moul moul commented Sep 11, 2026

Copy link
Copy Markdown
Member

Summary

g1skl80cuz8zq3lul9pgz5pc35l2pfzgxgfpsqkx — the [govdao] 4-of-7 multisig — held nothing. #79 deliberately left it out of chainServices:

Still UNFUNDED and not in this list: gnolang/gno's NAMES_ADMIN (g1skl80c…, the [govdao] 4-of-7). […] That is a separate decision -- the multisig is a governance body rather than a service, so Core may not be its bucket.

That reasoned from the wrong capability, and the objection is right about the capability it names.

r/sys/names is not the reason — and #79 was correct about that

The admin in r/sys/names/verifier.gno gates Enable() and nothing else. Enable is a one-shot genesis call, the flag is sticky, and the realm's own source says so:

After that the address is dead weight — no further capability flows through it.

Pause/unpause is gated on a GovDAO T1 proposal (ProposeSetPaused), not on this key. There is no SetEnabled(false) and no SetAdmin. Funding this address for names administration would have been funding nothing — the TODO in gnolang/gno's mainnet builder that asks for it is describing a capability that does not exist.

The actual reason: it owns two realms that ship in genesis

The same address is the hardcoded owner of:

realm binding what it can do
r/gnoland/blog adminAddr post, edit, moderate the official blog
r/gnoland/boards2/v1 gPerms = initRealmPermissions(…) realm permissions owner

Confirmed with gno tool deplist -test-dep over the mainnet FILTERED_PACKAGES: both reach genesis. r/gnoland/home and r/demo/defi/foo20 hardcode the same address but do not reach genesis, so they are out of scope here.

These are ordinary paid transactions, forever, and the owner is fixed at realm source — it cannot be reassigned without a realm upgrade. An owner that lands at zero under §126 with no faucet cannot post to the chain's own blog or administer its own boards, and cannot be topped up until the transfer lock lifts.

So this is a service float for realm operation, not a governance grant. GovDAO voting is paid by whoever proposes; that is unaffected, and §120 is not being asked to fund governance.

Which bucket pays

§120, the Core Treasury — "Core Software + Essential Services", the same as the approvals oracle. Operating the chain's own blog and boards is an essential service of the core software. The other two exclude it as before: §122 is "validation services only", and §121 is "External Contributions" with §346 restricting it to identified human contributors.

Why 5,000 and not 1,000

The same tier as the oracle after #80, for the same shape of reason — different in the details:

  • two realms, not one daemon;
  • episodic spend, not per-event;
  • but the window is the whole transfer lock: the pinned §132 schedules run to 2028-09-11, so "until §126 lifts" is years, not weeks.

At the 1,000,000 ugnot default gas fee that is ~5,000 owner actions across both realms. Still a float, not a standing budget — topping it up is GovDAO's business once §126 lifts.

Supply-neutral

before after
Core Treasury (§120) 39,989,000 39,984,000
balances.txt.gz accounts 3,262,480 3,262,481
balances.txt.gz total 1,332,999,998.328067 1,332,999,998.328067

Charged out of §120, not added beside it. The new row is byte-identical in shape to the oracle's:

g1yaaa6rcp4ew5yjzdj4yms596wx2dtrj3a86704=5000000000ugnot;vesting=4800000000ugnot,1789084800,1852243200
g1skl80cuz8zq3lul9pgz5pc35l2pfzgxgfpsqkx=5000000000ugnot;vesting=4800000000ugnot,1789084800,1852243200

New artifact checksums (SHA256SUMS updated in this PR):

7543eb026f24962f446c215c1481845d78c0d65bca0e05bc163bf3be79448070  allocate/genbalance.txt.gz
f78673663f8d5045c402a4bb90039e4b51d308e21acc17c74e6e86e36b09ed08  mkgenesis/balances.txt.gz

make verify passes: unit tests, the independent cross-check (balance files match), and the supply total.

Follow-up

gnolang/gno's misc/deployments/mainnet.gno.land/gen-genesis.sh needs the URL + sha re-pinned to this commit once merged, and its TODO(mainnet) at the NAMES_ADMIN line should be rewritten — the address is funded, but not for the reason the TODO gives. Tracked in gnolang/gno#6154.

g1skl80cuz8zq3lul9pgz5pc35l2pfzgxgfpsqkx held nothing. It was excluded from
chainServices in #79 on the grounds that a governance body is not a service, so
§120 Core may not be its bucket. That reasoned from the wrong capability.

The reason given at the time was gnolang/gno's NAMES_ADMIN, and r/sys/names is
the one realm where the objection holds: its `admin` gates Enable() and nothing
else, Enable is a one-shot genesis call, and the realm's own source calls the
address "dead weight" afterwards -- pause/unpause runs through a GovDAO T1
proposal (ProposeSetPaused), not through this key. Funding it for names
administration really would have been funding nothing.

But the same address is the hardcoded OWNER of two realms that ship in the
mainnet genesis set:

  r/gnoland/blog         adminAddr   post, edit, moderate the official blog
  r/gnoland/boards2/v1   gPerms      realm permissions owner

Confirmed against gnolang/gno master with `gno tool deplist -test-dep` over the
mainnet FILTERED_PACKAGES. r/gnoland/home and r/demo/defi/foo20 hardcode the
same address but do not reach genesis, so they are not part of this.

Those are ordinary paid txs, forever, and the owner is fixed at realm source --
it cannot be reassigned without a realm upgrade. An owner that lands at zero
under §126 with no faucet cannot post to the chain's own blog or administer its
own boards, and cannot be topped up until the transfer lock lifts. So this is a
service float for realm operation, not a governance grant: GovDAO voting is paid
by whoever proposes, and that is unaffected.

Same 5,000 GNOT tier as the approvals oracle, for the same shape of reason: two
realms rather than one daemon, episodic rather than per-event spend, and a
window that is the whole transfer lock -- the pinned §132 schedules run to
2028-09-11, so "until §126 lifts" is years. At the 1,000,000 ugnot default gas
fee that is ~5,000 owner actions across both realms.

Supply-neutral: Core goes 39,989,000 -> 39,984,000 and the sheet total is
unchanged at 1,332,999,998.328067 GNOT. Account count 3,262,480 -> 3,262,481.

  genbalance.txt.gz 7543eb026f24962f446c215c1481845d78c0d65bca0e05bc163bf3be79448070
  balances.txt.gz   f78673663f8d5045c402a4bb90039e4b51d308e21acc17c74e6e86e36b09ed08
@moul
moul merged commit 0108ede into main Sep 11, 2026
1 check passed
moul added a commit to gnolang/gno that referenced this pull request Sep 11, 2026
…de (#6169)

## Description

**Stacked on #6154** (base: `chain/mainnet`). Picks up
[independence-day#81](gnolang/independence-day#81),
merged as
[`0108ede`](gnolang/independence-day@0108ede).

| | before | after |
|---|---|---|
| `ALLOCATION_GZ_URL` | `…/raw/0927710/…` | `…/raw/0108ede/…` |
| `ALLOCATION_SHA256` | `10ce896b…` | `f7867366…` |
| `ALLOCATION_EXPECTED_ACCOUNTS` | 3,262,480 | **3,262,481** |
| `ALLOCATION_EXPECTED_TOTAL` | 1,332,999,998.328067 GNOT |
**unchanged** |
| `UNRESTRICTED_URL` | `…/raw/0927710/…` | `…/raw/0108ede/…` |
| `UNRESTRICTED_SHA256` | `7b37a168…` | **unchanged** |

Both pins move together, as before. The exemption list is byte-identical
at the new commit — verified by downloading it and hashing, not assumed
— so only its URL advances.

The one new account is `g1skl80cuz8zq3lul9pgz5pc35l2pfzgxgfpsqkx` at
5,000 GNOT, charged **out of** the §120 Core Treasury (39,989,000 →
39,984,000), so the supply is unchanged.

## The `NAMES_ADMIN` TODO is replaced, not deleted — the reason it gave
was wrong

The TODO said the address needed funding because *"any later names
administration is a paid tx it cannot pay for."* That capability does
not exist:

- `r/sys/names`' `admin` gates `Enable()` **and nothing else**;
- `Enable` is a one-shot genesis call and the flag is sticky;
- the realm's own source says *"After that the address is dead weight —
no further capability flows through it"*;
- pause/unpause runs through a GovDAO T1 proposal (`ProposeSetPaused`),
not this key;
- there is no `SetEnabled(false)` and no `SetAdmin`.

Funding it for names administration would have been funding nothing.

**The real exposure** is that the same address is the hardcoded owner of
two realms that ship in this genesis set:

| realm | binding |
|---|---|
| `r/gnoland/blog` | `adminAddr` |
| `r/gnoland/boards2/v1` | `gPerms = initRealmPermissions(…)` |

Ownership is fixed at realm source — not reassignable without a realm
upgrade — and every owner action is a paid tx. An owner at zero under
§126 with no faucet could not post to the chain's own blog or administer
its own boards, and could not be topped up until the transfer lock
lifts.

Confirmed with `gno tool deplist -test-dep` over `FILTERED_PACKAGES`.
`r/gnoland/home` and `r/demo/defi/foo20` hardcode the same address but
do **not** reach genesis, so they are out of scope.

## Derived numbers moved with the sheet

Re-pinning is not just three constants — several reviewed claims are
stated in prose and go stale silently:

- the vesting narrative at the `-vesting-start` guard: 3,262,416 of
3,262,480 continuous → **3,262,417 of 3,262,481** (recounted from the
artifact, not incremented on faith);
- the `VESTED_ACCOUNTS` redundancy note and the fee-payer∩vested TODO,
both of which name the pin commit;
- `README.md`'s account line and its `main @ 0927710` reference;
- the pin history block, now five commits and +8 accounts since
`91f7f56`.

## Verification

- `bash -n gen-genesis.sh` — clean.
- The pinned artifact was downloaded from the new commit and hashed:
`f78673663f8d5045c402a4bb90039e4b51d308e21acc17c74e6e86e36b09ed08`,
3,262,481 rows, 1,332,999,998,328,067 ugnot — matching all three
declared constants.
- The exemption list at the new commit hashes to the unchanged
`7b37a168…`, 120 lines.
- Vesting shape re-counted old vs new: rows +1, with-schedule +1,
unscheduled unchanged at 63, one `;type=delayed` — a clean single-row
delta with no reshaping.

The genesis build itself is not run here; it still stops at the
fee-payer ∩ vested-allocation decision (`TODO(mainnet)`, step 8), which
this PR does not touch.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants