@merkl/api 0.15.17 → 0.15.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/constants.d.ts +4 -1
 - package/dist/src/constants.js +9 -1
 - package/dist/src/entities/opportunity.js +58 -0
 - package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/tokenType.d.ts +3 -1
 - package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/tokenType.js +4 -0
 - package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/BeefyProcessor.js +0 -1
 - package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/SpectraProcessor.d.ts +31 -0
 - package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/SpectraProcessor.js +41 -0
 - package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/SpectraYTProcessor.d.ts +31 -0
 - package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/SpectraYTProcessor.js +39 -0
 - package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/processor/processorMapping.js +4 -0
 - package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/subtypesRound1.js +5 -1
 - package/dist/src/libs/campaigns/campaignTypes/UniswapV4DynamicData.d.ts +3 -0
 - package/dist/src/libs/campaigns/campaignTypes/UniswapV4DynamicData.js +228 -0
 - package/dist/src/libs/campaigns/campaignsDynamicData.js +4 -0
 - package/dist/src/modules/v4/campaign/campaign.model.d.ts +1 -0
 - package/dist/src/modules/v4/campaign/campaign.model.js +1 -0
 - package/dist/src/types/external/spectraAPI.d.ts +88 -0
 - package/dist/src/types/external/spectraAPI.js +1 -0
 - package/dist/src/utils/decodeCalls.js +9 -2
 - package/dist/src/utils/encodeCalls.js +17 -2
 - package/dist/src/utils/generateCardName.js +4 -0
 - package/dist/tsconfig.package.tsbuildinfo +1 -1
 - package/package.json +1 -1
 
    
        package/dist/src/constants.d.ts
    CHANGED
    
    | 
         @@ -1,3 +1,4 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            import { ChainId, type MerklChainId } from "@sdk";
         
     | 
| 
       1 
2 
     | 
    
         
             
            import Big from "big.js";
         
     | 
| 
       2 
3 
     | 
    
         
             
            export declare const zeroBN: Big.Big;
         
     | 
| 
       3 
4 
     | 
    
         
             
            export declare const baseTestAnalyticsGraphUrl = "https://api.thegraph.com/subgraphs/name/angleprotocol/test-analytics-";
         
     | 
| 
         @@ -29,7 +30,6 @@ export declare const RFX_DATASTORE = "0x895124783008C6c68eFcccac24c482Fdf30439B2 
     | 
|
| 
       29 
30 
     | 
    
         
             
            export declare const DOPEX_OPTION_MARKET: {
         
     | 
| 
       30 
31 
     | 
    
         
             
                [market: string]: string;
         
     | 
| 
       31 
32 
     | 
    
         
             
            };
         
     | 
| 
       32 
     | 
    
         
            -
            import { ChainId } from "@sdk";
         
     | 
| 
       33 
33 
     | 
    
         
             
            export declare const constantChain: {
         
     | 
| 
       34 
34 
     | 
    
         
             
                [x: number]: {
         
     | 
| 
       35 
35 
     | 
    
         
             
                    apw: string;
         
     | 
| 
         @@ -349,3 +349,6 @@ export declare const constantChain: { 
     | 
|
| 
       349 
349 
     | 
    
         
             
                };
         
     | 
| 
       350 
350 
     | 
    
         
             
            };
         
     | 
| 
       351 
351 
     | 
    
         
             
            export declare const MAVERICK_ZKSYNC_BP_LENS_ADDRESS = "0xd32CE31CaC98CAC0631764B8286358c0606D87F9";
         
     | 
| 
      
 352 
     | 
    
         
            +
            export declare const NETWORK_SLUGS: {
         
     | 
| 
      
 353 
     | 
    
         
            +
                [chainId in MerklChainId]?: string;
         
     | 
| 
      
 354 
     | 
    
         
            +
            };
         
     | 
    
        package/dist/src/constants.js
    CHANGED
    
    | 
         @@ -1,3 +1,4 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            import { ChainId } from "@sdk";
         
     | 
| 
       1 
2 
     | 
    
         
             
            import Big from "big.js";
         
     | 
| 
       2 
3 
     | 
    
         
             
            export const zeroBN = new Big(0);
         
     | 
| 
       3 
4 
     | 
    
         
             
            export const baseTestAnalyticsGraphUrl = "https://api.thegraph.com/subgraphs/name/angleprotocol/test-analytics-";
         
     | 
| 
         @@ -42,7 +43,6 @@ export const DOPEX_OPTION_MARKET = { 
     | 
|
| 
       42 
43 
     | 
    
         
             
                ["0xd9e2a1a61b6e61b275cec326465d417e52c1b95c".toLowerCase()]: "0x501B03BdB431154b8Df17BF1c00756E3a8F21744", // wETH / USDC
         
     | 
| 
       43 
44 
     | 
    
         
             
                ["0x9fFCA51D23Ac7F7df82da414865Ef1055E5aFCc3".toLowerCase()]: "0x4eed3A2b797Bf5630517EcCe2e31C1438A76bb92", // ARB / USDC
         
     | 
| 
       44 
45 
     | 
    
         
             
            };
         
     | 
| 
       45 
     | 
    
         
            -
            import { ChainId } from "@sdk";
         
     | 
| 
       46 
46 
     | 
    
         
             
            const COMMON_PREFIX_STAKE = "https://lockers.stakedao.org/api/strategies/cache/curve";
         
     | 
| 
       47 
47 
     | 
    
         
             
            const COMMON_PREFIX_CONVEX = "https://www.convexfinance.com/api/curve-apys";
         
     | 
| 
       48 
48 
     | 
    
         
             
            export const constantChain = {
         
     | 
| 
         @@ -118,3 +118,11 @@ export const constantChain = { 
     | 
|
| 
       118 
118 
     | 
    
         
             
                },
         
     | 
| 
       119 
119 
     | 
    
         
             
            };
         
     | 
| 
       120 
120 
     | 
    
         
             
            export const MAVERICK_ZKSYNC_BP_LENS_ADDRESS = "0xd32CE31CaC98CAC0631764B8286358c0606D87F9";
         
     | 
| 
      
 121 
     | 
    
         
            +
            export const NETWORK_SLUGS = {
         
     | 
| 
      
 122 
     | 
    
         
            +
                [ChainId.MAINNET]: "mainnet",
         
     | 
| 
      
 123 
     | 
    
         
            +
                [ChainId.ARBITRUM]: "arbitrum",
         
     | 
| 
      
 124 
     | 
    
         
            +
                [ChainId.OPTIMISM]: "optimism",
         
     | 
| 
      
 125 
     | 
    
         
            +
                [ChainId.BASE]: "base",
         
     | 
| 
      
 126 
     | 
    
         
            +
                [ChainId.POLYGON]: "polygon",
         
     | 
| 
      
 127 
     | 
    
         
            +
                [ChainId.SONIC]: "sonic",
         
     | 
| 
      
 128 
     | 
    
         
            +
            };
         
     | 
| 
         @@ -1122,6 +1122,64 @@ export const extractOpportunities = { 
     | 
|
| 
       1122 
1122 
     | 
    
         
             
                    };
         
     | 
| 
       1123 
1123 
     | 
    
         
             
                    return opportunity;
         
     | 
| 
       1124 
1124 
     | 
    
         
             
                },
         
     | 
