Skip to content

Commit a774c26

Browse files
committed
feat: courtesy of green, activity stats, most drawing chance, most reward chance
1 parent 80912c4 commit a774c26

File tree

3 files changed

+100
-58
lines changed

3 files changed

+100
-58
lines changed

web/src/hooks/queries/useHomePageBlockQuery.ts

+91-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,29 @@
11
import { useQuery } from "@tanstack/react-query";
22

33
import { useGraphqlBatcher } from "context/GraphqlBatcher";
4+
import { useMemo } from "react";
45

56
import { graphql } from "src/graphql";
67
import { HomePageBlockQuery } from "src/graphql/graphql";
78
export type { HomePageBlockQuery };
89

910
const homePageBlockQuery = graphql(`
1011
query HomePageBlock($blockNumber: Int) {
11-
courts(orderBy: id, orderDirection: asc, block: { number: $blockNumber }) {
12+
presentCourts: courts(orderBy: id, orderDirection: asc) {
1213
id
14+
parent {
15+
id
16+
}
17+
name
18+
numberDisputes
19+
feeForJuror
20+
stake
21+
}
22+
pastCourts: courts(orderBy: id, orderDirection: asc, block: { number: $blockNumber }) {
23+
id
24+
parent {
25+
id
26+
}
1327
name
1428
numberDisputes
1529
feeForJuror
@@ -22,7 +36,7 @@ export const useHomePageBlockQuery = (blockNumber: number) => {
2236
const isEnabled = blockNumber != null;
2337
const { graphqlBatcher } = useGraphqlBatcher();
2438

25-
return useQuery({
39+
const usedQuery = useQuery({
2640
queryKey: [`homePageBlockQuery${blockNumber}`],
2741
enabled: isEnabled,
2842
queryFn: async () => {
@@ -34,4 +48,79 @@ export const useHomePageBlockQuery = (blockNumber: number) => {
3448
return data;
3549
},
3650
});
51+
52+
const courtActivityStats = useMemo(() => {
53+
if (usedQuery.data && !usedQuery.isFetching) {
54+
// 1. court with most disputes
55+
// we only iterate through past courts, since more courts might exist at the present
56+
// these diffCourts have: average stakes, and dispute diff
57+
58+
const diffCourts = usedQuery.data.pastCourts.map((c, i) => ({
59+
...c,
60+
numberDisputes: usedQuery.data.presentCourts[i].numberDisputes - c.numberDisputes,
61+
treeNumberDisputes: usedQuery.data.presentCourts[i].numberDisputes - c.numberDisputes,
62+
stake: (BigInt(usedQuery.data.presentCourts[i].stake) + BigInt(c.stake)) / 2n,
63+
}));
64+
const mostDisputedCourt = diffCourts.sort((a, b) => b.numberDisputes - a.numberDisputes)[0];
65+
// 2. biggest chances of getting drawn
66+
// fact a: getting drawn in a parent court also subjects you to its rewards
67+
// fact b: staking in children, stakes in parents. but subgraph at this date doesn't reflect this
68+
// so, stakes trickle up, rewards/disputes trickle down
69+
70+
for (const parent of diffCourts) {
71+
for (const child of diffCourts) {
72+
if (parent.id === child.parent?.id) {
73+
child.treeNumberDisputes = String(Number(parent.treeNumberDisputes) + Number(child.treeNumberDisputes));
74+
}
75+
}
76+
}
77+
diffCourts.reverse();
78+
for (const child of diffCourts) {
79+
for (const parent of diffCourts) {
80+
if (parent.id === child.parent?.id) {
81+
parent.stake = String(BigInt(parent.stake) + BigInt(child.stake));
82+
}
83+
}
84+
}
85+
diffCourts.reverse();
86+
//
87+
for (const c of diffCourts) {
88+
c.disputesPerPnk = Number(c.numberDisputes) / (Number(c.stake) / 1e18);
89+
c.treeDisputesPerPnk = c.disputesPerPnk;
90+
}
91+
for (const parent of diffCourts) {
92+
for (const child of diffCourts) {
93+
if (parent.id === child.parent?.id) {
94+
child.treeDisputesPerPnk += parent.disputesPerPnk;
95+
}
96+
}
97+
}
98+
const bestDrawingChancesCourt = diffCourts.sort((a, b) => b.treeDisputesPerPnk - a.treeDisputesPerPnk)[0];
99+
// 3. expected reward
100+
// since we isolated the exclusive disputes from the cumulative disputes
101+
// we can calculate the "isolated reward" of every court
102+
// after that's done, then just trickle the rewards down
103+
104+
for (const c of diffCourts) {
105+
c.expectedRewardPerPnk = c.disputesPerPnk * c.feeForJuror;
106+
c.treeExpectedRewardPerPnk = c.expectedRewardPerPnk;
107+
}
108+
for (const parent of diffCourts) {
109+
for (const child of diffCourts) {
110+
if (parent.id === child.parent?.id) {
111+
child.treeExpectedRewardPerPnk = parent.treeExpectedRewardPerPnk + child.treeExpectedRewardPerPnk;
112+
}
113+
}
114+
}
115+
const bestExpectedRewardCourt = diffCourts.sort(
116+
(a, b) => b.treeExpectedRewardPerPnk - a.treeExpectedRewardPerPnk
117+
)[0];
118+
119+
return { mostDisputedCourt, bestDrawingChancesCourt, bestExpectedRewardCourt };
120+
} else {
121+
return undefined;
122+
}
123+
}, [usedQuery]);
124+
125+
return courtActivityStats;
37126
};
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,12 @@
1-
import { useEffect, useMemo, useState } from "react";
1+
import { useEffect, useState } from "react";
22

33
import { DEFAULT_CHAIN } from "consts/chains";
44

5-
import { HomePageBlockQuery } from "src/graphql/graphql";
6-
import { isUndefined } from "src/utils";
7-
8-
import { useHomePageContext } from "../useHomePageContext";
9-
105
import { useHomePageBlockQuery } from "./useHomePageBlockQuery";
116
import { useBlockNumber } from "wagmi";
127
import { averageBlockTimeInSeconds } from "consts/averageBlockTimeInSeconds";
138

14-
type Court = HomePageBlockQuery["courts"][number];
15-
16-
const getCourtWithMaxDifference = (lastWeekCourts: Court[], currentCourts: Court[]): Court => {
17-
const diffs = lastWeekCourts.map((court, idx) => {
18-
return Number(currentCourts[idx].numberDisputes) - Number(court.numberDisputes);
19-
});
20-
21-
const maxDiffCourtId = diffs.reduce((a, b) => (a > b ? a : b));
22-
23-
return lastWeekCourts[diffs.indexOf(maxDiffCourtId)];
24-
};
25-
26-
const getCourtWithMaxDrawingChance = (currentCourts: Court[]): Court => {
27-
return currentCourts.reduce((a, b) => (Number(a.stake) > Number(b.feeForJuror) ? b : a));
28-
};
29-
30-
const getCourtWithMaxRewardChance = (currentCourts: Court[]): Court => {
31-
return currentCourts.reduce((a, b) => (Number(a.feeForJuror) > Number(b.feeForJuror) ? a : b));
32-
};
33-
34-
export interface HomePageExtraStatsType {
35-
MostActiveCourt: string | null;
36-
HighestDrawingChance: string | null;
37-
HighestRewardChance: string | null;
38-
}
39-
40-
export const useHomePageExtraStats = (): HomePageExtraStatsType => {
41-
const { data } = useHomePageContext();
9+
export const useHomePageExtraStats = () => {
4210
const [oneWeekAgoBlockNumber, setOneWeekAgoBlockNumber] = useState<number>();
4311
const currentBlockNumber = useBlockNumber({ chainId: DEFAULT_CHAIN });
4412

@@ -49,22 +17,7 @@ export const useHomePageExtraStats = (): HomePageExtraStatsType => {
4917
}
5018
}, [DEFAULT_CHAIN, currentBlockNumber]);
5119

52-
const { data: relData } = useHomePageBlockQuery(oneWeekAgoBlockNumber!);
53-
54-
const MostActiveCourt = useMemo(() => {
55-
if (isUndefined(relData) || isUndefined(data)) {
56-
return null;
57-
}
58-
return getCourtWithMaxDifference(relData.courts, data.courts).name ?? null;
59-
}, [relData, data]);
60-
61-
const HighestDrawingChance = useMemo(() => {
62-
return data ? getCourtWithMaxDrawingChance(data.courts).name ?? null : null;
63-
}, [data]);
64-
65-
const HighestRewardChance = useMemo(() => {
66-
return data ? getCourtWithMaxRewardChance(data.courts).name ?? null : null;
67-
}, [data]);
20+
const data = useHomePageBlockQuery(oneWeekAgoBlockNumber!);
6821

69-
return { MostActiveCourt, HighestDrawingChance, HighestRewardChance };
22+
return data;
7023
};

web/src/pages/Home/CourtOverview/ExtraStats.tsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import styled from "styled-components";
44
import LawBalance from "svgs/icons/law-balance.svg";
55
import LongArrowUp from "svgs/icons/long-arrow-up.svg";
66

7-
import { useHomePageExtraStats, HomePageExtraStatsType } from "hooks/queries/useHomePageExtraStats";
7+
import { useHomePageExtraStats } from "hooks/queries/useHomePageExtraStats";
88

99
import ExtraStatsDisplay from "components/ExtraStatsDisplay";
1010

@@ -17,24 +17,24 @@ const StyledCard = styled.div`
1717

1818
interface IStat {
1919
title: string;
20-
getText: (data: HomePageExtraStatsType) => string | null;
20+
getText: (data) => string | null;
2121
icon: React.FC<React.SVGAttributes<SVGElement>>;
2222
}
2323

2424
const stats: IStat[] = [
2525
{
2626
title: "Most Cases",
27-
getText: (data) => data.MostActiveCourt,
27+
getText: (data) => data?.mostDisputedCourt?.name,
2828
icon: LongArrowUp,
2929
},
3030
{
3131
title: "Highest drawing chance",
32-
getText: (data) => data.HighestDrawingChance,
32+
getText: (data) => data?.bestDrawingChancesCourt?.name,
3333
icon: LongArrowUp,
3434
},
3535
{
3636
title: "Highest rewards chance",
37-
getText: (data) => data.HighestRewardChance,
37+
getText: (data) => data?.bestExpectedRewardCourt?.name,
3838
icon: LongArrowUp,
3939
},
4040
];

0 commit comments

Comments
 (0)