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

Fixing-Dev #495

Merged
merged 6 commits into from
Nov 26, 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
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
"use client";
import { useEffect, useState } from "react";
import { useEffect, useMemo, useState } from "react";
import { Hashicon } from "@emeraldpay/hashicon-react";
import {
AdjustmentsHorizontalIcon,
InformationCircleIcon,
UserIcon,
} from "@heroicons/react/24/outline";
import { ArrowPathIcon } from "@heroicons/react/24/solid";
import { usePathname, useRouter } from "next/navigation";
import { toast } from "react-toastify";
import { Address, encodeAbiParameters, formatUnits } from "viem";
import { useAccount, useToken } from "wagmi";
import {
getProposalDataDocument,
getProposalDataQuery,
isMemberDocument,
isMemberQuery,
} from "#/subgraph/.graphclient";
import {
Badge,
Expand All @@ -33,7 +34,7 @@ import { usePubSubContext } from "@/contexts/pubsub.context";
import { useChainIdFromPath } from "@/hooks/useChainIdFromPath";
import { useContractWriteWithConfirmations } from "@/hooks/useContractWriteWithConfirmations";
import { useConvictionRead } from "@/hooks/useConvictionRead";
import { useDisableButtons } from "@/hooks/useDisableButtons";
import { ConditionObject, useDisableButtons } from "@/hooks/useDisableButtons";
import { useMetadataIpfsFetch } from "@/hooks/useIpfsFetch";
import { useSubgraphQuery } from "@/hooks/useSubgraphQuery";
import { alloABI } from "@/src/generated";
Expand All @@ -43,10 +44,11 @@ import { useErrorDetails } from "@/utils/getErrorName";
import { prettyTimestamp } from "@/utils/text";

export default function Page({
params: { proposalId, garden, poolId },
params: { proposalId, garden, community: communityAddr, poolId },
}: {
params: {
proposalId: string;
community: string;
poolId: string;
chain: string;
garden: string;
Expand All @@ -56,6 +58,7 @@ export default function Page({
const router = useRouter();

const { address } = useAccount();

const [, proposalNumber] = proposalId.split("-");
const { data } = useSubgraphQuery<getProposalDataQuery>({
query: getProposalDataDocument,
Expand All @@ -71,11 +74,26 @@ export default function Page({
},
});

//query to get member registry in community
const { data: memberData } = useSubgraphQuery<isMemberQuery>({
query: isMemberDocument,
variables: {
me: address?.toLowerCase(),
comm: communityAddr?.toLowerCase(),
},
enabled: !!address,
});

const isMemberCommunity =
!!memberData?.member?.memberCommunity?.[0]?.isRegistered;
//

const proposalData = data?.cvproposal;
const proposalIdNumber =
proposalData?.proposalNumber ?
BigInt(proposalData.proposalNumber)
: undefined;

const poolTokenAddr = proposalData?.strategy.token as Address;

const { publish } = usePubSubContext();
Expand All @@ -102,7 +120,18 @@ export default function Page({
chainId,
});

const { tooltipMessage, isConnected, missmatchUrl } = useDisableButtons();
const disableManSupportBtn = useMemo<ConditionObject[]>(
() => [
{
condition: !isMemberCommunity,
message: "Join community to dispute",
},
],
[address],
);

const { tooltipMessage, isConnected, missmatchUrl } =
useDisableButtons(disableManSupportBtn);

const {
currentConvictionPct,
Expand Down Expand Up @@ -262,6 +291,7 @@ export default function Page({
proposalData={{ ...proposalData, ...metadata }}
/>
: <DisputeButton
isMemberCommunity={isMemberCommunity}
proposalData={{ ...proposalData, ...metadata }}
/>
}
Expand All @@ -285,7 +315,7 @@ export default function Page({
<Button
icon={<AdjustmentsHorizontalIcon height={24} width={24} />}
onClick={() => manageSupportClicked()}
disabled={!isConnected || missmatchUrl}
disabled={!isConnected || missmatchUrl || !isMemberCommunity}
tooltip={tooltipMessage}
>
Manage support
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ export default function Page({

const tokenGarden = data?.tokenGarden;

const maxAmount = strategyObj?.config?.maxAmount ?? 0;

useEffect(() => {
if (
searchParams[QUERY_PARAMS.poolPage.allocationView] !== undefined &&
Expand Down Expand Up @@ -148,6 +150,7 @@ export default function Page({
poolId={poolId}
ipfsResult={ipfsResult}
isEnabled={isEnabled}
maxAmount={maxAmount}
/>
{isEnabled && (
<>
Expand Down
25 changes: 19 additions & 6 deletions apps/web/components/DisputeButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,17 @@ type Props = {
}
> &
MetadataV1;
isMemberCommunity: boolean;
};

const ABSTAINED_RULING = 0;
const APPROVED_RULING = 1;
const REJECTED_RULING = 2;

export const DisputeButton: FC<Props> = ({ proposalData }) => {
export const DisputeButton: FC<Props> = ({
proposalData,
isMemberCommunity,
}) => {
const [isModalOpened, setIsModalOpened] = useState(false);
const [reason, setReason] = useState("");
const [isEnoughBalance, setIsEnoughBalance] = useState(true);
Expand Down Expand Up @@ -249,8 +253,12 @@ export const DisputeButton: FC<Props> = ({ proposalData }) => {
}
};

const disableSubmitBtn = useMemo<ConditionObject[]>(
const disableDisputeSubmitBtn = useMemo<ConditionObject[]>(
() => [
{
condition: !isMemberCommunity,
message: "Join community to dispute",
},
{
condition: !isEnoughBalance,
message: "Insufficient balance",
Expand All @@ -267,8 +275,9 @@ export const DisputeButton: FC<Props> = ({ proposalData }) => {
[isEnoughBalance, isCooldown],
);

const { isConnected, missmatchUrl, tooltipMessage } =
useDisableButtons(disableSubmitBtn);
const { isConnected, missmatchUrl, tooltipMessage } = useDisableButtons(
disableDisputeSubmitBtn,
);

const rulingTimeout = convertSecondsToReadableTime(
arbitrationConfig.defaultRulingTimeout,
Expand Down Expand Up @@ -437,7 +446,11 @@ export const DisputeButton: FC<Props> = ({ proposalData }) => {
onClick={handleSubmit}
color="danger"
disabled={
!isConnected || missmatchUrl || !isEnoughBalance || isCooldown
!isConnected ||
missmatchUrl ||
!isMemberCommunity ||
!isEnoughBalance ||
isCooldown
}
tooltip={tooltipMessage}
tooltipSide="tooltip-left"
Expand All @@ -460,7 +473,7 @@ export const DisputeButton: FC<Props> = ({ proposalData }) => {
btnStyle="outline"
onClick={() => setIsModalOpened(true)}
>
{(isDisputed ?? isProposalEnded) ? "Open dispute" : "Dispute"}
{isDisputed ?? isProposalEnded ? "Open dispute" : "Dispute"}
</Button>
<Modal
title={`Disputed Proposal: ${proposalData.title} #${proposalData.proposalNumber}`}
Expand Down
47 changes: 42 additions & 5 deletions apps/web/components/PoolHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { Badge } from "./Badge";
import { Button } from "./Button";
import { EthAddress } from "./EthAddress";
import PoolEditForm from "./Forms/PoolEditForm";
import { InfoBox } from "./InfoBox";
import MarkdownWrapper from "./MarkdownWrapper";
import { Modal } from "./Modal";
import { Skeleton } from "./Skeleton";
Expand Down Expand Up @@ -68,6 +69,7 @@ type Props = {
>;
token: Pick<TokenGarden, "address" | "name" | "symbol" | "decimals">;
poolToken?: FetchTokenResult;
maxAmount: number;
};

function calculateConvictionGrowthInSeconds(
Expand Down Expand Up @@ -102,6 +104,7 @@ export default function PoolHeader({
arbitrableConfig,
token,
poolToken,
maxAmount,
}: Props) {
const [isOpenModal, setIsOpenModal] = useState(false);
const { address } = useAccount();
Expand Down Expand Up @@ -149,6 +152,14 @@ export default function PoolHeader({
+token.decimals,
);

const totalPointsActivatedInPool = formatTokenAmount(
strategy.totalEffectiveActivePoints,
+token.decimals,
);

const minThGtTotalEffPoints =
+minThresholdPoints > +totalPointsActivatedInPool;

const spendingLimit =
(strategy.config.maxRatio / CV_SCALE_PRECISION) *
(1 - Math.sqrt(minimumConviction / 100)) *
Expand Down Expand Up @@ -197,10 +208,15 @@ export default function PoolHeader({
info: "It's the time for conviction to reach proposal support. This parameter is logarithmic, represented as a half life and may vary slightly over time depending on network block times.",
},
{
label: "Min Threshold",
label: "Min threshold",
value: `${minThresholdPoints}`,
info: `A fixed amount of ${token.symbol} that overrides Minimum Conviction when the Pool's activated governance is low.`,
},
{
label: "Max voting weight",
value: `${formatTokenAmount(maxAmount, token.decimals)} ${token.symbol}`,
info: "Staking above this specified limit won’t increase your voting weight.",
},
{
label: "Protection",
value:
Expand All @@ -220,17 +236,31 @@ export default function PoolHeader({
: "",
},
];

const filteredPoolConfig =
PoolTypes[proposalType] === "signaling" ?
(
PoolTypes[proposalType] === "signaling" &&
PointSystems[pointSystem] !== "capped"
) ?
poolConfig.filter(
(config) =>
!!config.value &&
![
"Spending limit",
"Min threshold",
"Min conviction",
"Pool staked cap",
].includes(config.label),
)
: PoolTypes[proposalType] === "signaling" ?
poolConfig.filter(
(config) =>
!!config.value &&
!["Spending limit", "Min Threshold", "Min conviction"].includes(
!["Spending limit", "Min threshold", "Min conviction"].includes(
config.label,
),
)
: poolConfig;
: PointSystems[pointSystem] === "capped" ? poolConfig
: poolConfig.filter((config) => config.label !== "Pool staked cap");

//hooks
const { data: isCouncilMember } = useContractRead({
Expand Down Expand Up @@ -449,6 +479,13 @@ export default function PoolHeader({
))}
</div>
</div>
{minThGtTotalEffPoints && isEnabled && (
<InfoBox
infoBoxType="warning"
content="Activated governance in this pool is too low. No proposals will pass unless more members activate their governance. You can still create and support proposals."
className="mb-4"
/>
)}
{!isEnabled ?
<div className="banner">
<ClockIcon className="h-8 w-8 text-secondary-content" />
Expand Down
4 changes: 3 additions & 1 deletion apps/web/components/Proposals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ export function Proposals({
!!memberData?.member?.memberCommunity?.[0]?.isRegistered;
const memberActivatedStrategy =
Number(memberStrategyData?.memberStrategy?.activatedPoints) > 0;
const memberTokensInCommunity =
memberData?.member?.memberCommunity?.[0].stakedTokens ?? 0;

const proposals = strategy.proposals;

Expand Down Expand Up @@ -444,7 +446,7 @@ export function Proposals({
tokenDecimals={tokenDecimals}
strategy={strategy}
communityAddress={communityAddress}
memberTokensInCommunity={memberActivatedPoints}
memberTokensInCommunity={memberTokensInCommunity}
isMemberCommunity={isMemberCommunity}
memberActivatedStrategy={memberActivatedStrategy}
/>
Expand Down
2 changes: 1 addition & 1 deletion apps/web/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const PoolTypes: Record<string, "signaling" | "funding" | "streaming"> =

export const PointSystems: Record<
string,
"fixed" | "capped" | "capped" | "unlimited" | "quadratic"
"fixed" | "capped" | "unlimited" | "quadratic"
> = {
0: "fixed",
1: "capped",
Expand Down
Loading