| 
      
 1125 
     | 
    
         
            +
                [Campaign.UNISWAP_V4]: ({ chainId, mainParameter, tvl, campaignParameters: params, poolBalanceToken0, poolBalanceToken1, computeChainId }, campaigns, prices) => {
         
     | 
| 
      
 1126 
     | 
    
         
            +
                    const { active, all } = campaigns;
         
     | 
| 
      
 1127 
     | 
    
         
            +
                    const pair = `${params.symbolCurrency0}-${params.symbolCurrency1}`;
         
     | 
| 
      
 1128 
     | 
    
         
            +
                    // const tvlDetails = active.reduce(
         
     | 
| 
      
 1129 
     | 
    
         
            +
                    //   (res, campaign) => {
         
     | 
| 
      
 1130 
     | 
    
         
            +
                    //     for (const forwarder of campaign?.forwarders ?? []) {
         
     | 
| 
      
 1131 
     | 
    
         
            +
                    //       const key = `${almName(forwarder.type)} ${forwarder.almAddress}`;
         
     | 
| 
      
 1132 
     | 
    
         
            +
                    //       if (!res[key])
         
     | 
| 
      
 1133 
     | 
    
         
            +
                    //         res[key] = {
         
     | 
| 
      
 1134 
     | 
    
         
            +
                    //           value: forwarder.almTVL,
         
     | 
| 
      
 1135 
     | 
    
         
            +
                    //           address: forwarder.almAddress,
         
     | 
| 
      
 1136 
     | 
    
         
            +
                    //           type: EAprBreakdownType.FORWARDER,
         
     | 
| 
      
 1137 
     | 
    
         
            +
                    //           label: forwarder.label.split(" ")[0],
         
     | 
| 
      
 1138 
     | 
    
         
            +
                    //         };
         
     | 
| 
      
 1139 
     | 
    
         
            +
                    //     }
         
     | 
| 
      
 1140 
     | 
    
         
            +
                    //     return res;
         
     | 
| 
      
 1141 
     | 
    
         
            +
                    //   },
         
     | 
| 
      
 1142 
     | 
    
         
            +
                    //   {} as { [key: string]: tvlBreakdown }
         
     | 
| 
      
 1143 
     | 
    
         
            +
                    // );
         
     | 
| 
      
 1144 
     | 
    
         
            +
                    // // @Hugo wip: new way to structure aprBreakdowns
         
     | 
| 
      
 1145 
     | 
    
         
            +
                    // const aprBreakdownByType = sumAprBreakdownsByType(campaigns.active);
         
     | 
| 
      
 1146 
     | 
    
         
            +
                    // const campaignApr = getCampaignsApr<Campaign.CLAMM>(active);
         
     | 
| 
      
 1147 
     | 
    
         
            +
                    // const aprBreakdown2 = [...aprBreakdownByType, ...campaignApr];
         
     | 
| 
      
 1148 
     | 
    
         
            +
                    const aprBreakdown = active.reduce((res, campaign) => {
         
     | 
| 
      
 1149 
     | 
    
         
            +
                        if (!campaign.aprs)
         
     | 
| 
      
 1150 
     | 
    
         
            +
                            return res;
         
     | 
| 
      
 1151 
     | 
    
         
            +
                        return res;
         
     | 
| 
      
 1152 
     | 
    
         
            +
                    }, {});
         
     | 
| 
      
 1153 
     | 
    
         
            +
                    const holdings = [
         
     | 
| 
      
 1154 
     | 
    
         
            +
                        { symbol: params.symbolCurrency0, amount: poolBalanceToken0 ?? 0 },
         
     | 
| 
      
 1155 
     | 
    
         
            +
                        { symbol: params.symbolCurrency1, amount: poolBalanceToken1 ?? 0 },
         
     | 
| 
      
 1156 
     | 
    
         
            +
                    ];
         
     | 
| 
      
 1157 
     | 
    
         
            +
                    const platform = "UniswapV4";
         
     | 
| 
      
 1158 
     | 
    
         
            +
                    const opportunity = {
         
     | 
| 
      
 1159 
     | 
    
         
            +
                        id: `${Campaign.UNISWAP_V4}_${mainParameter}`,
         
     | 
| 
      
 1160 
     | 
    
         
            +
                        platform,
         
     | 
| 
      
 1161 
     | 
    
         
            +
                        name: [platform, pair, params.lpFee && `${params.lpFee} %`].join(" "),
         
     | 
| 
      
 1162 
     | 
    
         
            +
                        chainId: computeChainId ?? chainId,
         
     | 
| 
      
 1163 
     | 
    
         
            +
                        distributionChainId: chainId,
         
     | 
| 
      
 1164 
     | 
    
         
            +
                        action: "pool",
         
     | 
| 
      
 1165 
     | 
    
         
            +
                        status: getStatus(all),
         
     | 
| 
      
 1166 
     | 
    
         
            +
                        tvlBreakdown: {
         
     | 
| 
      
 1167 
     | 
    
         
            +
                            tokens: holdings,
         
     | 
| 
      
 1168 
     | 
    
         
            +
                            details: {},
         
     | 
| 
      
 1169 
     | 
    
         
            +
                        },
         
     | 
| 
      
 1170 
     | 
    
         
            +
                        aprBreakdown,
         
     | 
| 
      
 1171 
     | 
    
         
            +
                        aprBreakdown2: {},
         
     | 
| 
      
 1172 
     | 
    
         
            +
                        tvl: !!tvl ? tvl : holdings.reduce((prev, curr) => (prices[curr?.symbol] ?? 0) * curr?.amount + prev, 0),
         
     | 
| 
      
 1173 
     | 
    
         
            +
                        apr: getApr(active),
         
     | 
| 
      
 1174 
     | 
    
         
            +
                        tags: getTags(campaigns.all),
         
     | 
| 
      
 1175 
     | 
    
         
            +
                        dailyrewards: getDailyRewards(active, prices),
         
     | 
| 
      
 1176 
     | 
    
         
            +
                        tokenIcons: [params.symbolCurrency0, params.symbolCurrency1],
         
     | 
| 
      
 1177 
     | 
    
         
            +
                        rewardTokenIcons: getRewardTokenIcons(campaigns.active),
         
     | 
| 
      
 1178 
     | 
    
         
            +
                        dailyRewardTokens: getRewardTokens(campaigns.active),
         
     | 
| 
      
 1179 
     | 
    
         
            +
                        campaigns: { ...campaigns, type: Campaign.UNISWAP_V4, ids: campaigns.all.map(c => c.campaignId) },
         
     | 
| 
      
 1180 
     | 
    
         
            +
                    };
         
     | 
| 
      
 1181 
     | 
    
         
            +
                    return opportunity;
         
     | 
| 
      
 1182 
     | 
    
         
            +
                },
         
     | 
| 
       1125 
1183 
     | 
    
         
             
            };
         
     | 
| 
       1126 
