@merkl/api 0.14.0 → 0.14.2
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/backgroundJobs/index.js +2 -1
- package/dist/src/eden/index.d.ts +33 -3
- package/dist/src/entities/opportunity.js +4 -1
- package/dist/src/index.d.ts +13 -1
- package/dist/src/jobs/etl/pendings.js +1 -3
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/tokenType.d.ts +2 -1
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/tokenType.js +83 -112
- package/dist/src/libs/campaigns/utils/getEulerV2Vaults.d.ts +2 -16
- package/dist/src/libs/campaigns/utils/getEulerV2Vaults.js +115 -57
- package/dist/src/modules/v4/bucket/bucket.service.d.ts +1 -1
- package/dist/src/modules/v4/bucket/bucket.service.js +6 -6
- package/dist/src/modules/v4/opportunity/subservices/getErc20Metadata.service.js +1 -1
- package/dist/src/modules/v4/programPayload/programPayload.repository.d.ts +12 -2
- package/dist/src/modules/v4/programPayload/programPayload.repository.js +52 -1
- package/dist/src/routes/v3/euler.d.ts +13 -1
- package/dist/src/routes/v3/euler.js +10 -2
- package/dist/src/routes/v3/router.d.ts +13 -1
- package/dist/tsconfig.package.tsbuildinfo +1 -1
- package/package.json +1 -1
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            import { Redis } from "../cache";
         | 
| 2 2 | 
             
            import { redisClient } from "../cache/redis";
         | 
| 3 | 
            -
            import { getEulerV2Vaults } from "../libs/campaigns/utils/getEulerV2Vaults";
         | 
| 3 | 
            +
            import { getEulerV2Vaults, updateEulerVaultsCollatInDatabase } from "../libs/campaigns/utils/getEulerV2Vaults";
         | 
| 4 4 | 
             
            import { getUniswapV4Pools } from "../libs/campaigns/utils/getUniswapV4Pools";
         | 
| 5 5 | 
             
            import { DungeonKeeperController } from "../modules/v4/dungeonKeeper";
         | 
| 6 6 | 
             
            import { log } from "../utils/logger";
         | 
| @@ -30,6 +30,7 @@ new Elysia({ | |
| 30 30 | 
             
                .use(sync) // GET /jobs/api/sync-with-engine
         | 
| 31 31 | 
             
                .get("/eulerUpdate", async () => {
         | 
| 32 32 | 
             
                log.info("🔃 updating Euler vaults...");
         | 
| 33 | 
            +
                await updateEulerVaultsCollatInDatabase();
         | 
| 33 34 | 
             
                await Redis.safeSet("EulerV2Vaults", await getEulerV2Vaults());
         | 
| 34 35 | 
             
            })
         | 
| 35 36 | 
             
                .get("/uniswapv4Update", async () => {
         | 
    
        package/dist/src/eden/index.d.ts
    CHANGED
    
    | @@ -6372,7 +6372,16 @@ declare const eden: { | |
| 6372 6372 | 
             
                            query: {};
         | 
| 6373 6373 | 
             
                            fetch?: RequestInit | undefined;
         | 
| 6374 6374 | 
             
                        }) => Promise<import("@elysiajs/eden").Treaty.TreatyResponse<{
         | 
| 6375 | 
            -
                            200:  | 
| 6375 | 
            +
                            200: EulerVaultType[];
         | 
| 6376 | 
            +
                        }>>;
         | 
| 6377 | 
            +
                    };
         | 
| 6378 | 
            +
                    "euler-update-collat": {
         | 
| 6379 | 
            +
                        get: (options: {
         | 
| 6380 | 
            +
                            headers?: Record<string, unknown> | undefined;
         | 
| 6381 | 
            +
                            query: {};
         | 
| 6382 | 
            +
                            fetch?: RequestInit | undefined;
         | 
| 6383 | 
            +
                        }) => Promise<import("@elysiajs/eden").Treaty.TreatyResponse<{
         | 
| 6384 | 
            +
                            200: void;
         | 
| 6376 6385 | 
             
                        }>>;
         | 
| 6377 6386 | 
             
                    };
         | 
| 6378 6387 | 
             
                    fetch: {
         | 
| @@ -10930,7 +10939,19 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa | |
| 10930 10939 | 
             
                            query: {};
         | 
| 10931 10940 | 
             
                            headers: unknown;
         | 
| 10932 10941 | 
             
                            response: {
         | 
| 10933 | 
            -
                                200:  | 
| 10942 | 
            +
                                200: EulerVaultType[];
         | 
| 10943 | 
            +
                            };
         | 
| 10944 | 
            +
                        };
         | 
| 10945 | 
            +
                    };
         | 
| 10946 | 
            +
                } & {
         | 
| 10947 | 
            +
                    "euler-update-collat": {
         | 
| 10948 | 
            +
                        get: {
         | 
| 10949 | 
            +
                            body: unknown;
         | 
| 10950 | 
            +
                            params: {};
         | 
| 10951 | 
            +
                            query: {};
         | 
| 10952 | 
            +
                            headers: unknown;
         | 
| 10953 | 
            +
                            response: {
         | 
| 10954 | 
            +
                                200: void;
         | 
| 10934 10955 | 
             
                            };
         | 
| 10935 10956 | 
             
                        };
         | 
| 10936 10957 | 
             
                    };
         | 
| @@ -17827,7 +17848,16 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa | |
| 17827 17848 | 
             
                            query: {};
         | 
| 17828 17849 | 
             
                            fetch?: RequestInit | undefined;
         | 
| 17829 17850 | 
             
                        }) => Promise<import("@elysiajs/eden").Treaty.TreatyResponse<{
         | 
| 17830 | 
            -
                            200:  | 
| 17851 | 
            +
                            200: EulerVaultType[];
         | 
| 17852 | 
            +
                        }>>;
         | 
| 17853 | 
            +
                    };
         | 
| 17854 | 
            +
                    "euler-update-collat": {
         | 
| 17855 | 
            +
                        get: (options: {
         | 
| 17856 | 
            +
                            headers?: Record<string, unknown> | undefined;
         | 
| 17857 | 
            +
                            query: {};
         | 
| 17858 | 
            +
                            fetch?: RequestInit | undefined;
         | 
| 17859 | 
            +
                        }) => Promise<import("@elysiajs/eden").Treaty.TreatyResponse<{
         | 
| 17860 | 
            +
                            200: void;
         | 
| 17831 17861 | 
             
                        }>>;
         | 
| 17832 17862 | 
             
                    };
         | 
| 17833 17863 | 
             
                    fetch: {
         | 
| @@ -328,7 +328,10 @@ export const extractOpportunities = { | |
| 328 328 | 
             
                            },
         | 
| 329 329 | 
             
                        },
         | 
| 330 330 | 
             
                    };
         | 
| 331 | 
            -
                    const action =  | 
| 331 | 
            +
                    const action = typeInfo.action.toLowerCase() ?? "hold";
         | 
| 332 | 
            +
                    // (Object.entries(map.actions).find(([_action, _types]) =>
         | 
