Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New society strategy, #1034 #1039

Merged
merged 2 commits into from
Sep 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions backend/packages/backend/src/consts/voting.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const strategies = Object.freeze({
quorumQuadraticBalanceOf: "quorum-quadratic-balance-of",
biasedVoting: "biased-voting",
onePersonOneVote: "one-person-one-vote",
society: "society",
});

module.exports = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const config = {
],
},
],
weightStrategy: [strategies.onePersonOneVote],
weightStrategy: [strategies.society],
version: "4",
spaceIcon: "kusamasociety.png",
seoImage: "QmYB3YVU3Sa27EfqTk3cGZ9S3GhiH6Z2ANpQdHKETpRrEZ",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ async function getSocietyMember(network, address, height) {
if (isTestAccount(address)) {
return {
data: {
rank: 0,
rank: 1,
strikes: 10,
vouching: null,
index: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ const calcWeights = (vote, decimals) => {
vote.weights.balanceOf?.toString(),
decimals,
),
societyVote: vote.weights.societyVote?.toString(),
details: vote.weights.details,
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,30 @@ async function getProposalById(proposalId) {

const votes = await voteCol.find({ proposal: proposal._id }).toArray();
const calculatedVotes = votes.map((v) => calcWeights(v, decimals));

const votedWeights = {};

for (const vote of calculatedVotes) {
votedWeights.balanceOf = new BigNumber(votedWeights.balanceOf || 0)
.plus(vote.weights.balanceOf)
.plus(vote.weights.balanceOf || 0)
.toString();
votedWeights.quadraticBalanceOf = new BigNumber(
votedWeights.quadraticBalanceOf || 0,
)
.plus(vote.weights.quadraticBalanceOf)
.plus(vote.weights.quadraticBalanceOf || 0)
.toString();

votedWeights.onePersonOneVote = new BigNumber(
votedWeights.onePersonOneVote || 0,
)
.plus(1)
.toString();

votedWeights.societyVote = new BigNumber(votedWeights.societyVote || 0)
.plus(vote.weights.societyVote || 0)
.toString();
}

proposal.votesCount = votesCount;
proposal.votedWeights = votedWeights;

Expand Down
12 changes: 10 additions & 2 deletions backend/packages/backend/src/services/proposal.service/getStats.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ async function getStats(proposalCid) {
const calculatedVotes = votes.map((v) =>
calcWeights(v, spaceService.decimals),
);

const stats = Object.fromEntries(
proposal.choices.map((choice) => [
choice,
{
choice,
balanceOf: "0",
quadraticBalanceOf: "0",
societyVote: "0",
onePersonOneVote: "0",
votesCount: 0,
},
Expand All @@ -33,14 +35,20 @@ async function getStats(proposalCid) {
for (const vote of calculatedVotes) {
for (const choice of vote.choices) {
const weights = (stats[choice] = stats[choice] || { choice });

weights.balanceOf = new BigNumber(weights.balanceOf || 0)
.plus(vote.weights.balanceOf)
.plus(vote.weights.balanceOf || 0)
.toString();
weights.quadraticBalanceOf = new BigNumber(
weights.quadraticBalanceOf || 0,
)
.plus(vote.weights.quadraticBalanceOf)
.plus(vote.weights.quadraticBalanceOf || 0)
.toString();

weights.societyVote = new BigNumber(weights.societyVote || 0)
.plus(vote.weights.societyVote || 0)
.toString();

weights.onePersonOneVote = new BigNumber(weights.onePersonOneVote || 0)
.plus(1)
.toString();
Expand Down
58 changes: 45 additions & 13 deletions backend/packages/backend/src/services/proposal.service/vote.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ const { getDemocracyDelegated } = require("../node.service/getDelegated");
const { findDelegationStrategies } = require("../../utils/delegation");
const { getSocietyMember } = require("../node.service/getSocietyMember");
const { Accessibility } = require("../../consts/space");
const {
hasBalanceStrategy,
hasSocietyStrategy,
} = require("../../utils/strategy");

async function getDelegatorBalances({
proposal,
Expand Down Expand Up @@ -220,6 +224,22 @@ async function checkSocietyVote({
}
}

async function getSocietyVote({ voterNetwork, voter, snapshotHeight }) {
const societyMember = await getSocietyMember(
voterNetwork,
voter,
snapshotHeight,
);
if (societyMember.data) {
const rank = societyMember.data.rank;
if (rank === 1) {
return 4;
}
return 1;
}
return 0;
}

async function vote(
proposalCid,
choices,
Expand Down Expand Up @@ -255,17 +275,32 @@ async function vote(
const snapshotHeight = proposal.snapshotHeights?.[voterNetwork];
const voter = realVoter || address;

const networkBalance = await getBalanceFromNetwork({
networksConfig: proposal.networksConfig,
networkName: voterNetwork,
address: voter,
blockHeight: snapshotHeight,
});
const weights = {};

const balanceOf = networkBalance?.balanceOf;
const networkBalanceDetails = networkBalance?.details;
if (hasBalanceStrategy(proposal)) {
const networkBalance = await getBalanceFromNetwork({
networksConfig: proposal.networksConfig,
networkName: voterNetwork,
address: voter,
blockHeight: snapshotHeight,
});

const balanceOf = networkBalance?.balanceOf;
const networkBalanceDetails = networkBalance?.details;

await checkVoteThreshold({ networkBalanceDetails, proposal, voterNetwork });

await checkVoteThreshold({ networkBalanceDetails, proposal, voterNetwork });
weights.balanceOf = toDecimal128(balanceOf);
weights.details = networkBalanceDetails;
}

if (hasSocietyStrategy(proposal)) {
weights.societyVote = await getSocietyVote({
voterNetwork,
voter,
snapshotHeight,
});
}

const delegators = await getDelegatorBalances({
proposal,
Expand Down Expand Up @@ -301,10 +336,7 @@ async function vote(
updatedAt: now,
cid,
pinHash,
weights: {
balanceOf: toDecimal128(balanceOf),
details: networkBalanceDetails,
},
weights,
// Version 2: multiple network space support
// Version 3: multiple choices support
// Version 4: multi-assets network
Expand Down
3 changes: 3 additions & 0 deletions backend/packages/backend/src/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ function toSymbolUnit(value, decimals) {
}

function enhancedSqrtOfBalance(balance, decimals) {
if (!balance) {
return balance;
}
return new BigNumber(balance)
.div(Math.pow(10, decimals))
.sqrt()
Expand Down
25 changes: 25 additions & 0 deletions backend/packages/backend/src/utils/strategy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const { strategies } = require("../consts/voting");

function hasBalanceStrategy(proposal) {
return [
strategies.balanceOf,
strategies.quorumBalanceOf,
strategies.quadraticBalanceOf,
strategies.quorumQuadraticBalanceOf,
strategies.biasedVoting,
].some((strategy) => proposal.weightStrategy.includes(strategy));
}

function hasSocietyStrategy(proposal) {
return proposal.weightStrategy.includes(strategies.society);
}

function hasOnePersonOneVoteStrategy(proposal) {
return proposal.weightStrategy.includes(strategies.onePersonOneVote);
}

module.exports = {
hasBalanceStrategy,
hasSocietyStrategy,
hasOnePersonOneVoteStrategy,
};
4 changes: 2 additions & 2 deletions next/components/listInfo/details.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Flex, FlexBetween } from "@osn/common-ui";
import uniq from "lodash.uniq";
import { getSpaceAssets } from "frontedUtils/getSpaceAssets";
import AssetList from "../assetList";
import { isOnePersonOnVoteOnly } from "frontedUtils/strategy";
import { hasBalanceStrategy } from "frontedUtils/strategy";

const Wrapper = styled.div``;

Expand Down Expand Up @@ -117,7 +117,7 @@ export default function Details({ space }) {
</div>
</DetailsItem>

{!isOnePersonOnVoteOnly(space?.weightStrategy) && (
{hasBalanceStrategy(space?.weightStrategy) && (
<DetailsItem>
<DetailsLabel>Assets({assets.length})</DetailsLabel>
<AssetList assets={assets} />
Expand Down
4 changes: 2 additions & 2 deletions next/components/postCreate/information.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
proxyBalanceLoadingSelector,
} from "../../store/reducers/statusSlice";
import BalanceRow from "@/components/postCreate/BalanceRow";
import { isOnePersonOnVoteOnly } from "frontedUtils/strategy";
import { hasBalanceStrategy } from "frontedUtils/strategy";
import SocietyMemberHit from "./societyMemberHit";

const Hint = styled.div`
Expand Down Expand Up @@ -94,7 +94,7 @@ export default function Information({ space }) {

return (
<>
{!isOnePersonOnVoteOnly(weightStrategy) && (
{hasBalanceStrategy(weightStrategy) && (
<BalanceRow
balance={balance}
isLoading={useProxy ? proxyBalanceLoading : balanceLoading}
Expand Down
4 changes: 2 additions & 2 deletions next/components/postDetail/postInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Panel from "@/components/postDetail/panel";
import SideSectionTitle from "@/components/sideBar/sideSectionTitle";
import AssetList from "../assetList";
import { getSpaceAssets } from "frontedUtils/getSpaceAssets";
import { isOnePersonOnVoteOnly } from "frontedUtils/strategy";
import { hasBalanceStrategy } from "frontedUtils/strategy";

const Wrapper = styled(Panel)`
> :not(:first-child) {
Expand Down Expand Up @@ -116,7 +116,7 @@ export default function PostInfo({ data, space }) {
)}
</div>
</div>
{!isOnePersonOnVoteOnly(space?.weightStrategy) && (
{hasBalanceStrategy(space?.weightStrategy) && (
<div>
<SideSectionTitle
title={`Assets(${assets.length})`}
Expand Down
46 changes: 37 additions & 9 deletions next/components/postDetail/postResults.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ import { VoteItem } from "./strategyResult/common/styled";
import QuorumBalanceOfResult from "./strategyResult/quorumBalanceOfResult";
import QuorumQuadraticBalanceOfResult from "./strategyResult/quorumQuadraticBalanceOfResult";
import OnePersonOneVoteResult from "./strategyResult/onePersonOneVoteResult";
import { isOnePersonOnVoteOnly } from "frontedUtils/strategy";
import {
hasBalanceStrategy,
hasSocietyVoteStrategyOnly,
} from "frontedUtils/strategy";
import SocietyVoteResult from "./strategyResult/societyVoteResult";

export default function PostResult({ data, voteStatus, space }) {
const votedAmount = data?.votedWeights?.balanceOf || 0;
const societyVotedAmount = data?.votedWeights?.societyVote || 0;

const results = data?.weightStrategy?.map((strategy) => {
if (strategy === "balance-of") {
Expand Down Expand Up @@ -70,26 +75,49 @@ export default function PostResult({ data, voteStatus, space }) {
);
}

if (strategy === "society") {
return (
<SocietyVoteResult
key={strategy}
proposal={data}
space={space}
voteStatus={voteStatus}
/>
);
}

return null;
});

const biasedVoting = (
<BiasedVotingResult proposal={data} space={space} voteStatus={voteStatus} />
);

let voted = null;
if (hasBalanceStrategy(data?.weightStrategy)) {
voted = (
<VoteItem>
<div>Voted</div>
<div>
<ValueDisplay value={votedAmount?.toString()} space={space} />
</div>
</VoteItem>
);
} else if (hasSocietyVoteStrategyOnly(data?.weightStrategy)) {
voted = (
<VoteItem>
<div>Voted</div>
<div>{societyVotedAmount} VOTE</div>
</VoteItem>
);
}

return (
<Panel>
<SideSectionTitle title="Results" img="/imgs/icons/strategy.svg" />
<Divider />
<div>
{!isOnePersonOnVoteOnly(data?.weightStrategy) && (
<VoteItem>
<div>Voted</div>
<div>
<ValueDisplay value={votedAmount?.toString()} space={space} />
</div>
</VoteItem>
)}
{voted}
<VoteItem>
<div>Voters</div>
<div>{data?.votesCount}</div>
Expand Down
4 changes: 2 additions & 2 deletions next/components/postDetail/postVote.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import { useTerminate } from "./terminate";
import { Tooltip } from "@osn/common-ui";
import VoteBalanceDetail from "./VoteBalanceDetail";
import DelegationInfo from "./delegationInfo";
import { isOnePersonOnVoteOnly } from "frontedUtils/strategy";
import { hasBalanceStrategy } from "frontedUtils/strategy";
import SocietyMemberHit from "../postCreate/societyMemberHit";
import SocietyMemberButton from "../societyMemberButton";

Expand Down Expand Up @@ -265,7 +265,7 @@ export default function PostVote({ proposal }) {
if (!proposalClosed) {
let balanceInfo = null;

if (!isOnePersonOnVoteOnly(proposal?.weightStrategy)) {
if (hasBalanceStrategy(proposal?.weightStrategy)) {
if (voteDelegation) {
balanceInfo = (
<DelegationInfo
Expand Down
Loading
Loading