Skip to content

Commit 6f3cd29

Browse files
authored
Refactor/reserve overview page sdk (#2698)
1 parent 95759d9 commit 6f3cd29

21 files changed

+506
-252
lines changed

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,14 @@
3232
},
3333
"dependencies": {
3434
"@aave/contract-helpers": "1.36.1",
35+
"@aave/graphql": "^0.8.0",
3536
"@aave/math-utils": "1.36.1",
36-
"@aave/react": "0.6.1",
37+
"@aave/react": "^0.7.1",
3738
"@amplitude/analytics-browser": "^2.13.0",
3839
"@bgd-labs/aave-address-book": "^4.36.3",
3940
"@cowprotocol/cow-sdk": "7.1.1",
40-
"@cowprotocol/sdk-flash-loans": "1.5.3",
4141
"@cowprotocol/sdk-ethers-v5-adapter": "0.2.0",
42+
"@cowprotocol/sdk-flash-loans": "1.5.3",
4243
"@emotion/cache": "11.10.3",
4344
"@emotion/react": "11.10.4",
4445
"@emotion/server": "latest",

pages/reserve-overview.page.tsx

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ import StyledToggleButton from 'src/components/StyledToggleButton';
77
import StyledToggleButtonGroup from 'src/components/StyledToggleButtonGroup';
88
import {
99
ComputedReserveData,
10+
ReserveWithId,
1011
useAppDataContext,
1112
} from 'src/hooks/app-data-provider/useAppDataProvider';
1213
import { AssetCapsProvider } from 'src/hooks/useAssetCaps';
14+
import { AssetCapsProviderSDK } from 'src/hooks/useAssetCapsSDK';
1315
import { MainLayout } from 'src/layouts/MainLayout';
1416
import { ReserveActions } from 'src/modules/reserve-overview/ReserveActions';
1517
import { ReserveConfigurationWrapper } from 'src/modules/reserve-overview/ReserveConfigurationWrapper';
@@ -44,23 +46,28 @@ const UnStakeModal = dynamic(() =>
4446

4547
export default function ReserveOverview() {
4648
const router = useRouter();
47-
const { reserves } = useAppDataContext();
49+
const { supplyReserves, reserves } = useAppDataContext();
4850
const underlyingAsset = router.query.underlyingAsset as string;
4951

5052
const [mode, setMode] = useState<'overview' | 'actions' | ''>('overview');
5153
const trackEvent = useRootStore((store) => store.trackEvent);
5254

53-
const reserve = reserves.find(
54-
(reserve) => reserve.underlyingAsset === underlyingAsset
55-
) as ComputedReserveData;
55+
//With SDK
56+
const reserve = supplyReserves.find((reserve) => {
57+
return reserve.underlyingToken.address.toLowerCase() === underlyingAsset?.toLowerCase();
58+
}) as ReserveWithId;
5659

60+
//With Reserves
61+
const reserveLegacy = reserves.find((reserve) => {
62+
return reserve.underlyingAsset.toLowerCase() === underlyingAsset?.toLowerCase();
63+
}) as ComputedReserveData;
5764
const [pageEventCalled, setPageEventCalled] = useState(false);
5865

5966
useEffect(() => {
60-
if (!pageEventCalled && reserve && reserve.iconSymbol && underlyingAsset) {
67+
if (!pageEventCalled && reserve && reserve.underlyingToken.symbol && underlyingAsset) {
6168
trackEvent('Page Viewed', {
6269
'Page Name': 'Reserve Overview',
63-
Reserve: reserve.iconSymbol,
70+
Reserve: reserve.underlyingToken.symbol,
6471
Asset: underlyingAsset,
6572
});
6673
setPageEventCalled(true);
@@ -70,7 +77,7 @@ export default function ReserveOverview() {
7077
const isOverview = mode === 'overview';
7178

7279
return (
73-
<AssetCapsProvider asset={reserve}>
80+
<AssetCapsProviderSDK asset={reserve}>
7481
<ReserveTopDetailsWrapper underlyingAsset={underlyingAsset} />
7582

7683
<ContentContainer>
@@ -120,11 +127,14 @@ export default function ReserveOverview() {
120127
width: { xs: '100%', lg: '416px' },
121128
}}
122129
>
123-
<ReserveActions reserve={reserve} />
130+
{/* Wrapped in AssetCapsProvider to provide the data using legacy method to avoid braking actions */}
131+
<AssetCapsProvider asset={reserveLegacy}>
132+
<ReserveActions reserve={reserveLegacy} />
133+
</AssetCapsProvider>
124134
</Box>
125135
</Box>
126136
</ContentContainer>
127-
</AssetCapsProvider>
137+
</AssetCapsProviderSDK>
128138
);
129139
}
130140

src/hooks/useAssetCapsSDK.tsx

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
import { valueToBigNumber } from '@aave/math-utils';
2+
import { SxProps, Theme } from '@mui/system';
3+
import { createContext, ReactNode, useContext } from 'react';
4+
import { BorrowCapMaxedTooltip } from 'src/components/infoTooltips/BorrowCapMaxedTooltip';
5+
import { DebtCeilingMaxedTooltip } from 'src/components/infoTooltips/DebtCeilingMaxedTooltip';
6+
import { SupplyCapMaxedTooltip } from 'src/components/infoTooltips/SupplyCapMaxedTooltip';
7+
import { BorrowCapWarning } from 'src/components/transactions/Warnings/BorrowCapWarning';
8+
import { DebtCeilingWarning } from 'src/components/transactions/Warnings/DebtCeilingWarning';
9+
import { SupplyCapWarning } from 'src/components/transactions/Warnings/SupplyCapWarning';
10+
11+
import { ReserveWithId } from './app-data-provider/useAppDataProvider';
12+
13+
type WarningDisplayProps = {
14+
supplyCap?: AssetCapData;
15+
borrowCap?: AssetCapData;
16+
debtCeiling?: AssetCapData;
17+
icon?: boolean;
18+
sx?: SxProps<Theme>;
19+
};
20+
21+
export type AssetCapData = {
22+
percentUsed: number;
23+
isMaxed: boolean;
24+
};
25+
26+
export type AssetCapHookData = AssetCapData & {
27+
determineWarningDisplay: (props: WarningDisplayProps) => JSX.Element | null;
28+
displayMaxedTooltip: (props: WarningDisplayProps) => JSX.Element | null;
29+
};
30+
31+
export type AssetCapUsageData = {
32+
reserve: ReserveWithId;
33+
supplyCap: AssetCapHookData;
34+
borrowCap: AssetCapHookData;
35+
debtCeiling: AssetCapHookData;
36+
};
37+
38+
const getAssetCapData = (asset: ReserveWithId): AssetCapUsageData => {
39+
const { supplyCapUsage, supplyCapReached } = getSupplyCapData(asset);
40+
const { borrowCapUsage, borrowCapReached } = getBorrowCapData(asset);
41+
const { debtCeilingUsage, debtCeilingReached } = getDebtCeilingData(asset);
42+
/*
43+
Aggregated Data
44+
*/
45+
const assetCapUsageData: AssetCapUsageData = {
46+
reserve: asset,
47+
supplyCap: {
48+
percentUsed: supplyCapUsage,
49+
isMaxed: supplyCapReached,
50+
// percentUsed: 99.9,
51+
// isMaxed: true,
52+
determineWarningDisplay: ({ supplyCap, icon, ...rest }) =>
53+
supplyCap ? <SupplyCapWarning supplyCap={supplyCap} icon={icon} {...rest} /> : null,
54+
displayMaxedTooltip: ({ supplyCap }) =>
55+
supplyCap ? <SupplyCapMaxedTooltip supplyCap={supplyCap} /> : null,
56+
},
57+
borrowCap: {
58+
percentUsed: borrowCapUsage,
59+
isMaxed: borrowCapReached,
60+
// percentUsed: 98.5,
61+
// isMaxed: false,
62+
determineWarningDisplay: ({ borrowCap, icon, ...rest }) =>
63+
borrowCap ? <BorrowCapWarning borrowCap={borrowCap} icon={icon} {...rest} /> : null,
64+
displayMaxedTooltip: ({ borrowCap }) =>
65+
borrowCap ? <BorrowCapMaxedTooltip borrowCap={borrowCap} /> : null,
66+
},
67+
debtCeiling: {
68+
percentUsed: debtCeilingUsage,
69+
isMaxed: debtCeilingReached,
70+
// percentUsed: 99.994,
71+
// isMaxed: true,
72+
determineWarningDisplay: ({ debtCeiling, icon, ...rest }) =>
73+
debtCeiling ? <DebtCeilingWarning debtCeiling={debtCeiling} icon={icon} {...rest} /> : null,
74+
displayMaxedTooltip: ({ debtCeiling }) =>
75+
debtCeiling ? <DebtCeilingMaxedTooltip debtCeiling={debtCeiling} /> : null,
76+
},
77+
};
78+
79+
return assetCapUsageData;
80+
};
81+
82+
/*
83+
Asset Caps Context
84+
*/
85+
export const AssetCapsSDKContext = createContext({} as AssetCapUsageData);
86+
87+
/*
88+
Asset Caps Provider Component
89+
*/
90+
export const AssetCapsProvider = ({
91+
children,
92+
asset,
93+
}: {
94+
children: ReactNode;
95+
asset: ReserveWithId;
96+
}): JSX.Element | null => {
97+
// Return if no reserve is provided
98+
if (!asset) {
99+
console.warn('<AssetCapsProvider /> was not given a valid reserve asset to parse');
100+
return null;
101+
}
102+
103+
const providerValue = getAssetCapData(asset);
104+
105+
return (
106+
<AssetCapsSDKContext.Provider value={providerValue}>{children}</AssetCapsSDKContext.Provider>
107+
);
108+
};
109+
110+
/*
111+
useAssetCaspsSDKContext hook
112+
*/
113+
export const useAssetCapsSDK = () => {
114+
const context = useContext(AssetCapsSDKContext);
115+
116+
if (context === undefined) {
117+
throw new Error(
118+
'useAssetCaps() can only be used inside of <AssetCapsProvider />, ' +
119+
'please declare it at a higher level.'
120+
);
121+
}
122+
123+
return context;
124+
};
125+
126+
export { AssetCapsProvider as AssetCapsProviderSDK };
127+
128+
/**
129+
* Calculates % of totalLiquidity / supplyCap.
130+
* @param asset ReserveWithId
131+
* @returns { supplyCapUsage: number, supplyCapReached: boolean }
132+
*/
133+
export const getSupplyCapData = (asset: ReserveWithId) => {
134+
const total = valueToBigNumber(asset?.supplyInfo?.total.value ?? '0');
135+
const cap = valueToBigNumber(asset?.supplyInfo?.supplyCap.amount.value ?? '0');
136+
137+
const rawUsage = cap.isZero() ? 0 : total.dividedBy(cap).multipliedBy(100).toNumber();
138+
139+
return {
140+
supplyCapUsage: Number.isFinite(rawUsage) ? rawUsage : 0,
141+
supplyCapReached: asset?.supplyInfo?.supplyCapReached || rawUsage >= 99.99,
142+
};
143+
};
144+
145+
/**
146+
* Calculates borrow cap usage and % of totalDebt / borrowCap.
147+
* @param asset ReserveWithId
148+
* @returns { borrowCapUsage: number, borrowCapReached: boolean }
149+
*/
150+
export const getBorrowCapData = (asset: ReserveWithId) => {
151+
const totalDebt = valueToBigNumber(asset?.borrowInfo?.total.amount.value ?? '0');
152+
const cap = valueToBigNumber(asset?.borrowInfo?.borrowCap.amount.value ?? '0');
153+
154+
const rawUsage = cap.isZero() ? 0 : totalDebt.dividedBy(cap).multipliedBy(100).toNumber();
155+
156+
const borrowCapReached = asset?.borrowInfo?.borrowCapReached || rawUsage >= 99.99;
157+
158+
return {
159+
borrowCapUsage: Number.isFinite(rawUsage) ? rawUsage : 0,
160+
borrowCapReached: borrowCapReached ?? false,
161+
};
162+
};
163+
164+
/**
165+
* Calculates debt ceiling usage and % of isolationModeTotalDebt / debtCeiling.
166+
* @param asset
167+
* @returns {debtCeilingUsage: number, debtCeilingReached: boolean}
168+
*/
169+
export const getDebtCeilingData = (asset: ReserveWithId) => {
170+
const totalBorrows = valueToBigNumber(
171+
asset?.isolationModeConfig?.totalBorrows.amount.value ?? '0'
172+
);
173+
const debtCeilingCap = valueToBigNumber(
174+
asset?.isolationModeConfig?.debtCeiling.amount.value ?? '0'
175+
);
176+
const rawUsage = debtCeilingCap.isZero()
177+
? 0
178+
: totalBorrows.dividedBy(debtCeilingCap).multipliedBy(100).toNumber();
179+
180+
return {
181+
debtCeilingUsage: Number.isFinite(rawUsage) ? rawUsage : 0,
182+
debtCeilingReached: rawUsage >= 99.99,
183+
};
184+
};

src/locales/el/messages.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/locales/en/messages.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/locales/en/messages.po

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2095,10 +2095,6 @@ msgstr "Loading quote..."
20952095
msgid "Estimated Costs & Fees"
20962096
msgstr "Estimated Costs & Fees"
20972097

2098-
#: src/modules/reserve-overview/SupplyInfo.tsx
2099-
msgid "Unbacked"
2100-
msgstr "Unbacked"
2101-
21022098
#: src/components/infoTooltips/EModeTooltip.tsx
21032099
msgid "E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more</1>"
21042100
msgstr "E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more</1>"

src/locales/es/messages.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/locales/fr/messages.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)