Compare commits
16 Commits
dao-govern
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 83761d54ca | |||
| de84f8e40f | |||
| 7733a6cd3b | |||
| e05fc99296 | |||
| aaae299b32 | |||
| 718e9a7be4 | |||
| 6f0e5e2af3 | |||
| 44f927faf8 | |||
| 83dc5ea8e9 | |||
| a176a16aaf | |||
| 1052bced83 | |||
| a384b6164d | |||
| 133e911274 | |||
| 4fceba6f49 | |||
| 419cbde251 | |||
| 4ffa0f4b17 |
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "ghost-dao-interface",
|
"name": "ghost-dao-interface",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.5.20",
|
"version": "0.5.32",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@ -9,12 +9,12 @@ const classes = {
|
|||||||
|
|
||||||
const StyledMuiChip = styled(MuiChip, {
|
const StyledMuiChip = styled(MuiChip, {
|
||||||
shouldForwardProp: prop => prop !== "template" && prop !== "strong",
|
shouldForwardProp: prop => prop !== "template" && prop !== "strong",
|
||||||
})(({ theme, template, strong }) => {
|
})(({ theme, template, background, strong }) => {
|
||||||
return {
|
return {
|
||||||
[`&.${classes.chip}`]: {
|
[`&.${classes.chip}`]: {
|
||||||
height: "21px",
|
height: "21px",
|
||||||
borderRadius: "16px",
|
borderRadius: "16px",
|
||||||
backgroundColor: template
|
backgroundColor: background ? background : template
|
||||||
? template === "purple"
|
? template === "purple"
|
||||||
? theme.colors.special["olyZaps"]
|
? theme.colors.special["olyZaps"]
|
||||||
: template === "gray"
|
: template === "gray"
|
||||||
@ -42,8 +42,8 @@ const StyledMuiChip = styled(MuiChip, {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const Chip = ({ template, strong = false, ...props }) => {
|
const Chip = ({ background, template, strong = false, ...props }) => {
|
||||||
return <StyledMuiChip className={classes.chip} template={template} strong={strong} {...props} />;
|
return <StyledMuiChip className={classes.chip} background={background} template={template} strong={strong} {...props} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Chip;
|
export default Chip;
|
||||||
|
|||||||
@ -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",
|
||||||
|
|||||||
@ -67,7 +67,7 @@ export const DISTRIBUTOR_ADDRESSES = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const GHOST_GOVERNANCE_ADDRESSES = {
|
export const GHOST_GOVERNANCE_ADDRESSES = {
|
||||||
[NetworkId.TESTNET_SEPOLIA]: "0x4823F1DC785D721eAdD2bD218E1eeD63aF67fBF4",
|
[NetworkId.TESTNET_SEPOLIA]: "0xaf7Ad1b83C47405BB9aa96868bCFbb6D65e4C2a1",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const BONDING_CALCULATOR_ADDRESSES = {
|
export const BONDING_CALCULATOR_ADDRESSES = {
|
||||||
|
|||||||
@ -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,14 +195,14 @@ 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 && (
|
||||||
<DataRow title={`Recipient`} balance={shorten(recipientAddress)} />
|
<DataRow title={`Recipient`} balance={shorten(recipientAddress)} />
|
||||||
|
|||||||
@ -43,7 +43,7 @@ const NewProposal = ({ config, address, connect, chainId }) => {
|
|||||||
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const myStoredProposals = localStorage.getItem(MY_PROPOSALS_PREFIX);
|
const myStoredProposals = localStorage.getItem(`${MY_PROPOSALS_PREFIX}-${address}`);
|
||||||
const [myProposals, setMyProposals] = useState(
|
const [myProposals, setMyProposals] = useState(
|
||||||
myStoredProposals ? JSON.parse(myStoredProposals).map(id => BigInt(id)) : []
|
myStoredProposals ? JSON.parse(myStoredProposals).map(id => BigInt(id)) : []
|
||||||
);
|
);
|
||||||
@ -63,7 +63,7 @@ const NewProposal = ({ config, address, connect, chainId }) => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const toStore = JSON.stringify(myProposals.map(id => id.toString()));
|
const toStore = JSON.stringify(myProposals.map(id => id.toString()));
|
||||||
localStorage.setItem(MY_PROPOSALS_PREFIX, toStore);
|
localStorage.setItem(`${MY_PROPOSALS_PREFIX}-${address}`, toStore);
|
||||||
}, [myProposals]);
|
}, [myProposals]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -163,6 +163,14 @@ const NewProposal = ({ config, address, connect, chainId }) => {
|
|||||||
isVertical
|
isVertical
|
||||||
>
|
>
|
||||||
<Box display="flex" flexDirection="column" alignItems="center">
|
<Box display="flex" flexDirection="column" alignItems="center">
|
||||||
|
<TertiaryButton
|
||||||
|
sx={{ maxWidth: isSemiSmallScreen ? "100%" : "350px" }}
|
||||||
|
fullWidth
|
||||||
|
disabled={isPending}
|
||||||
|
onClick={() => setIsModalOpened(true)}
|
||||||
|
>
|
||||||
|
Add New Function
|
||||||
|
</TertiaryButton>
|
||||||
<PrimaryButton
|
<PrimaryButton
|
||||||
disabled={
|
disabled={
|
||||||
proposalFunctions.length === 0 ||
|
proposalFunctions.length === 0 ||
|
||||||
@ -174,14 +182,6 @@ const NewProposal = ({ config, address, connect, chainId }) => {
|
|||||||
>
|
>
|
||||||
{isPending ? "Submitting..." : "Submit Proposal"}
|
{isPending ? "Submitting..." : "Submit Proposal"}
|
||||||
</PrimaryButton>
|
</PrimaryButton>
|
||||||
<TertiaryButton
|
|
||||||
sx={{ maxWidth: isSemiSmallScreen ? "100%" : "350px" }}
|
|
||||||
fullWidth
|
|
||||||
disabled={isPending}
|
|
||||||
onClick={() => setIsModalOpened(true)}
|
|
||||||
>
|
|
||||||
Add New
|
|
||||||
</TertiaryButton>
|
|
||||||
</Box>
|
</Box>
|
||||||
</TokenAllowanceGuard>
|
</TokenAllowanceGuard>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import { useEffect, useState, useMemo } from "react";
|
import { useEffect, useState, useMemo } from "react";
|
||||||
import ReactGA from "react-ga4";
|
import ReactGA from "react-ga4";
|
||||||
import { useParams } from 'react-router-dom';
|
import { useParams } from 'react-router-dom';
|
||||||
import { useBlock, useBlockNumber } from 'wagmi'
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
|
import { useBlock, useBlockNumber } from "wagmi";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
@ -32,7 +33,7 @@ import { formatNumber, formatCurrency, shorten } from "../../helpers";
|
|||||||
import { prettifySecondsInDays } from "../../helpers/timeUtil";
|
import { prettifySecondsInDays } from "../../helpers/timeUtil";
|
||||||
import { DecimalBigNumber, } from "../../helpers/DecimalBigNumber";
|
import { DecimalBigNumber, } from "../../helpers/DecimalBigNumber";
|
||||||
|
|
||||||
import { convertStatusToTemplate, convertStatusToLabel } from "./helpers";
|
import { convertStatusToColor, convertStatusToLabel } from "./helpers";
|
||||||
import { parseFunctionCalldata } from "./components/functions";
|
import { parseFunctionCalldata } from "./components/functions";
|
||||||
|
|
||||||
import { networkAvgBlockSpeed } from "../../constants";
|
import { networkAvgBlockSpeed } from "../../constants";
|
||||||
@ -72,6 +73,7 @@ import RepeatIcon from '@mui/icons-material/Repeat';
|
|||||||
|
|
||||||
const HUNDRED = new DecimalBigNumber(100n, 0);
|
const HUNDRED = new DecimalBigNumber(100n, 0);
|
||||||
|
|
||||||
|
|
||||||
const ProposalDetails = ({ chainId, address, connect, config }) => {
|
const ProposalDetails = ({ chainId, address, connect, config }) => {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const proposalId = BigInt(id);
|
const proposalId = BigInt(id);
|
||||||
@ -84,6 +86,7 @@ const ProposalDetails = ({ chainId, address, connect, config }) => {
|
|||||||
const isVerySmallScreen = useMediaQuery("(max-width: 379px)");
|
const isVerySmallScreen = useMediaQuery("(max-width: 379px)");
|
||||||
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST");
|
const { symbol: ghstSymbol } = useTokenSymbol(chainId, "GHST");
|
||||||
const { balance } = useBalance(chainId, "GHST", address);
|
const { balance } = useBalance(chainId, "GHST", address);
|
||||||
@ -112,47 +115,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();
|
||||||
@ -168,29 +166,33 @@ const ProposalDetails = ({ chainId, address, connect, config }) => {
|
|||||||
return url;
|
return url;
|
||||||
}, [proposalProposer, config]);
|
}, [proposalProposer, config]);
|
||||||
|
|
||||||
const handleVote = async (against) => {
|
const handleVote = async (support) => {
|
||||||
setIsPending(true);
|
setIsPending(true);
|
||||||
const support = against ? 0 : 1;
|
|
||||||
const result = await castVote(chainId, address, proposalId, support);
|
const result = await castVote(chainId, address, proposalId, support);
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
const toStore = JSON.stringify(proposalId.toString());
|
const storedVotedProposals = localStorage.getItem(`${VOTED_PROPOSALS_PREFIX}-${address}`);
|
||||||
localStorage.setItem(VOTED_PROPOSALS_PREFIX, toStore);
|
const proposals = JSON.parse(storedVotedProposals || "[]").map(id => BigInt(id));
|
||||||
|
proposals.push(proposalId);
|
||||||
|
const toStore = JSON.stringify(proposals.map(id => id.toString()));
|
||||||
|
localStorage.setItem(`${VOTED_PROPOSALS_PREFIX}-${address}`, toStore);
|
||||||
|
await queryClient.invalidateQueries();
|
||||||
}
|
}
|
||||||
|
setIsPending(false);
|
||||||
setIsPending(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleExecute = async () => {
|
const handleExecute = async () => {
|
||||||
setIsPending(true);
|
setIsPending(true);
|
||||||
await executeProposal(chainId, address, proposalId);
|
await executeProposal(chainId, address, proposalId);
|
||||||
setIsPending(true);
|
await queryClient.invalidateQueries();
|
||||||
|
setIsPending(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleRelease = async (proposalId) => {
|
const handleRelease = async () => {
|
||||||
setIsPending(true);
|
setIsPending(true);
|
||||||
await releaseLocked(chainId, address, proposalId);
|
await releaseLocked(chainId, address, proposalId);
|
||||||
setIsPending(true);
|
await queryClient.invalidateQueries();
|
||||||
|
setIsPending(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -199,7 +201,7 @@ const ProposalDetails = ({ chainId, address, connect, config }) => {
|
|||||||
name={`GBP-${id.slice(-5)}`}
|
name={`GBP-${id.slice(-5)}`}
|
||||||
subtitle={
|
subtitle={
|
||||||
<Typography component="span">
|
<Typography component="span">
|
||||||
Proposal details, need more in-depth description
|
{`Cast $${ghstSymbol} to shape this proposal's outcome`}
|
||||||
</Typography>
|
</Typography>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@ -226,7 +228,7 @@ const ProposalDetails = ({ chainId, address, connect, config }) => {
|
|||||||
<Chip
|
<Chip
|
||||||
sx={{ marginTop: "4px", width: "88px" }}
|
sx={{ marginTop: "4px", width: "88px" }}
|
||||||
label={convertStatusToLabel(proposalState)}
|
label={convertStatusToLabel(proposalState)}
|
||||||
template={convertStatusToTemplate(proposalState)}
|
background={convertStatusToColor(proposalState)}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
}
|
}
|
||||||
@ -346,6 +348,7 @@ const ProposalDetails = ({ chainId, address, connect, config }) => {
|
|||||||
isProposer={proposalProposer === address}
|
isProposer={proposalProposer === address}
|
||||||
chainId={chainId}
|
chainId={chainId}
|
||||||
proposalId={id}
|
proposalId={id}
|
||||||
|
isPending={isPending}
|
||||||
/>
|
/>
|
||||||
</Paper>
|
</Paper>
|
||||||
</Box>
|
</Box>
|
||||||
@ -383,7 +386,7 @@ const ProposalDetails = ({ chainId, address, connect, config }) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const VotingTimeline = ({ connect, handleExecute, handleRelease, proposalLocked, proposalId, chainId, state, address, isProposer }) => {
|
const VotingTimeline = ({ connect, handleExecute, handleRelease, proposalLocked, proposalId, chainId, state, address, isProposer, isPending }) => {
|
||||||
const { delay: propsalVotingDelay } = useProposalVotingDelay(chainId, proposalId);
|
const { delay: propsalVotingDelay } = useProposalVotingDelay(chainId, proposalId);
|
||||||
const { snapshot: proposalSnapshot } = useProposalSnapshot(chainId, proposalId);
|
const { snapshot: proposalSnapshot } = useProposalSnapshot(chainId, proposalId);
|
||||||
const { deadline: proposalDeadline } = useProposalDeadline(chainId, proposalId);
|
const { deadline: proposalDeadline } = useProposalDeadline(chainId, proposalId);
|
||||||
@ -403,19 +406,19 @@ const VotingTimeline = ({ connect, handleExecute, handleRelease, proposalLocked,
|
|||||||
<VotingTimelineItem chainId={chainId} occured={proposalDeadline} message="Voting ends" />
|
<VotingTimelineItem chainId={chainId} occured={proposalDeadline} message="Voting ends" />
|
||||||
</Timeline>
|
</Timeline>
|
||||||
<Box width="100%" display="flex" gap="10px">
|
<Box width="100%" display="flex" gap="10px">
|
||||||
{isProposer && <SecondaryButton
|
{(isProposer && (proposalLocked?._value ?? 0n) > 0n) && <SecondaryButton
|
||||||
fullWidth
|
fullWidth
|
||||||
disabled={(proposalLocked?._value ?? 0n) === 0n || state < 2}
|
disabled={isPending || state < 2}
|
||||||
onClick={() => address === "" ? connect() : handleRelease()}
|
onClick={() => address === "" ? connect() : handleRelease()}
|
||||||
>
|
>
|
||||||
{address === "" ? "Connect" : "Release"}
|
{address === "" ? "Connect" : "Release"}
|
||||||
</SecondaryButton>}
|
</SecondaryButton>}
|
||||||
<SecondaryButton
|
<SecondaryButton
|
||||||
fullWidth
|
fullWidth
|
||||||
disabled={state !== 4}
|
disabled={isPending || state !== 4}
|
||||||
onClick={() => address === "" ? connect() : handleExecute()}
|
onClick={() => address === "" ? connect() : handleExecute()}
|
||||||
>
|
>
|
||||||
{address === "" ? "Connect" : "Execute"}
|
{address === "" ? "Connect" : state === 4 ? "Execute" : convertStatusToLabel(state)}
|
||||||
</SecondaryButton>
|
</SecondaryButton>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -12,7 +12,7 @@ const GovernanceInfoText = () => {
|
|||||||
ghostDAO’s adaptive governance system algorithmically sets minimum collateral based on activity.
|
ghostDAO’s adaptive governance system algorithmically sets minimum collateral based on activity.
|
||||||
<Link
|
<Link
|
||||||
color={theme.colors.primary[300]}
|
color={theme.colors.primary[300]}
|
||||||
href="https://docs.dao.ghostchain.io/"
|
href="http://forum.ghostchain.io/"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
>Learn more here.</Link>
|
>Learn more here.</Link>
|
||||||
|
|||||||
@ -103,7 +103,11 @@ const InitialStep = ({ selectedOption, handleChange, handleCalldata, handleProce
|
|||||||
return allPossibleFunctions.find(opt => opt.value === selected)?.label || selected;
|
return allPossibleFunctions.find(opt => opt.value === selected)?.label || selected;
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Typography align="center" variant="body2">{functionDescription}</Typography>
|
<Typography align="center" variant="body2">
|
||||||
|
<b>{selectedOption}</b>
|
||||||
|
{" "}
|
||||||
|
{functionDescription}
|
||||||
|
</Typography>
|
||||||
{ready
|
{ready
|
||||||
? <TertiaryButton disabled={!selectedOption} onClick={() => handleProceed()} fullWidth>Proceed</TertiaryButton>
|
? <TertiaryButton disabled={!selectedOption} onClick={() => handleProceed()} fullWidth>Proceed</TertiaryButton>
|
||||||
: <PrimaryButton disabled={!selectedOption} onClick={() => handleCalldata()} fullWidth>Create Function</PrimaryButton>
|
: <PrimaryButton disabled={!selectedOption} onClick={() => handleCalldata()} fullWidth>Create Function</PrimaryButton>
|
||||||
|
|||||||
@ -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";
|
||||||
@ -32,7 +33,7 @@ import { PrimaryButton, TertiaryButton } from "../../../components/Button";
|
|||||||
|
|
||||||
import ProposalInfoText from "./ProposalInfoText";
|
import ProposalInfoText from "./ProposalInfoText";
|
||||||
import {
|
import {
|
||||||
convertStatusToTemplate,
|
convertStatusToColor,
|
||||||
convertStatusToLabel,
|
convertStatusToLabel,
|
||||||
MY_PROPOSALS_PREFIX,
|
MY_PROPOSALS_PREFIX,
|
||||||
VOTED_PROPOSALS_PREFIX
|
VOTED_PROPOSALS_PREFIX
|
||||||
@ -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;
|
||||||
|
|
||||||
@ -53,12 +52,12 @@ const ProposalsList = ({ chainId, address, config }) => {
|
|||||||
|
|
||||||
const [proposalsFilter, setProposalFilter] = useState("active");
|
const [proposalsFilter, setProposalFilter] = useState("active");
|
||||||
|
|
||||||
const myStoredProposals = localStorage.getItem(MY_PROPOSALS_PREFIX);
|
const myStoredProposals = localStorage.getItem(`${MY_PROPOSALS_PREFIX}-${address}`);
|
||||||
const [myProposals, setMyProposals] = useState(
|
const [myProposals, setMyProposals] = useState(
|
||||||
myStoredProposals ? JSON.parse(myStoredProposals).map(id => BigInt(id)) : []
|
myStoredProposals ? JSON.parse(myStoredProposals).map(id => BigInt(id)) : []
|
||||||
);
|
);
|
||||||
|
|
||||||
const storedVotedProposals = localStorage.getItem(VOTED_PROPOSALS_PREFIX);
|
const storedVotedProposals = localStorage.getItem(`${VOTED_PROPOSALS_PREFIX}-${address}`);
|
||||||
const [votedProposals, setVotedProposals] = useState(
|
const [votedProposals, setVotedProposals] = useState(
|
||||||
storedVotedProposals ? JSON.parse(storedVotedProposals).map(id => BigInt(id)) : []
|
storedVotedProposals ? JSON.parse(storedVotedProposals).map(id => BigInt(id)) : []
|
||||||
);
|
);
|
||||||
@ -175,7 +174,7 @@ const ProposalTable = ({ children }) => (
|
|||||||
<TableCell align="center" style={{ width: "130px", padding: "8px 0" }}>Status</TableCell>
|
<TableCell align="center" style={{ width: "130px", padding: "8px 0" }}>Status</TableCell>
|
||||||
<TableCell align="center" style={{ padding: "8px 0" }}>Vote Ends</TableCell>
|
<TableCell align="center" style={{ padding: "8px 0" }}>Vote Ends</TableCell>
|
||||||
<TableCell align="center" style={{ padding: "8px 0" }}>Voting Stats</TableCell>
|
<TableCell align="center" style={{ padding: "8px 0" }}>Voting Stats</TableCell>
|
||||||
<TableCell align="center" style={{ padding: "8px 0" }}></TableCell>
|
<TableCell align="center" style={{ width: "180px", padding: "8px 0" }}></TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
|
|
||||||
@ -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 (
|
||||||
@ -224,7 +231,7 @@ const ProposalRow = ({ proposal, blockNumber, openProposal, chainId }) => {
|
|||||||
<Chip
|
<Chip
|
||||||
sx={{ width: "100px" }}
|
sx={{ width: "100px" }}
|
||||||
label={convertStatusToLabel(proposal.state)}
|
label={convertStatusToLabel(proposal.state)}
|
||||||
template={convertStatusToTemplate(proposal.state)}
|
background={convertStatusToColor(proposal.state)}
|
||||||
/>
|
/>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
|
||||||
@ -283,7 +290,7 @@ const ProposalCard = ({ proposal, blockNumber, openProposal, chainId }) => {
|
|||||||
<Chip
|
<Chip
|
||||||
sx={{ width: "88px" }}
|
sx={{ width: "88px" }}
|
||||||
label={convertStatusToLabel(proposal.state)}
|
label={convertStatusToLabel(proposal.state)}
|
||||||
template={convertStatusToTemplate(proposal.state)}
|
background={convertStatusToColor(proposal.state)}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<Typography>
|
<Typography>
|
||||||
|
|||||||
@ -20,7 +20,7 @@ export const prepareAuditReservesCalldata = (chainId) => {
|
|||||||
return { label, target, calldata, value };
|
return { label, target, calldata, value };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const prepareAuditReservesDescription = "Audit Reserves function audits and updates the protocol's total reserve value. It sums the value of all approved reserve and liquidity tokens, then stores and logs the new total.";
|
export const prepareAuditReservesDescription = "function audits and updates the protocol's total reserve value. It sums the value of all approved reserve and liquidity tokens, then stores and logs the new total.";
|
||||||
|
|
||||||
export const AuditReservesSteps = () => {
|
export const AuditReservesSteps = () => {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -29,7 +29,7 @@ export const prepareCreateBondCalldata = (chainId, markets, terms, quoteToken, i
|
|||||||
return { label, target, calldata, value };
|
return { label, target, calldata, value };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const prepareCreateBondDescription = "Create Bond function creates a new bond market by processing pricing, capacity, and term inputs. It initializes and stores the new bond market's complete configuration in the protocol.";
|
export const prepareCreateBondDescription = "function creates a new bond market by processing pricing, capacity, and term inputs. It initializes and stores the new bond market's complete configuration in the protocol.";
|
||||||
|
|
||||||
export const CreateBondParsed = (props) => {
|
export const CreateBondParsed = (props) => {
|
||||||
const [isOpened, setIsOpened] = useState(false);
|
const [isOpened, setIsOpened] = useState(false);
|
||||||
@ -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])}` },
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ export const CreateBondSteps = ({ nativeCurrency, ftsoSymbol, chainId, toInitial
|
|||||||
createMode={createMode}
|
createMode={createMode}
|
||||||
possibleTokens={possibleTokens}
|
possibleTokens={possibleTokens}
|
||||||
setTokenAddress={createMode ? setTokenAddress : empty}
|
setTokenAddress={createMode ? setTokenAddress : empty}
|
||||||
nativeCurrency={nativeCurrency}
|
nativeCurrency={reserveSymbol}
|
||||||
ftsoSymbol={ftsoSymbol}
|
ftsoSymbol={ftsoSymbol}
|
||||||
capacityInQuote={capacityInQuote}
|
capacityInQuote={capacityInQuote}
|
||||||
setCapacityInQuote={createMode ? setCapacityInQuote : empty}
|
setCapacityInQuote={createMode ? setCapacityInQuote : empty}
|
||||||
@ -296,7 +296,7 @@ const TokenAndBooleansArguments = ({
|
|||||||
rightText={"False"}
|
rightText={"False"}
|
||||||
setLeftValue={() => setCapacityInQuote(true)}
|
setLeftValue={() => setCapacityInQuote(true)}
|
||||||
setRightValue={() => setCapacityInQuote(false)}
|
setRightValue={() => setCapacityInQuote(false)}
|
||||||
tooltip={`Determines how the bond market capacity is measured. True = measured in ${nativeCurrency}, False = measured in ${ftsoSymbol}.`}
|
tooltip={`Determines how the bond market capacity is measured. True = measured in _quoteToken, False = measured in ${ftsoSymbol}.`}
|
||||||
/>
|
/>
|
||||||
<BooleanTrigger
|
<BooleanTrigger
|
||||||
value={fixedTerm}
|
value={fixedTerm}
|
||||||
|
|||||||
@ -24,7 +24,7 @@ export const prepareSetAdjustmentCalldata = (chainId, rateChange, targetRate, in
|
|||||||
return { label, target, calldata, value };
|
return { label, target, calldata, value };
|
||||||
}
|
}
|
||||||
|
|
||||||
export const prepareSetAdjustmentDescription = "Set Adjustment function schedules a gradual change to the staking APY. It increases or decreases the staking APY by a specified rate per epoch until a target rate reached.";
|
export const prepareSetAdjustmentDescription = "function schedules a gradual change to the staking APY. It increases or decreases the staking APY by a specified rate per epoch until a target rate reached.";
|
||||||
|
|
||||||
export const SetAdjustmentParsed = (props) => {
|
export const SetAdjustmentParsed = (props) => {
|
||||||
const [isOpened, setIsOpened] = useState(false);
|
const [isOpened, setIsOpened] = useState(false);
|
||||||
|
|||||||
@ -1,18 +1,24 @@
|
|||||||
export const MY_PROPOSALS_PREFIX = "MY_PROPOSALS";
|
export const MY_PROPOSALS_PREFIX = "MY_PROPOSALS";
|
||||||
export const VOTED_PROPOSALS_PREFIX = "VOTED_PROPOSALS";
|
export const VOTED_PROPOSALS_PREFIX = "VOTED_PROPOSALS";
|
||||||
|
|
||||||
export const convertStatusToTemplate = (status) => {
|
export const convertStatusToColor = (status) => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case 7:
|
case 1:
|
||||||
return 'darkGray';
|
return "#f2e370";
|
||||||
case 2:
|
case 2:
|
||||||
return 'warning';
|
return "#f06f73";
|
||||||
case 4:
|
|
||||||
return 'success';
|
|
||||||
case 3:
|
case 3:
|
||||||
return 'error';
|
return "#f06f73";
|
||||||
|
case 4:
|
||||||
|
return "#60c45b";
|
||||||
|
case 5:
|
||||||
|
return "#60c45b";
|
||||||
|
case 6:
|
||||||
|
return "#f06f73";
|
||||||
|
case 7:
|
||||||
|
return "#f2e370";
|
||||||
default:
|
default:
|
||||||
return 'darkGray';
|
return "#a2b7ce";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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: `Total reserves of native coins, LP tokens, and other assets 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)}`;
|
||||||
|
|||||||
@ -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, LP tokens, and other assets 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);
|
||||||
|
|||||||
@ -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}
|
||||||
|
|||||||
@ -96,6 +96,7 @@ export const useMinQuorum = (chainId) => {
|
|||||||
|
|
||||||
export const useProposalThreshold = (chainId, name) => {
|
export const useProposalThreshold = (chainId, name) => {
|
||||||
const decimals = getTokenDecimals(name);
|
const decimals = getTokenDecimals(name);
|
||||||
|
const { proposalCount } = useProposalCount(chainId);
|
||||||
|
|
||||||
const { data } = useReadContract({
|
const { data } = useReadContract({
|
||||||
abi: GovernorStorageAbi,
|
abi: GovernorStorageAbi,
|
||||||
@ -113,13 +114,17 @@ export const useProposalThreshold = (chainId, name) => {
|
|||||||
chainId: chainId,
|
chainId: chainId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const lastIndex = proposalCount === 0n ? 0n : proposalCount - 1n;
|
||||||
|
const { proposalId } = useProposalDetailsAt(chainId, lastIndex, {
|
||||||
|
enabled: proposalCount !== 0n
|
||||||
|
});
|
||||||
|
const { state } = useProposalState(chainId, proposalId, {
|
||||||
|
enabled: proposalCount !== 0n && !!proposalId
|
||||||
|
});
|
||||||
|
|
||||||
let threshold = new DecimalBigNumber(data ?? 0n, decimals);
|
let threshold = new DecimalBigNumber(data ?? 0n, decimals);
|
||||||
|
|
||||||
const { proposalCount } = useProposalCount(chainId);
|
if (proposalCount !== 0n && state !== undefined && state < 2) {
|
||||||
const { proposalId } = useProposalDetailsAt(chainId, proposalCount === 0n ? 0n : proposalCount - 1n);
|
|
||||||
const { state } = useProposalState(chainId, proposalId);
|
|
||||||
|
|
||||||
if (state < 2) {
|
|
||||||
threshold = new DecimalBigNumber(activeProposedLock ?? 0n, decimals);
|
threshold = new DecimalBigNumber(activeProposedLock ?? 0n, decimals);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,7 +340,7 @@ export const useProposals = (chainId, depth, searchedIndexes) => {
|
|||||||
const { data: proposalDeadlines } = useReadContracts({
|
const { data: proposalDeadlines } = useReadContracts({
|
||||||
contracts: indexes?.map(index => {
|
contracts: indexes?.map(index => {
|
||||||
const proposalId = searchedIndexes
|
const proposalId = searchedIndexes
|
||||||
? searchedIndexes?.at(0)
|
? searchedIndexes?.at(index)
|
||||||
: proposalsDetailsAt?.at(index)?.result?.at(0);
|
: proposalsDetailsAt?.at(index)?.result?.at(0);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -352,7 +357,7 @@ export const useProposals = (chainId, depth, searchedIndexes) => {
|
|||||||
const { data: proposalVotes } = useReadContracts({
|
const { data: proposalVotes } = useReadContracts({
|
||||||
contracts: indexes?.map(index => {
|
contracts: indexes?.map(index => {
|
||||||
const proposalId = searchedIndexes
|
const proposalId = searchedIndexes
|
||||||
? searchedIndexes?.at(0)
|
? searchedIndexes?.at(index)
|
||||||
: proposalsDetailsAt?.at(index)?.result?.at(0);
|
: proposalsDetailsAt?.at(index)?.result?.at(0);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -369,7 +374,7 @@ export const useProposals = (chainId, depth, searchedIndexes) => {
|
|||||||
const { data: proposalStates } = useReadContracts({
|
const { data: proposalStates } = useReadContracts({
|
||||||
contracts: indexes?.map(index => {
|
contracts: indexes?.map(index => {
|
||||||
const proposalId = searchedIndexes
|
const proposalId = searchedIndexes
|
||||||
? searchedIndexes?.at(0)
|
? searchedIndexes?.at(index)
|
||||||
: proposalsDetailsAt?.at(index)?.result?.at(0);
|
: proposalsDetailsAt?.at(index)?.result?.at(0);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -386,7 +391,7 @@ export const useProposals = (chainId, depth, searchedIndexes) => {
|
|||||||
const { data: proposalSnapshots } = useReadContracts({
|
const { data: proposalSnapshots } = useReadContracts({
|
||||||
contracts: indexes?.map(index => {
|
contracts: indexes?.map(index => {
|
||||||
const proposalId = searchedIndexes
|
const proposalId = searchedIndexes
|
||||||
? searchedIndexes?.at(0)
|
? searchedIndexes?.at(index)
|
||||||
: proposalsDetailsAt?.at(index)?.result?.at(0);
|
: proposalsDetailsAt?.at(index)?.result?.at(0);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -401,8 +406,8 @@ export const useProposals = (chainId, depth, searchedIndexes) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const { data: proposalQuorums } = useReadContracts({
|
const { data: proposalQuorums } = useReadContracts({
|
||||||
contracts: indexes?.map(index => {
|
contracts: proposalSnapshots?.map((proposal, index) => {
|
||||||
const timepoint = proposalSnapshots?.at(index)?.result;
|
const timepoint = proposal?.result;
|
||||||
return {
|
return {
|
||||||
abi: GovernorAbi,
|
abi: GovernorAbi,
|
||||||
address: GHOST_GOVERNANCE_ADDRESSES[chainId],
|
address: GHOST_GOVERNANCE_ADDRESSES[chainId],
|
||||||
@ -415,8 +420,8 @@ export const useProposals = (chainId, depth, searchedIndexes) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const { data: pastTotalSupplies } = useReadContracts({
|
const { data: pastTotalSupplies } = useReadContracts({
|
||||||
contracts: indexes?.map(index => {
|
contracts: proposalSnapshots?.map((proposal, index) => {
|
||||||
const timepoint = proposalSnapshots?.at(index)?.result;
|
const timepoint = proposal?.result;
|
||||||
return {
|
return {
|
||||||
abi: ghstAbi,
|
abi: ghstAbi,
|
||||||
address: ghstAddress,
|
address: ghstAddress,
|
||||||
@ -431,7 +436,7 @@ export const useProposals = (chainId, depth, searchedIndexes) => {
|
|||||||
const { data: proposalProposer } = useReadContracts({
|
const { data: proposalProposer } = useReadContracts({
|
||||||
contracts: indexes?.map(index => {
|
contracts: indexes?.map(index => {
|
||||||
const proposalId = searchedIndexes
|
const proposalId = searchedIndexes
|
||||||
? searchedIndexes?.at(0)
|
? searchedIndexes?.at(index)
|
||||||
: proposalsDetailsAt?.at(index)?.result?.at(0);
|
: proposalsDetailsAt?.at(index)?.result?.at(0);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -448,7 +453,7 @@ export const useProposals = (chainId, depth, searchedIndexes) => {
|
|||||||
const hashes = indexes?.map(index => {
|
const hashes = indexes?.map(index => {
|
||||||
let result = { short: index + 1, full: undefined };
|
let result = { short: index + 1, full: undefined };
|
||||||
const proposalId = searchedIndexes
|
const proposalId = searchedIndexes
|
||||||
? searchedIndexes?.at(0)
|
? searchedIndexes?.at(index)
|
||||||
: proposalsDetailsAt?.at(index)?.result?.at(0);
|
: proposalsDetailsAt?.at(index)?.result?.at(0);
|
||||||
|
|
||||||
if (proposalId) {
|
if (proposalId) {
|
||||||
@ -464,10 +469,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),
|
||||||
),
|
),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user