app rev.6

Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
This commit is contained in:
Uncle Fatso 2026-02-19 12:53:57 +03:00
parent a384b6164d
commit 1052bced83
Signed by: f4ts0
GPG Key ID: 565F4F2860226EBB
10 changed files with 45 additions and 43 deletions

View File

@ -1,7 +1,7 @@
{ {
"name": "ghost-dao-interface", "name": "ghost-dao-interface",
"private": true, "private": true,
"version": "0.5.21", "version": "0.5.22",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View File

@ -25,7 +25,7 @@ const LinearProgressBar = (props) => {
{props.target && <Box {props.target && <Box
sx={{ sx={{
position: 'absolute', position: 'absolute',
left: `${props.target}%`, left: `${Math.min(Math.max(props.target, 0), 100)}%`,
top: props.targetTop || 0, top: props.targetTop || 0,
bottom: props.targetBottom || 0, bottom: props.targetBottom || 0,
width: props.targetWidth || "2px", width: props.targetWidth || "2px",

View File

@ -177,12 +177,12 @@ const BondInputArea = ({
)} )}
</span> </span>
} }
tooltip={`The total amount of payout asset you will receive from this bond purchase`} tooltip={`Total amount of ${ftsoSymbol} you will receive from this bond purchase`}
/> />
<DataRow <DataRow
title="Max You Can Buy" title="Max You Can Buy"
tooltip={`The maximum quantity of payout token offered via bonds at this moment in time`} tooltip={`Maximum ${ftsoSymbol} that can be purchased in a single transaction. Prevents whales from buying entire bond supply at once.`}
balance={ balance={
<span> <span>
{bond.baseToken.tokenAddress.toUpperCase() === bond.quoteToken.quoteTokenAddress.toUpperCase() {bond.baseToken.tokenAddress.toUpperCase() === bond.quoteToken.quoteTokenAddress.toUpperCase()
@ -195,13 +195,13 @@ const BondInputArea = ({
<DataRow <DataRow
title="Discount" title="Discount"
balance={<BondDiscount discount={bond.discount} textOnly />} balance={<BondDiscount discount={bond.discount} textOnly />}
tooltip={`The bond discount is the percentage difference between ${ftsoSymbol} market value and the bond's price`} tooltip={`The discount (or premium) between ${ftsoSymbol} market price and bond price. Higher discount = better deal for bond buyers.`}
/> />
<DataRow <DataRow
title={`Vesting Term`} title={`Vesting Term`}
balance={<BondVesting vesting={bond.vesting} />} balance={<BondVesting vesting={bond.vesting} />}
tooltip={"The duration of the Bond whereby the bond can be claimed in its entirety"} tooltip={"Time until bond fully vests and becomes claimable. Vesting period aligns bond buyer with the protocol by encouraging longer-term holding."}
/> />
{recipientAddress !== address && ( {recipientAddress !== address && (

View File

@ -112,47 +112,42 @@ const ProposalDetails = ({ chainId, address, connect, config }) => {
const votePercentage = useMemo(() => { const votePercentage = useMemo(() => {
if (totalSupply._value === 0n) return 0; if (totalSupply._value === 0n) return 0;
const value = (totalVotes?._value ?? 0n) * 100n / (totalSupply?._value ?? 1n); return totalVotes * HUNDRED / totalSupply;
return new DecimalBigNumber(value, 0);
}, [totalVotes, totalSupply]); }, [totalVotes, totalSupply]);
const forPercentage = useMemo(() => { const forPercentage = useMemo(() => {
if (totalSupply._value === 0n) return new DecimalBigNumber(0n, 2); if (totalSupply._value === 0n) return new DecimalBigNumber(0n, 2);
const value = (forVotes?._value ?? 0n) * 10000n / (totalSupply?._value ?? 1n); return forVotes * HUNDRED / totalSupply;
return new DecimalBigNumber(value, 2);
}, [forVotes, totalSupply]); }, [forVotes, totalSupply]);
const againstPercentage= useMemo(() => { const againstPercentage= useMemo(() => {
if (totalSupply._value === 0n) return new DecimalBigNumber(0n, 2); if (totalSupply._value === 0n) return new DecimalBigNumber(0n, 2);
const value = (againstVotes?._value ?? 0n) * 10000n / (totalSupply?._value ?? 1n); return againstVotes * HUNDRED / totalSupply;
return new DecimalBigNumber(value, 2);
}, [againstVotes, totalSupply]); }, [againstVotes, totalSupply]);
const voteWeightPercentage = useMemo(() => { const voteWeightPercentage = useMemo(() => {
if (totalSupply._value === 0n) return new DecimalBigNumber(0n, 2); if (totalSupply._value === 0n) return new DecimalBigNumber(0n, 2);
const value = (pastVotes?._value ?? 0n) * 10000n / (totalSupply?._value ?? 1n); return pastVotes * HUNDRED / totalSupply;
return new DecimalBigNumber(value, 2);
}, [pastVotes, totalSupply]); }, [pastVotes, totalSupply]);
const voteValue = useMemo(() => { const voteValue = useMemo(() => {
if (totalVotes?._value == 0n) { if (totalVotes?._value == 0n) {
return 0; return 0;
} }
return Number(forVotes._value * 100n / totalVotes._value); const value = forVotes * HUNDRED / totalVotes;
return Math.floor(Number(value.toString()));
}, [forVotes, totalVotes]); }, [forVotes, totalVotes]);
const voteTarget = useMemo(() => { const voteTarget = useMemo(() => {
const first = (5n * againstVotes._value + forVotes._value); if (totalSupply._value == 0n) {
const second = BigInt(Math.floor(Math.sqrt(Number(totalVotes._value))));
const bias = 3n * first + second;
const denominator = totalVotes._value + bias;
if (denominator === 0n) {
return 80; return 80;
} }
return Number(totalVotes?._value * 100n / denominator); const value = Number(totalVotes / totalSupply);
}, [againstVotes, forVotes, totalVotes]); const result = (5 - Math.sqrt(1 + 80/9 * (value - 0.1) )) / 4
return Math.floor(result * 100);
}, [totalVotes, totalSupply]);
const nativeCurrency = useMemo(() => { const nativeCurrency = useMemo(() => {
const client = config?.getClient(); const client = config?.getClient();

View File

@ -23,6 +23,7 @@ import ArrowUpIcon from "../../../assets/icons/arrow-up.svg?react";
import { networkAvgBlockSpeed } from "../../../constants"; import { networkAvgBlockSpeed } from "../../../constants";
import { prettifySecondsInDays, prettifySeconds } from "../../../helpers/timeUtil"; import { prettifySecondsInDays, prettifySeconds } from "../../../helpers/timeUtil";
import { DecimalBigNumber } from "../../../helpers/DecimalBigNumber";
import Chip from "../../../components/Chip/Chip"; import Chip from "../../../components/Chip/Chip";
import Modal from "../../../components/Modal/Modal"; import Modal from "../../../components/Modal/Modal";
@ -40,9 +41,7 @@ import {
import { useScreenSize } from "../../../hooks/useScreenSize"; import { useScreenSize } from "../../../hooks/useScreenSize";
import { import { useProposals } from "../../../hooks/governance";
useProposals,
} from "../../../hooks/governance";
const MAX_PROPOSALS_TO_SHOW = 10; const MAX_PROPOSALS_TO_SHOW = 10;
@ -188,30 +187,38 @@ const ProposalRow = ({ proposal, blockNumber, openProposal, chainId }) => {
const theme = useTheme(); const theme = useTheme();
const voteValue = useMemo(() => { const voteValue = useMemo(() => {
const againstVotes = proposal?.votes?.at(0)?._value ?? 0n; const againstVotes = proposal?.votes?.at(0)?._value ?? 0n
const forVotes = proposal?.votes?.at(1)?._value ?? 0n; const forVotes = proposal?.votes?.at(1)?._value ?? 0n;
const totalVotes = againstVotes + forVotes; const totalVotes = againstVotes + forVotes;
if (totalVotes == 0) {
if (totalVotes == 0n) {
return 0; return 0;
} }
return Number(forVotes * 100n / totalVotes); const value = forVotes * 100n / totalVotes;
return Math.floor(Number(value.toString()));
}, [proposal]); }, [proposal]);
const voteTarget = useMemo(() => { const voteTarget = useMemo(() => {
const againstVotes = proposal?.votes?.at(0)?._value ?? 0n; const againstVotes = proposal?.votes?.at(0)?._value ?? 0n;
const forVotes = proposal?.votes?.at(1)?._value ?? 0n; const forVotes = proposal?.votes?.at(1)?._value ?? 0n;
const totalVotes = againstVotes + forVotes;
const first = (5n * againstVotes + forVotes); const totalSupply = new DecimalBigNumber(
const second = BigInt(Math.floor(Math.sqrt(Number(totalVotes)))); proposal?.pastTotalSupply?._value ?? 0n,
const bias = 3n * first + second; proposal?.pastTotalSupply?._decimals
const denominator = totalVotes + bias; );
const totalVotes = new DecimalBigNumber(
againstVotes + forVotes,
proposal?.pastTotalSupply?._decimals
);
if (denominator === 0n) { if (totalSupply._value == 0n) {
return 80; return 80;
} }
return Number(totalVotes * 100n / denominator); const value = Number(totalVotes / totalSupply);
const result = (5 - Math.sqrt(1 + 80/9 * (value - 0.1) )) / 4;
return Math.floor(result * 100);
}, [proposal]); }, [proposal]);
return ( return (

View File

@ -118,7 +118,7 @@ export const CreateBondSteps = ({ nativeCurrency, ftsoSymbol, chainId, toInitial
}, [step, tokenAddress, capacity, initialPrice, debtBuffer, depositInterval, tuneInterval]); }, [step, tokenAddress, capacity, initialPrice, debtBuffer, depositInterval, tuneInterval]);
const possibleTokens = [ const possibleTokens = [
{ value: FTSO_DAI_LP_ADDRESSES[chainId], symbol: `${ftsoSymbol}-${nativeCurrency} LP`, label: `${ftsoSymbol}-${nativeCurrency} LP: ${shorten(FTSO_DAI_LP_ADDRESSES[chainId])}` }, { value: FTSO_DAI_LP_ADDRESSES[chainId], symbol: `${ftsoSymbol}-${reserveSymbol} LP`, label: `${ftsoSymbol}-${reserveSymbol} LP: ${shorten(FTSO_DAI_LP_ADDRESSES[chainId])}` },
{ value: RESERVE_ADDRESSES[chainId], symbol: reserveSymbol, label: `${reserveSymbol}: ${shorten(RESERVE_ADDRESSES[chainId])}` }, { value: RESERVE_ADDRESSES[chainId], symbol: reserveSymbol, label: `${reserveSymbol}: ${shorten(RESERVE_ADDRESSES[chainId])}` },
]; ];

View File

@ -52,7 +52,7 @@ export const TotalDeposit = props => {
const _props = { const _props = {
...props, ...props,
label: "Total Deposit", label: "Total Deposit",
tooltip: `The total stablecoin reserves in the ghostDAO treasury backing the entire circulating supply of ${props.stnkSymbol}.`, tooltip: `The total native coin reserves in the ghostDAO treasury backing the entire circulating supply of ${props.stnkSymbol}.`,
}; };
if (deposit) _props.metric = `${formatCurrency(deposit, 2)}`; if (deposit) _props.metric = `${formatCurrency(deposit, 2)}`;

View File

@ -84,7 +84,7 @@ export const FatsoBacking = props => {
const _props = { const _props = {
...props, ...props,
label: `Backing per ${props.ftsoSymbol}`, label: `Backing per ${props.ftsoSymbol}`,
tooltip: `The total amount of stablecoins held by the ghostDAO treasury to support the value of each ${props.ftsoSymbol} in circulation.` tooltip: `The total amount of native coins held by the ghostDAO treasury to support the value of each ${props.ftsoSymbol} in circulation.`
}; };
if (backing) _props.metric = formatCurrency(backing, 2); if (backing) _props.metric = formatCurrency(backing, 2);

View File

@ -138,7 +138,7 @@ const TokenInfo = ({ chainId, isMobileScreen }) => {
tokenName={ghstSymbol} tokenName={ghstSymbol}
balance={ghstBalance} balance={ghstBalance}
price={ghstPrice} price={ghstPrice}
description={`${ghstSymbol} enables ghostDAO to have on-chain governance and to be truly cross-chain. ${ghstSymbol} Price = ${ftsoSymbol} Price x Current Index.`} description={`${ghstSymbol} is the governance token enabling pure Web3 cross-chain magic. 1 ${ghstSymbol} = 1 ${ftsoSymbol} x Current Index.`}
/> />
<TokenTab <TokenTab
isMobileScreen={isMobileScreen} isMobileScreen={isMobileScreen}

View File

@ -464,10 +464,10 @@ export const useProposals = (chainId, depth, searchedIndexes) => {
proposer: proposalProposer?.at(index)?.result, proposer: proposalProposer?.at(index)?.result,
details: proposalsDetailsAt?.at(index)?.result, details: proposalsDetailsAt?.at(index)?.result,
deadline: proposalDeadlines?.at(index)?.result ?? 0n, deadline: proposalDeadlines?.at(index)?.result ?? 0n,
snapshot: proposalSnapshots?.at(index)?.result ?? 0n,
state: proposalStates?.at(index)?.result ?? 0, state: proposalStates?.at(index)?.result ?? 0,
pastTotalSupply: new DecimalBigNumber(pastTotalSupplies?.at(index)?.result ?? 0n, decimals), pastTotalSupply: new DecimalBigNumber(pastTotalSupplies?.at(index)?.result ?? 0n, decimals),
quorum: new DecimalBigNumber(proposalQuorums?.at(index)?.result ?? 0n, decimals), quorum: new DecimalBigNumber(proposalQuorums?.at(index)?.result ?? 0n, decimals),
snapshot: new DecimalBigNumber(proposalSnapshots?.at(index)?.result ?? 0n, decimals),
votes: proposalVotes?.at(index)?.result?.map( votes: proposalVotes?.at(index)?.result?.map(
vote => new DecimalBigNumber(vote ?? 0n, decimals), vote => new DecimalBigNumber(vote ?? 0n, decimals),
), ),