1184 
     | 
    
         
             
            /**
         
     | 
| 
       1127 
1185 
     | 
    
         
             
             * @returns the opportunities map with their corresponding campaign's data added
         
     | 
| 
         @@ -83,7 +83,9 @@ export declare enum tokenType { 
     | 
|
| 
       83 
83 
     | 
    
         
             
                takotako_lending = "takotako_lending",
         
     | 
| 
       84 
84 
     | 
    
         
             
                equalizer_gauge = "equalizer_gauge",
         
     | 
| 
       85 
85 
     | 
    
         
             
                vicuna_lending = "vicuna_lending",
         
     | 
| 
       86 
     | 
    
         
            -
                vicuna_borrowing = "vicuna_borrowing"
         
     | 
| 
      
 86 
     | 
    
         
            +
                vicuna_borrowing = "vicuna_borrowing",
         
     | 
| 
      
 87 
     | 
    
         
            +
                spectra_lpt = "spectra_lpt",
         
     | 
| 
      
 88 
     | 
    
         
            +
                spectra_yt = "spectra_yt"
         
     | 
| 
       87 
89 
     | 
    
         
             
            }
         
     | 
| 
       88 
90 
     | 
    
         
             
            export declare const tokenTypeToProtocol: {
         
     | 
| 
       89 
91 
     | 
    
         
             
                [key in tokenType]: {
         
     | 
| 
         @@ -85,6 +85,8 @@ export var tokenType; 
     | 
|
| 
       85 
85 
     | 
    
         
             
                tokenType["equalizer_gauge"] = "equalizer_gauge";
         
     | 
| 
       86 
86 
     | 
    
         
             
                tokenType["vicuna_lending"] = "vicuna_lending";
         
     | 
| 
       87 
87 
     | 
    
         
             
                tokenType["vicuna_borrowing"] = "vicuna_borrowing";
         
     | 
| 
      
 88 
     | 
    
         
            +
                tokenType["spectra_lpt"] = "spectra_lpt";
         
     | 
| 
      
 89 
     | 
    
         
            +
                tokenType["spectra_yt"] = "spectra_yt";
         
     | 
| 
       88 
90 
     | 
    
         
             
            })(tokenType || (tokenType = {}));
         
     | 
| 
       89 
91 
     | 
    
         
             
            export const tokenTypeToProtocol = {
         
     | 
| 
       90 
92 
     | 
    
         
             
                [tokenType.aave_borrowing]: { protocol: "Aave", action: OpportunityAction.BORROW },
         
     | 
| 
         @@ -170,4 +172,6 @@ export const tokenTypeToProtocol = { 
     | 
|
| 
       170 
172 
     | 
    
         
             
                [tokenType.equalizer_gauge]: { protocol: "Equalizer", action: OpportunityAction.HOLD },
         
     | 
| 
       171 
173 
     | 
    
         
             
                [tokenType.vicuna_lending]: { protocol: "Vicuna", action: OpportunityAction.LEND },
         
     | 
| 
       172 
174 
     | 
    
         
             
                [tokenType.vicuna_borrowing]: { protocol: "Vicuna", action: OpportunityAction.BORROW },
         
     | 
| 
      
 175 
     | 
    
         
            +
                [tokenType.spectra_lpt]: { protocol: "Spectra", action: OpportunityAction.POOL },
         
     | 
| 
      
 176 
     | 
    
         
            +
                [tokenType.spectra_yt]: { protocol: "Spectra", action: OpportunityAction.POOL },
         
     | 
| 
       173 
177 
     | 
    
         
             
            };
         
     | 
| 
         @@ -24,7 +24,6 @@ export class BeefyProcessor extends GenericProcessor { 
     | 
|
| 
       24 
24 
     | 
    
         
             
                        { key: "totalSupplyUnderlying", call: "totalSupply", target: "underlying" },
         
     | 
| 
       25 
25 
     | 
    
         
             
                    ],
         
     | 
| 
       26 
26 
     | 
    
         
             
                };
         
     | 
| 
       27 
     | 
    
         
            -
                // override computeRound1(): void {}
         
     | 
| 
       28 
27 
     | 
    
         
             
                async processingRound5(_index, type, typeInfo, _calls, campaign, pricer) {
         
     | 
| 
       29 
28 
     | 
    
         
             
                    const { whitelistedSupplyTargetToken, totalSupply, blacklistedSupply } = this.handleWhiteListBlacklistRound5(typeInfo, campaign);
         
     | 
| 
       30 
29 
     | 
    
         
             
                    const priceToken0 = (await pricer.get({ symbol: typeInfo.symbolToken0 })) ?? 0;
         
     | 
| 
         @@ -0,0 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            import type { Pricer } from "../../../../../utils/pricer";
         
     | 
| 
      
 2 
     | 
    
         
            +
            import type { Campaign, CampaignParameters } from "@sdk";
         
     | 
| 
      
 3 
     | 
    
         
            +
            import type { tokenType } from "../helpers/tokenType";
         
     | 
| 
      
 4 
     | 
    
         
            +
            import { GenericProcessor, type dataType, type mandatoryCallKeys } from "./GenericProcessor";
         
     | 
| 
      
 5 
     | 
    
         
            +
            type callType = {
         
     | 
| 
      
 6 
     | 
    
         
            +
                key: keyof dataRawSpectra;
         
     | 
| 
      
 7 
     | 
    
         
            +
                call: string;
         
     | 
| 
      
 8 
     | 
    
         
            +
                target: keyof callKeysSpectra;
         
     | 
| 
      
 9 
     | 
    
         
            +
                metaData?: any;
         
     | 
| 
      
 10 
     | 
    
         
            +
            };
         
     | 
| 
      
 11 
     | 
    
         
            +
            type callKeysSpectra = mandatoryCallKeys & {
         
     | 
| 
      
 12 
     | 
    
         
            +
                tokenPrice: string;
         
     | 
| 
      
 13 
     | 
    
         
            +
                name: string;
         
     | 
| 
      
 14 
     | 
    
         
            +
                minter: string;
         
     | 
| 
      
 15 
     | 
    
         
            +
            };
         
     | 
| 
      
 16 
     | 
    
         
            +
            type dataRawSpectra = callKeysSpectra & {
         
     | 
| 
      
 17 
     | 
    
         
            +
                curvePool: string;
         
     | 
| 
      
 18 
     | 
    
         
            +
            };
         
     | 
| 
      
 19 
     | 
    
         
            +
            type dataTypeSpectra = dataType & {
         
     | 
| 
      
 20 
     | 
    
         
            +
                tokenPrice: string;
         
     | 
| 
      
 21 
     | 
    
         
            +
            };
         
     | 
| 
      
 22 
     | 
    
         
            +
            export declare class SpectraProcessor extends GenericProcessor<callKeysSpectra, dataRawSpectra, dataTypeSpectra> {
         
     | 
| 
      
 23 
     | 
    
         
            +
                rounds: {
         
     | 
| 
      
 24 
     | 
    
         
            +
                    round1: callType[];
         
     | 
| 
      
 25 
     | 
    
         
            +
                    round2: callType[];
         
     | 
| 
      
 26 
     | 
    
         
            +
                    round3: callType[];
         
     | 
| 
      
 27 
     | 
    
         
            +
                    round4: callType[];
         
     | 
| 
      
 28 
     | 
    
         
            +
                };
         
     | 
| 
      
 29 
     | 
    
         
            +
                processingRound5(_index: number, type: tokenType, typeInfo: dataRawSpectra, _calls: string[], campaign: CampaignParameters<Campaign.ERC20> | CampaignParameters<Campaign.EULER>, _pricer: Pricer): Promise<dataTypeSpectra>;
         
     | 
| 
      
 30 
     | 
    
         
            +
            }
         
     | 
| 
      
 31 
     | 
    
         
            +
            export {};
         
     | 
| 
         @@ -0,0 +1,41 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            import { NETWORK_SLUGS } from "../../../../../constants";
         
     | 
| 
      
 2 
     | 
    
         
            +
            import { generateCardName } from "../../../../../utils/generateCardName";
         
     | 
| 
      
 3 
     | 
    
         
            +
            import { GenericProcessor } from "./GenericProcessor";
         
     | 
| 
      
 4 
     | 
    
         
            +
            export class SpectraProcessor extends GenericProcessor {
         
     | 
| 
      
 5 
     | 
    
         
            +
                rounds = {
         
     | 
| 
      
 6 
     | 
    
         
            +
                    round1: [{ key: "curvePool", call: "minter", target: "tokenAddress" }],
         
     | 
| 
      
 7 
     | 
    
         
            +
                    round2: [],
         
     | 
| 
      
 8 
     | 
    
         
            +
                    round3: [],
         
     | 
| 
      
 9 
     | 
    
         
            +
                    round4: [{ key: "totalSupply", call: "totalSupply", target: "tokenAddress" }],
         
     | 
| 
      
 10 
     | 
    
         
            +
                };
         
     | 
| 
      
 11 
     | 
    
         
            +
                async processingRound5(_index, type, typeInfo, _calls, campaign, _pricer) {
         
     | 
| 
      
 12 
     | 
    
         
            +
                    const { whitelistedSupplyTargetToken, totalSupply, blacklistedSupply } = this.handleWhiteListBlacklistRound5(typeInfo, campaign);
         
     | 
| 
      
 13 
     | 
    
         
            +
                    if (!NETWORK_SLUGS[campaign.computeChainId]) {
         
     | 
| 
      
 14 
     | 
    
         
            +
                        throw new Error("Network slug not found");
         
     | 
| 
      
 15 
     | 
    
         
            +
                    }
         
     | 
| 
      
 16 
     | 
    
         
            +
                    const curvePool = typeInfo.curvePool.toLowerCase();
         
     | 
| 
      
 17 
     | 
    
         
            +
                    const spectraData = (await (await fetch(`https://app.spectra.finance/api/v1/${NETWORK_SLUGS[campaign.computeChainId]}/pools`, {
         
     | 
| 
      
 18 
     | 
    
         
            +
                        headers: {
         
     | 
| 
      
 19 
     | 
    
         
            +
                            "x-client-id": "Merkl Studio",
         
     | 
| 
      
 20 
     | 
    
         
            +
                            source: "Merkl Studio",
         
     | 
| 
      
 21 
     | 
    
         
            +
                        },
         
     | 
| 
      
 22 
     | 
    
         
            +
                    })).json());
         
     | 
| 
      
 23 
     | 
    
         
            +
                    const poolData = spectraData
         
     | 
| 
      
 24 
     | 
    
         
            +
                        .find(d => d.pools.map(pool => pool.address.toLowerCase()).includes(curvePool))
         
     | 
| 
      
 25 
     | 
    
         
            +
                        ?.pools.find(pool => pool.address.toLowerCase() === curvePool);
         
     | 
| 
      
 26 
     | 
    
         
            +
                    if (!poolData) {
         
     | 
| 
      
 27 
     | 
    
         
            +
                        throw new Error("Pool not found in Spectra API");
         
     | 
| 
      
 28 
     | 
    
         
            +
                    }
         
     | 
| 
      
 29 
     | 
    
         
            +
                    const tvl = poolData.liquidity.usd; // in USD
         
     | 
| 
      
 30 
     | 
    
         
            +
                    const priceTargetToken = tvl / totalSupply;
         
     | 
| 
      
 31 
     | 
    
         
            +
                    return {
         
     | 
| 
      
 32 
     | 
    
         
            +
                        ...typeInfo,
         
     | 
| 
      
 33 
     | 
    
         
            +
                        totalSupply,
         
     | 
| 
      
 34 
     | 
    
         
            +
                        tvl,
         
     | 
| 
      
 35 
     | 
    
         
            +
                        whitelistedSupplyTargetToken,
         
     | 
| 
      
 36 
     | 
    
         
            +
                        blacklistedSupply,
         
     | 
| 
      
 37 
     | 
    
         
            +
                        priceTargetToken,
         
     | 
| 
      
 38 
     | 
    
         
            +
                        cardName: generateCardName(type, typeInfo, campaign),
         
     | 
| 
      
 39 
     | 
    
         
            +
                    };
         
     | 
| 
      
 40 
     | 
    
         
            +
                }
         
     | 
| 
      
 41 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -0,0 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            import type { Pricer } from "../../../../../utils/pricer";
         
     | 
| 
      
 2 
     | 
    
         
            +
            import type { Campaign, CampaignParameters } from "@sdk";
         
     | 
| 
      
 3 
     | 
    
         
            +
            import type { tokenType } from "../helpers/tokenType";
         
     | 
| 
      
 4 
     | 
    
         
            +
            import { GenericProcessor, type dataType, type mandatoryCallKeys } from "./GenericProcessor";
         
     | 
| 
      
 5 
     | 
    
         
            +
            type callType = {
         
     | 
| 
      
 6 
     | 
    
         
            +
                key: keyof dataRawSpectra;
         
     | 
| 
      
 7 
     | 
    
         
            +
                call: string;
         
     | 
| 
      
 8 
     | 
    
         
            +
                target: keyof callKeysSpectra;
         
     | 
| 
      
 9 
     | 
    
         
            +
                metaData?: any;
         
     | 
| 
      
 10 
     | 
    
         
            +
            };
         
     | 
| 
      
 11 
     | 
    
         
            +
            type callKeysSpectra = mandatoryCallKeys & {
         
     | 
| 
      
 12 
     | 
    
         
            +
                tokenPrice: string;
         
     | 
| 
      
 13 
     | 
    
         
            +
                name: string;
         
     | 
| 
      
 14 
     | 
    
         
            +
                principalToken: string;
         
     | 
| 
      
 15 
     | 
    
         
            +
            };
         
     | 
| 
      
 16 
     | 
    
         
            +
            type dataRawSpectra = callKeysSpectra & {
         
     | 
| 
      
 17 
     | 
    
         
            +
                principalToken: string;
         
     | 
| 
      
 18 
     | 
    
         
            +
            };
         
     | 
| 
      
 19 
     | 
    
         
            +
            type dataTypeSpectra = dataType & {
         
     | 
| 
      
 20 
     | 
    
         
            +
                tokenPrice: string;
         
     | 
| 
      
 21 
     | 
    
         
            +
            };
         
     | 
| 
      
 22 
     | 
    
         
            +
            export declare class SpectraYTProcessor extends GenericProcessor<callKeysSpectra, dataRawSpectra, dataTypeSpectra> {
         
     | 
| 
      
 23 
     | 
    
         
            +
                rounds: {
         
     | 
| 
      
 24 
     | 
    
         
            +
                    round1: callType[];
         
     | 
| 
      
 25 
     | 
    
         
            +
                    round2: callType[];
         
     | 
| 
      
 26 
     | 
    
         
            +
                    round3: callType[];
         
     | 
| 
      
 27 
     | 
    
         
            +
                    round4: callType[];
         
     | 
| 
      
 28 
     | 
    
         
            +
                };
         
     | 
| 
      
 29 
     | 
    
         
            +
                processingRound5(_index: number, type: tokenType, typeInfo: dataRawSpectra, _calls: string[], campaign: CampaignParameters<Campaign.ERC20> | CampaignParameters<Campaign.EULER>, _pricer: Pricer): Promise<dataTypeSpectra>;
         
     | 
| 
      
 30 
     | 
    
         
            +
            }
         
     | 
| 
      
 31 
     | 
    
         
            +
            export {};
         
     | 
| 
         @@ -0,0 +1,39 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            import { NETWORK_SLUGS } from "../../../../../constants";
         
     | 
| 
      
 2 
     | 
    
         
            +
            import { generateCardName } from "../../../../../utils/generateCardName";
         
     | 
| 
      
 3 
     | 
    
         
            +
            import { GenericProcessor } from "./GenericProcessor";
         
     | 
| 
      
 4 
     | 
    
         
            +
            export class SpectraYTProcessor extends GenericProcessor {
         
     | 
| 
      
 5 
     | 
    
         
            +
                rounds = {
         
     | 
| 
      
 6 
     | 
    
         
            +
                    round1: [{ key: "principalToken", call: "principalToken", target: "tokenAddress" }],
         
     | 
| 
      
 7 
     | 
    
         
            +
                    round2: [],
         
     | 
| 
      
 8 
     | 
    
         
            +
                    round3: [],
         
     | 
| 
      
 9 
     | 
    
         
            +
                    round4: [{ key: "totalSupply", call: "totalSupply", target: "tokenAddress" }],
         
     | 
| 
      
 10 
     | 
    
         
            +
                };
         
     | 
| 
      
 11 
     | 
    
         
            +
                async processingRound5(_index, type, typeInfo, _calls, campaign, _pricer) {
         
     | 
| 
      
 12 
     | 
    
         
            +
                    const { whitelistedSupplyTargetToken, totalSupply, blacklistedSupply } = this.handleWhiteListBlacklistRound5(typeInfo, campaign);
         
     | 
| 
      
 13 
     | 
    
         
            +
                    if (!NETWORK_SLUGS[campaign.computeChainId]) {
         
     | 
| 
      
 14 
     | 
    
         
            +
                        throw new Error("Network slug not found");
         
     | 
| 
      
 15 
     | 
    
         
            +
                    }
         
     | 
| 
      
 16 
     | 
    
         
            +
                    const principalToken = typeInfo.principalToken.toLowerCase();
         
     | 
| 
      
 17 
     | 
    
         
            +
                    const spectraData = (await (await fetch(`https://app.spectra.finance/api/v1/${NETWORK_SLUGS[campaign.computeChainId]}/pools`, {
         
     | 
| 
      
 18 
     | 
    
         
            +
                        headers: {
         
     | 
| 
      
 19 
     | 
    
         
            +
                            "x-client-id": "Merkl Studio",
         
     | 
| 
      
 20 
     | 
    
         
            +
                            source: "Merkl Studio",
         
     | 
| 
      
 21 
     | 
    
         
            +
                        },
         
     | 
| 
      
 22 
     | 
    
         
            +
                    })).json());
         
     | 
| 
      
 23 
     | 
    
         
            +
                    const poolData = spectraData.find(d => d.address.toLowerCase() === principalToken);
         
     | 
| 
      
 24 
     | 
    
         
            +
                    if (!poolData) {
         
     | 
| 
      
 25 
     | 
    
         
            +
                        throw new Error("Pool not found in Spectra API");
         
     | 
| 
      
 26 
     | 
    
         
            +
                    }
         
     | 
| 
      
 27 
     | 
    
         
            +
                    const tvl = poolData.pools[0].ytPrice.usd * totalSupply; // in USD
         
     | 
| 
      
 28 
     | 
    
         
            +
                    const priceTargetToken = tvl / totalSupply;
         
     | 
| 
      
 29 
     | 
    
         
            +
                    return {
         
     | 
| 
      
 30 
     | 
    
         
            +
                        ...typeInfo,
         
     | 
| 
      
 31 
     | 
    
         
            +
                        totalSupply,
         
     | 
| 
      
 32 
     | 
    
         
            +
                        tvl,
         
     | 
| 
      
 33 
     | 
    
         
            +
                        whitelistedSupplyTargetToken,
         
     | 
| 
      
 34 
     | 
    
         
            +
                        blacklistedSupply,
         
     | 
| 
      
 35 
     | 
    
         
            +
                        priceTargetToken,
         
     | 
| 
      
 36 
     | 
    
         
            +
                        cardName: generateCardName(type, typeInfo, campaign),
         
     | 
| 
      
 37 
     | 
    
         
            +
                    };
         
     | 
| 
      
 38 
     | 
    
         
            +
                }
         
     | 
| 
      
 39 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -26,6 +26,8 @@ import { PendleYTProcessor } from "./PendleYTProcessor"; 
     | 
|
| 
       26 
26 
     | 
    
         
             
            import { RadiantProcessor } from "./RadiantProcessor";
         
     | 
| 
       27 
27 
     | 
    
         
             
            import { RfxProcessor } from "./RfxProcessor";
         
     | 
| 
       28 
28 
     | 
    
         
             
            import { SatlayerProcessor } from "./Satlayer";
         
     | 
| 
      
 29 
     | 
    
         
            +
            import { SpectraProcessor } from "./SpectraProcessor";
         
     | 
| 
      
 30 
     | 
    
         
            +
            import { SpectraYTProcessor } from "./SpectraYTProcessor";
         
     | 
| 
       29 
31 
     | 
    
         
             
            import { SpliceProcessor } from "./SpliceProcessor";
         
     | 
| 
       30 
32 
     | 
    
         
             
            import { StakingProcessor } from "./StakingProcessor";
         
     | 
| 
       31 
33 
     | 
    
         
             
            import { SturdySiloProcessor } from "./SturdySiloProcessor";
         
     | 
| 
         @@ -122,4 +124,6 @@ export const processorMapping = { 
     | 
|
| 
       122 
124 
     | 
    
         
             
                [tokenType.vicuna_borrowing]: AaveProcessor,
         
     | 
| 
       123 
125 
     | 
    
         
             
                [tokenType.vicuna_lending]: AaveProcessor,
         
     | 
| 
       124 
126 
     | 
    
         
             
                [tokenType.anglesLiquid]: AnglesLiquidProcessor,
         
     | 
| 
      
 127 
     | 
    
         
            +
                [tokenType.spectra_lpt]: SpectraProcessor,
         
     | 
| 
      
 128 
     | 
    
         
            +
                [tokenType.spectra_yt]: SpectraYTProcessor,
         
     | 
| 
       125 
129 
     | 
    
         
             
            };
         
     | 
| 
         @@ -142,6 +142,10 @@ function satisfiesNameConditions(name, type) { 
     | 
|
| 
       142 
142 
     | 
    
         
             
                        return lowerCaseName.includes("concrete");
         
     | 
| 
       143 
143 
     | 
    
         
             
                    case tokenType.equalizer_gauge:
         
     | 
| 
       144 
144 
     | 
    
         
             
                        return lowerCaseName.includes("equalizer");
         
     | 
| 
      
 145 
     | 
    
         
            +
                    case tokenType.spectra_lpt:
         
     | 
| 
      
 146 
     | 
    
         
            +
                        return lowerCaseName.includes("spectra") && lowerCaseName.includes("curve");
         
     | 
| 
      
 147 
     | 
    
         
            +
                    case tokenType.spectra_yt:
         
     | 
| 
      
 148 
     | 
    
         
            +
                        return lowerCaseName.includes("yield") && lowerCaseName.includes("token");
         
     | 
| 
       145 
149 
     | 
    
         
             
                    default:
         
     | 
| 
       146 
150 
     | 
    
         
             
                        return false;
         
     | 
| 
       147 
151 
     | 
    
         
             
                }
         
     | 
| 
         @@ -301,7 +305,7 @@ export function getTokenTypeRound1(calls, targetToken, index, campaign) { 
     | 
|
| 
       301 
305 
     | 
    
         
             
                try {
         
     | 
| 
       302 
306 
     | 
    
         
             
                    name = decodeCall(returnValueOfCalls, index + 2, "name");
         
     | 
| 
       303 
307 
     | 
    
         
             
                }
         
     | 
| 
       304 
     | 
    
         
            -
                catch  
     | 
| 
      
 308 
     | 
    
         
            +
                catch {
         
     | 
| 
       305 
309 
     | 
    
         
             
                    return generateResult(tokenType.unknown, "Unknown", targetToken, {});
         
     | 
| 
       306 
310 
     | 
    
         
             
                }
         
     | 
| 
       307 
311 
     | 
    
         
             
                result = parseForBalancer(returnValue, targetToken, name);
         
     | 
| 
         @@ -0,0 +1,3 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            import { type Campaign, type CampaignDynamicData, type CampaignParameters, type MerklChainId } from "@sdk";
         
     | 
| 
      
 2 
     | 
    
         
            +
            import type { UncachedResult } from "../../../utils/execute";
         
     | 
| 
      
 3 
     | 
    
         
            +
            export declare function UniswapV4DynamicData(chainId: MerklChainId, campaigns: CampaignParameters<Campaign.UNISWAP_V4>[]): Promise<UncachedResult<Partial<CampaignDynamicData<Campaign.UNISWAP_V4>[]>>>;
         
     | 
| 
         @@ -0,0 +1,228 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            import { BN2Number, EAprBreakdownType, NETWORK_LABELS, UniswapV4Addresses, UniswapV4StateViewInterface, getSqrtRatioAtTick, shortenAddress, } from "@sdk";
         
     | 
| 
      
 2 
     | 
    
         
            +
            import moment from "moment";
         
     | 
| 
      
 3 
     | 
    
         
            +
            import { log } from "../../../utils/logger";
         
     | 
| 
      
 4 
     | 
    
         
            +
            import { Pricer } from "../../../utils/pricer";
         
     | 
| 
      
 5 
     | 
    
         
            +
            const CALLS_LENGTH = 2;
         
     | 
| 
      
 6 
     | 
    
         
            +
            export async function UniswapV4DynamicData(chainId, campaigns) {
         
     | 
| 
      
 7 
     | 
    
         
            +
                const dynamicData = [];
         
     | 
| 
      
 8 
     | 
    
         
            +
                const pricer = await Pricer.load();
         
     | 
| 
      
 9 
     | 
    
         
            +
                const calls = [];
         
     | 
| 
      
 10 
     | 
    
         
            +
                /** Dedupe pools from campaigns to build pool list */
         
     | 
