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

Fix collator power #70

Merged
merged 3 commits into from
Nov 28, 2023
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
15 changes: 10 additions & 5 deletions src/components/bond-more-deposit-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { Key, useCallback, useMemo, useState } from "react";
import Modal from "./modal";
import CheckboxGroup from "./checkbox-group";
import { formatBlanace, getChainConfig, notifyTransaction } from "@/utils";
import { commissionWeightedPower, formatBlanace, getChainConfig, notifyTransaction } from "@/utils";
import { ExtraPower } from "./balance-input";
import { useApp, useStaking } from "@/hooks";
import { notification } from "./notification";
import { writeContract, waitForTransaction } from "@wagmi/core";

export default function BondMoreDepositModal({
commission,
isOpen,
onClose = () => undefined,
}: {
commission: string;
isOpen: boolean;
onClose?: () => void;
}) {
Expand All @@ -22,11 +24,14 @@ export default function BondMoreDepositModal({

const extraPower = useMemo(
() =>
calcExtraPower(
deposits.filter(({ id }) => checkedDeposits.includes(id)).reduce((acc, cur) => acc + cur.value, 0n),
0n
commissionWeightedPower(
calcExtraPower(
deposits.filter(({ id }) => checkedDeposits.includes(id)).reduce((acc, cur) => acc + cur.value, 0n),
0n
),
commission
),
[deposits, checkedDeposits, calcExtraPower]
[deposits, commission, checkedDeposits, calcExtraPower]
);

const availableDeposits = deposits.filter(({ id }) => !stakedDeposits.includes(id));
Expand Down
6 changes: 4 additions & 2 deletions src/components/bond-more-kton-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getChainConfig, notifyTransaction } from "@/utils";
import { commissionWeightedPower, getChainConfig, notifyTransaction } from "@/utils";
import BondMoreTokenModal from "./bond-more-token-modal";
import { useApp, useStaking } from "@/hooks";
import { useAccount, useBalance } from "wagmi";
Expand All @@ -7,9 +7,11 @@ import { notification } from "./notification";
import { writeContract, waitForTransaction } from "@wagmi/core";

export default function BondMoreKtonModal({
commission,
isOpen,
onClose = () => undefined,
}: {
commission: string;
isOpen: boolean;
onClose?: () => void;
}) {
Expand Down Expand Up @@ -60,7 +62,7 @@ export default function BondMoreKtonModal({
isOpen={isOpen}
symbol={ktonToken.symbol}
decimals={ktonToken.decimals}
power={calcExtraPower(0n, inputAmount)}
power={commissionWeightedPower(calcExtraPower(0n, inputAmount), commission)}
balance={ktonBalance?.value || 0n}
busy={busy}
disabled={inputAmount <= 0n}
Expand Down
6 changes: 4 additions & 2 deletions src/components/bond-more-ring-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getChainConfig, notifyTransaction } from "@/utils";
import { commissionWeightedPower, getChainConfig, notifyTransaction } from "@/utils";
import BondMoreTokenModal from "./bond-more-token-modal";
import { useAccount, useBalance } from "wagmi";
import { useApp, useStaking } from "@/hooks";
Expand All @@ -7,9 +7,11 @@ import { notification } from "./notification";
import { writeContract, waitForTransaction } from "@wagmi/core";

export default function BondMoreRingModal({
commission,
isOpen,
onClose = () => undefined,
}: {
commission: string;
isOpen: boolean;
onClose?: () => void;
}) {
Expand Down Expand Up @@ -58,7 +60,7 @@ export default function BondMoreRingModal({
isOpen={isOpen}
symbol={nativeToken.symbol}
decimals={nativeToken.decimals}
power={calcExtraPower(inputAmount, 0n)}
power={commissionWeightedPower(calcExtraPower(inputAmount, 0n), commission)}
balance={ringBalance?.value || 0n}
busy={busy}
disabled={inputAmount <= 0n}
Expand Down
35 changes: 32 additions & 3 deletions src/components/collator-select-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import Image from "next/image";
import { useAccount } from "wagmi";
import Table, { ColumnType } from "./table";
import Jazzicon from "./jazzicon";
import { prettyNumber } from "@/utils";
import { commissionWeightedPower, prettyNumber } from "@/utils";
import { notification } from "./notification";
import DisplayAccountName from "./display-account-name";
import { useStaking } from "@/hooks";
import Tooltip from "./tooltip";

type TabKey = "active" | "waiting";

Expand Down Expand Up @@ -59,10 +60,38 @@ const columns: ColumnType<DataSource>[] = [
title: (
<div className="inline-flex flex-col text-xs font-bold text-white">
<span>Total-staked</span>
<span>(Power)</span>
<div className="inline-flex items-center gap-small">
<span>(Power)</span>
<Tooltip
content={
<div className="inline-block text-xs font-light text-white">
{`The Collator's total-staked power is a dynamic value, inversely proportional to the commission set by
the Collator. Higher commission results in lower total-staked power and vice versa. `}
<a
rel="noopener noreferrer"
target="_blank"
className="text-primary hover:underline"
href="https://github.com/darwinia-network/DIPs/blob/main/DIPs/dip-1.md"
>
Learn More
</a>
</div>
}
enabledSafePolygon
contentClassName="w-80"
>
<Image
width={15}
height={14}
alt="Info"
src="/images/help.svg"
className="opacity-60 transition-opacity hover:opacity-100"
/>
</Tooltip>
</div>
</div>
),
render: (row) => <span>{prettyNumber(row.power)}</span>,
render: (row) => <span>{prettyNumber(commissionWeightedPower(row.power, row.commission))}</span>,
},
{
key: "commission",
Expand Down
37 changes: 28 additions & 9 deletions src/components/do-stake.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getChainConfig, notifyTransaction } from "@/utils";
import { commissionWeightedPower, getChainConfig, notifyTransaction } from "@/utils";
import ActiveDepositSelector from "./active-deposit-selector";
import CollatorSelector from "./collator-selector";
import BalanceInput, { ExtraPower } from "./balance-input";
Expand All @@ -11,8 +11,14 @@ import { ChainID } from "@/types";
import { notification } from "./notification";

export default function DoStake() {
const { deposits, nominatorCollators, isNominatorCollatorsLoading, calcExtraPower, updateNominatorCollators } =
useStaking();
const {
deposits,
nominatorCollators,
collatorCommission,
isNominatorCollatorsLoading,
calcExtraPower,
updateNominatorCollators,
} = useStaking();
const [delegateCollator, setDelegateCollator] = useState<string | undefined>(undefined);
const [delegateRing, setDelegateRing] = useState(0n);
const [delegateKton, setDelegateKton] = useState(0n);
Expand All @@ -28,15 +34,28 @@ export default function DoStake() {
const { data: ringBalance } = useBalance({ address, watch: true });
const { data: ktonBalance } = useBalance({ address, watch: true, token: ktonToken?.address });

const ringExtraPower = useMemo(() => calcExtraPower(delegateRing, 0n), [delegateRing, calcExtraPower]);
const ktonExtraPower = useMemo(() => calcExtraPower(0n, delegateKton), [delegateKton, calcExtraPower]);
const commission = useMemo(() => {
return (delegateCollator && collatorCommission[delegateCollator]) || "0.00%";
}, [delegateCollator, collatorCommission]);

const ringExtraPower = useMemo(
() => commissionWeightedPower(calcExtraPower(delegateRing, 0n), commission),
[commission, delegateRing, calcExtraPower]
);
const ktonExtraPower = useMemo(
() => commissionWeightedPower(calcExtraPower(0n, delegateKton), commission),
[commission, delegateKton, calcExtraPower]
);
const depositsExtraPower = useMemo(
() =>
calcExtraPower(
deposits.filter(({ id }) => delegateDeposits.includes(id)).reduce((acc, cur) => acc + cur.value, 0n),
0n
commissionWeightedPower(
calcExtraPower(
deposits.filter(({ id }) => delegateDeposits.includes(id)).reduce((acc, cur) => acc + cur.value, 0n),
0n
),
commission
),
[delegateDeposits, deposits, calcExtraPower]
[delegateDeposits, commission, deposits, calcExtraPower]
);

const handleStake = useCallback(async () => {
Expand Down
33 changes: 28 additions & 5 deletions src/components/power.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { GET_LATEST_STAKING_REWARDS } from "@/config";
import { useApp, useStaking } from "@/hooks";
import { formatBlanace, getChainConfig, prettyNumber } from "@/utils";
import { commissionWeightedPower, formatBlanace, getChainConfig, prettyNumber } from "@/utils";
import { formatDistanceStrict } from "date-fns";
import Image from "next/image";
import { getAddress } from "viem";
import { useAccount } from "wagmi";
import CountLoading from "./count-loading";
import { useRef } from "react";
import { useMemo, useRef } from "react";
import { CSSTransition } from "react-transition-group";
import { useQuery } from "@apollo/client";

Expand Down Expand Up @@ -36,7 +36,16 @@ interface QueryResult {

export default function Power() {
const loadingRef = useRef<HTMLDivElement>(null);
const { power, isLedgersInitialized, isRingPoolInitialized, isKtonPoolInitialized } = useStaking();
const {
power,
nominatorCollators,
collatorCommission,
isNominatorCollatorsInitialized,
isCollatorCommissionInitialized,
isLedgersInitialized,
isRingPoolInitialized,
isKtonPoolInitialized,
} = useStaking();
const { activeChain } = useApp();
const { address } = useAccount();
const { data: rewardData, loading: rewardLoading } = useQuery<QueryResult, QueryVariables>(
Expand All @@ -46,6 +55,16 @@ export default function Power() {
}
);

const thePower = useMemo(() => {
const isCollator =
address && Object.keys(collatorCommission).some((addr) => addr.toLowerCase() === address.toLowerCase())
? true
: false;
const collator = isCollator ? address : address ? nominatorCollators[address]?.at(0) : undefined;
const commission = collator ? collatorCommission[collator] : undefined;
return commissionWeightedPower(power, commission ?? "0.00%");
}, [address, power, collatorCommission, nominatorCollators]);

const chainConfig = getChainConfig(activeChain);

return (
Expand All @@ -56,8 +75,12 @@ export default function Power() {
<Image alt="Icon of Power" src="/images/power.svg" width={30} height={42} />
<span className="text-3xl font-bold text-white">Power</span>
</div>
{isLedgersInitialized && isRingPoolInitialized && isKtonPoolInitialized ? (
<span className="text-3xl font-bold text-white">{prettyNumber(power)}</span>
{isLedgersInitialized &&
isRingPoolInitialized &&
isKtonPoolInitialized &&
isNominatorCollatorsInitialized &&
isCollatorCommissionInitialized ? (
<span className="text-3xl font-bold text-white">{prettyNumber(thePower)}</span>
) : (
<CountLoading color="white" size="large" />
)}
Expand Down
36 changes: 18 additions & 18 deletions src/components/records-bonded-tokens.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ export default function RecordsBondedTokens({ row }: { row: StakingRecordsDataSo
</span>
{row.collator.length > 0 && (
<>
<BondMoreRing />
<UnbondRing />
<BondMoreRing commission={row.commission} />
<UnbondRing commission={row.commission} />
</>
)}
</div>
Expand Down Expand Up @@ -155,8 +155,8 @@ export default function RecordsBondedTokens({ row }: { row: StakingRecordsDataSo
</span>
{row.collator.length > 0 && (
<>
<BondMoreDeposit />
<UnbondDeposit />
<BondMoreDeposit commission={row.commission} />
<UnbondDeposit commission={row.commission} />
</>
)}
</div>
Expand All @@ -183,71 +183,71 @@ export default function RecordsBondedTokens({ row }: { row: StakingRecordsDataSo
</span>
{row.collator.length > 0 && (
<>
<BondMoreKton />
<UnbondKton />
<BondMoreKton commission={row.commission} />
<UnbondKton commission={row.commission} />
</>
)}
</div>
</div>
);
}

function BondMoreRing() {
function BondMoreRing({ commission }: { commission: string }) {
const [isOpen, setIsOpen] = useState(false);
return (
<>
<ChangeBondButton action="bond" onClick={() => setIsOpen(true)} />
<BondMoreRingModal isOpen={isOpen} onClose={() => setIsOpen(false)} />
<BondMoreRingModal commission={commission} isOpen={isOpen} onClose={() => setIsOpen(false)} />
</>
);
}

function BondMoreKton() {
function BondMoreKton({ commission }: { commission: string }) {
const [isOpen, setIsOpen] = useState(false);
return (
<>
<ChangeBondButton action="bond" onClick={() => setIsOpen(true)} />
<BondMoreKtonModal isOpen={isOpen} onClose={() => setIsOpen(false)} />
<BondMoreKtonModal commission={commission} isOpen={isOpen} onClose={() => setIsOpen(false)} />
</>
);
}

function BondMoreDeposit() {
function BondMoreDeposit({ commission }: { commission: string }) {
const [isOpen, setIsOpen] = useState(false);
return (
<>
<ChangeBondButton action="bond" onClick={() => setIsOpen(true)} />
<BondMoreDepositModal isOpen={isOpen} onClose={() => setIsOpen(false)} />
<BondMoreDepositModal commission={commission} isOpen={isOpen} onClose={() => setIsOpen(false)} />
</>
);
}

function UnbondRing() {
function UnbondRing({ commission }: { commission: string }) {
const [isOpen, setIsOpen] = useState(false);
return (
<>
<ChangeBondButton action="unbond" onClick={() => setIsOpen(true)} />
<UnbondRingModal isOpen={isOpen} onClose={() => setIsOpen(false)} />
<UnbondRingModal commission={commission} isOpen={isOpen} onClose={() => setIsOpen(false)} />
</>
);
}

function UnbondKton() {
function UnbondKton({ commission }: { commission: string }) {
const [isOpen, setIsOpen] = useState(false);
return (
<>
<ChangeBondButton action="unbond" onClick={() => setIsOpen(true)} />
<UnbondKtonModal isOpen={isOpen} onClose={() => setIsOpen(false)} />
<UnbondKtonModal commission={commission} isOpen={isOpen} onClose={() => setIsOpen(false)} />
</>
);
}

function UnbondDeposit() {
function UnbondDeposit({ commission }: { commission: string }) {
const [isOpen, setIsOpen] = useState(false);
return (
<>
<ChangeBondButton action="unbond" onClick={() => setIsOpen(true)} />
<UnbondDepositModal isOpen={isOpen} onClose={() => setIsOpen(false)} />
<UnbondDepositModal commission={commission} isOpen={isOpen} onClose={() => setIsOpen(false)} />
</>
);
}
Expand Down
Loading
Loading