diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx
index b4be144..60e6bc6 100644
--- a/src/pages/home/index.tsx
+++ b/src/pages/home/index.tsx
@@ -1,123 +1,184 @@
import './index.css';
-import { useMemo } from 'react';
-
-import { ArrowRight, CircleHelp } from 'lucide-react';
+import { ArrowRight } from 'lucide-react';
import { useNavigate } from 'react-router-dom';
import { PulseLoader } from 'react-spinners';
import NEARLogo from '@/assets/images/near-green.jpg';
-import ApprovedImg from '@/assets/images/approved.png';
import Bg1 from '@/assets/images/home-star-bg1.png';
import Bg2 from '@/assets/images/home-star-bg2.png';
import Markdown from '@/components/markdown';
import { Button } from '@/components/ui/button';
-import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import config from '@/config';
import VoteContainer from '@/containers/vote';
import { cn, formatBigNumber, isNotNullAndNumber } from '@/lib/utils';
import { article } from './article';
+import YesIcon from '@/assets/icons/yes.svg?react';
+import NoIcon from '@/assets/icons/no.svg?react';
+import ApprovedImg from '@/assets/images/approved.png';
import Countdown from './components/Countdown';
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
+import Big from 'big.js';
dayjs.extend(utc);
-function toFraction(x: number): string {
- if (!x) return '2/3';
- if (x > 1) x = x / 100;
- try {
- const tolerance = 0.01;
- let h1 = 1,
- h2 = 0,
- k1 = 0,
- k2 = 1,
- b = x;
- do {
- const a = Math.floor(b);
- let aux = h1;
- h1 = a * h1 + h2;
- h2 = aux;
- aux = k1;
- k1 = a * k1 + k2;
- k2 = aux;
- b = 1 / (b - a);
- } while (Math.abs(x - h1 / k1) > x * tolerance);
-
- return h1 + '/' + k1;
- } catch (error) {
- console.error('Error converting to fraction:', error);
- return '2/3';
- }
-}
-
export default function Home() {
const navigate = useNavigate();
const {
isLoading,
deadline,
- votesCount,
+ votes,
+ voteResult,
+ yesVotesCount,
votedPercent,
- progressList,
- voteFinishedAt,
- votedStakeAmount,
+ votedYeaStakeAmount,
} = VoteContainer.useContainer();
const NEAR_ENV = config.proposalContractId?.split('.').pop() === 'near' ? 'mainnet' : 'testnet';
- const passed = useMemo(() => {
- return Number(votedPercent) >= progressList[progressList.length - 1];
- }, [votedPercent, progressList]);
-
- const showTooltip = useMemo(() => {
- if (voteFinishedAt) return false;
- return passed;
- }, [voteFinishedAt, passed]);
-
const renderVoteProgressStatus = () => {
- if (!voteFinishedAt) {
- return
;
+ if (voteResult) {
+ return (
+
+ {/*
+ {votedPercent}% of Stake Voted for YEA
+
*/}
+

+
+ );
}
+ return
;
+ };
+
+ const renderProgress = () => {
+ const votedPercentNum = Number(votedPercent);
+ const targetPercent = 33.33;
+ const gt50Percent = votedPercentNum >= 50;
+ const totalPercent = gt50Percent ? votedPercentNum : 50;
+ const currentProgressPercent = gt50Percent
+ ? 100
+ : Math.round((votedPercentNum / totalPercent) * 100);
+
+ const targetBadge = (
+
+ );
return (
-
-
- {votedPercent}% of Stake Voted for YEA
+
+
+ {votedPercentNum}% of STAKE VOTED
-

+
+
+
+ {!!votedPercentNum && (
+
20,
+ 'text-app-black pl-1.5': currentProgressPercent <= 20,
+ })}
+ >
+ {votedPercentNum}%
+
+ )}
+
+
+
+
+
0%
+
+
+ {targetPercent}%{targetBadge}
+
+
+
+ {!gt50Percent &&
50%
}
+
);
};
- const renderProgress = () => {
- const _percent = Number(votedPercent);
+ const renderVoteBar = () => {
+ const voteData = Object.values(votes).reduce(
+ (acc, [vote, stake]) => {
+ if (!acc[vote]) {
+ acc[vote] = Big(stake);
+ } else {
+ acc[vote] = acc[vote].plus(Big(stake));
+ }
+ return acc;
+ },
+ {} as Record<'yes' | 'no', Big.Big>,
+ );
+
+ const safeBig = (val: Big.Big | undefined): Big => (val instanceof Big ? val : Big(val || 0));
+
+ const yes = safeBig(voteData?.yes);
+ const no = safeBig(voteData?.no);
+ const voteTotal = yes.plus(no);
+
+ const yesPercent = voteTotal.eq(0) ? '0.00' : yes.div(voteTotal).times(100).toFixed(2);
+ const noPercent = voteTotal.eq(0) ? '0.00' : no.div(voteTotal).times(100).toFixed(2);
+
return (
-
-
- {progressList.map((p) => (
-
- ))}
+
+
+
+ YEA
+
+
- {!!votedPercent && (
-
20,
- 'text-app-black pl-1.5': _percent <= 20,
- })}
- >
- {votedPercent}%
-
- )}
+
+ {yesPercent}%
+
+
+
+
+
+
+ NAY
);
@@ -135,67 +196,19 @@ export default function Home() {
return (
<>
{/* progress bar */}
-
-
-
- {renderProgress()}
-
-
0%
- {progressList.map((p) => (
-
- {p}%
-
- ))}
+ {renderProgress()}
-
100%
-
-
+ {/* vote bar */}
+ {renderVoteBar()}
{/* voting process status */}
{renderVoteProgressStatus()}
- {isNotNullAndNumber(votesCount) ? votesCount : '-'} Votes &{' '}
- {formatBigNumber(votedStakeAmount)}
+ {isNotNullAndNumber(yesVotesCount) ? yesVotesCount : '-'} Votes &{' '}
+ {formatBigNumber(votedYeaStakeAmount)}

-
- Voting Power for YEA
- {showTooltip && (
-
-
-
-
-
- The proposal will pass if the total voted stake keeps above{' '}
- {toFraction(Number(votedPercent))} at the beginning of next epoch or a new vote
- comes in.
-
-
- )}
-
+
Voting Power for YEA
@@ -238,11 +251,10 @@ export default function Home() {
'## Vote with
NEAR CLI\n' +
'Instructions for Validator Voting:\n' +
'- If you are a validator, please use the CLI commands shown below to vote. We do not support voting through wallet for security considerations. This page is only used to display voting results.\n' +
- '- You can vote **yes** or **no** for the proposal. You can change your vote before the voting ends.\n' +
- `- This voting ends when **2/3 of stake votes yes** or when **the deadline (${dayjs.utc(deadline).format('MM/DD/YYYY HH:mm:ss')} UTC) passes**.\n` +
+ `- You can vote **yes** or **no** for the proposal. You can change your vote before the deadline (**${dayjs.utc(deadline).format('MM/DD/YYYY HH:mm:ss')} UTC**).\n` +
+ '- This proposal will be approved if more than **1/3 of total stake** joins the voting and more than **2/3 of stake participating in the voting** is **yes** when the deadline is reached.\n' +
'- Replace **<validator-account-id>** and **<validator-owner-id>** in the commands below with your own account IDs.\n' +
"- [The indexer](https://thegraph.com/explorer/subgraphs/3EbPN5sxnMtSof4M8LuaSKLcNzvzDLrY3eyrRKBhVGaK?view=Query&chain=arbitrum-one) that tracks the voting results may have several minutes delay. If you don't see your vote in the details page, please refresh the page after a while.\n" +
- "- If the voting power of your validator is **0** on the details page, it's probably because your validator is kicked out in recent epochs. This is a known limitation of the current voting contract. Please try **vote again** after your validator is back online for such case.\n" +
'\n' +
'Vote **yes** with the below command, if you support this proposal. \n' +
'\n' +