diff --git a/app/api/oracle-metadata/[chainId]/route.ts b/app/api/oracle-metadata/[chainId]/route.ts
index 9aabc59d..61de9d40 100644
--- a/app/api/oracle-metadata/[chainId]/route.ts
+++ b/app/api/oracle-metadata/[chainId]/route.ts
@@ -17,7 +17,7 @@ export async function GET(request: Request, { params }: { params: Promise<{ chai
try {
const url = `${ORACLE_GIST_BASE_URL}/oracles.${chainId}.json`;
const response = await fetch(url, {
- next: { revalidate: 1800 }, // Cache for 30 minutes
+ cache: 'no-store',
});
if (!response.ok) {
@@ -29,11 +29,7 @@ export async function GET(request: Request, { params }: { params: Promise<{ chai
const data = await response.json();
- return NextResponse.json(data, {
- headers: {
- 'Cache-Control': 'public, s-maxage=1800, stale-while-revalidate=3600',
- },
- });
+ return NextResponse.json(data);
} catch (error) {
console.error('Failed to fetch oracle metadata:', error);
return NextResponse.json({ error: 'Failed to fetch oracle metadata' }, { status: 500 });
diff --git a/src/features/markets/components/oracle/MarketOracle/FeedEntry.tsx b/src/features/markets/components/oracle/MarketOracle/FeedEntry.tsx
index a328e478..388aabab 100644
--- a/src/features/markets/components/oracle/MarketOracle/FeedEntry.tsx
+++ b/src/features/markets/components/oracle/MarketOracle/FeedEntry.tsx
@@ -10,6 +10,7 @@ import type { OracleFeed } from '@/utils/types';
import { ChainlinkFeedTooltip } from './ChainlinkFeedTooltip';
import { CompoundFeedTooltip } from './CompoundFeedTooltip';
import { GeneralFeedTooltip } from './GeneralFeedTooltip';
+import { PendleFeedTooltip } from './PendleFeedTooltip';
import { RedstoneFeedTooltip } from './RedstoneFeedTooltip';
import { UnknownFeedTooltip } from './UnknownFeedTooltip';
@@ -56,6 +57,7 @@ export function FeedEntry({ feed, chainId, oracleAddress, oracleMetadataMap }: F
const isChainlink = vendor === PriceFeedVendors.Chainlink;
const isCompound = vendor === PriceFeedVendors.Compound;
const isRedstone = vendor === PriceFeedVendors.Redstone;
+ const isPendle = vendor === PriceFeedVendors.Pendle;
const getTooltipContent = () => {
switch (vendor) {
@@ -86,6 +88,15 @@ export function FeedEntry({ feed, chainId, oracleAddress, oracleMetadataMap }: F
/>
);
+ case PriceFeedVendors.Pendle:
+ return (
+
+ );
+
case PriceFeedVendors.PythNetwork:
case PriceFeedVendors.Oval:
case PriceFeedVendors.Lido:
@@ -143,7 +154,7 @@ export function FeedEntry({ feed, chainId, oracleAddress, oracleMetadataMap }: F
)}
- {(isChainlink || isCompound || isRedstone) && vendorIcon ? (
+ {(isChainlink || isCompound || isRedstone || isPendle) && vendorIcon ? (
+ {/* Header with icon and title */}
+
+ {vendorIcon && (
+
+
+
+ )}
+
Pendle Feed Details
+
+
+ {/* Feed pair name */}
+
+
+ {baseAsset} / {quoteAsset}
+
+
+
+ {/* Pendle Specific Data */}
+ {(feedData?.ptSymbol != null || feedData?.baseDiscountPerYear != null) && (
+
+ {feedData?.ptSymbol != null && (
+
+ PT Token:
+ {feedData.ptSymbol}
+
+ )}
+ {feedData?.baseDiscountPerYear != null && (
+
+ Base Discount / Year:
+ {formatDiscountPerYear(feedData.baseDiscountPerYear)}
+
+ )}
+
+ )}
+
+ {/* External Links */}
+
+
View on:
+
+
+
+ Etherscan
+
+
+
+
+ );
+}
diff --git a/src/hooks/useOracleMetadata.ts b/src/hooks/useOracleMetadata.ts
index a95aef45..b3ec81bf 100644
--- a/src/hooks/useOracleMetadata.ts
+++ b/src/hooks/useOracleMetadata.ts
@@ -29,6 +29,10 @@ export type EnrichedFeed = {
deviationThreshold?: number;
ens?: string; // Chainlink ENS name for feed URL (e.g. "eth-usd")
feedType?: string; // Redstone feed type: "market" or "fundamental"
+ baseDiscountPerYear?: string; // Pendle base discount per year (raw 18-decimal value)
+ innerOracle?: string; // Pendle inner oracle address
+ pt?: string; // Pendle PT token address
+ ptSymbol?: string; // Pendle PT token symbol
};
export type OracleOutputData = {
diff --git a/src/imgs/oracles/pendle.png b/src/imgs/oracles/pendle.png
new file mode 100644
index 00000000..27586919
Binary files /dev/null and b/src/imgs/oracles/pendle.png differ
diff --git a/src/utils/oracle.ts b/src/utils/oracle.ts
index bec1237a..5c5467de 100644
--- a/src/utils/oracle.ts
+++ b/src/utils/oracle.ts
@@ -48,6 +48,7 @@ export enum PriceFeedVendors {
Oval = 'Oval',
Compound = 'Compound',
Lido = 'Lido',
+ Pendle = 'Pendle',
Unknown = 'Unknown',
}
@@ -58,6 +59,7 @@ export const OracleVendorIcons: Record = {
[PriceFeedVendors.Oval]: require('../imgs/oracles/uma.png') as string,
[PriceFeedVendors.Compound]: require('../imgs/oracles/compound.webp') as string,
[PriceFeedVendors.Lido]: require('../imgs/oracles/lido.png') as string,
+ [PriceFeedVendors.Pendle]: require('../imgs/oracles/pendle.png') as string,
[PriceFeedVendors.Unknown]: '',
};
@@ -74,6 +76,7 @@ export function mapProviderToVendor(provider: OracleFeedProvider): PriceFeedVend
Lido: PriceFeedVendors.Lido,
Oval: PriceFeedVendors.Oval,
Pyth: PriceFeedVendors.PythNetwork,
+ Pendle: PriceFeedVendors.Pendle,
};
return mapping[provider] ?? PriceFeedVendors.Unknown;
@@ -110,6 +113,10 @@ export type FeedData = {
deviationThreshold?: number;
ens?: string; // Chainlink ENS name for feed URL (e.g. "eth-usd")
feedType?: string; // Redstone feed type: "market" or "fundamental"
+ baseDiscountPerYear?: string; // Pendle base discount per year (raw 18-decimal value)
+ innerOracle?: string; // Pendle inner oracle address
+ pt?: string; // Pendle PT token address
+ ptSymbol?: string; // Pendle PT token symbol
};
export type FeedVendorResult = {
@@ -175,6 +182,10 @@ export function detectFeedVendorFromMetadata(feed: EnrichedFeed | null | undefin
deviationThreshold: feed.deviationThreshold,
ens: feed.ens,
feedType: feed.feedType,
+ baseDiscountPerYear: feed.baseDiscountPerYear,
+ innerOracle: feed.innerOracle,
+ pt: feed.pt,
+ ptSymbol: feed.ptSymbol,
};
return {