The Baal read adapter (PR #34) was pointed at incorrect contract addresses, so config() read all-zero governance values and the documented Shares/Loot tokens returned totalSupply=0. This PR corrects the addresses to the verified live Kokonut DAO deployment on Gnosis Chain and hardens the adapter against getters this deployment does not expose.
services/ingestion/config.py: KOKONUT_BAAL_ADDRESSES now uses the verified addresses; removed stale 0x5DcE1044 / 0x8124Cb / 0x0444AE / 0xd9Db270.
services/governance/baal.py: config() reads only the getters this deployment exposes and fails soft on the rest (previously baalVersion() crashed the whole call). proposals()/proposal() degrade gracefully when individual proposal structs cannot be decoded with the committed Baal ABI.
python3 -m services.migration dry-run -> 114 would apply, 0 failed
python3 -m services.governance.cli baal config returns real config from the Kokonut DAO
ruff clean on modified files
Notes
proposalCount=16 but individual proposal structs use a storage layout the committed Baal.json ABI cannot decode; baal proposals now reports this clearly instead of crashing. Decoding requires either an updated ABI or the baal_indexer populating governance_event.
The legacy Moloch v2 indexer (gnosis_indexer.py) and KOKONUT_MOLOCH_ADDRESSES are untouched.
Cross-reference
Follow-up to PR #34 (read-first Baal integration).
- KOKONUT_BAAL_ADDRESSES now points at the verified Moloch v3 (Baal) core
0x8977c56e... with shares 0xc6b075ac... (vKKN) and loot 0x2508a11a...,
treasury 0xeb55b753... (Gnosis Safe). Removes stale 0x5DcE1044 /
0x8124Cb / 0x0444AE / 0xd9Db270 addresses.
- BaalReadClient.config() reads only the getters this deployment exposes
(totalShares, totalLoot, votingPeriod, gracePeriod, quorumPercent,
sharesToken, lootToken, avatar, proposalCount) and fails soft on the rest
instead of raising (baalVersion previously crashed the whole call).
- proposals()/proposal() degrade gracefully when individual proposal structs
cannot be decoded with the committed Baal ABI.
- Baal.json ABI gains proposalCount, sharesToken, lootToken, avatar.
- 020_gnosis_chain.sql seed aligned to verified addresses (idempotent upsert).
- Optional live smoke test (RUN_LIVE_BAAL_TEST=1) asserts on-chain reads.
PR #34 added migration 324_baal_governance.sql (creates governance_framework,
baal_governance_config, baal_shaman; extends dao_proposal) and the 'dao' mount
in services/cli.py, but the fix/baal-addresses branch was branched from main
before those landed, so the seed 020_gnosis_chain.sql INSERT into
governance_framework failed CI with 'relation does not exist'.
- Restore schemas/postgres/324_baal_governance.sql from the Baal integration.
- Restore the read-only 'dao' typer mount in services/cli.py.
Migration dry-run: 115 would apply, 0 failed; validate passes.
- KOKONUT_BAAL_ADDRESSES now points at the verified Moloch v3 (Baal) core
0x8977c56e... with shares 0xc6b075ac... (vKKN) and loot 0x2508a11a...,
treasury 0xeb55b753... (Gnosis Safe). Removes stale 0x5DcE1044 /
0x8124Cb / 0x0444AE / 0xd9Db270 addresses.
- BaalReadClient.config() reads only the getters this deployment exposes
(totalShares, totalLoot, votingPeriod, gracePeriod, quorumPercent,
sharesToken, lootToken, avatar, proposalCount) and fails soft on the rest
instead of raising (baalVersion previously crashed the whole call).
- proposals()/proposal() degrade gracefully when individual proposal structs
cannot be decoded with the committed Baal ABI.
- Baal.json ABI gains proposalCount, sharesToken, lootToken, avatar.
- 020_gnosis_chain.sql seed aligned to verified addresses (idempotent upsert).
- Optional live smoke test (RUN_LIVE_BAAL_TEST=1) asserts on-chain reads.
Summary
The Baal read adapter (PR #34) was pointed at incorrect contract addresses, so
config()read all-zero governance values and the documented Shares/Loot tokens returnedtotalSupply=0. This PR corrects the addresses to the verified live Kokonut DAO deployment on Gnosis Chain and hardens the adapter against getters this deployment does not expose.Verified on-chain (Gnosis Chain id=100)
0x8977c56e979f0d8b76afb5ad85549acd2e96422davatar=treasury Safe,sharesToken=vKKN,lootToken=loot,totalShares=687e18,votingPeriod=432000,gracePeriod=2592000xeb55b75328a8dffd45bbf34b7e7efc431a179085avatartarget of Baal0xc6b075ac3234a7ac729114b27370b552fa284690sharesToken; supply 687e180x2508a11aee11ad545bae87cd42131c04613b2099lootToken; Loot supply 8e18Changes
services/ingestion/config.py:KOKONUT_BAAL_ADDRESSESnow uses the verified addresses; removed stale0x5DcE1044/0x8124Cb/0x0444AE/0xd9Db270.services/governance/baal.py:config()reads only the getters this deployment exposes and fails soft on the rest (previouslybaalVersion()crashed the whole call).proposals()/proposal()degrade gracefully when individual proposal structs cannot be decoded with the committed Baal ABI.contracts/abis/Baal.json: addedproposalCount,sharesToken,lootToken,avatar.schemas/seeds/020_gnosis_chain.sql: alignedwallet_profile/governance_frameworkrows to verified addresses (idempotent upsert; legacymoloch_v2row marked historical, no longer claims the Baal-core address).services/governance/cli.py:baal proposalssurfaces a helpful note when proposal structs are undecodable.tests/test_governance_framework.py: added an opt-in live smoke test (RUN_LIVE_BAAL_TEST=1) asserting on-chain reads.Verification
python3 -m pytest tests/test_governance_framework.py-> 7 passed, 1 skipped (live test skipped unless opted in)RUN_LIVE_BAAL_TEST=1 python3 -m pytest tests/test_governance_framework.py-> 8 passed (real chain)python3 -m services.migration dry-run-> 114 would apply, 0 failedpython3 -m services.governance.cli baal configreturns real config from the Kokonut DAONotes
proposalCount=16 but individual proposal structs use a storage layout the committedBaal.jsonABI cannot decode;baal proposalsnow reports this clearly instead of crashing. Decoding requires either an updated ABI or thebaal_indexerpopulatinggovernance_event.gnosis_indexer.py) andKOKONUT_MOLOCH_ADDRESSESare untouched.Cross-reference
Follow-up to PR #34 (read-first Baal integration).