From f010060b6dd9faa8bc15851ea00cbe99143f746b Mon Sep 17 00:00:00 2001 From: chaojun Date: Thu, 5 Mar 2026 17:39:25 +0800 Subject: [PATCH 1/4] No proxy in collectives Dao space --- .../fix-collectives-dao-space-config.js | 26 +++++++++++++++++++ .../backend/src/scripts/spaces/jamdao.js | 16 +----------- .../backend/src/scripts/spaces/permanence.js | 16 +----------- .../backend/src/scripts/spaces/truthdao.js | 18 +++---------- .../createWhitelistProposal.js | 6 ++++- .../src/services/proposal.service/vote.js | 6 ++++- 6 files changed, 41 insertions(+), 47 deletions(-) create mode 100644 backend/packages/backend/src/scripts/fix-collectives-dao-space-config.js diff --git a/backend/packages/backend/src/scripts/fix-collectives-dao-space-config.js b/backend/packages/backend/src/scripts/fix-collectives-dao-space-config.js new file mode 100644 index 00000000..2a535736 --- /dev/null +++ b/backend/packages/backend/src/scripts/fix-collectives-dao-space-config.js @@ -0,0 +1,26 @@ +require("dotenv").config(); + +const { daoSpaces } = require("./spaces"); +const { getSpaceCollection } = require("../mongo"); + +async function main() { + const col = await getSpaceCollection(); + for (const item of daoSpaces) { + await col.updateOne( + { id: item.id }, + { + $set: item, + $unset: { + whitelist: "", + symbol: "", + decimals: "", + networks: "", + }, + }, + ); + } +} + +main() + .catch(console.error) + .finally(() => process.exit()); diff --git a/backend/packages/backend/src/scripts/spaces/jamdao.js b/backend/packages/backend/src/scripts/spaces/jamdao.js index 02757e9c..3f5f2dd1 100644 --- a/backend/packages/backend/src/scripts/spaces/jamdao.js +++ b/backend/packages/backend/src/scripts/spaces/jamdao.js @@ -1,11 +1,9 @@ const { Accessibility, SpaceType } = require("../../consts/space"); -const { networks, strategies } = require("./consts"); +const { strategies } = require("./consts"); const config = { id: "jamdao", name: "JAM DAO", - symbol: "DOT", - decimals: 10, accessibility: Accessibility.WHITELIST, type: SpaceType.CollectivesDao, members: [ @@ -26,18 +24,6 @@ const config = { "15R1pWegyu7AfMev8DBMT67qxYoJhA1v7BbA2nn7S2uJ5QDF", // JamBrains "15fGrDWmFoaApnZXEw1Zg45zuCqpkbMS9YPzczeU9dHseUUu", // Fluffy Labs ], - networks: [ - { - network: networks.polkadot, - ss58Format: 0, - assets: [ - { - symbol: "DOT", - decimals: 10, - }, - ], - }, - ], weightStrategy: [strategies.onePersonOneVote], version: "4", spaceIcon: "jamdao.svg", diff --git a/backend/packages/backend/src/scripts/spaces/permanence.js b/backend/packages/backend/src/scripts/spaces/permanence.js index c4e2ab51..83729336 100644 --- a/backend/packages/backend/src/scripts/spaces/permanence.js +++ b/backend/packages/backend/src/scripts/spaces/permanence.js @@ -1,11 +1,9 @@ const { Accessibility, SpaceType } = require("../../consts/space"); -const { networks, strategies } = require("./consts"); +const { strategies } = require("./consts"); const config = { id: "permanence", name: "Permanence DAO", - symbol: "DOT", - decimals: 10, accessibility: Accessibility.WHITELIST, type: SpaceType.CollectivesDao, members: [ @@ -23,18 +21,6 @@ const config = { "13znFMMjHyM2UvSewvaKMC2bLUcySRMzcM8BAMTzm1G2P5ju", // PERMANENCE DAO/GOV-PROXY "12KtA8mtfsK1CyQb4utLiwG3ao22z77w2cM2GqnaL2RiDCoJ", // Flez ], - networks: [ - { - network: networks.polkadot, - ss58Format: 0, - assets: [ - { - symbol: "DOT", - decimals: 10, - }, - ], - }, - ], weightStrategy: [strategies.onePersonOneVote], version: "4", spaceIcon: "permanence.svg", diff --git a/backend/packages/backend/src/scripts/spaces/truthdao.js b/backend/packages/backend/src/scripts/spaces/truthdao.js index a617e89e..0ab8bff9 100644 --- a/backend/packages/backend/src/scripts/spaces/truthdao.js +++ b/backend/packages/backend/src/scripts/spaces/truthdao.js @@ -1,11 +1,9 @@ const { Accessibility, SpaceType } = require("../../consts/space"); -const { networks, strategies } = require("./consts"); +const { strategies } = require("./consts"); const config = { id: "truthdao", name: "Truth DAO", - symbol: "DOT", - decimals: 10, accessibility: Accessibility.WHITELIST, type: SpaceType.CollectivesDao, members: [ @@ -16,18 +14,7 @@ const config = { "16ap6fdqS2rqFsyYah35hX1FH6rPNWtLqqXZDQC9x6GW141C", // Lurpis "14pa3BAYZLPvZfRDjWEfZXZWBVU45E67HUQEUxNCrdXGoata", // Tiny/Mimir "14qwyVVvW4Tuhq4Fvt2AHZqhbCtGfVb8HUY2xM2PKrzKsmZT", - ], - networks: [ - { - network: networks.polkadot, - ss58Format: 0, - assets: [ - { - symbol: "DOT", - decimals: 10, - }, - ], - }, + "12ZBQqk7SD9qA7qPwpzAND6ZznXtgZuCMFWZr8xpdsVdbeva", ], weightStrategy: [strategies.onePersonOneVote], version: "4", @@ -36,6 +23,7 @@ const config = { admins: [ "15MFgTrCqjnLRPkDymuuhBMpzxQmcRyfFDETRiEtBRjpfLzE", "14gMJV95zwxUsFEZDSC8mtBVifS6SypKJkfBKANkMsLZdeVb", // Yongfeng + "12ZBQqk7SD9qA7qPwpzAND6ZznXtgZuCMFWZr8xpdsVdbeva", ], }; diff --git a/backend/packages/backend/src/services/proposal.service/createWhitelistProposal.js b/backend/packages/backend/src/services/proposal.service/createWhitelistProposal.js index fe3bdc3b..18fa1050 100644 --- a/backend/packages/backend/src/services/proposal.service/createWhitelistProposal.js +++ b/backend/packages/backend/src/services/proposal.service/createWhitelistProposal.js @@ -1,3 +1,4 @@ +const { SpaceType } = require("../../consts/space"); const { HttpError } = require("../../exc"); const { spaces: spaceServices } = require("../../spaces"); const { isSameAddress } = require("../../utils/address"); @@ -34,7 +35,10 @@ async function createWhitelistProposal({ const spaceService = spaceServices[space]; const weightStrategy = spaceService.weightStrategy; - if (realProposer && realProposer !== address) { + if (realProposer && !isSameAddress(realProposer, address)) { + if (networksConfig?.type === SpaceType.CollectivesDao) { + throw new HttpError(400, "Proxy is not allowed in collectives DAO"); + } const lastHeight = await getLatestHeight(proposerNetwork); await checkProxy(proposerNetwork, address, realProposer, lastHeight); } diff --git a/backend/packages/backend/src/services/proposal.service/vote.js b/backend/packages/backend/src/services/proposal.service/vote.js index 0495cdbf..fff18946 100644 --- a/backend/packages/backend/src/services/proposal.service/vote.js +++ b/backend/packages/backend/src/services/proposal.service/vote.js @@ -16,7 +16,7 @@ const { adaptBalance } = require("../../utils/balance"); const { getDemocracyDelegated } = require("../node.service/getDelegated"); const { findDelegationStrategies } = require("../../utils/delegation"); const { getSocietyMember } = require("../node.service/getSocietyMember"); -const { Accessibility } = require("../../consts/space"); +const { Accessibility, SpaceType } = require("../../consts/space"); const { hasBalanceStrategy, hasSocietyStrategy, @@ -146,6 +146,10 @@ async function checkProxy({ proposal, voterNetwork, address, realVoter }) { return; } + if (proposal.networksConfig?.type === SpaceType.CollectivesDao) { + throw new HttpError(400, "Proxy is not allowed in collectives DAO"); + } + const snapshotHeight = proposal.snapshotHeights?.[voterNetwork]; await _checkProxy(voterNetwork, address, realVoter, snapshotHeight); } From 87d23d2a9e2dc4d7a234e9b3f511c97710fc6182 Mon Sep 17 00:00:00 2001 From: chaojun Date: Thu, 5 Mar 2026 17:42:07 +0800 Subject: [PATCH 2/4] Remove debug data --- backend/packages/backend/src/scripts/spaces/truthdao.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/backend/packages/backend/src/scripts/spaces/truthdao.js b/backend/packages/backend/src/scripts/spaces/truthdao.js index 0ab8bff9..2533fc9c 100644 --- a/backend/packages/backend/src/scripts/spaces/truthdao.js +++ b/backend/packages/backend/src/scripts/spaces/truthdao.js @@ -14,7 +14,6 @@ const config = { "16ap6fdqS2rqFsyYah35hX1FH6rPNWtLqqXZDQC9x6GW141C", // Lurpis "14pa3BAYZLPvZfRDjWEfZXZWBVU45E67HUQEUxNCrdXGoata", // Tiny/Mimir "14qwyVVvW4Tuhq4Fvt2AHZqhbCtGfVb8HUY2xM2PKrzKsmZT", - "12ZBQqk7SD9qA7qPwpzAND6ZznXtgZuCMFWZr8xpdsVdbeva", ], weightStrategy: [strategies.onePersonOneVote], version: "4", @@ -23,7 +22,6 @@ const config = { admins: [ "15MFgTrCqjnLRPkDymuuhBMpzxQmcRyfFDETRiEtBRjpfLzE", "14gMJV95zwxUsFEZDSC8mtBVifS6SypKJkfBKANkMsLZdeVb", // Yongfeng - "12ZBQqk7SD9qA7qPwpzAND6ZznXtgZuCMFWZr8xpdsVdbeva", ], }; From 1fe8b4dc0e149e590f1b3049905867b144b0fdef Mon Sep 17 00:00:00 2001 From: chaojun Date: Thu, 5 Mar 2026 18:17:27 +0800 Subject: [PATCH 3/4] feat: allow unused fields in proposal creation config --- backend/packages/backend/package.json | 1 + .../src/features/proposals/createProposal.js | 51 +++++++++++-------- backend/yarn.lock | 5 ++ 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/backend/packages/backend/package.json b/backend/packages/backend/package.json index 926f3978..f7438b46 100644 --- a/backend/packages/backend/package.json +++ b/backend/packages/backend/package.json @@ -30,6 +30,7 @@ "lodash.flatten": "^4.4.0", "lodash.isempty": "^4.4.0", "lodash.isequal": "^4.5.0", + "lodash.ismatch": "^4.4.0", "lodash.isnil": "^4.0.0", "lodash.omit": "^4.5.0", "lodash.uniq": "^4.5.0", diff --git a/backend/packages/backend/src/features/proposals/createProposal.js b/backend/packages/backend/src/features/proposals/createProposal.js index ce9dc536..62e9b21d 100644 --- a/backend/packages/backend/src/features/proposals/createProposal.js +++ b/backend/packages/backend/src/features/proposals/createProposal.js @@ -3,9 +3,9 @@ const proposalService = require("../../services/proposal.service"); const { ChoiceType } = require("../../constants"); const isEmpty = require("lodash.isempty"); const { spaces: spaceServices } = require("../../spaces"); -const { Accessibility } = require("../../consts/space"); +const { Accessibility, SpaceType } = require("../../consts/space"); const { checkProposalContent } = require("./checkProposalContent"); -const isEqual = require("lodash.isequal"); +const isMatch = require("lodash.ismatch"); const pick = require("lodash/pick"); const { getLatestHeight } = require("../../services/chain.service"); const { strategies } = require("../../consts/voting"); @@ -85,9 +85,10 @@ async function checkSnapshotHeights(data) { const { networksConfig, snapshotHeights } = data; if ( - networksConfig.accessibility === Accessibility.WHITELIST && - networksConfig.strategies?.length === 1 && - networksConfig.strategies[0] === strategies.onePersonOneVote + networksConfig.type === SpaceType.CollectivesDao || + (networksConfig.accessibility === Accessibility.WHITELIST && + networksConfig.strategies?.length === 1 && + networksConfig.strategies[0] === strategies.onePersonOneVote) ) { // We don't need snapshotHeights in this case return; @@ -141,21 +142,31 @@ function checkNetworkConfig(data) { } const spaceService = spaceServices[space]; - const spaceNetworksConfig = { - ...pick(spaceService, [ - "type", - "symbol", - "decimals", - "networks", - "accessibility", - "whitelist", - "members", - ]), - strategies: spaceService.weightStrategy, - ...pick(spaceService, ["quorum", "version"]), - }; - - if (!isEqual(networksConfig, spaceNetworksConfig)) { + + let spaceNetworksConfig = {}; + if (spaceService.type === SpaceType.CollectivesDao) { + spaceNetworksConfig = { + ...pick(spaceService, ["type", "accessibility", "whitelist", "members"]), + strategies: spaceService.weightStrategy, + ...pick(spaceService, ["quorum", "version"]), + }; + } else { + spaceNetworksConfig = { + ...pick(spaceService, [ + "type", + "symbol", + "decimals", + "networks", + "accessibility", + "whitelist", + "members", + ]), + strategies: spaceService.weightStrategy, + ...pick(spaceService, ["quorum", "version"]), + }; + } + + if (!isMatch(networksConfig, spaceNetworksConfig)) { throw new HttpError(400, { networksConfig: [ "The proposal networks config is not matching the space config", diff --git a/backend/yarn.lock b/backend/yarn.lock index 895ea3a1..a4f88a68 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -5380,6 +5380,11 @@ lodash.isequal@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== +lodash.ismatch@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" + integrity sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g== + lodash.isnil@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/lodash.isnil/-/lodash.isnil-4.0.0.tgz#49e28cd559013458c814c5479d3c663a21bfaa6c" From 6cf124ec1d1ac56e5e1a098e06aa98ea15e0e5e2 Mon Sep 17 00:00:00 2001 From: chaojun Date: Thu, 5 Mar 2026 18:19:32 +0800 Subject: [PATCH 4/4] Simplify --- .../src/features/proposals/createProposal.js | 36 +++++++------------ 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/backend/packages/backend/src/features/proposals/createProposal.js b/backend/packages/backend/src/features/proposals/createProposal.js index 62e9b21d..23ee0e1a 100644 --- a/backend/packages/backend/src/features/proposals/createProposal.js +++ b/backend/packages/backend/src/features/proposals/createProposal.js @@ -142,29 +142,19 @@ function checkNetworkConfig(data) { } const spaceService = spaceServices[space]; - - let spaceNetworksConfig = {}; - if (spaceService.type === SpaceType.CollectivesDao) { - spaceNetworksConfig = { - ...pick(spaceService, ["type", "accessibility", "whitelist", "members"]), - strategies: spaceService.weightStrategy, - ...pick(spaceService, ["quorum", "version"]), - }; - } else { - spaceNetworksConfig = { - ...pick(spaceService, [ - "type", - "symbol", - "decimals", - "networks", - "accessibility", - "whitelist", - "members", - ]), - strategies: spaceService.weightStrategy, - ...pick(spaceService, ["quorum", "version"]), - }; - } + const spaceNetworksConfig = { + ...pick(spaceService, [ + "type", + "symbol", + "decimals", + "networks", + "accessibility", + "whitelist", + "members", + ]), + strategies: spaceService.weightStrategy, + ...pick(spaceService, ["quorum", "version"]), + }; if (!isMatch(networksConfig, spaceNetworksConfig)) { throw new HttpError(400, {