Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
114328f
refactor: sdk integrated in market page
AGMASO Sep 26, 2025
940cdf4
chore: clean code
AGMASO Sep 26, 2025
fcb1a39
fix: simplified icon fetch logic & clean code
AGMASO Sep 29, 2025
92eeffd
fix: build error
AGMASO Sep 29, 2025
a80c04b
fix: build error
AGMASO Sep 29, 2025
4a5e1fe
fix: build error
AGMASO Sep 29, 2025
eff6ed6
chore: clean code
AGMASO Sep 30, 2025
8653eb9
chore: clean code
AGMASO Sep 30, 2025
75769d3
refactor: integrate sdk into reserve-overview. missing few flags from…
AGMASO Oct 3, 2025
be28f80
fix: show disabled only for > 0 amounts
AGMASO Oct 3, 2025
c4d503f
Merge branch 'refactor/sdk-in-markets' into refactor/reserve-overview…
AGMASO Oct 3, 2025
9f5d624
fix: solved issue on tokenIcons in reserve-overview page
AGMASO Oct 6, 2025
47ec420
fix: clean code
AGMASO Oct 6, 2025
18dadae
fix: clean code
AGMASO Oct 6, 2025
27eb9b8
fix: clean code
AGMASO Oct 6, 2025
8f7da60
chore: clean code
AGMASO Oct 7, 2025
2e502e9
feat: added interest Rate Strategy Address to link, after updated sdk
AGMASO Oct 8, 2025
d3d3e45
fix: use typescript guards
AGMASO Oct 10, 2025
3610842
fix: simplified code
AGMASO Oct 10, 2025
4e83b97
refactor: move incentives calculation to parent component
AGMASO Oct 10, 2025
de6b877
chore: clean code
AGMASO Oct 13, 2025
cdc1ae9
Merge branch 'refactor/sdk-in-markets' into refactor/reserve-overview…
AGMASO Oct 13, 2025
f8fa340
feat: added Pts-ethena tokens to mapping
AGMASO Oct 21, 2025
5b6f0ee
chore: trigger rebuild
AGMASO Oct 21, 2025
ca6db43
Merge remote-tracking branch 'origin/refactor/sdk-in-markets' into re…
AGMASO Oct 21, 2025
21ca830
chore: bump aave-sdk versions
AGMASO Nov 5, 2025
d31da54
fix: isolationdebtceiling values displaying correct now
AGMASO Nov 5, 2025
2ea35f5
Merge branch 'main' into refactor/reserve-overview-page-sdk
AGMASO Nov 27, 2025
16ed69e
fix: build error
AGMASO Nov 27, 2025
c7f5220
feat: deleted unbacked section, not used
AGMASO Nov 27, 2025
b0bae0b
fix: changed logic and add guard to show apys for borrow and supply
AGMASO Nov 27, 2025
a17e754
Merge remote-tracking branch 'origin' into refactor/reserve-overview-…
AGMASO Dec 2, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,14 @@
},
"dependencies": {
"@aave/contract-helpers": "1.36.1",
"@aave/graphql": "^0.8.0",
"@aave/math-utils": "1.36.1",
"@aave/react": "0.6.1",
"@aave/react": "^0.7.1",
"@amplitude/analytics-browser": "^2.13.0",
"@bgd-labs/aave-address-book": "^4.36.3",
"@cowprotocol/cow-sdk": "7.1.1",
"@cowprotocol/sdk-flash-loans": "1.5.3",
"@cowprotocol/sdk-ethers-v5-adapter": "0.2.0",
"@cowprotocol/sdk-flash-loans": "1.5.3",
"@emotion/cache": "11.10.3",
"@emotion/react": "11.10.4",
"@emotion/server": "latest",
Expand Down
28 changes: 19 additions & 9 deletions pages/reserve-overview.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import StyledToggleButton from 'src/components/StyledToggleButton';
import StyledToggleButtonGroup from 'src/components/StyledToggleButtonGroup';
import {
ComputedReserveData,
ReserveWithId,
useAppDataContext,
} from 'src/hooks/app-data-provider/useAppDataProvider';
import { AssetCapsProvider } from 'src/hooks/useAssetCaps';
import { AssetCapsProviderSDK } from 'src/hooks/useAssetCapsSDK';
import { MainLayout } from 'src/layouts/MainLayout';
import { ReserveActions } from 'src/modules/reserve-overview/ReserveActions';
import { ReserveConfigurationWrapper } from 'src/modules/reserve-overview/ReserveConfigurationWrapper';
Expand Down Expand Up @@ -44,23 +46,28 @@ const UnStakeModal = dynamic(() =>

export default function ReserveOverview() {
const router = useRouter();
const { reserves } = useAppDataContext();
const { supplyReserves, reserves } = useAppDataContext();
const underlyingAsset = router.query.underlyingAsset as string;

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

const reserve = reserves.find(
(reserve) => reserve.underlyingAsset === underlyingAsset
) as ComputedReserveData;
//With SDK
const reserve = supplyReserves.find((reserve) => {
return reserve.underlyingToken.address.toLowerCase() === underlyingAsset?.toLowerCase();
}) as ReserveWithId;

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

useEffect(() => {
if (!pageEventCalled && reserve && reserve.iconSymbol && underlyingAsset) {
if (!pageEventCalled && reserve && reserve.underlyingToken.symbol && underlyingAsset) {
trackEvent('Page Viewed', {
'Page Name': 'Reserve Overview',
Reserve: reserve.iconSymbol,
Reserve: reserve.underlyingToken.symbol,
Asset: underlyingAsset,
});
setPageEventCalled(true);
Expand All @@ -70,7 +77,7 @@ export default function ReserveOverview() {
const isOverview = mode === 'overview';

return (
<AssetCapsProvider asset={reserve}>
<AssetCapsProviderSDK asset={reserve}>
<ReserveTopDetailsWrapper underlyingAsset={underlyingAsset} />

<ContentContainer>
Expand Down Expand Up @@ -120,11 +127,14 @@ export default function ReserveOverview() {
width: { xs: '100%', lg: '416px' },
}}
>
<ReserveActions reserve={reserve} />
{/* Wrapped in AssetCapsProvider to provide the data using legacy method to avoid braking actions */}
<AssetCapsProvider asset={reserveLegacy}>
<ReserveActions reserve={reserveLegacy} />
</AssetCapsProvider>
</Box>
</Box>
</ContentContainer>
</AssetCapsProvider>
</AssetCapsProviderSDK>
);
}

Expand Down
184 changes: 184 additions & 0 deletions src/hooks/useAssetCapsSDK.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
import { valueToBigNumber } from '@aave/math-utils';
import { SxProps, Theme } from '@mui/system';
import { createContext, ReactNode, useContext } from 'react';
import { BorrowCapMaxedTooltip } from 'src/components/infoTooltips/BorrowCapMaxedTooltip';
import { DebtCeilingMaxedTooltip } from 'src/components/infoTooltips/DebtCeilingMaxedTooltip';
import { SupplyCapMaxedTooltip } from 'src/components/infoTooltips/SupplyCapMaxedTooltip';
import { BorrowCapWarning } from 'src/components/transactions/Warnings/BorrowCapWarning';
import { DebtCeilingWarning } from 'src/components/transactions/Warnings/DebtCeilingWarning';
import { SupplyCapWarning } from 'src/components/transactions/Warnings/SupplyCapWarning';

import { ReserveWithId } from './app-data-provider/useAppDataProvider';

type WarningDisplayProps = {
supplyCap?: AssetCapData;
borrowCap?: AssetCapData;
debtCeiling?: AssetCapData;
icon?: boolean;
sx?: SxProps<Theme>;
};

export type AssetCapData = {
percentUsed: number;
isMaxed: boolean;
};

export type AssetCapHookData = AssetCapData & {
determineWarningDisplay: (props: WarningDisplayProps) => JSX.Element | null;
displayMaxedTooltip: (props: WarningDisplayProps) => JSX.Element | null;
};

export type AssetCapUsageData = {
reserve: ReserveWithId;
supplyCap: AssetCapHookData;
borrowCap: AssetCapHookData;
debtCeiling: AssetCapHookData;
};

const getAssetCapData = (asset: ReserveWithId): AssetCapUsageData => {
const { supplyCapUsage, supplyCapReached } = getSupplyCapData(asset);
const { borrowCapUsage, borrowCapReached } = getBorrowCapData(asset);
const { debtCeilingUsage, debtCeilingReached } = getDebtCeilingData(asset);
/*
Aggregated Data
*/
const assetCapUsageData: AssetCapUsageData = {
reserve: asset,
supplyCap: {
percentUsed: supplyCapUsage,
isMaxed: supplyCapReached,
// percentUsed: 99.9,
// isMaxed: true,
determineWarningDisplay: ({ supplyCap, icon, ...rest }) =>
supplyCap ? <SupplyCapWarning supplyCap={supplyCap} icon={icon} {...rest} /> : null,
displayMaxedTooltip: ({ supplyCap }) =>
supplyCap ? <SupplyCapMaxedTooltip supplyCap={supplyCap} /> : null,
},
borrowCap: {
percentUsed: borrowCapUsage,
isMaxed: borrowCapReached,
// percentUsed: 98.5,
// isMaxed: false,
determineWarningDisplay: ({ borrowCap, icon, ...rest }) =>
borrowCap ? <BorrowCapWarning borrowCap={borrowCap} icon={icon} {...rest} /> : null,
displayMaxedTooltip: ({ borrowCap }) =>
borrowCap ? <BorrowCapMaxedTooltip borrowCap={borrowCap} /> : null,
},
debtCeiling: {
percentUsed: debtCeilingUsage,
isMaxed: debtCeilingReached,
// percentUsed: 99.994,
// isMaxed: true,
determineWarningDisplay: ({ debtCeiling, icon, ...rest }) =>
debtCeiling ? <DebtCeilingWarning debtCeiling={debtCeiling} icon={icon} {...rest} /> : null,
displayMaxedTooltip: ({ debtCeiling }) =>
debtCeiling ? <DebtCeilingMaxedTooltip debtCeiling={debtCeiling} /> : null,
},
};

return assetCapUsageData;
};

/*
Asset Caps Context
*/
export const AssetCapsSDKContext = createContext({} as AssetCapUsageData);

/*
Asset Caps Provider Component
*/
export const AssetCapsProvider = ({
children,
asset,
}: {
children: ReactNode;
asset: ReserveWithId;
}): JSX.Element | null => {
// Return if no reserve is provided
if (!asset) {
console.warn('<AssetCapsProvider /> was not given a valid reserve asset to parse');
return null;
}

const providerValue = getAssetCapData(asset);

return (
<AssetCapsSDKContext.Provider value={providerValue}>{children}</AssetCapsSDKContext.Provider>
);
};

/*
useAssetCaspsSDKContext hook
*/
export const useAssetCapsSDK = () => {
const context = useContext(AssetCapsSDKContext);

if (context === undefined) {
throw new Error(
'useAssetCaps() can only be used inside of <AssetCapsProvider />, ' +
'please declare it at a higher level.'
);
}

return context;
};

export { AssetCapsProvider as AssetCapsProviderSDK };

/**
* Calculates % of totalLiquidity / supplyCap.
* @param asset ReserveWithId
* @returns { supplyCapUsage: number, supplyCapReached: boolean }
*/
export const getSupplyCapData = (asset: ReserveWithId) => {
const total = valueToBigNumber(asset?.supplyInfo?.total.value ?? '0');
const cap = valueToBigNumber(asset?.supplyInfo?.supplyCap.amount.value ?? '0');

const rawUsage = cap.isZero() ? 0 : total.dividedBy(cap).multipliedBy(100).toNumber();

return {
supplyCapUsage: Number.isFinite(rawUsage) ? rawUsage : 0,
supplyCapReached: asset?.supplyInfo?.supplyCapReached || rawUsage >= 99.99,
};
};

/**
* Calculates borrow cap usage and % of totalDebt / borrowCap.
* @param asset ReserveWithId
* @returns { borrowCapUsage: number, borrowCapReached: boolean }
*/
export const getBorrowCapData = (asset: ReserveWithId) => {
const totalDebt = valueToBigNumber(asset?.borrowInfo?.total.amount.value ?? '0');
const cap = valueToBigNumber(asset?.borrowInfo?.borrowCap.amount.value ?? '0');

const rawUsage = cap.isZero() ? 0 : totalDebt.dividedBy(cap).multipliedBy(100).toNumber();

const borrowCapReached = asset?.borrowInfo?.borrowCapReached || rawUsage >= 99.99;

return {
borrowCapUsage: Number.isFinite(rawUsage) ? rawUsage : 0,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when does it go into the 0 block?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the cap is zero and the supplied != 0 (e.g. after a gov freeze), shouldn't usage be 100%?

borrowCapReached: borrowCapReached ?? false,
};
};

/**
* Calculates debt ceiling usage and % of isolationModeTotalDebt / debtCeiling.
* @param asset
* @returns {debtCeilingUsage: number, debtCeilingReached: boolean}
*/
export const getDebtCeilingData = (asset: ReserveWithId) => {
const totalBorrows = valueToBigNumber(
asset?.isolationModeConfig?.totalBorrows.amount.value ?? '0'
);
const debtCeilingCap = valueToBigNumber(
asset?.isolationModeConfig?.debtCeiling.amount.value ?? '0'
);
const rawUsage = debtCeilingCap.isZero()
? 0
: totalBorrows.dividedBy(debtCeilingCap).multipliedBy(100).toNumber();

return {
debtCeilingUsage: Number.isFinite(rawUsage) ? rawUsage : 0,
debtCeilingReached: rawUsage >= 99.99,
};
};
2 changes: 1 addition & 1 deletion src/locales/el/messages.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/locales/en/messages.js

Large diffs are not rendered by default.

4 changes: 0 additions & 4 deletions src/locales/en/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -2095,10 +2095,6 @@ msgstr "Loading quote..."
msgid "Estimated Costs & Fees"
msgstr "Estimated Costs & Fees"

#: src/modules/reserve-overview/SupplyInfo.tsx
msgid "Unbacked"
msgstr "Unbacked"

#: src/components/infoTooltips/EModeTooltip.tsx
msgid "E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more</1>"
msgstr "E-Mode increases your LTV for a selected category of assets up to<0/>. <1>Learn more</1>"
Expand Down
2 changes: 1 addition & 1 deletion src/locales/es/messages.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/locales/fr/messages.js

Large diffs are not rendered by default.

Loading
Loading