| 
      
 11 
     | 
    
         
            +
                const poolList = [];
         
     | 
| 
      
 12 
     | 
    
         
            +
                for (const campaign of campaigns ?? []) {
         
     | 
| 
      
 13 
     | 
    
         
            +
                    /** Loop through all campaigns to add pools */
         
     | 
| 
      
 14 
     | 
    
         
            +
                    if (!poolList?.map(p => p.mainParameter.toLowerCase()).includes(campaign.mainParameter.toLowerCase())) {
         
     | 
| 
      
 15 
     | 
    
         
            +
                        poolList.push({
         
     | 
| 
      
 16 
     | 
    
         
            +
                            poolId: campaign.campaignParameters.poolId,
         
     | 
| 
      
 17 
     | 
    
         
            +
                            mainParameter: campaign.mainParameter, // FIXME
         
     | 
| 
      
 18 
     | 
    
         
            +
                        });
         
     | 
| 
      
 19 
     | 
    
         
            +
                    }
         
     | 
| 
      
 20 
     | 
    
         
            +
                }
         
     | 
| 
      
 21 
     | 
    
         
            +
                if (!!poolList) {
         
     | 
| 
      
 22 
     | 
    
         
            +
                    for (const pool of poolList) {
         
     | 
| 
      
 23 
     | 
    
         
            +
                        calls.push({
         
     | 
| 
      
 24 
     | 
    
         
            +
                            allowFailure: true,
         
     | 
| 
      
 25 
     | 
    
         
            +
                            callData: UniswapV4StateViewInterface.encodeFunctionData("getLiquidity", [pool.poolId]),
         
     | 
| 
      
 26 
     | 
    
         
            +
                            target: UniswapV4Addresses[chainId].StateView,
         
     | 
| 
      
 27 
     | 
    
         
            +
                        }, {
         
     | 
| 
      
 28 
     | 
    
         
            +
                            allowFailure: true,
         
     | 
| 
      
 29 
     | 
    
         
            +
                            callData: UniswapV4StateViewInterface.encodeFunctionData("getSlot0", [pool.poolId]),
         
     | 
| 
      
 30 
     | 
    
         
            +
                            target: UniswapV4Addresses[chainId].StateView,
         
     | 
| 
      
 31 
     | 
    
         
            +
                        }
         
     | 
| 
      
 32 
     | 
    
         
            +
                        // {
         
     | 
| 
      
 33 
     | 
    
         
            +
                        //   allowFailure: true,
         
     | 
| 
      
 34 
     | 
    
         
            +
                        //   callData: ERC20Interface.encodeFunctionData("balanceOf", [pool.address]),
         
     | 
| 
      
 35 
     | 
    
         
            +
                        //   target: d.campaignParameters.token0,
         
     | 
| 
      
 36 
     | 
    
         
            +
                        // },
         
     | 
| 
      
 37 
     | 
    
         
            +
                        // {
         
     | 
| 
      
 38 
     | 
    
         
            +
                        //   allowFailure: true,
         
     | 
| 
      
 39 
     | 
    
         
            +
                        //   callData: ERC20Interface.encodeFunctionData("balanceOf", [pool.address]),
         
     | 
| 
      
 40 
     | 
    
         
            +
                        //   target: d.campaignParameters.token1,
         
     | 
| 
      
 41 
     | 
    
         
            +
                        // }
         
     | 
| 
      
 42 
     | 
    
         
            +
                        );
         
     | 
| 
      
 43 
     | 
    
         
            +
                    }
         
     | 
| 
      
 44 
     | 
    
         
            +
                    return {
         
     | 
| 
      
 45 
     | 
    
         
            +
                        cached: false,
         
     | 
| 
      
 46 
     | 
    
         
            +
                        call: {
         
     | 
| 
      
 47 
     | 
    
         
            +
                            callData: calls,
         
     | 
| 
      
 48 
     | 
    
         
            +
                            handler: () => { },
         
     | 
| 
      
 49 
     | 
    
         
            +
                            reducer: async (result) => {
         
     | 
| 
      
 50 
     | 
    
         
            +
                                let i = 0;
         
     | 
| 
      
 51 
     | 
    
         
            +
                                if (!!poolList) {
         
     | 
| 
      
 52 
     | 
    
         
            +
                                    for (const pool of poolList) {
         
     | 
| 
      
 53 
     | 
    
         
            +
                                        // This liquidity call gives the active liquidity on the pool. To get the total liquidity we would need to loop over all positions
         
     | 
| 
      
 54 
     | 
    
         
            +
                                        let poolTotalLiquidity;
         
     | 
| 
      
 55 
     | 
    
         
            +
                                        let sqrtPrice;
         
     | 
| 
      
 56 
     | 
    
         
            +
                                        let tick;
         
     | 
| 
      
 57 
     | 
    
         
            +
                                        const poolBalanceToken0 = 0;
         
     | 
| 
      
 58 
     | 
    
         
            +
                                        const poolBalanceToken1 = 0;
         
     | 
| 
      
 59 
     | 
    
         
            +
                                        const campaignsForPool = campaigns?.filter(campaign => campaign.mainParameter.toLowerCase() === pool.mainParameter.toLowerCase());
         
     | 
| 
      
 60 
     | 
    
         
            +
                                        //   const decimalsToken0 = d.campaignParameters.decimalsCurrency0;
         
     | 
| 
      
 61 
     | 
    
         
            +
                                        //   const decimalsToken1 = d.campaignParameters.decimalsCurrency1;
         
     | 
| 
      
 62 
     | 
    
         
            +
                                        const symbolToken0 = campaignsForPool[0].campaignParameters.symbolCurrency0;
         
     | 
| 
      
 63 
     | 
    
         
            +
                                        const symbolToken1 = campaignsForPool[0].campaignParameters.symbolCurrency1;
         
     | 
| 
      
 64 
     | 
    
         
            +
                                        const prevI = i;
         
     | 
| 
      
 65 
     | 
    
         
            +
                                        try {
         
     | 
| 
      
 66 
     | 
    
         
            +
                                            poolTotalLiquidity = UniswapV4StateViewInterface.decodeFunctionResult("getLiquidity", result[i++])[0].toString();
         
     | 
| 
      
 67 
     | 
    
         
            +
                                            const poolData = UniswapV4StateViewInterface.decodeFunctionResult("getSlot0", result[i++]);
         
     | 
| 
      
 68 
     | 
    
         
            +
                                            tick = poolData.tick;
         
     | 
| 
      
 69 
     | 
    
         
            +
                                            sqrtPrice = getSqrtRatioAtTick(tick).toString();
         
     | 
| 
      
 70 
     | 
    
         
            +
                                            // poolBalanceToken0 = BN2Number(
         
     | 
| 
      
 71 
     | 
    
         
            +
                                            //   ERC20Interface.decodeFunctionResult("balanceOf", result[i++])[0],
         
     | 
| 
      
 72 
     | 
    
         
            +
                                            //   decimalsToken0
         
     | 
| 
      
 73 
     | 
    
         
            +
                                            // );
         
     | 
| 
      
 74 
     | 
    
         
            +
                                            // poolBalanceToken1 = BN2Number(
         
     | 
| 
      
 75 
     | 
    
         
            +
                                            //   ERC20Interface.decodeFunctionResult("balanceOf", result[i++])[0],
         
     | 
| 
      
 76 
     | 
    
         
            +
                                            //   decimalsToken1
         
     | 
| 
      
 77 
     | 
    
         
            +
                                            // );
         
     | 
| 
      
 78 
     | 
    
         
            +
                                        }
         
     | 
| 
      
 79 
     | 
    
         
            +
                                        catch {
         
     | 
| 
      
 80 
     | 
    
         
            +
                                            log.warn(`merklDynamic data - failed to decode state of pool ${pool.poolId} on ${NETWORK_LABELS[chainId]}`);
         
     | 
| 
      
 81 
     | 
    
         
            +
                                            i = prevI + CALLS_LENGTH;
         
     | 
| 
      
 82 
     | 
    
         
            +
                                            continue;
         
     | 
| 
      
 83 
     | 
    
         
            +
                                        }
         
     | 
| 
      
 84 
     | 
    
         
            +
                                        const priceToken0 = (await pricer.get({
         
     | 
| 
      
 85 
     | 
    
         
            +
                                            address: campaignsForPool[0].campaignParameters.currency0,
         
     | 
| 
      
 86 
     | 
    
         
            +
                                            chainId: chainId,
         
     | 
| 
      
 87 
     | 
    
         
            +
                                            symbol: symbolToken0,
         
     | 
| 
      
 88 
     | 
    
         
            +
                                        }));
         
     | 
| 
      
 89 
     | 
    
         
            +
                                        const priceToken1 = (await pricer.get({
         
     | 
| 
      
 90 
     | 
    
         
            +
                                            address: campaignsForPool[0].campaignParameters.currency1,
         
     | 
| 
      
 91 
     | 
    
         
            +
                                            chainId: chainId,
         
     | 
| 
      
 92 
     | 
    
         
            +
                                            symbol: symbolToken1,
         
     | 
| 
      
 93 
     | 
    
         
            +
                                        }));
         
     | 
| 
      
 94 
     | 
    
         
            +
                                        /** Iterate over distributions to compute APRs */
         
     | 
| 
      
 95 
     | 
    
         
            +
                                        for (const campaign of campaignsForPool) {
         
     | 
| 
      
 96 
     | 
    
         
            +
                                            const c = campaign;
         
     | 
| 
      
 97 
     | 
    
         
            +
                                            const amount = BN2Number(c.amount, c.campaignParameters.decimalsRewardToken);
         
     | 
| 
      
 98 
     | 
    
         
            +
                                            const startTimestamp = BN2Number(c.startTimestamp, 0);
         
     | 
| 
      
 99 
     | 
    
         
            +
                                            const endTimestamp = BN2Number(c.endTimestamp, 0);
         
     | 
| 
      
 100 
     | 
    
         
            +
                                            const isLive = moment().unix() > startTimestamp && moment().unix() < endTimestamp;
         
     | 
| 
      
 101 
     | 
    
         
            +
                                            const totalWeight = BN2Number(c.campaignParameters.weightFees, 4) +
         
     | 
| 
      
 102 
     | 
    
         
            +
                                                BN2Number(c.campaignParameters.weightToken0, 4) +
         
     | 
| 
      
 103 
     | 
    
         
            +
                                                BN2Number(c.campaignParameters.weightToken1, 4);
         
     | 
| 
      
 104 
     | 
    
         
            +
                                            // Proportions in percentage
         
     | 
| 
      
 105 
     | 
    
         
            +
                                            const propFees = (BN2Number(c.campaignParameters.weightFees, 4) / totalWeight) * 100;
         
     | 
| 
      
 106 
     | 
    
         
            +
                                            const propToken0 = (BN2Number(c.campaignParameters.weightToken0, 4) / totalWeight) * 100;
         
     | 
| 
      
 107 
     | 
    
         
            +
                                            const propToken1 = (BN2Number(c.campaignParameters.weightToken1, 4) / totalWeight) * 100;
         
     | 
| 
      
 108 
     | 
    
         
            +
                                            let distributionMeanAPR = 0;
         
     | 
| 
      
 109 
     | 
    
         
            +
                                            const blacklistedBalance0 = 0;
         
     | 
| 
      
 110 
     | 
    
         
            +
                                            const blacklistedBalance1 = 0;
         
     | 
| 
      
 111 
     | 
    
         
            +
                                            const blacklistedLiquidity = 0;
         
     | 
| 
      
 112 
     | 
    
         
            +
                                            const aprs = {};
         
     | 
| 
      
 113 
     | 
    
         
            +
                                            const aprBreakdowns = [];
         
     | 
| 
      
 114 
     | 
    
         
            +
                                            let priceRewardToken = 0;
         
     | 
| 
      
 115 
     | 
    
         
            +
                                            if (isLive && c.campaignParameters.symbolRewardToken !== "aglaMerkl") {
         
     | 
| 
      
 116 
     | 
    
         
            +
                                                priceRewardToken = (await pricer.get({
         
     | 
| 
      
 117 
     | 
    
         
            +
                                                    address: c.rewardToken,
         
     | 
| 
      
 118 
     | 
    
         
            +
                                                    chainId: chainId,
         
     | 
| 
      
 119 
     | 
    
         
            +
                                                    symbol: c.campaignParameters.symbolRewardToken,
         
     | 
| 
      
 120 
     | 
    
         
            +
                                                }));
         
     | 
| 
      
 121 
     | 
    
         
            +
                                                /**
         
     | 
| 
      
 122 
     | 
    
         
            +
                                                 * Handle whitelisted/blacklisted addresses to compute APR
         
     | 
| 
      
 123 
     | 
    
         
            +
                                                 */
         
     | 
| 
      
 124 
     | 
    
         
            +
                                                if (c.campaignParameters.whitelist.length > 0) {
         
     | 
| 
      
 125 
     | 
    
         
            +
                                                    // TODO
         
     | 
| 
      
 126 
     | 
    
         
            +
                                                }
         
     | 
| 
      
 127 
     | 
    
         
            +
                                                else if (c.campaignParameters.blacklist.length > 0) {
         
     | 
| 
      
 128 
     | 
    
         
            +
                                                    // TODO
         
     | 
| 
      
 129 
     | 
    
         
            +
                                                }
         
     | 
| 
      
 130 
     | 
    
         
            +
                                                /** Yearly rewards in $ */
         
     | 
| 
      
 131 
     | 
    
         
            +
                                                const yearlyToken0Rewards = (propToken0 * priceRewardToken * amount * (365 * 24 * 3_600)) / (endTimestamp - startTimestamp);
         
     | 
| 
      
 132 
     | 
    
         
            +
                                                const yearlyToken1Rewards = (propToken1 * priceRewardToken * amount * (365 * 24 * 3_600)) / (endTimestamp - startTimestamp);
         
     | 
| 
      
 133 
     | 
    
         
            +
                                                const yearlyFeeRewards = (propFees * priceRewardToken * amount * (365 * 24 * 3_600)) / (endTimestamp - startTimestamp);
         
     | 
| 
      
 134 
     | 
    
         
            +
                                                let poolAPRkey = "";
         
     | 
| 
      
 135 
     | 
    
         
            +
                                                /**
         
     | 
| 
      
 136 
     | 
    
         
            +
                                                 * General APR (@notice potentially with a boost)
         
     | 
| 
      
 137 
     | 
    
         
            +
                                                 */
         
     | 
| 
      
 138 
     | 
    
         
            +
                                                const poolBalanceToken0WithoutBlacklist = 0;
         
     | 
| 
      
 139 
     | 
    
         
            +
                                                const poolBalanceToken1WithoutBlacklist = 0;
         
     | 
| 
      
 140 
     | 
    
         
            +
                                                //   const poolLiquidityWithoutBlacklist = poolTotalLiquidity - (blacklistedLiquidity ?? 0);
         
     | 
| 
      
 141 
     | 
    
         
            +
                                                const tvl = poolBalanceToken0WithoutBlacklist * priceToken0 + poolBalanceToken1WithoutBlacklist * priceToken1;
         
     | 
| 
      
 142 
     | 
    
         
            +
                                                distributionMeanAPR = (yearlyToken0Rewards + yearlyToken1Rewards + yearlyFeeRewards) / tvl;
         
     | 
| 
      
 143 
     | 
    
         
            +
                                                distributionMeanAPR =
         
     | 
| 
      
 144 
     | 
    
         
            +
                                                    !distributionMeanAPR || Number.isNaN(distributionMeanAPR) ? 0 : distributionMeanAPR;
         
     | 
| 
      
 145 
     | 
    
         
            +
                                                /**
         
     | 
| 
      
 146 
     | 
    
         
            +
                                                 * @dev We cannot include a whitelisted distrib apr into the mean APR
         
     | 
| 
      
 147 
     | 
    
         
            +
                                                 */
         
     | 
| 
      
 148 
     | 
    
         
            +
                                                if (c.campaignParameters.whitelist.length === 0) {
         
     | 
| 
      
 149 
     | 
    
         
            +
                                                    poolAPRkey = "Average APR (rewards / pool TVL)";
         
     | 
| 
      
 150 
     | 
    
         
            +
                                                    if (!aprs[poolAPRkey])
         
     | 
| 
      
 151 
     | 
    
         
            +
                                                        aprs[poolAPRkey] = 0;
         
     | 
| 
      
 152 
     | 
    
         
            +
                                                    aprs[poolAPRkey] += distributionMeanAPR;
         
     | 
| 
      
 153 
     | 
    
         
            +
                                                    // @Hugo wip: new way to structure aprBreakdowns
         
     | 
| 
      
 154 
     | 
    
         
            +
                                                    aprBreakdowns.push({
         
     | 
| 
      
 155 
     | 
    
         
            +
                                                        address: pool.poolId,
         
     | 
| 
      
 156 
     | 
    
         
            +
                                                        value: distributionMeanAPR,
         
     | 
| 
      
 157 
     | 
    
         
            +
                                                        type: EAprBreakdownType.AVERAGE,
         
     | 
| 
      
 158 
     | 
    
         
            +
                                                        label: "Average APR (rewards / pool TVL)",
         
     | 
| 
      
 159 
     | 
    
         
            +
                                                    });
         
     | 
| 
      
 160 
     | 
    
         
            +
                                                    // APR per token
         
     | 
| 
      
 161 
     | 
    
         
            +
                                                    poolAPRkey = `APR for holding ${c.campaignParameters.symbolCurrency0} in pool`;
         
     | 
| 
      
 162 
     | 
    
         
            +
                                                    if (!aprs[poolAPRkey])
         
     | 
| 
      
 163 
     | 
    
         
            +
                                                        aprs[poolAPRkey] = 0;
         
     | 
| 
      
 164 
     | 
    
         
            +
                                                    aprs[poolAPRkey] += yearlyToken0Rewards / (poolBalanceToken0WithoutBlacklist * priceToken0);
         
     | 
| 
      
 165 
     | 
    
         
            +
                                                    // @Hugo wip: new way to structure aprBreakdowns
         
     | 
| 
      
 166 
     | 
    
         
            +
                                                    aprBreakdowns.push({
         
     | 
| 
      
 167 
     | 
    
         
            +
                                                        address: pool.poolId,
         
     | 
| 
      
 168 
     | 
    
         
            +
                                                        value: yearlyToken0Rewards / (poolBalanceToken0WithoutBlacklist * priceToken0),
         
     | 
| 
      
 169 
     | 
    
         
            +
                                                        type: EAprBreakdownType.TOKEN1,
         
     | 
| 
      
 170 
     | 
    
         
            +
                                                        label: c.campaignParameters.symbolCurrency0,
         
     | 
| 
      
 171 
     | 
    
         
            +
                                                    });
         
     | 
| 
      
 172 
     | 
    
         
            +
                                                    poolAPRkey = `APR for holding  ${c.campaignParameters.symbolCurrency1} in pool`;
         
     | 
| 
      
 173 
     | 
    
         
            +
                                                    if (!aprs[poolAPRkey])
         
     | 
| 
      
 174 
     | 
    
         
            +
                                                        aprs[poolAPRkey] = 0;
         
     | 
| 
      
 175 
     | 
    
         
            +
                                                    aprs[poolAPRkey] += yearlyToken1Rewards / (poolBalanceToken1WithoutBlacklist * priceToken1);
         
     | 
| 
      
 176 
     | 
    
         
            +
                                                    // @Hugo wip: new way to structure aprBreakdowns
         
     | 
| 
      
 177 
     | 
    
         
            +
                                                    aprBreakdowns.push({
         
     | 
| 
      
 178 
     | 
    
         
            +
                                                        address: pool.poolId,
         
     | 
| 
      
 179 
     | 
    
         
            +
                                                        value: yearlyToken1Rewards / (poolBalanceToken1WithoutBlacklist * priceToken1),
         
     | 
| 
      
 180 
     | 
    
         
            +
                                                        type: EAprBreakdownType.TOKEN2,
         
     | 
| 
      
 181 
     | 
    
         
            +
                                                        label: c.campaignParameters.symbolCurrency1,
         
     | 
| 
      
 182 
     | 
    
         
            +
                                                    });
         
     | 
| 
      
 183 
     | 
    
         
            +
                                                }
         
     | 
| 
      
 184 
     | 
    
         
            +
                                                else {
         
     | 
| 
      
 185 
     | 
    
         
            +
                                                    for (const _ of c.campaignParameters.whitelist) {
         
     | 
| 
      
 186 
     | 
    
         
            +
                                                        const poolAPRkey = `Whitelisted campaign on UniswapV4 via address ${shortenAddress(c.campaignParameters.whitelist[0])} Average APR`;
         
     | 
| 
      
 187 
     | 
    
         
            +
                                                        if (!aprs[poolAPRkey])
         
     | 
| 
      
 188 
     | 
    
         
            +
                                                            aprs[poolAPRkey] = 0;
         
     | 
| 
      
 189 
     | 
    
         
            +
                                                    }
         
     | 
| 
      
 190 
     | 
    
         
            +
                                                    aprs[poolAPRkey] += distributionMeanAPR;
         
     | 
| 
      
 191 
     | 
    
         
            +
                                                }
         
     | 
| 
      
 192 
     | 
    
         
            +
                                            }
         
     | 
| 
      
 193 
     | 
    
         
            +
                                            dynamicData.push({
         
     | 
| 
      
 194 
     | 
    
         
            +
                                                ...campaign,
         
     | 
| 
      
 195 
     | 
    
         
            +
                                                apr: distributionMeanAPR,
         
     | 
| 
      
 196 
     | 
    
         
            +
                                                aprs,
         
     | 
| 
      
 197 
     | 
    
         
            +
                                                aprBreakdowns,
         
     | 
| 
      
 198 
     | 
    
         
            +
                                                blacklistedBalance0,
         
     | 
| 
      
 199 
     | 
    
         
            +
                                                blacklistedBalance1,
         
     | 
| 
      
 200 
     | 
    
         
            +
                                                blacklistedLiquidity,
         
     | 
| 
      
 201 
     | 
    
         
            +
                                                poolBalanceToken0,
         
     | 
| 
      
 202 
     | 
    
         
            +
                                                poolBalanceToken1,
         
     | 
| 
      
 203 
     | 
    
         
            +
                                                poolTotalLiquidity,
         
     | 
| 
      
 204 
     | 
    
         
            +
                                                sqrtPrice,
         
     | 
| 
      
 205 
     | 
    
         
            +
                                                tick: tick,
         
     | 
| 
      
 206 
     | 
    
         
            +
                                                priceRewardToken: priceRewardToken,
         
     | 
| 
      
 207 
     | 
    
         
            +
                                                tvl: poolBalanceToken0 * priceToken0 + poolBalanceToken1 * priceToken1,
         
     | 
| 
      
 208 
     | 
    
         
            +
                                            });
         
     | 
| 
      
 209 
     | 
    
         
            +
                                        }
         
     | 
| 
      
 210 
     | 
    
         
            +
                                    }
         
     | 
| 
      
 211 
     | 
    
         
            +
                                }
         
     | 
| 
      
 212 
     | 
    
         
            +
                                return dynamicData;
         
     | 
| 
      
 213 
     | 
    
         
            +
                            },
         
     | 
| 
      
 214 
     | 
    
         
            +
                        },
         
     | 
| 
      
 215 
     | 
    
         
            +
                    };
         
     | 
| 
      
 216 
     | 
    
         
            +
                }
         
     | 
