Skip to content
Merged
Changes from all commits
Commits
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
40 changes: 40 additions & 0 deletions src/hooks/useMerklIncentives.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ProtocolAction } from '@aave/contract-helpers';
import { ReserveIncentiveResponse } from '@aave/math-utils/dist/esm/formatters/incentive/calculate-reserve-incentives';
import { AaveV3Ethereum } from '@bgd-labs/aave-address-book';
import { useQuery } from '@tanstack/react-query';
import { useRootStore } from 'src/store/root';
import { convertAprToApy } from 'src/utils/utils';
Expand Down Expand Up @@ -99,6 +100,28 @@ type WhitelistApiResponse = {
additionalIncentiveInfo: Record<string, ReserveIncentiveAdditionalData>;
};

const hardcodedIncentives: Record<string, ExtendedReserveIncentiveResponse> = {
[AaveV3Ethereum.ASSETS.PYUSD.A_TOKEN]: {
incentiveAPR: '0.43',
rewardTokenAddress: AaveV3Ethereum.ASSETS.PYUSD.A_TOKEN,
rewardTokenSymbol: 'aEthPYUSD',
customMessage:
'You need to supply PYUSD without holding any PYUSD debt. This is a program initiated and implemented by ACI in collaboration with Merkl.',
breakdown: {
protocolAPY: 0,
protocolIncentivesAPR: 0,
merklIncentivesAPR: 0,
totalAPY: 0,
isBorrow: false,
breakdown: {
protocol: 0,
protocolIncentives: 0,
merklIncentives: 0,
},
},
Comment on lines +110 to +121
Copy link

Copilot AI Oct 8, 2025

Choose a reason for hiding this comment

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

The breakdown object in the hardcoded incentives appears to be duplicated and potentially inconsistent with the dynamically calculated breakdown returned later. Consider removing the hardcoded breakdown since it's recalculated anyway.

Suggested change
breakdown: {
protocolAPY: 0,
protocolIncentivesAPR: 0,
merklIncentivesAPR: 0,
totalAPY: 0,
isBorrow: false,
breakdown: {
protocol: 0,
protocolIncentives: 0,
merklIncentives: 0,
},
},

Copilot uses AI. Check for mistakes.
},
};

const MERKL_ENDPOINT = 'https://api.merkl.xyz/v4/opportunities?mainProtocolId=aave'; // Merkl API
const WHITELIST_ENDPOINT = 'https://apps.aavechan.com/api/aave/merkl/whitelist-token-list'; // Endpoint to fetch whitelisted tokens
const checkOpportunityAction = (
Expand Down Expand Up @@ -153,6 +176,23 @@ export const useMerklIncentives = ({
queryKey: ['merklIncentives', market],
staleTime: 1000 * 60 * 5,
select: (merklOpportunities) => {
const hardcodedIncentive = rewardedAsset ? hardcodedIncentives[rewardedAsset] : undefined;

if (hardcodedIncentive) {
const protocolIncentivesAPR = protocolIncentives.reduce((sum, inc) => {
return sum + (inc.incentiveAPR === 'Infinity' ? 0 : +inc.incentiveAPR);
}, 0);
const merklIncentivesAPY = convertAprToApy(0.1);
Copy link

Copilot AI Oct 8, 2025

Choose a reason for hiding this comment

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

The hardcoded value 0.1 (10%) should be extracted as a named constant to improve maintainability and make the source of this value clear.

Copilot uses AI. Check for mistakes.
return {
...hardcodedIncentive,
breakdown: {
protocolAPY,
protocolIncentivesAPR,
merklIncentivesAPR: merklIncentivesAPY,
totalAPY: protocolAPY + protocolIncentivesAPR + merklIncentivesAPY,
} as MerklIncentivesBreakdown,
} as ExtendedReserveIncentiveResponse;
Comment on lines +193 to +194
Copy link

Copilot AI Oct 8, 2025

Choose a reason for hiding this comment

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

Using type assertions with 'as' can bypass TypeScript's type checking. Consider ensuring the object structure matches the expected types or use proper type guards to validate the structure.

Copilot uses AI. Check for mistakes.
}
const opportunities = merklOpportunities.filter(
(opportunitiy) =>
rewardedAsset &&
Expand Down
Loading