@merkl/api 0.17.24 → 0.17.26
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/libs/campaigns/campaignTypes/EventBasedDynamicData.d.ts +3 -0
- package/dist/src/libs/campaigns/campaignTypes/EventBasedDynamicData.js +117 -0
- package/dist/src/libs/campaigns/campaignsDynamicData.js +5 -0
- package/dist/src/modules/v4/opportunity/opportunity.service.js +3 -0
- package/dist/src/modules/v4/opportunity/subservices/getEventBasedMetadata.service.ts.d.ts +3 -0
- package/dist/src/modules/v4/opportunity/subservices/getEventBasedMetadata.service.ts.js +43 -0
- package/dist/tsconfig.package.tsbuildinfo +1 -1
- package/package.json +1 -1
@@ -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 EventBasedDynamicData(chainId: MerklChainId, campaigns: CampaignParameters<Campaign.EVENT_BASED>[]): Promise<UncachedResult<Partial<CampaignDynamicData<Campaign.EVENT_BASED>[]>>>;
|
@@ -0,0 +1,117 @@
|
|
1
|
+
import { BucketService } from "../../../modules/v4/bucket/bucket.service";
|
2
|
+
import { engineDbClient } from "../../../utils/prisma";
|
3
|
+
import { BN2Number, ChainInteractionService, NETWORK_LABELS, } from "@sdk";
|
4
|
+
import moment from "moment";
|
5
|
+
import { log } from "../../../utils/logger";
|
6
|
+
import { Pricer } from "../../../utils/pricer";
|
7
|
+
// Constants
|
8
|
+
const CALLS_LENGTH = 2;
|
9
|
+
/**
|
10
|
+
* Compute TVL
|
11
|
+
* @dev important: using the most recent state save with current prices
|
12
|
+
* it's only an estimate
|
13
|
+
*/
|
14
|
+
async function computeEventBasedPoolTVLFromMostRecentStateSave(chainId, campaignID, priceCurrency, decimalsCurrency) {
|
15
|
+
let stateSave;
|
16
|
+
let blockNumber;
|
17
|
+
let states = {};
|
18
|
+
try {
|
19
|
+
const currentBlock = await ChainInteractionService(chainId).getBlockNumber();
|
20
|
+
const mostRecentStateSave = await engineDbClient.stateSave.findFirst({
|
21
|
+
where: {
|
22
|
+
id: `EventBasedProcessor_${chainId}_${campaignID}`,
|
23
|
+
blockNumber: {
|
24
|
+
lte: currentBlock,
|
25
|
+
},
|
26
|
+
},
|
27
|
+
orderBy: {
|
28
|
+
blockNumber: "desc",
|
29
|
+
},
|
30
|
+
});
|
31
|
+
stateSave = mostRecentStateSave.state;
|
32
|
+
blockNumber = mostRecentStateSave?.blockNumber;
|
33
|
+
states = stateSave.states;
|
34
|
+
// const globalState = stateSave.globalState as { tick: number; liquidity: string };
|
35
|
+
}
|
36
|
+
catch (e) {
|
37
|
+
log.warn(`merklDynamic data - failed to read a recent state of ${campaignID} on ${NETWORK_LABELS[chainId]}`);
|
38
|
+
}
|
39
|
+
const { fileName, bucketName } = states;
|
40
|
+
// Bucket service
|
41
|
+
let tvl = 0;
|
42
|
+
try {
|
43
|
+
const bucket = new BucketService(bucketName, "merkl-production");
|
44
|
+
const storedStates = JSON.parse(await bucket.pull(fileName));
|
45
|
+
for (const [_, { value, params: _params }] of Object.entries(storedStates)) {
|
46
|
+
tvl += priceCurrency * BN2Number(value.allTimeValue, decimalsCurrency);
|
47
|
+
}
|
48
|
+
}
|
49
|
+
catch (e) {
|
50
|
+
console.log(e);
|
51
|
+
log.warn(`merklDynamic data - failed to decode state of event based on ${NETWORK_LABELS[chainId]}`);
|
52
|
+
}
|
53
|
+
return { tvl, blockNumber: blockNumber };
|
54
|
+
}
|
55
|
+
export async function EventBasedDynamicData(chainId, campaigns) {
|
56
|
+
const dynamicData = [];
|
57
|
+
const pricer = await Pricer.load();
|
58
|
+
const calls = [];
|
59
|
+
return {
|
60
|
+
cached: false,
|
61
|
+
call: {
|
62
|
+
callData: calls,
|
63
|
+
handler: () => { },
|
64
|
+
reducer: async (result) => {
|
65
|
+
for (const campaign of campaigns) {
|
66
|
+
try {
|
67
|
+
const decimalsCurrency0 = 6;
|
68
|
+
const symbolCurrency0 = "USDC";
|
69
|
+
const priceToken = (await pricer.get({
|
70
|
+
chainId: chainId,
|
71
|
+
symbol: symbolCurrency0,
|
72
|
+
}));
|
73
|
+
const { tvl, blockNumber } = await computeEventBasedPoolTVLFromMostRecentStateSave(chainId, campaign.campaignId, priceToken, decimalsCurrency0);
|
74
|
+
const c = campaign;
|
75
|
+
const amount = BN2Number(c.amount, c.campaignParameters.decimalsRewardToken);
|
76
|
+
const multiplier = BN2Number(c.campaignParameters.topicToData[0].multiplier, 9);
|
77
|
+
const startTimestamp = BN2Number(c.startTimestamp, 0);
|
78
|
+
const endTimestamp = BN2Number(c.endTimestamp, 0);
|
79
|
+
const isLive = moment().unix() > startTimestamp && moment().unix() < endTimestamp;
|
80
|
+
let distributionMeanAPR = 0;
|
81
|
+
const priceRewardToken = 1;
|
82
|
+
if (isLive && c.campaignParameters.symbolRewardToken !== "aglaMerkl") {
|
83
|
+
/**
|
84
|
+
* Handle whitelisted/blacklisted addresses to compute APR
|
85
|
+
*/
|
86
|
+
if (c.campaignParameters.whitelist.length > 0) {
|
87
|
+
// TODO
|
88
|
+
}
|
89
|
+
else if (c.campaignParameters.blacklist.length > 0) {
|
90
|
+
// TODO
|
91
|
+
}
|
92
|
+
/** Yearly rewards in $ */
|
93
|
+
const yearlyTokenRewards = (multiplier * priceRewardToken * amount * (365 * 24 * 3_600)) / (endTimestamp - startTimestamp);
|
94
|
+
distributionMeanAPR = yearlyTokenRewards / tvl;
|
95
|
+
distributionMeanAPR = !distributionMeanAPR || Number.isNaN(distributionMeanAPR) ? 0 : distributionMeanAPR;
|
96
|
+
dynamicData.push({
|
97
|
+
...campaign,
|
98
|
+
apr: distributionMeanAPR,
|
99
|
+
priceRewardToken: priceRewardToken,
|
100
|
+
tvl: tvl,
|
101
|
+
});
|
102
|
+
}
|
103
|
+
}
|
104
|
+
catch (e) {
|
105
|
+
dynamicData.push({
|
106
|
+
...campaign,
|
107
|
+
apr: 0,
|
108
|
+
priceRewardToken: 0,
|
109
|
+
tvl: 1,
|
110
|
+
});
|
111
|
+
}
|
112
|
+
}
|
113
|
+
return dynamicData;
|
114
|
+
},
|
115
|
+
},
|
116
|
+
};
|
117
|
+
}
|
@@ -10,6 +10,7 @@ import { ERC20DynamicData } from "./campaignTypes/ERC20DynamicData";
|
|
10
10
|
import { ERC20_SNAPSHOTDynamicData } from "./campaignTypes/ERC20_SNAPSHOTDynamicData";
|
11
11
|
import { EigenLayerDynamicData } from "./campaignTypes/EigenLayerDynamicData";
|
12
12
|
import { EncompassingDynamicData } from "./campaignTypes/EncompassingDynamicData";
|
13
|
+
import { EventBasedDynamicData } from "./campaignTypes/EventBasedDynamicData";
|
13
14
|
import { HyperdriveDynamicData } from "./campaignTypes/HyperdriveDynamicData";
|
14
15
|
import { JSON_AIRDROPDynamicData } from "./campaignTypes/JSON_AIRDROPDynamicData";
|
15
16
|
import { MORPHODynamicData } from "./campaignTypes/MORPHODynamicData";
|
@@ -112,6 +113,10 @@ export async function campaignsDynamicData(chainId, campaigns, type) {
|
|
112
113
|
case Campaign.ENCOMPASSING: {
|
113
114
|
return EncompassingDynamicData(chainId, campaigns);
|
114
115
|
}
|
116
|
+
case "EVENT_BASED":
|
117
|
+
case Campaign.EVENT_BASED: {
|
118
|
+
return EventBasedDynamicData(chainId, campaigns);
|
119
|
+
}
|
115
120
|
}
|
116
121
|
return {
|
117
122
|
cached: false,
|
@@ -22,6 +22,7 @@ import { getEncompassingMetadata } from "./subservices/getEncompassingMetadata.s
|
|
22
22
|
import { getErc20Metadata } from "./subservices/getErc20Metadata.service";
|
23
23
|
import { getErc20SnapshotMetadata } from "./subservices/getErc20SnapshotMetadata.service";
|
24
24
|
import { getEulerMetadata } from "./subservices/getEulerMetadata.service";
|
25
|
+
import { getEventBasedMetadata } from "./subservices/getEventBasedMetadata.service.ts";
|
25
26
|
import { getHyperdriveMetadata } from "./subservices/getHyperdriveMetadata.service";
|
26
27
|
import { getJsonAirdropMetadata } from "./subservices/getJsonAirDropMetadata.service";
|
27
28
|
import { getMorphoMetadata } from "./subservices/getMorphoMetadata.service";
|
@@ -99,6 +100,8 @@ export class OpportunityService {
|
|
99
100
|
return getUniswapV4Metadata(chainId, campaignParams);
|
100
101
|
case "ENCOMPASSING":
|
101
102
|
return getEncompassingMetadata(chainId, campaign.rewardTokenAddress, campaignParams);
|
103
|
+
case "EVENT_BASED":
|
104
|
+
return getEventBasedMetadata(chainId, campaign.computeChainId, campaign.campaignId, campaign.rewardTokenAddress, campaign.amount, campaignParams);
|
102
105
|
case "INVALID":
|
103
106
|
return {
|
104
107
|
name: "Invalid Campaigns",
|
@@ -0,0 +1,3 @@
|
|
1
|
+
import type { OpportunityMetadata } from "..";
|
2
|
+
import type { ChainId, EventBasedCampaign } from "@sdk";
|
3
|
+
export declare const getEventBasedMetadata: (computeChainId: ChainId, _distributionChainId: ChainId, _campaignId: string, _rewardToken: string, _amount: string, params: EventBasedCampaign["campaignParameters"]) => Promise<OpportunityMetadata>;
|
@@ -0,0 +1,43 @@
|
|
1
|
+
export const getEventBasedMetadata = async (computeChainId, _distributionChainId, _campaignId, _rewardToken, _amount, params) => {
|
2
|
+
try {
|
3
|
+
const action = "INVALID";
|
4
|
+
const mainProtocolId = "Hanji";
|
5
|
+
let name = `${params.eventID.split("(")[0]} on ${mainProtocolId}`;
|
6
|
+
let tokens = [{ chainId: computeChainId, address: params.contract }];
|
7
|
+
if (params.contract === "0xd0bc067cf877f7b76ceb331891331d9e6acda1a7") {
|
8
|
+
name = `Trade USDC/XTZ on ${mainProtocolId}`;
|
9
|
+
tokens = [
|
10
|
+
{ chainId: computeChainId, address: "0x796Ea11Fa2dD751eD01b53C372fFDB4AAa8f00F9" },
|
11
|
+
{ chainId: computeChainId, address: "0xc9B53AB2679f573e480d01e0f49e2B5CFB7a3EAb" },
|
12
|
+
];
|
13
|
+
}
|
14
|
+
if (params.contract === "0x65ea4dd7f789c71c0f57ed84b3bdc3062898d3cb") {
|
15
|
+
name = `Trade USDC/ETH on ${mainProtocolId}`;
|
16
|
+
tokens = [
|
17
|
+
{ chainId: computeChainId, address: "0x796Ea11Fa2dD751eD01b53C372fFDB4AAa8f00F9" },
|
18
|
+
{ chainId: computeChainId, address: "0xfc24f770F94edBca6D6f885E12d4317320BcB401" },
|
19
|
+
];
|
20
|
+
}
|
21
|
+
if (params.contract === "0xbb6b01d94e3f6ebae8647cb56d544f57928ab758") {
|
22
|
+
name = `Trade USDC/BTC on ${mainProtocolId}`;
|
23
|
+
tokens = [
|
24
|
+
{ chainId: computeChainId, address: "0x796Ea11Fa2dD751eD01b53C372fFDB4AAa8f00F9" },
|
25
|
+
{ chainId: computeChainId, address: "0xbFc94CD2B1E55999Cfc7347a9313e88702B83d0F" },
|
26
|
+
];
|
27
|
+
}
|
28
|
+
return {
|
29
|
+
action,
|
30
|
+
name,
|
31
|
+
tokens,
|
32
|
+
mainProtocol: mainProtocolId,
|
33
|
+
};
|
34
|
+
}
|
35
|
+
catch (error) {
|
36
|
+
return {
|
37
|
+
action: "INVALID",
|
38
|
+
name: "Event Based Campaign",
|
39
|
+
tokens: [],
|
40
|
+
mainProtocol: undefined,
|
41
|
+
};
|
42
|
+
}
|
43
|
+
};
|