| 
      
 217 
     | 
    
         
            +
                // Fallback in case something fails
         
     | 
| 
      
 218 
     | 
    
         
            +
                return {
         
     | 
| 
      
 219 
     | 
    
         
            +
                    cached: false,
         
     | 
| 
      
 220 
     | 
    
         
            +
                    call: {
         
     | 
| 
      
 221 
     | 
    
         
            +
                        callData: [],
         
     | 
| 
      
 222 
     | 
    
         
            +
                        handler: () => { },
         
     | 
| 
      
 223 
     | 
    
         
            +
                        reducer: async (_result) => {
         
     | 
| 
      
 224 
     | 
    
         
            +
                            return campaigns;
         
     | 
| 
      
 225 
     | 
    
         
            +
                        },
         
     | 
| 
      
 226 
     | 
    
         
            +
                    },
         
     | 
| 
      
 227 
     | 
    
         
            +
                };
         
     | 
| 
      
 228 
     | 
    
         
            +
            }
         
     | 
| 
         @@ -14,6 +14,7 @@ import { JSON_AIRDROPDynamicData } from "./campaignTypes/JSON_AIRDROPDynamicData 
     | 
|
| 
       14 
14 
     | 
    
         
             
            import { MORPHODynamicData } from "./campaignTypes/MORPHODynamicData";
         
     | 
