-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathuseFloatingPoolAPR.ts
96 lines (79 loc) · 3.21 KB
/
useFloatingPoolAPR.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import { useCallback, useMemo, useState } from 'react';
import { parseUnits } from 'viem';
import WAD from '@exactly/lib/esm/fixed-point-math/WAD';
import floatingRate from '@exactly/lib/esm/interest-rate-model/floatingRate';
import floatingUtilization from '@exactly/lib/esm/interest-rate-model/floatingUtilization';
import globalUtilization from '@exactly/lib/esm/interest-rate-model/globalUtilization';
import networkData from 'config/networkData.json' assert { type: 'json' };
import type { Operation } from 'types/Operation';
import queryRates from 'utils/queryRates';
import useAccountData from './useAccountData';
import useDelayedEffect from './useDelayedEffect';
import { useWeb3 } from './useWeb3';
import { useGlobalError } from 'contexts/GlobalErrorContext';
import useIRM from './useIRM';
type FloatingPoolAPR = {
depositAPR: number | undefined;
borrowAPR: number | undefined;
loading: boolean;
};
export default (
symbol: string,
qty?: string,
operation?: Extract<Operation, 'deposit' | 'borrow'>,
): FloatingPoolAPR => {
const { chain } = useWeb3();
const { marketAccount } = useAccountData(symbol);
const irm = useIRM(symbol);
const [depositAPR, setDepositAPR] = useState<number | undefined>();
const [loading, setLoading] = useState<boolean>(true);
const { setIndexerError } = useGlobalError();
const borrowAPR = useMemo((): number | undefined => {
if (!marketAccount || !irm || operation === 'deposit') {
return undefined;
}
const { totalFloatingDepositAssets, totalFloatingBorrowAssets, decimals, floatingBackupBorrowed } = marketAccount;
const delta = parseUnits(qty || '0', decimals);
const debt = totalFloatingBorrowAssets + delta;
return (
Number(
floatingRate(
floatingUtilization(totalFloatingDepositAssets, debt),
globalUtilization(totalFloatingDepositAssets, debt, floatingBackupBorrowed),
irm,
),
) / 1e18
);
}, [marketAccount, irm, operation, qty]);
const fetchAPRs = useCallback(
async (cancelled: () => boolean) => {
if (operation === 'borrow') return;
setLoading(true);
if (!marketAccount) return setDepositAPR(undefined);
try {
const subgraphUrl = networkData[String(chain.id) as keyof typeof networkData]?.subgraph.exactly;
if (!subgraphUrl) return;
const [{ apr: depositAPRRate }] = await queryRates(subgraphUrl, marketAccount.market, 'deposit', {
maxFuturePools: marketAccount.maxFuturePools,
});
if (cancelled()) return;
const { totalFloatingDepositAssets, decimals } = marketAccount;
const futureSupply = totalFloatingDepositAssets + parseUnits(qty || '0', decimals);
const ratio = Number(futureSupply === 0n ? 0n : (totalFloatingDepositAssets * WAD) / futureSupply) / 1e18;
const finalAPR = ratio * depositAPRRate;
setDepositAPR(finalAPR);
setLoading(false);
} catch {
setIndexerError();
setDepositAPR(undefined);
}
},
[operation, marketAccount, chain, qty, setIndexerError],
);
const { isLoading: delayedLoading } = useDelayedEffect({ effect: fetchAPRs });
return {
depositAPR,
borrowAPR,
loading: loading || delayedLoading,
};
};