Repository navigation
feat: fund the founding validator set with a 1,000 GNOT gas float - #78
Merged
Merged
Conversation
The four gnoland-1 founding validators are seeded as (signing address, operator address) pairs -- `gnogenesis fork valoper-seed` requires the two to be distinct so that a compromised signing key does not become control of the validator slot. Six of those eight addresses held nothing in the sheet. Every management action on a validator is a paid transaction: rotating the signing key, editing the valoper profile, signalling opt-out. There is no mainnet faucet and Constitution §126 locks ugnot transfers to the §127 exemption list, so an address that lands at zero at genesis can never be funded afterwards and can never act. This closes the INITIAL_VALSET_OPERATORS TODO(mainnet) in gnolang/gno's misc/deployments/mainnet.gno.land. 1,000 GNOT each, the same tier as the founders grant and the multisig signer float, charged to the §122 Validator Services Treasury (§346 rules Ecosystem out; Core already carries the founders). Two of the eight are skipped because they are already funded -- aeddi by the founders grant, the Berty operator by the signer float -- and their 1,000 stays in §122, exactly as Jae's skipped founders grant stays in Core. Supply-neutral: the Validator Services Treasury goes 20,000,000 -> 19,994,000 and the sheet total is unchanged at 1,332,999,998.328067 GNOT. Account count 3,262,473 -> 3,262,479. balances.txt.gz 517c17546fba721dcbfcaa01d51a5772be253df4afe9499bdc5206f131021ab3 genbalance.txt.gz 4228b52fafa4bb09f7fbb88a5e8c6a13fbf04acd7b617997a01ddab56fb4de3f
This was referenced Sep 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The four founding validators of
gnoland-1are seeded as (signing address, operator address) pairs —gnogenesis fork valoper-seedrequires the two to be distinct, so that compromising a signing key does not collapse into control of the validator slot. That is eight addresses, and six of them held nothing in the sheet:g1mmgvcs…❌g1aeddlf…✅ founders grantg1hqhetn…❌g12gtvlc…❌g15t7f9q…❌g1n9y62a…❌g1l983yy…❌g1qynsu9…✅ signer floatEvery management action on a validator is a paid transaction: rotating the signing key, editing the valoper profile in
r/gnops/valopers, signalling opt-out throughr/sys/validators. There is no mainnet faucet, and Constitution §126 locksugnottransfers to the §127 exemption list — so an address that lands at zero at genesis can never be funded afterwards and can never act. This closes theINITIAL_VALSET_OPERATORSTODO(mainnet)ingnolang/gno'smisc/deployments/mainnet.gno.land/gen-genesis.sh, which asks for exactly this decision.1,000 GNOT each — the same tier as the GovDAO founders grant and the multisig signer float in
mkgenesis/non-airdrop.txt. It is a float so a genesis validator can act, not a payment for validating.Which bucket pays
§122, the Validator Services Treasury. A float that exists solely so a founding validator can rotate its key, edit its profile or opt out is a validator service. The alternatives both fail §226's purpose test: §346 restricts Ecosystem to "contributors whose real human identity is known and recorded" — the clause that removed the faucet — and Core already carries the founders.
Two of the eight are skipped because they are already funded to the same tier; their 1,000 simply stays in §122, exactly the shape of Jae's skipped founders grant staying in Core (#62 / the
govdaoFoundersSkippedprecedent):g1aeddlf…— gno-core operator (aeddi), holds the 1,000 GNOTgovdaoFoundersgrant. Funding again would panic inassign().g1qynsu9…— berty operator, holds the 1,000 GNOT multisig signer float. Funding again would silently become 2,000 viaaccumulate().Supply-neutral
balances.txt.gzaccountsbalances.txt.gztotalThe float is charged out of §122, not added beside it, so the cap does not move. The six new rows are whole GNOT, so the truncation residual is unchanged too.
New artifact checksums (
SHA256SUMSupdated in this PR):Vesting
The six new rows carry the standard §132 schedule like every other row (4% at genesis, linear to 2028-09-11). That is deliberate and does not weaken the float: genesis-time fees are collected with
SendCoinsUnrestricted, which bypasses both the vesting lock and the §126 restriction. No §132 exemption is claimed here — §136 admits exactly one, and this is not it.Guards
TestGenesisValidatorFloatMatchesSkipList— the amount charged to §122 is exactly what is paid out, with no remainder. Adding a validator without raising the budget, or skipping one without lowering it, is a red build.TestGenesisValidatorsAreFunded— asserts the end state on the shipped sheet: all eight addresses hold ≥ 1,000 GNOT, whichever line put it there. A skip is only safe while the other funding line exists; delete either one and this fails here rather than at launch.validateHardcodedAddresses()— the valset is its own namespace (a duplicated slot is a transcription error and is caught even when both copies are skipped), a skip-list entry that is not in the valset panics, and no address may be paid by two roles.TestSplitPreservesTheAggregate— everything charged out of the three treasuries still sums inside the 120M.Each was verified by tripping it: an unfunded validator address, a budget one off the skip list, a skip-list entry absent from the valset, a slot listed twice, and an address paid by two roles.
Testing
make verifygreen — 47 tests, independent cross-check reportsBalance files match.,make checksumsOK. The pipeline was run twice end to end and produced byte-identical artifacts (GNU gzip 1.12, darwin/arm64).Note for review
genesisValidatorsis a mirror ofgnolang/gno'sINITIAL_VALSET+INITIAL_VALSET_OPERATORS. If the valset changes there, it must change here. Funding the signing addresses as well as the operators is a judgement call: it puts 1,000 GNOT on keys that live in tmkms/horcrux/an HSM. The reasoning is that §126 makes an unfunded address permanently unfundable, so the cost of guessing wrong in that direction is unrecoverable and the cost of guessing wrong in this direction is 4,000 GNOT. Dropping the four signing rows is four deleted lines if that trade is unwanted.