| 
       15 
15 
     | 
    
         
             
            import { RadiantDynamicData } from "./campaignTypes/RadiantDynamicData";
         
     | 
| 
       16 
16 
     | 
    
         
             
            import { SILODynamicData } from "./campaignTypes/SILODynamicData";
         
     | 
| 
      
 17 
     | 
    
         
            +
            import { UniswapV4DynamicData } from "./campaignTypes/UniswapV4DynamicData";
         
     | 
| 
       17 
18 
     | 
    
         
             
            import { VestDynamicData } from "./campaignTypes/VestDynamicData";
         
     | 
| 
       18 
19 
     | 
    
         
             
            export async function campaignsDynamicData(chainId, campaigns, type) {
         
     | 
| 
       19 
20 
     | 
    
         
             
                try {
         
     | 
| 
         @@ -82,6 +83,9 @@ export async function campaignsDynamicData(chainId, campaigns, type) { 
     | 
|
| 
       82 
83 
     | 
    
         
             
                    case Campaign.AMBIENTPROCESSOR: {
         
     | 
| 
       83 
84 
     | 
    
         
             
                        return AmbientDynamicData(chainId, campaigns);
         
     | 
| 
       84 
85 
     | 
    
         
             
                    }
         
     | 
| 
      
 86 
     | 
    
         
            +
                    case Campaign.UNISWAP_V4: {
         
     | 
| 
      
 87 
     | 
    
         
            +
                        return UniswapV4DynamicData(chainId, campaigns);
         
     | 
| 
      
 88 
     | 
    
         
            +
                    }
         
     | 
| 
       85 
89 
     | 
    
         
             
                }
         
     | 
| 
       86 
90 
     | 
    
         
             
                return {
         
     | 
| 
       87 
91 
     | 
    
         
             
                    cached: false,
         
     | 
| 
         @@ -46,6 +46,7 @@ export declare const campaignTypeToEnumMap: { 
     | 
|
| 
       46 
46 
     | 
    
         
             
                readonly M0: any;
         
     | 
| 
       47 
47 
     | 
    
         
             
                readonly MORPHOSUPPLY: any;
         
     | 
| 
       48 
48 
     | 
    
         
             
                readonly SYNCSWAP_VAULT: any;
         
     | 
| 
      
 49 
     | 
    
         
            +
                readonly UNISWAP_V4_LP: any;
         
     | 
| 
       49 
50 
     | 
    
         
             
            };
         
     | 
| 
       50 
51 
     | 
    
         
             
            export type ConvertedCampaignType<C extends CampaignType> = (typeof campaignTypeToEnumMap)[C];
         
     | 
| 
       51 
52 
     | 
    
         
             
            export declare const CampaignUniqueDto: import("@sinclair/typebox").TObject<{
         
     | 
| 
         @@ -33,6 +33,7 @@ export const campaignTypeToEnumMap = { 
     | 
|
| 
       33 
33 
     | 
    
         
             
                M0: CampaignTypeEnum.M0,
         
     | 
| 
       34 
34 
     | 
    
         
             
                MORPHOSUPPLY: CampaignTypeEnum.MORPHOSUPPLY,
         
     | 
| 
       35 
35 
     | 
    
         
             
                SYNCSWAP_VAULT: CampaignTypeEnum.SYNCSWAP_VAULT,
         
     | 
| 
      
 36 
     | 
    
         
            +
                UNISWAP_V4_LP: CampaignTypeEnum.UNISWAP_V4,
         
     | 
| 
       36 
37 
     | 
    
         
             
            };
         
     | 
| 
       37 
38 
     | 
    
         
             
            // ─── DTOs ────────────────────────────────────────────────────────────────────
         
     | 
| 
       38 
39 
     | 
    
         
             
            export const CampaignUniqueDto = t.Object({
         
     |