| 333 | 
            +
                    //   _types.includes(campaign.type ?? "")
         | 
| 334 | 
            +
                    // )?.[0] as ERC20Actions) ?? "hold";
         | 
| 332 335 | 
             
                    const icons = map.icons[action]();
         | 
| 333 336 | 
             
                    const opportunity = {
         | 
| 334 337 | 
             
                        id: `${Campaign.ERC20}_${mainParameter}`,
         | 
    
        package/dist/src/index.d.ts
    CHANGED
    
    | @@ -4147,7 +4147,19 @@ declare const app: Elysia<"", false, { | |
| 4147 4147 | 
             
                            query: {};
         | 
| 4148 4148 | 
             
                            headers: unknown;
         | 
| 4149 4149 | 
             
                            response: {
         | 
| 4150 | 
            -
                                200:  | 
| 4150 | 
            +
                                200: EulerVaultType[];
         | 
| 4151 | 
            +
                            };
         | 
| 4152 | 
            +
                        };
         | 
| 4153 | 
            +
                    };
         | 
| 4154 | 
            +
                } & {
         | 
| 4155 | 
            +
                    "euler-update-collat": {
         | 
| 4156 | 
            +
                        get: {
         | 
| 4157 | 
            +
                            body: unknown;
         | 
| 4158 | 
            +
                            params: {};
         | 
| 4159 | 
            +
                            query: {};
         | 
| 4160 | 
            +
                            headers: unknown;
         | 
| 4161 | 
            +
                            response: {
         | 
| 4162 | 
            +
                                200: void;
         | 
| 4151 4163 | 
             
                            };
         | 
| 4152 4164 | 
             
                        };
         | 
| 4153 4165 | 
             
                    };
         | 
| @@ -17,9 +17,7 @@ const gcsClient = new S3Client({ | |
| 17 17 | 
             
                endpoint: process.env.GCS_ENDPOINT,
         | 
| 18 18 | 
             
                bucket: `merkl-rewards-lake-${process.env.ENV}`,
         | 
| 19 19 | 
             
            });
         | 
| 20 | 
            -
             | 
| 21 | 
            -
            if (!(await file.exists))
         | 
| 22 | 
            -
                file = gcsClient.file(`pendings/${process.env.FILENAME}.gz`);
         | 
| 20 | 
            +
            const file = gcsClient.file(`pendings/${process.env.FILENAME}`);
         | 
| 23 21 | 
             
            // ─── Extract ─────────────────────────────────────────────────────────────────
         | 
| 24 22 | 
             
            const extract = async () => {
         | 
| 25 23 | 
             
                if (!file.exists())
         | 
| @@ -1,3 +1,4 @@ | |
| 1 | 
            +
            import { OpportunityAction } from "../../../../../../database/api/.generated";
         | 
| 1 2 | 
             
            import type { CallDto } from "@sdk";
         | 
| 2 3 | 
             
            export declare enum tokenType {
         | 
| 3 4 | 
             
                aura = "aura",
         | 
| @@ -85,7 +86,7 @@ export declare enum tokenType { | |
| 85 86 | 
             
            }
         | 
| 86 87 | 
             
            export declare const tokenTypeToProtocol: {
         | 
| 87 88 | 
             
                [key in tokenType]: {
         | 
| 88 | 
            -
                    [key: string]: string;
         | 
| 89 | 
            +
                    [key: string]: string | OpportunityAction;
         | 
| 89 90 | 
             
                };
         | 
| 90 91 | 
             
            };
         | 
| 91 92 | 
             
            export type tokenTypeStruct = {
         | 
| @@ -1,3 +1,4 @@ | |
| 1 | 
            +
            import { OpportunityAction } from "../../../../../../database/api/.generated";
         | 
| 1 2 | 
             
            // This enum's order is important, do not change it unless you know what you are doing
         | 
| 2 3 | 
             
            export var tokenType;
         | 
| 3 4 | 
             
            (function (tokenType) {
         | 
| @@ -85,116 +86,86 @@ export var tokenType; | |
| 85 86 | 
             
                tokenType["vicuna_borrowing"] = "vicuna_borrowing";
         | 
| 86 87 | 
             
            })(tokenType || (tokenType = {}));
         | 
| 87 88 | 
             
            export const tokenTypeToProtocol = {
         | 
| 88 | 
            -
                [tokenType.aave_borrowing]: { protocol: "Aave" },
         | 
| 89 | 
            -
                [tokenType.aave_lending]: { protocol: "Aave" },
         | 
| 90 | 
            -
                [tokenType.aerodrome]: { protocol: "Aerodrome V2" },
         | 
| 91 | 
            -
                [tokenType.akron]: { protocol: "Akron V2" },
         | 
| 92 | 
            -
                [tokenType.aura]: { protocol: "Aura" },
         | 
| 93 | 
            -
                [tokenType.balancerGauge]: { protocol: "Balancer Gauge" },
         | 
| 94 | 
            -
                [tokenType.balancerPool]: { protocol: "Balancer Pool" },
         | 
| 95 | 
            -
                [tokenType.baseswap]: { protocol: "Baseswap V2" },
         | 
| 96 | 
            -
                [tokenType.beefy]: { protocol: "Moo Velodrome V2" },
         | 
| 97 | 
            -
                [tokenType.compound]: { protocol: "Compound" },
         | 
| 98 | 
            -
                [tokenType.curve]: { protocol: "Curve" },
         | 
| 99 | 
            -
                [tokenType.curve_2]: { protocol: "Curve" },
         | 
| 100 | 
            -
                [tokenType.dragonswap]: { protocol: "Dragonswap V2" },
         | 
| 101 | 
            -
                [tokenType.enzyme]: { protocol: "Enzyme" },
         | 
| 102 | 
            -
                [tokenType.euler_borrow]: { protocol: "Euler V2" },
         | 
| 103 | 
            -
                [tokenType.euler_lend]: { protocol: "Euler V2" },
         | 
| 104 | 
            -
                [tokenType.fenix]: { protocol: "Fenix V2" },
         | 
| 105 | 
            -
                [tokenType.filament]: { protocol: "Filament" },
         | 
| 106 | 
            -
                [tokenType.fluid]: { protocol: "Fluid" },
         | 
| 107 | 
            -
                [tokenType.fraxlend]: { protocol: "Fraxlend" },
         | 
| 108 | 
            -
                [tokenType.gearbox]: { protocol: "Gearbox" },
         | 
| 109 | 
            -
                [tokenType.ionic]: { protocol: "Ionic" },
         | 
| 110 | 
            -
                [tokenType.ironclad_borrowing]: { protocol: "Ironclad" },
         | 
| 111 | 
            -
                [tokenType.ironclad_lending]: { protocol: "Ironclad" },
         | 
| 112 | 
            -
                [tokenType.koi]: { protocol: "Koi" },
         | 
| 113 | 
            -
                [tokenType.layerbank]: { protocol: "Layerbank" },
         | 
| 114 | 
            -
                [tokenType.metamorpho]: { protocol: "Metamorpho" },
         | 
| 115 | 
            -
                [tokenType.moonwell]: { protocol: "Moonwell" },
         | 
| 116 | 
            -
                [tokenType.pendle]: { protocol: "Pendle" },
         | 
| 117 | 
            -
                [tokenType.poolside]: { protocol: "Poolside" },
         | 
| 118 | 
            -
                [tokenType.ra]: { protocol: "Ra" },
         | 
| 119 | 
            -
                [tokenType.radiant_borrow]: { protocol: "Radiant" },
         | 
| 120 | 
            -
                [tokenType.radiant_lend]: { protocol: "Radiant" },
         | 
| 121 | 
            -
                [tokenType.reactor_fusion]: { protocol: "Reactor Fusion" },
         | 
| 122 | 
            -
                [tokenType.silostaking]: { protocol: "Silo Staking",  | 
| 123 | 
            -
                [tokenType.splice]: { protocol: "Splice" },
         | 
| 124 | 
            -
                [tokenType.sturdy_aggregator]: { protocol: "Sturdy" },
         | 
| 125 | 
            -
                [tokenType.sturdy_silo]: { protocol: "Sturdy" },
         | 
| 126 | 
            -
                [tokenType.syncswap]: { protocol: "SyncSwap" },
         | 
| 127 | 
            -
                [tokenType.toros]: { protocol: "Toros" },
         | 
| 128 | 
            -
                [tokenType.uniswapv2]: { protocol: "Uniswap V2" },
         | 
| 129 | 
            -
                [tokenType.velodrome]: { protocol: "Velodrome V2" },
         | 
| 130 | 
            -
                [tokenType.venus]: { protocol: "Venus" },
         | 
| 131 | 
            -
                [tokenType.unknown]: { protocol: "Unknown" },
         | 
| 132 | 
            -
                [tokenType.yei_borrowing]: { protocol: "Yei Finance" },
         | 
| 133 | 
            -
                [tokenType.yei_lending]: { protocol: "Yei Finance" },
         | 
| 134 | 
            -
                [tokenType.zerolend_borrowing]: { protocol: "ZeroLend" },
         | 
| 135 | 
            -
                [tokenType.zerolend_lending]: { protocol: "ZeroLend" },
         | 
| 136 | 
            -
                [tokenType.zkswap]: { protocol: "ZKSwap" },
         | 
| 137 | 
            -
                [tokenType.rfx]: { protocol: "RFX" },
         | 
| 138 | 
            -
                [tokenType.woofi]: {
         | 
| 139 | 
            -
             | 
| 140 | 
            -
                },
         | 
| 141 | 
            -
                [tokenType. | 
| 142 | 
            -
             | 
| 143 | 
            -
                },
         | 
| 144 | 
            -
                [tokenType. | 
| 145 | 
            -
             | 
| 146 | 
            -
                },
         | 
| 147 | 
            -
                [tokenType. | 
| 148 | 
            -
             | 
| 149 | 
            -
                },
         | 
| 150 | 
            -
                [tokenType. | 
| 151 | 
            -
             | 
| 152 | 
            -
                },
         | 
| 153 | 
            -
                [tokenType. | 
| 154 | 
            -
             | 
| 155 | 
            -
                },
         | 
| 156 | 
            -
                [tokenType. | 
| 157 | 
            -
             | 
| 158 | 
            -
                },
         | 
| 159 | 
            -
                [tokenType. | 
| 160 | 
            -
             | 
| 161 | 
            -
                },
         | 
| 162 | 
            -
                [tokenType. | 
| 163 | 
            -
             | 
| 164 | 
            -
                },
         | 
| 165 | 
            -
                [tokenType. | 
| 166 | 
            -
             | 
| 167 | 
            -
                },
         | 
| 168 | 
            -
                [tokenType. | 
| 169 | 
            -
             | 
| 170 | 
            -
                },
         | 
| 171 | 
            -
                [tokenType.noLinkVault]: {
         | 
| 172 | 
            -
                    protocol: "NoLinkVault",
         | 
| 173 | 
            -
                },
         | 
| 174 | 
            -
                [tokenType.cpmmGamma]: {
         | 
| 175 | 
            -
                    protocol: "GammaSwap",
         | 
| 176 | 
            -
                },
         | 
| 177 | 
            -
                [tokenType.crosscurve]: {
         | 
| 178 | 
            -
                    protocol: "CrossCurve",
         | 
| 179 | 
            -
                },
         | 
| 180 | 
            -
                [tokenType.curveNPool]: {
         | 
| 181 | 
            -
                    protocol: "Curve",
         | 
| 182 | 
            -
                },
         | 
| 183 | 
            -
                [tokenType.vicuna]: { protocol: "Vicuna" },
         | 
| 184 | 
            -
                [tokenType.traderJoe]: { protocol: "Trader Joe" },
         | 
| 185 | 
            -
                [tokenType.avalon_lending]: { protocol: "Avalon" },
         | 
| 186 | 
            -
                [tokenType.avalon_borrowing]: { protocol: "Avalon" },
         | 
| 187 | 
            -
                [tokenType.satlayer]: { protocol: "Satlayer" },
         | 
| 188 | 
            -
                [tokenType.veda]: { protocol: "Veda" },
         | 
| 189 | 
            -
                [tokenType.superlend_borrowing]: { protocol: "Superlend" },
         | 
| 190 | 
            -
                [tokenType.superlend_lending]: { protocol: "Superlend" },
         | 
| 191 | 
            -
                [tokenType.cian]: { protocol: "Cian" },
         | 
| 192 | 
            -
                [tokenType.concrete]: { protocol: "Concrete" },
         | 
| 193 | 
            -
                [tokenType.lendle_borrowing]: { protocol: "Lendle" },
         | 
| 194 | 
            -
                [tokenType.lendle_lending]: { protocol: "Lendle" },
         | 
| 195 | 
            -
                [tokenType.takotako_borrowing]: { protocol: "TakoTako" },
         | 
| 196 | 
            -
                [tokenType.takotako_lending]: { protocol: "TakoTako" },
         | 
| 197 | 
            -
                [tokenType.equalizer_gauge]: { protocol: "Equalizer" },
         | 
| 198 | 
            -
                [tokenType.vicuna_lending]: { protocol: "Vicuna" },
         | 
| 199 | 
            -
                [tokenType.vicuna_borrowing]: { protocol: "Vicuna" },
         | 
| 89 | 
            +
                [tokenType.aave_borrowing]: { protocol: "Aave", action: OpportunityAction.BORROW },
         | 
| 90 | 
            +
                [tokenType.aave_lending]: { protocol: "Aave", action: OpportunityAction.LEND },
         | 
| 91 | 
            +
                [tokenType.aerodrome]: { protocol: "Aerodrome V2", action: OpportunityAction.POOL },
         | 
| 92 | 
            +
                [tokenType.akron]: { protocol: "Akron V2", action: OpportunityAction.POOL },
         | 
| 93 | 
            +
                [tokenType.aura]: { protocol: "Aura", action: OpportunityAction.POOL },
         | 
| 94 | 
            +
                [tokenType.balancerGauge]: { protocol: "Balancer Gauge", action: OpportunityAction.POOL },
         | 
| 95 | 
            +
                [tokenType.balancerPool]: { protocol: "Balancer Pool", action: OpportunityAction.POOL },
         | 
| 96 | 
            +
                [tokenType.baseswap]: { protocol: "Baseswap V2", action: OpportunityAction.HOLD },
         | 
| 97 | 
            +
                [tokenType.beefy]: { protocol: "Moo Velodrome V2", action: OpportunityAction.POOL },
         | 
| 98 | 
            +
                [tokenType.compound]: { protocol: "Compound", action: OpportunityAction.LEND },
         | 
| 99 | 
            +
                [tokenType.curve]: { protocol: "Curve", action: OpportunityAction.POOL },
         | 
| 100 | 
            +
                [tokenType.curve_2]: { protocol: "Curve", action: OpportunityAction.POOL },
         | 
| 101 | 
            +
                [tokenType.dragonswap]: { protocol: "Dragonswap V2", action: OpportunityAction.POOL },
         | 
| 102 | 
            +
                [tokenType.enzyme]: { protocol: "Enzyme", action: OpportunityAction.HOLD },
         | 
| 103 | 
            +
                [tokenType.euler_borrow]: { protocol: "Euler V2", action: OpportunityAction.BORROW },
         | 
| 104 | 
            +
                [tokenType.euler_lend]: { protocol: "Euler V2", action: OpportunityAction.LEND },
         | 
| 105 | 
            +
                [tokenType.fenix]: { protocol: "Fenix V2", action: OpportunityAction.HOLD },
         | 
| 106 | 
            +
                [tokenType.filament]: { protocol: "Filament", action: OpportunityAction.HOLD },
         | 
| 107 | 
            +
                [tokenType.fluid]: { protocol: "Fluid", action: OpportunityAction.LEND },
         | 
| 108 | 
            +
                [tokenType.fraxlend]: { protocol: "Fraxlend", action: OpportunityAction.LEND },
         | 
| 109 | 
            +
                [tokenType.gearbox]: { protocol: "Gearbox", action: OpportunityAction.LEND },
         | 
| 110 | 
            +
                [tokenType.ionic]: { protocol: "Ionic", action: OpportunityAction.LEND },
         | 
| 111 | 
            +
                [tokenType.ironclad_borrowing]: { protocol: "Ironclad", action: OpportunityAction.HOLD },
         | 
| 112 | 
            +
                [tokenType.ironclad_lending]: { protocol: "Ironclad", action: OpportunityAction.HOLD },
         | 
| 113 | 
            +
                [tokenType.koi]: { protocol: "Koi", action: OpportunityAction.POOL },
         | 
| 114 | 
            +
                [tokenType.layerbank]: { protocol: "Layerbank", action: OpportunityAction.LEND },
         | 
| 115 | 
            +
                [tokenType.metamorpho]: { protocol: "Metamorpho", action: OpportunityAction.HOLD },
         | 
| 116 | 
            +
                [tokenType.moonwell]: { protocol: "Moonwell", action: OpportunityAction.LEND },
         | 
| 117 | 
            +
                [tokenType.pendle]: { protocol: "Pendle", action: OpportunityAction.HOLD },
         | 
| 118 | 
            +
                [tokenType.poolside]: { protocol: "Poolside", action: OpportunityAction.POOL },
         | 
| 119 | 
            +
                [tokenType.ra]: { protocol: "Ra", action: OpportunityAction.HOLD },
         | 
| 120 | 
            +
                [tokenType.radiant_borrow]: { protocol: "Radiant", action: OpportunityAction.BORROW },
         | 
| 121 | 
            +
                [tokenType.radiant_lend]: { protocol: "Radiant", action: OpportunityAction.LEND },
         | 
| 122 | 
            +
                [tokenType.reactor_fusion]: { protocol: "Reactor Fusion", action: OpportunityAction.LEND },
         | 
| 123 | 
            +
                [tokenType.silostaking]: { protocol: "Silo Staking", action: OpportunityAction.LEND },
         | 
| 124 | 
            +
                [tokenType.splice]: { protocol: "Splice", action: OpportunityAction.HOLD },
         | 
| 125 | 
            +
                [tokenType.sturdy_aggregator]: { protocol: "Sturdy", action: OpportunityAction.LEND },
         | 
| 126 | 
            +
                [tokenType.sturdy_silo]: { protocol: "Sturdy", action: OpportunityAction.LEND },
         | 
| 127 | 
            +
                [tokenType.syncswap]: { protocol: "SyncSwap", action: OpportunityAction.POOL },
         | 
| 128 | 
            +
                [tokenType.toros]: { protocol: "Toros", action: OpportunityAction.HOLD },
         | 
| 129 | 
            +
                [tokenType.uniswapv2]: { protocol: "Uniswap V2", action: OpportunityAction.POOL },
         | 
| 130 | 
            +
                [tokenType.velodrome]: { protocol: "Velodrome V2", action: OpportunityAction.POOL },
         | 
| 131 | 
            +
                [tokenType.venus]: { protocol: "Venus", action: OpportunityAction.LEND },
         | 
| 132 | 
            +
                [tokenType.unknown]: { protocol: "Unknown", action: OpportunityAction.HOLD },
         | 
| 133 | 
            +
                [tokenType.yei_borrowing]: { protocol: "Yei Finance", action: OpportunityAction.HOLD },
         | 
| 134 | 
            +
                [tokenType.yei_lending]: { protocol: "Yei Finance", action: OpportunityAction.HOLD },
         | 
| 135 | 
            +
                [tokenType.zerolend_borrowing]: { protocol: "ZeroLend", action: OpportunityAction.BORROW },
         | 
| 136 | 
            +
                [tokenType.zerolend_lending]: { protocol: "ZeroLend", action: OpportunityAction.LEND },
         | 
| 137 | 
            +
                [tokenType.zkswap]: { protocol: "ZKSwap", action: OpportunityAction.POOL },
         | 
| 138 | 
            +
                [tokenType.rfx]: { protocol: "RFX", action: OpportunityAction.POOL },
         | 
| 139 | 
            +
                [tokenType.woofi]: { protocol: "Woofi", action: OpportunityAction.LEND },
         | 
| 140 | 
            +
                [tokenType.ironcladStaking]: { protocol: "Ironclad", action: OpportunityAction.HOLD },
         | 
| 141 | 
            +
                [tokenType.maverickBoostedPosition]: { protocol: "Maverick", action: OpportunityAction.POOL },
         | 
| 142 | 
            +
                [tokenType.zkSwapThreePool]: { protocol: "ZKSwap", action: OpportunityAction.POOL },
         | 
| 143 | 
            +
                [tokenType.maha]: { protocol: "Maha", action: OpportunityAction.HOLD },
         | 
| 144 | 
            +
                [tokenType.tempest]: { protocol: "Tempest", action: OpportunityAction.POOL },
         | 
| 145 | 
            +
                [tokenType.pendleYT]: { protocol: "Pendle", action: OpportunityAction.HOLD },
         | 
| 146 | 
            +
                [tokenType.pancakeswap]: { protocol: "PancakeSwap V2", action: OpportunityAction.POOL },
         | 
| 147 | 
            +
                [tokenType.tempestStaking]: { protocol: "Tempest", action: OpportunityAction.HOLD },
         | 
| 148 | 
            +
                [tokenType.holdstation]: { protocol: "HoldStation", action: OpportunityAction.HOLD },
         | 
| 149 | 
            +
                [tokenType.staking]: { protocol: "Staking", action: OpportunityAction.HOLD },
         | 
| 150 | 
            +
                [tokenType.noLinkVault]: { protocol: "NoLinkVault", action: OpportunityAction.HOLD },
         | 
| 151 | 
            +
                [tokenType.cpmmGamma]: { protocol: "GammaSwap", action: OpportunityAction.HOLD },
         | 
| 152 | 
            +
                [tokenType.crosscurve]: { protocol: "CrossCurve", action: OpportunityAction.POOL },
         | 
| 153 | 
            +
                [tokenType.curveNPool]: { protocol: "Curve", action: OpportunityAction.POOL },
         | 
| 154 | 
            +
                [tokenType.vicuna]: { protocol: "Vicuna", action: OpportunityAction.HOLD },
         | 
| 155 | 
            +
                [tokenType.traderJoe]: { protocol: "Trader Joe", action: OpportunityAction.HOLD },
         | 
| 156 | 
            +
                [tokenType.avalon_lending]: { protocol: "Avalon", action: OpportunityAction.HOLD },
         | 
| 157 | 
            +
                [tokenType.avalon_borrowing]: { protocol: "Avalon", action: OpportunityAction.HOLD },
         | 
| 158 | 
            +
                [tokenType.satlayer]: { protocol: "Satlayer", action: OpportunityAction.HOLD },
         | 
| 159 | 
            +
                [tokenType.veda]: { protocol: "Veda", action: OpportunityAction.HOLD },
         | 
| 160 | 
            +
                [tokenType.superlend_borrowing]: { protocol: "Superlend", action: OpportunityAction.BORROW },
         | 
| 161 | 
            +
                [tokenType.superlend_lending]: { protocol: "Superlend", action: OpportunityAction.LEND },
         | 
| 162 | 
            +
                [tokenType.cian]: { protocol: "Cian", action: OpportunityAction.HOLD },
         | 
| 163 | 
            +
                [tokenType.concrete]: { protocol: "Concrete", action: OpportunityAction.HOLD },
         | 
| 164 | 
            +
                [tokenType.lendle_borrowing]: { protocol: "Lendle", action: OpportunityAction.BORROW },
         | 
| 165 | 
            +
                [tokenType.lendle_lending]: { protocol: "Lendle", action: OpportunityAction.LEND },
         | 
| 166 | 
            +
                [tokenType.takotako_borrowing]: { protocol: "TakoTako", action: OpportunityAction.BORROW },
         | 
| 167 | 
            +
                [tokenType.takotako_lending]: { protocol: "TakoTako", action: OpportunityAction.LEND },
         | 
| 168 | 
            +
                [tokenType.equalizer_gauge]: { protocol: "Equalizer", action: OpportunityAction.HOLD },
         | 
| 169 | 
            +
                [tokenType.vicuna_lending]: { protocol: "Vicuna", action: OpportunityAction.LEND },
         | 
| 170 | 
            +
                [tokenType.vicuna_borrowing]: { protocol: "Vicuna", action: OpportunityAction.BORROW },
         | 
| 200 171 | 
             
            };
         | 
| @@ -1,22 +1,8 @@ | |
| 1 | 
            -
            import { type  | 
| 1 | 
            +
            import { type EulerVaultType } from "@sdk";
         | 
| 2 2 | 
             
            export declare enum LoggedEntityType {
         | 
| 3 3 | 
             
                EULER = "EULER_VAULT",
         | 
| 4 4 | 
             
                UNISWAP_V4 = "UNISWAP_V4"
         | 
| 5 5 | 
             
            }
         | 
| 6 | 
            -
            export type EulerVaultType = {
         | 
| 7 | 
            -
                address: string;
         | 
| 8 | 
            -
                asset: string;
         | 
| 9 | 
            -
                chainId: MerklChainId;
         | 
| 10 | 
            -
                debtTokenAddress: string;
         | 
| 11 | 
            -
                name: string;
         | 
| 12 | 
            -
                fetchedAtBlock: number;
         | 
| 13 | 
            -
                collaterals: {
         | 
| 14 | 
            -
                    address: string;
         | 
| 15 | 
            -
                    borrowLTV: string;
         | 
| 16 | 
            -
                    nameCollateral: string;
         | 
| 17 | 
            -
                    symbolCollateral: string;
         | 
| 18 | 
            -
                    symbolUnderlying: string;
         | 
| 19 | 
            -
                }[];
         | 
| 20 | 
            -
            };
         | 
| 21 6 | 
             
            export declare function getEulerV2Vaults(): Promise<EulerVaultType[]>;
         | 
| 22 7 | 
             
            export declare const getEulerV2VaultsWithCache: () => Promise<EulerVaultType[]>;
         | 
| 8 | 
            +
            export declare function updateEulerVaultsCollatInDatabase(): Promise<void>;
         | 
| @@ -5,6 +5,7 @@ import { apiDbClient } from "../../../utils/prisma"; | |
| 5 5 | 
             
            import { providers } from "../../../utils/providers";
         | 
| 6 6 | 
             
            import { ChainInteractionService, ERC20Interface, EULER_ADDRESSES, EulerEVKInterface, EulerVaultLensInterface, EulerVault__factory, NETWORK_LABELS, eulerChainIds, getContractCreationBlock, } from "@sdk";
         | 
| 7 7 | 
             
            import { getAddress } from "ethers/lib/utils";
         | 
| 8 | 
            +
            import _ from "lodash";
         | 
| 8 9 | 
             
            import { fetchEulerVaultName } from "../campaignTypes/ERC20SubTypes/helpers/eulerVaultNames";
         | 
| 9 10 | 
             
            import { safeFetchLogs } from "./fetchLogs";
         | 
| 10 11 | 
             
            export var LoggedEntityType;
         | 
| @@ -12,6 +13,79 @@ export var LoggedEntityType; | |
| 12 13 | 
             
                LoggedEntityType["EULER"] = "EULER_VAULT";
         | 
| 13 14 | 
             
                LoggedEntityType["UNISWAP_V4"] = "UNISWAP_V4";
         | 
| 14 15 | 
             
            })(LoggedEntityType || (LoggedEntityType = {}));
         | 
| 16 | 
            +
            async function computeCollatListAndReturnVaults(chainId, vaults) {
         | 
| 17 | 
            +
                let vaultsPerChain = [];
         | 
| 18 | 
            +
                /** Extra calls batch to get the collateral addresses */
         | 
| 19 | 
            +
                const resCollat = await batchMulticallCallWithRetry(chainId, {
         | 
| 20 | 
            +
                    calls: vaults
         | 
| 21 | 
            +
                        .map(vault => vault.address)
         | 
| 22 | 
            +
                        .map(vaultAddress => {
         | 
| 23 | 
            +
                        return {
         | 
| 24 | 
            +
                            allowFailure: true,
         | 
| 25 | 
            +
                            callData: EulerVaultLensInterface.encodeFunctionData("getRecognizedCollateralsLTVInfo", [vaultAddress]),
         | 
| 26 | 
            +
                            target: EULER_ADDRESSES[chainId].VAULT_LENS,
         | 
| 27 | 
            +
                        };
         | 
| 28 | 
            +
                    }),
         | 
| 29 | 
            +
                });
         | 
| 30 | 
            +
                const callsCollatUnderlying = [];
         | 
| 31 | 
            +
                const callsCollatUnderlyingSymbol = [];
         | 
| 32 | 
            +
                for (const [index, vault] of vaults.entries()) {
         | 
| 33 | 
            +
                    const collatArray = EulerVaultLensInterface.decodeFunctionResult("getRecognizedCollateralsLTVInfo", resCollat[index].returnData)[0];
         | 
| 34 | 
            +
                    for (const collat of collatArray) {
         | 
| 35 | 
            +
                        if (!!vault.collaterals &&
         | 
| 36 | 
            +
                            vault.collaterals.map(c => c.address.toLowerCase()).includes(collat.collateral.toLowerCase()))
         | 
| 37 | 
            +
                            continue;
         | 
| 38 | 
            +
                        log.info(`🦭 found new collateral ${collat.collateral} for vault ${vault.address} (${NETWORK_LABELS[chainId]})`);
         | 
| 39 | 
            +
                        callsCollatUnderlying.push({
         | 
| 40 | 
            +
                            allowFailure: true,
         | 
| 41 | 
            +
                            callData: EulerEVKInterface.encodeFunctionData("asset"),
         | 
| 42 | 
            +
                            target: collat.collateral,
         | 
| 43 | 
            +
                        }, {
         | 
| 44 | 
            +
                            allowFailure: true,
         | 
| 45 | 
            +
                            callData: EulerEVKInterface.encodeFunctionData("symbol"),
         | 
| 46 | 
            +
                            target: collat.collateral,
         | 
| 47 | 
            +
                        });
         | 
| 48 | 
            +
                    }
         | 
| 49 | 
            +
                }
         | 
| 50 | 
            +
                const resCollatUnderlying = await batchMulticallCallWithRetry(chainId, {
         | 
| 51 | 
            +
                    calls: callsCollatUnderlying,
         | 
| 52 | 
            +
                });
         | 
| 53 | 
            +
                for (let i = 0; i < resCollatUnderlying.length; i = i + 2) {
         | 
| 54 | 
            +
                    const underlyingToken = EulerEVKInterface.decodeFunctionResult("asset", resCollatUnderlying[i].returnData)[0];
         | 
| 55 | 
            +
                    callsCollatUnderlyingSymbol.push({
         | 
| 56 | 
            +
                        allowFailure: true,
         | 
| 57 | 
            +
                        callData: ERC20Interface.encodeFunctionData("symbol"),
         | 
| 58 | 
            +
                        target: underlyingToken,
         | 
| 59 | 
            +
                    });
         | 
| 60 | 
            +
                }
         | 
| 61 | 
            +
                const resCollatUnderlyingSymbol = await batchMulticallCallWithRetry(chainId, {
         | 
| 62 | 
            +
                    calls: callsCollatUnderlyingSymbol,
         | 
| 63 | 
            +
                });
         | 
| 64 | 
            +
                vaultsPerChain = vaultsPerChain.concat((await Promise.all(vaults.map(async (vault, index) => {
         | 
| 65 | 
            +
                    const collatArray = EulerVaultLensInterface.decodeFunctionResult("getRecognizedCollateralsLTVInfo", resCollat[index].returnData)[0];
         | 
| 66 | 
            +
                    if (!vault.collaterals)
         | 
| 67 | 
            +
                        vault.collaterals = [];
         | 
| 68 | 
            +
                    let offset = 0;
         | 
| 69 | 
            +
                    for (const [_index, collat] of collatArray.entries()) {
         | 
| 70 | 
            +
                        // _ Check whether the collat was already registered
         | 
| 71 | 
            +
                        if (!!vault.collaterals &&
         | 
| 72 | 
            +
                            vault.collaterals.map(c => c.address.toLowerCase()).includes(collat.collateral.toLowerCase())) {
         | 
| 73 | 
            +
                            offset += 1;
         | 
| 74 | 
            +
                            continue;
         | 
| 75 | 
            +
                        }
         | 
| 76 | 
            +
                        const symbolUnderlying = ERC20Interface.decodeFunctionResult("symbol", resCollatUnderlyingSymbol[_index - offset].returnData)[0];
         | 
| 77 | 
            +
                        vault.collaterals.push({
         | 
| 78 | 
            +
                            address: collat.collateral,
         | 
| 79 | 
            +
                            symbolCollateral: EulerEVKInterface.decodeFunctionResult("symbol", resCollatUnderlying[2 * (_index - offset) + 1].returnData)[0],
         | 
| 80 | 
            +
                            symbolUnderlying,
         | 
| 81 | 
            +
                            borrowLTV: collat.borrowLTV.toString(),
         | 
| 82 | 
            +
                            nameCollateral: (await fetchEulerVaultName(collat.collateral, chainId)) ?? symbolUnderlying,
         | 
| 83 | 
            +
                        });
         | 
| 84 | 
            +
                    }
         | 
| 85 | 
            +
                    return { ...vault };
         | 
| 86 | 
            +
                }))));
         | 
| 87 | 
            +
                return vaultsPerChain;
         | 
| 88 | 
            +
            }
         | 
| 15 89 | 
             
            export async function getEulerV2Vaults() {
         | 
| 16 90 | 
             
                let vaults = [];
         | 
| 17 91 | 
             
                // 0_ Fetch all euler vaults from database
         | 
| @@ -53,61 +127,7 @@ export async function getEulerV2Vaults() { | |
| 53 127 | 
             
                            };
         | 
| 54 128 | 
             
                        }));
         | 
| 55 129 | 
             
                        log.local(`fetched ${decodedVaults.length} vaults(s) on ${NETWORK_LABELS[chainId]} between blocks ${fromBlock} and ${toBlock}`);
         | 
| 56 | 
            -
                         | 
| 57 | 
            -
                        const resCollat = await batchMulticallCallWithRetry(chainId, {
         | 
| 58 | 
            -
                            calls: decodedVaults.map(vault => {
         | 
| 59 | 
            -
                                return {
         | 
| 60 | 
            -
                                    allowFailure: true,
         | 
| 61 | 
            -
                                    callData: EulerVaultLensInterface.encodeFunctionData("getRecognizedCollateralsLTVInfo", [vault.address]),
         | 
| 62 | 
            -
                                    target: EULER_ADDRESSES[chainId].VAULT_LENS,
         | 
| 63 | 
            -
                                };
         | 
| 64 | 
            -
                            }),
         | 
| 65 | 
            -
                        });
         | 
| 66 | 
            -
                        const callsCollatUnderlying = [];
         | 
| 67 | 
            -
                        const callsCollatUnderlyingSymbol = [];
         | 
| 68 | 
            -
                        for (const [index, _] of decodedVaults.entries()) {
         | 
| 69 | 
            -
                            const collatArray = EulerVaultLensInterface.decodeFunctionResult("getRecognizedCollateralsLTVInfo", resCollat[index].returnData)[0];
         | 
| 70 | 
            -
                            for (const collat of collatArray) {
         | 
| 71 | 
            -
                                callsCollatUnderlying.push({
         | 
| 72 | 
            -
                                    allowFailure: true,
         | 
| 73 | 
            -
                                    callData: EulerEVKInterface.encodeFunctionData("asset"),
         | 
| 74 | 
            -
                                    target: collat.collateral,
         | 
| 75 | 
            -
                                }, {
         | 
| 76 | 
            -
                                    allowFailure: true,
         | 
| 77 | 
            -
                                    callData: EulerEVKInterface.encodeFunctionData("symbol"),
         | 
| 78 | 
            -
                                    target: collat.collateral,
         | 
| 79 | 
            -
                                });
         | 
| 80 | 
            -
                            }
         | 
| 81 | 
            -
                        }
         | 
| 82 | 
            -
                        const resCollatUnderlying = await batchMulticallCallWithRetry(chainId, {
         | 
| 83 | 
            -
                            calls: callsCollatUnderlying,
         | 
| 84 | 
            -
                        });
         | 
| 85 | 
            -
                        for (let i = 0; i < resCollatUnderlying.length; i = i + 2) {
         | 
| 86 | 
            -
                            const underlyingToken = EulerEVKInterface.decodeFunctionResult("asset", resCollatUnderlying[i].returnData)[0];
         | 
| 87 | 
            -
                            callsCollatUnderlyingSymbol.push({
         | 
| 88 | 
            -
                                allowFailure: true,
         | 
| 89 | 
            -
                                callData: ERC20Interface.encodeFunctionData("symbol"),
         | 
| 90 | 
            -
                                target: underlyingToken,
         | 
| 91 | 
            -
                            });
         | 
| 92 | 
            -
                        }
         | 
| 93 | 
            -
                        const resCollatUnderlyingSymbol = await batchMulticallCallWithRetry(chainId, {
         | 
| 94 | 
            -
                            calls: callsCollatUnderlyingSymbol,
         | 
| 95 | 
            -
                        });
         | 
| 96 | 
            -
                        vaultsPerChain = vaultsPerChain.concat((await Promise.all(decodedVaults.map(async (decodedVault, index) => {
         | 
| 97 | 
            -
                            const collatArray = EulerVaultLensInterface.decodeFunctionResult("getRecognizedCollateralsLTVInfo", resCollat[index].returnData)[0];
         | 
| 98 | 
            -
                            const collaterals = [];
         | 
| 99 | 
            -
                            for (const [_index, collat] of collatArray.entries()) {
         | 
| 100 | 
            -
                                const symbolUnderlying = ERC20Interface.decodeFunctionResult("symbol", resCollatUnderlyingSymbol[_index].returnData)[0];
         | 
| 101 | 
            -
                                collaterals.push({
         | 
| 102 | 
            -
                                    address: collat.collateral,
         | 
| 103 | 
            -
                                    symbolCollateral: EulerEVKInterface.decodeFunctionResult("symbol", resCollatUnderlying[2 * _index + 1].returnData)[0],
         | 
| 104 | 
            -
                                    symbolUnderlying,
         | 
| 105 | 
            -
                                    borrowLTV: collat.borrowLTV.toString(),
         | 
| 106 | 
            -
                                    nameCollateral: (await fetchEulerVaultName(collat.collateral, chainId)) ?? symbolUnderlying,
         | 
| 107 | 
            -
                                });
         | 
| 108 | 
            -
                            }
         | 
| 109 | 
            -
                            return { ...decodedVault, collaterals };
         | 
| 110 | 
            -
                        }))));
         | 
| 130 | 
            +
                        vaultsPerChain = await computeCollatListAndReturnVaults(chainId, decodedVaults);
         | 
| 111 131 | 
             
                        return vaultsPerChain;
         | 
| 112 132 | 
             
                    }
         | 
| 113 133 | 
             
                    catch (e) {
         | 
| @@ -140,8 +160,7 @@ export async function getEulerV2Vaults() { | |
| 140 160 | 
             
                        throw new Error("Error while saving vaults to API database (`Logged` table)");
         | 
| 141 161 | 
             
                    }
         | 
| 142 162 | 
             
                }
         | 
| 143 | 
            -
                log.info("✅ successfully fetched vaults on Euler V2");
         | 
| 144 | 
            -
                // FIXME _ Merge previoulsy stored vaults with newly fetched ones
         | 
| 163 | 
            +
                log.info("✅ successfully fetched new vaults on Euler V2");
         | 
| 145 164 | 
             
                if (storedVaults.length > 0) {
         | 
| 146 165 | 
             
                    vaults = vaults.concat(storedVaults.map(v => v.entityData));
         | 
| 147 166 | 
             
                }
         | 
| @@ -149,3 +168,42 @@ export async function getEulerV2Vaults() { | |
| 149 168 | 
             
                return vaults;
         | 
| 150 169 | 
             
            }
         | 
| 151 170 | 
             
            export const getEulerV2VaultsWithCache = async () => await Redis.getOrSet("EulerV2Vaults", getEulerV2Vaults);
         | 
| 171 | 
            +
            export async function updateEulerVaultsCollatInDatabase() {
         | 
| 172 | 
            +
                // 0_ Fetch all euler vaults from database
         | 
| 173 | 
            +
                const vaults = await apiDbClient.logged.findMany({
         | 
| 174 | 
            +
                    where: { type: LoggedEntityType.EULER },
         | 
| 175 | 
            +
                });
         | 
| 176 | 
            +
                const clonedVaults = _.cloneDeep(vaults);
         | 
| 177 | 
            +
                let toUpdateVaults = [];
         | 
| 178 | 
            +
                // 1_ Return all vaults already stored with their collateral updated
         | 
| 179 | 
            +
                const res = await Promise.all(eulerChainIds.map(async (chainId) => computeCollatListAndReturnVaults(chainId, clonedVaults.filter(entity => entity.chainId === chainId).map(entity => entity.entityData))));
         | 
| 180 | 
            +
                for (const resPerChain of res) {
         | 
| 181 | 
            +
                    if (!!resPerChain && resPerChain.length > 0) {
         | 
| 182 | 
            +
                        toUpdateVaults = toUpdateVaults.concat(resPerChain.filter(updatedVault => {
         | 
| 183 | 
            +
                            return (updatedVault.collaterals.length >
         | 
| 184 | 
            +
                                vaults.find(vault => vault.address?.toLowerCase() === updatedVault.address.toLowerCase())
         | 
| 185 | 
            +
                                    ?.entityData?.collaterals.length);
         | 
| 186 | 
            +
                        }));
         | 
| 187 | 
            +
                    }
         | 
| 188 | 
            +
                }
         | 
| 189 | 
            +
                // 2_ Update the API database
         | 
| 190 | 
            +
                if (toUpdateVaults.length > 0) {
         | 
| 191 | 
            +
                    try {
         | 
| 192 | 
            +
                        for (const vault of toUpdateVaults) {
         | 
| 193 | 
            +
                            await apiDbClient.logged.updateMany({
         | 
| 194 | 
            +
                                where: {
         | 
| 195 | 
            +
                                    address: vault.address,
         | 
| 196 | 
            +
                                    chainId: vault.chainId,
         | 
| 197 | 
            +
                                },
         | 
| 198 | 
            +
                                data: {
         | 
| 199 | 
            +
                                    entityData: vault,
         | 
| 200 | 
            +
                                },
         | 
| 201 | 
            +
                            });
         | 
| 202 | 
            +
                        }
         | 
| 203 | 
            +
                        log.info(`✅ successfully updated ${toUpdateVaults.length} vault(s) collaterals in API database ('Logged' table)`);
         | 
| 204 | 
            +
                    }
         | 
| 205 | 
            +
                    catch {
         | 
| 206 | 
            +
                        throw new Error("Error while updating vaults to API database (`Logged` table)");
         | 
| 207 | 
            +
                    }
         | 
| 208 | 
            +
                }
         | 
| 209 | 
            +
            }
         | 
| @@ -2,7 +2,7 @@ import type { UploadOptions } from "./bucket.model"; | |
| 2 2 | 
             
            export declare class BucketService {
         | 
| 3 3 | 
             
                #private;
         | 
| 4 4 | 
             
                defaultUploadOptions: UploadOptions<unknown>;
         | 
| 5 | 
            -
                constructor(bucket: string);
         | 
| 5 | 
            +
                constructor(bucket: string, projectId: string);
         | 
| 6 6 | 
             
                pushArray<T>(filename: string, arr: T[], options?: UploadOptions<T>): Promise<number>;
         | 
| 7 7 | 
             
                push(filename: string, text: string, options?: Omit<UploadOptions<never>, "transform">): Promise<number>;
         | 
| 8 8 | 
             
                pullArray<T>(filename: string, callback: (elem: string) => T, separator?: string): Promise<T[]>;
         | 
| @@ -17,14 +17,14 @@ export class BucketService { | |
| 17 17 | 
             
                    separator: "\n",
         | 
| 18 18 | 
             
                };
         | 
| 19 19 | 
             
                // ─── Constructor ─────────────────────────────────────────────────────
         | 
| 20 | 
            -
                constructor(bucket) {
         | 
| 20 | 
            +
                constructor(bucket, projectId) {
         | 
| 21 21 | 
             
                    this.#s3Client = new S3Client({
         | 
| 22 22 | 
             
                        accessKeyId: process.env.GCS_ACCESS_ID,
         | 
| 23 23 | 
             
                        secretAccessKey: process.env.GCS_SECRET,
         | 
| 24 24 | 
             
                        endpoint: process.env.GCS_ENDPOINT,
         | 
| 25 25 | 
             
                        bucket,
         | 
| 26 26 | 
             
                    });
         | 
| 27 | 
            -
                    this.#gcsBucket = new Storage().bucket(bucket);
         | 
| 27 | 
            +
                    this.#gcsBucket = new Storage({ projectId }).bucket(bucket);
         | 
| 28 28 | 
             
                    this.#encoder = new TextEncoder();
         | 
| 29 29 | 
             
                    this.#decoder = new TextDecoder();
         | 
| 30 30 | 
             
                }
         | 
| @@ -52,7 +52,7 @@ export class BucketService { | |
| 52 52 | 
             
                        data = gzipSync(data);
         | 
| 53 53 | 
             
                    // ─── ReadableStream Initialization From Blob ─────────────────
         | 
| 54 54 | 
             
                    const blob = new Blob([data]);
         | 
| 55 | 
            -
                    const stream = blob.stream( | 
| 55 | 
            +
                    const stream = blob.stream();
         | 
| 56 56 | 
             
                    const reader = stream.getReader();
         | 
| 57 57 | 
             
                    // ─── Start Writing Data To Bucket ────────────────────────────
         | 
| 58 58 | 
             
                    if (options.overwrite && (await file.exists()))
         | 
| @@ -74,7 +74,7 @@ export class BucketService { | |
| 74 74 | 
             
                    if (options.compression)
         | 
| 75 75 | 
             
                        await this.#gcsBucket.file(filename).setMetadata({ contentEncoding: "gzip" });
         | 
| 76 76 | 
             
                    if (options.isPublic)
         | 
| 77 | 
            -
                        await this.#gcsBucket.makePublic();
         | 
| 77 | 
            +
                        await this.#gcsBucket.file(filename).makePublic();
         | 
| 78 78 | 
             
                    // ─── Return The Number Of Bytes Written ──────────────────────
         | 
| 79 79 | 
             
                    return bytes;
         | 
| 80 80 | 
             
                }
         | 
| @@ -92,7 +92,7 @@ export class BucketService { | |
| 92 92 | 
             
                        type: options.type,
         | 
| 93 93 | 
             
                    });
         | 
| 94 94 | 
             
                    const blob = new Blob([data]);
         | 
| 95 | 
            -
                    const stream = blob.stream( | 
| 95 | 
            +
                    const stream = blob.stream();
         | 
| 96 96 | 
             
                    const reader = stream.getReader();
         | 
| 97 97 | 
             
                    if (options.overwrite && (await file.exists()))
         | 
| 98 98 | 
             
                        await file.delete();
         | 
| @@ -114,7 +114,7 @@ export class BucketService { | |
| 114 114 | 
             
                    if (options.compression)
         | 
| 115 115 | 
             
                        await this.#gcsBucket.file(filename).setMetadata({ contentEncoding: "gzip" });
         | 
| 116 116 | 
             
                    if (options.isPublic)
         | 
| 117 | 
            -
                        await this.#gcsBucket.makePublic();
         | 
| 117 | 
            +
                        await this.#gcsBucket.file(filename).makePublic();
         | 
| 118 118 | 
             
                    // ─── Return The Number Of Bytes Written ──────────────────────
         | 
| 119 119 | 
             
                    return bytes;
         | 
| 120 120 | 
             
                }
         | 
| @@ -18,7 +18,7 @@ export const getErc20Metadata = async (computeChainId, distributionChainId, camp | |
| 18 18 | 
             
                            campaignParameters: params,
         | 
| 19 19 | 
             
                        },
         | 
| 20 20 | 
             
                    ]);
         | 
| 21 | 
            -
                    action =  | 
| 21 | 
            +
                    action = dynamicData?.typeInfo?.action;
         | 
| 22 22 | 
             
                    name = dynamicData?.typeInfo?.cardName;
         | 
| 23 23 | 
             
                    mainProtocolId = dynamicData?.typeInfo?.protocol?.toLowerCase().replace(" ", "");
         | 
| 24 24 | 
             
                    const protocol = (await ProtocolService.findMany({ id: mainProtocolId }))?.[0];
         |