Skip to content

Commit a84ece0

Browse files
authored
SOV-5278: estimated amm weekly rewards (#1133)
* fix: estimated amm weekly rewards * chore: add changeset
1 parent 2541d6e commit a84ece0

7 files changed

Lines changed: 116 additions & 75 deletions

File tree

.changeset/few-bugs-remember.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'frontend': patch
3+
---
4+
5+
SOV-5278: fix amm rewards estimation

apps/frontend/src/app/5_pages/MarketMakingPage/components/AdjustAndDepositModal/components/NewPoolStatistics/NewPoolStatistics.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,10 @@ export const NewPoolStatistics: FC<NewPoolStatisticsProps> = ({
100100

101101
const { weeklyRewardsEstimation } = useGetPoolBalanceAndRewards(
102102
pool,
103+
newPoolBalanceA,
103104
newPoolBalanceB,
105+
isTokenA,
106+
isV2Pool,
104107
);
105108

106109
return (
Lines changed: 71 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,96 @@
1-
import { useCallback, useEffect, useState } from 'react';
1+
import { useQuery } from '@tanstack/react-query';
22

33
import { Decimal } from '@sovryn/utils';
44

55
import { RSK_CHAIN_ID } from '../../../../../../config/chains';
66

77
import { useGetTokenContract } from '../../../../../../hooks/useGetContract';
8-
import { COMMON_SYMBOLS } from '../../../../../../utils/asset';
8+
import {
9+
COMMON_SYMBOLS,
10+
maybeWrappedAsset,
11+
} from '../../../../../../utils/asset';
912
import { decimalic } from '../../../../../../utils/math';
1013
import { useGetTokenPrice } from '../../../../BorrowPage/hooks/useGetTokenPrice';
14+
import { useGetReturnRate } from '../../../hooks/useGetReturnRate';
1115
import { AmmLiquidityPool } from '../../../utils/AmmLiquidityPool';
12-
import { WEEKLY_REWARDS_AMOUNT } from '../AdjustAndDepositModal.constants';
1316

1417
export const useGetPoolBalanceAndRewards = (
1518
pool: AmmLiquidityPool,
1619
newPoolBalanceA: Decimal,
20+
newPoolBalanceB: Decimal,
21+
isTokenA: boolean,
22+
isV2Pool: boolean,
1723
) => {
18-
const [weeklyRewardsEstimation, setWeeklyRewardsEstimation] =
19-
useState<Decimal>(Decimal.ZERO);
20-
2124
const poolContract = useGetTokenContract(COMMON_SYMBOLS.WBTC, RSK_CHAIN_ID);
2225

23-
const tokenContract = useGetTokenContract(pool.assetA, RSK_CHAIN_ID);
24-
const { data: tokenPrice } = useGetTokenPrice(tokenContract?.address || '');
26+
const tokenContractA = useGetTokenContract(
27+
maybeWrappedAsset(pool.assetA),
28+
RSK_CHAIN_ID,
29+
);
30+
const tokenContractB = useGetTokenContract(
31+
maybeWrappedAsset(pool.assetB),
32+
RSK_CHAIN_ID,
33+
);
34+
const { data: tokenPriceA } = useGetTokenPrice(tokenContractA?.address || '');
35+
const { data: tokenPriceB } = useGetTokenPrice(tokenContractB?.address || '');
36+
const returnRates = useGetReturnRate(pool);
2537

26-
const fetchPoolBalance = useCallback(async () => {
27-
if (!poolContract || !newPoolBalanceA || !tokenPrice || !tokenContract) {
28-
return;
29-
}
30-
try {
38+
const { data: weeklyRewardsEstimation } = useQuery({
39+
queryKey: [
40+
'poolBalanceAndRewards',
41+
pool.converter,
42+
newPoolBalanceA.toString(),
43+
newPoolBalanceB.toString(),
44+
tokenPriceA,
45+
tokenPriceB,
46+
isTokenA,
47+
isV2Pool,
48+
returnRates,
49+
],
50+
queryFn: async () => {
51+
if (
52+
!poolContract ||
53+
!newPoolBalanceA ||
54+
!tokenPriceA ||
55+
!tokenContractA
56+
) {
57+
return Decimal.ZERO;
58+
}
3159
const poolBalance = await poolContract
3260
.balanceOf(pool.converter)
3361
.then(Decimal.fromBigNumberString);
3462
if (poolBalance) {
35-
const value = newPoolBalanceA
36-
.div(poolBalance)
37-
.mul(WEEKLY_REWARDS_AMOUNT)
38-
.mul(decimalic(tokenPrice?.token?.lastPriceBtc || '0'));
39-
setWeeklyRewardsEstimation(value);
63+
if (isV2Pool) {
64+
const balance = isTokenA ? newPoolBalanceA : newPoolBalanceB;
65+
return balance
66+
.mul(
67+
decimalic(
68+
isTokenA
69+
? tokenPriceA.token?.lastPriceBtc || '0'
70+
: tokenPriceB?.token?.lastPriceBtc || '0',
71+
),
72+
)
73+
.mul(decimalic(returnRates.beforeRewards).div(100))
74+
.div(52);
75+
} else {
76+
const value1 = newPoolBalanceA
77+
.mul(decimalic(tokenPriceA?.token?.lastPriceBtc || '0'))
78+
.mul(decimalic(returnRates.beforeRewards).div(100))
79+
.div(52);
80+
const value2 = newPoolBalanceB
81+
.mul(decimalic(tokenPriceB?.token?.lastPriceBtc || '0'))
82+
.mul(decimalic(returnRates.beforeRewards).div(100))
83+
.div(52);
84+
return value1.add(value2);
85+
}
4086
}
41-
} catch (error) {
42-
console.error('Error fetching pool balance:', error);
43-
}
44-
}, [
45-
pool.converter,
46-
newPoolBalanceA,
47-
tokenPrice,
48-
poolContract,
49-
tokenContract,
50-
]);
51-
52-
useEffect(() => {
53-
fetchPoolBalance();
54-
}, [fetchPoolBalance]);
87+
88+
return Decimal.ZERO;
89+
},
90+
enabled:
91+
!!poolContract && !!newPoolBalanceA && !!tokenPriceA && !!tokenContractA,
92+
initialData: Decimal.ZERO,
93+
});
5594

5695
return { weeklyRewardsEstimation };
5796
};

apps/frontend/src/app/5_pages/MarketMakingPage/components/PoolsTable/components/PoolsTableReturns/PoolsTableReturns.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export const PoolsTableReturns: FC<PoolsTableReturnsProps> = ({
1515
pool,
1616
className,
1717
}) => {
18-
const { returnRates } = useGetReturnRate(pool);
18+
const returnRates = useGetReturnRate(pool);
1919

2020
const returnRate = useMemo(
2121
() =>
Lines changed: 33 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState, useEffect } from 'react';
1+
import { useQuery } from '@tanstack/react-query';
22

33
import { useBlockNumber } from '../../../../hooks/useBlockNumber';
44
import { getAmmServiceUrl } from '../../../../utils/helpers';
@@ -32,53 +32,44 @@ export const useGetReturnRate = ({
3232
const ammServiceUrl = getAmmServiceUrl();
3333
const { value: block } = useBlockNumber();
3434

35-
const [returnRates, setReturnRates] = useState<ReturnRates>({
36-
beforeRewards: '0',
37-
afterRewards: '0',
38-
});
39-
40-
useEffect(() => {
41-
const fetchData = async () => {
42-
try {
43-
const response = await fetch(`${ammServiceUrl}/amm`);
44-
const data: AmmResponse = await response.json();
35+
const { data } = useQuery({
36+
queryKey: ['ammPoolReturnRates', converter, block],
37+
queryFn: async () => {
38+
const response = await fetch(`${ammServiceUrl}/amm`);
39+
const data: AmmResponse = await response.json();
4540

46-
if (data[converter]) {
47-
const poolData =
48-
converterVersion === 1
49-
? data[converter].data[Object.keys(data[converter].data)[0]]
50-
: data[converter].data[poolTokenA];
41+
if (data[converter]) {
42+
const poolData =
43+
converterVersion === 1
44+
? data[converter].data[Object.keys(data[converter].data)[0]]
45+
: data[converter].data[poolTokenA];
5146

52-
if (poolData && poolData.length > 0) {
53-
const sumFeesApy = poolData.reduce(
54-
(acc, entry) => acc + parseFloat(entry.APY_fees_pc),
55-
0,
56-
);
57-
const sumTotalApy = poolData.reduce(
58-
(acc, entry) => acc + parseFloat(entry.APY_pc),
59-
0,
60-
);
47+
if (poolData && poolData.length > 0) {
48+
const sumFeesApy = poolData.reduce(
49+
(acc, entry) => acc + parseFloat(entry.APY_fees_pc),
50+
0,
51+
);
52+
const sumTotalApy = poolData.reduce(
53+
(acc, entry) => acc + parseFloat(entry.APY_pc),
54+
0,
55+
);
6156

62-
const avgFeesApy = (sumFeesApy / poolData.length).toFixed(2);
63-
const avgTotalApy = (sumTotalApy / poolData.length).toFixed(2);
57+
const avgFeesApy = (sumFeesApy / poolData.length).toFixed(2);
58+
const avgTotalApy = (sumTotalApy / poolData.length).toFixed(2);
6459

65-
setReturnRates({
66-
beforeRewards: avgFeesApy,
67-
afterRewards: avgTotalApy,
68-
});
69-
} else {
70-
setReturnRates({ beforeRewards: '0', afterRewards: '0' });
71-
}
60+
return {
61+
beforeRewards: avgFeesApy,
62+
afterRewards: avgTotalApy,
63+
};
7264
} else {
73-
setReturnRates({ beforeRewards: '0', afterRewards: '0' });
65+
return { beforeRewards: '0', afterRewards: '0' };
7466
}
75-
} catch (error) {
76-
console.error('Error fetching amm pool data:', error);
67+
} else {
68+
return { beforeRewards: '0', afterRewards: '0' };
7769
}
78-
};
79-
80-
fetchData();
81-
}, [ammServiceUrl, block, converter, converterVersion, poolTokenA]);
70+
},
71+
initialData: { beforeRewards: '0', afterRewards: '0' },
72+
});
8273

83-
return { returnRates };
74+
return data;
8475
};

apps/frontend/src/utils/graphql/rsk/generated.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16669,6 +16669,7 @@ export type GetTokenQuery = {
1666916669
__typename?: 'Query';
1667016670
token?: {
1667116671
__typename?: 'Token';
16672+
symbol?: string | null;
1667216673
lastPriceUsd: string;
1667316674
lastPriceBtc: string;
1667416675
} | null;
@@ -19108,6 +19109,7 @@ export type GetSwapHistoryQueryResult = Apollo.QueryResult<
1910819109
export const GetTokenDocument = gql`
1910919110
query getToken($id: ID!) {
1911019111
token(id: $id) {
19112+
symbol
1911119113
lastPriceUsd
1911219114
lastPriceBtc
1911319115
}

apps/frontend/src/utils/graphql/rsk/operations/getToken.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
query getToken($id: ID!) {
22
token(id: $id) {
3+
symbol
34
lastPriceUsd
45
lastPriceBtc
56
}

0 commit comments

Comments
 (0)