@merkl/api 0.21.28 → 0.21.29
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/engine/implementations/Erc20/subTypes/factories.js +10 -12
- package/dist/src/engine/implementations/Erc20/subTypes/implementations/aave/metadata.d.ts +30 -0
- package/dist/src/engine/implementations/Erc20/subTypes/implementations/{superlend → aave}/metadata.js +21 -4
- package/dist/src/engine/implementations/Erc20/subTypes/implementations/{dlend → aave}/tvl.d.ts +1 -1
- package/dist/src/engine/implementations/Erc20/subTypes/implementations/{dlend → aave}/tvl.js +1 -1
- package/dist/src/engine/implementations/UniswapV4/tvl.js +49 -13
- package/dist/tsconfig.package.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/dist/src/engine/implementations/Erc20/subTypes/implementations/dlend/metadata.d.ts +0 -17
- package/dist/src/engine/implementations/Erc20/subTypes/implementations/dlend/metadata.js +0 -29
- package/dist/src/engine/implementations/Erc20/subTypes/implementations/superlend/metadata.d.ts +0 -17
- package/dist/src/engine/implementations/Erc20/subTypes/implementations/superlend/tvl.d.ts +0 -6
- package/dist/src/engine/implementations/Erc20/subTypes/implementations/superlend/tvl.js +0 -51
@@ -1,14 +1,12 @@
|
|
1
1
|
import { Erc20SubType } from ".";
|
2
|
-
import {
|
3
|
-
import {
|
2
|
+
import { AaveMetadata } from "./implementations/aave/metadata";
|
3
|
+
import { AaveTVLBuilder } from "./implementations/aave/tvl";
|
4
4
|
import { EulerMetadata } from "./implementations/euler/metadata";
|
5
5
|
import { EulerTVLBuilder } from "./implementations/euler/tvl";
|
6
6
|
import { GearboxMetadata } from "./implementations/gearbox/metadata";
|
7
7
|
import { GearboxTVLBuilder } from "./implementations/gearbox/tvl";
|
8
8
|
import { LendleMetadata } from "./implementations/lendleVaults/metadata";
|
9
9
|
import { LendleTVLBuilder } from "./implementations/lendleVaults/tvl";
|
10
|
-
import { SuperlendMetadata } from "./implementations/superlend/metadata";
|
11
|
-
import { SuperlendTVLBuilder } from "./implementations/superlend/tvl";
|
12
10
|
import { TermMaxMetadata } from "./implementations/termmax/metadata";
|
13
11
|
import { TermMaxTVLBuilder } from "./implementations/termmax/tvl";
|
14
12
|
/**
|
@@ -19,14 +17,14 @@ import { TermMaxTVLBuilder } from "./implementations/termmax/tvl";
|
|
19
17
|
*/
|
20
18
|
const tvlMap = {
|
21
19
|
[Erc20SubType.gearbox]: new GearboxTVLBuilder(),
|
22
|
-
[Erc20SubType.superlend_borrowing]: new
|
23
|
-
[Erc20SubType.superlend_lending]: new
|
20
|
+
[Erc20SubType.superlend_borrowing]: new AaveTVLBuilder(),
|
21
|
+
[Erc20SubType.superlend_lending]: new AaveTVLBuilder(),
|
24
22
|
[Erc20SubType.euler_borrow]: new EulerTVLBuilder(),
|
25
23
|
[Erc20SubType.euler_lend]: new EulerTVLBuilder(),
|
26
24
|
[Erc20SubType.lendle_vaults]: new LendleTVLBuilder(),
|
27
25
|
[Erc20SubType.termmax]: new TermMaxTVLBuilder(),
|
28
|
-
[Erc20SubType.dlend_lending]: new
|
29
|
-
[Erc20SubType.dlend_borrowing]: new
|
26
|
+
[Erc20SubType.dlend_lending]: new AaveTVLBuilder(),
|
27
|
+
[Erc20SubType.dlend_borrowing]: new AaveTVLBuilder(),
|
30
28
|
};
|
31
29
|
export const erc20SubTypeTVLBuilderFactory = (erc20Subtype) => {
|
32
30
|
if (!tvlMap[erc20Subtype]) {
|
@@ -42,14 +40,14 @@ export const erc20SubTypeTVLBuilderFactory = (erc20Subtype) => {
|
|
42
40
|
*/
|
43
41
|
const metadataMap = {
|
44
42
|
[Erc20SubType.gearbox]: new GearboxMetadata(),
|
45
|
-
[Erc20SubType.superlend_borrowing]: new
|
46
|
-
[Erc20SubType.superlend_lending]: new
|
43
|
+
[Erc20SubType.superlend_borrowing]: new AaveMetadata("superlend", "Superlend", (underlyingToken) => `https://markets.superlend.xyz/reserve-overview/?underlyingAsset=${underlyingToken}`),
|
44
|
+
[Erc20SubType.superlend_lending]: new AaveMetadata("superlend", "Superlend", (underlyingToken) => `https://markets.superlend.xyz/reserve-overview/?underlyingAsset=${underlyingToken}`),
|
47
45
|
[Erc20SubType.euler_borrow]: new EulerMetadata(),
|
48
46
|
[Erc20SubType.euler_lend]: new EulerMetadata(),
|
49
47
|
[Erc20SubType.lendle_vaults]: new LendleMetadata(),
|
50
48
|
[Erc20SubType.termmax]: new TermMaxMetadata(),
|
51
|
-
[Erc20SubType.dlend_lending]: new
|
52
|
-
[Erc20SubType.dlend_borrowing]: new
|
49
|
+
[Erc20SubType.dlend_lending]: new AaveMetadata("dlend", "dTrinity dLend", (underlyingToken) => `https://app.dtrinity.org/dlend/reserve-overview/?underlyingAsset=${underlyingToken}`),
|
50
|
+
[Erc20SubType.dlend_borrowing]: new AaveMetadata("dlend", "dTrinity dLend", (underlyingToken) => `https://app.dtrinity.org/dlend/reserve-overview/?underlyingAsset=${underlyingToken}`),
|
53
51
|
};
|
54
52
|
export const erc20SubTypeMetadataBuilderFactory = (erc20Subtype) => {
|
55
53
|
if (!metadataMap[erc20Subtype]) {
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import type { MetadataBuilder } from "@/engine/metadata/interface";
|
2
|
+
import type { CampaignWithParams } from "@/modules/v4/campaign/campaign.model";
|
3
|
+
import type { ProtocolId } from "@/modules/v4/protocol/protocol.model";
|
4
|
+
import type { Erc20LikeCampaignEnum } from "../..";
|
5
|
+
export declare class AaveMetadata implements MetadataBuilder<Erc20LikeCampaignEnum> {
|
6
|
+
/**
|
7
|
+
* @notice Protocol entity ID - must be defined in the corresponding file and created in DB
|
8
|
+
*/
|
9
|
+
mainProtocol: ProtocolId;
|
10
|
+
/**
|
11
|
+
* @notice Protocol name - used to create the opportunity name
|
12
|
+
*/
|
13
|
+
protocolName: string;
|
14
|
+
/**
|
15
|
+
* @notice Function to generate the deposit URL for the opportunity
|
16
|
+
*/
|
17
|
+
depositUrl: (underlyingToken: string) => string;
|
18
|
+
constructor(mainProtocol: ProtocolId, protocolName: string, depositUrl: (underlyingToken: string) => string);
|
19
|
+
build(campaign: Omit<CampaignWithParams<Erc20LikeCampaignEnum>, "manualOverrides">, _opportunityIdentifier: string): Promise<{
|
20
|
+
action: "LEND" | "BORROW";
|
21
|
+
mainProtocol: "splice" | "reserve" | "morpho" | "quickswap" | "euler" | "uniswap" | "ambient" | "arthswap" | "base-swap" | "camelot" | "crust" | "fenix" | "horiza" | "izumi" | "kim" | "pancake-swap" | "ramses" | "retro" | "stryke" | "sushi-swap" | "swapr" | "thruster" | "voltage" | "zero" | "koi" | "supswap" | "zk-swap" | "thirdtrade" | "swap-x" | "velodrome" | "aerodrome" | "balancer" | "curve" | "cross_curve" | "curveNPool" | "aura" | "akron" | "beefy" | "dragonswap" | "poolside" | "syncswap" | "neptune" | "zkSwapThreePool" | "rfx" | "ra" | "maverick" | "trader-joe" | "hanji" | "radiant" | "aave" | "fraxlend" | "ironclad" | "gearbox" | "compound" | "sturdy" | "frax" | "ionic" | "moonwell" | "fluid" | "silo" | "dolomite" | "badger" | "ajna" | "layerbank" | "ion" | "venus" | "woofi" | "reactor_fusion" | "eigenlayer" | "vest" | "zerolend" | "lnd" | "dlend" | "hyperdrive" | "gamma" | "oku" | "hourglass" | "veda" | "kyo" | "sonex" | "lendle" | "tako-tako" | "equalizer" | "spectra" | "beraborrow" | "superlend" | "avalon" | "iguana" | "xlend" | "sake" | "sonicmarket" | "stability" | "angles" | "enzyme" | "toros" | "vicuna" | "bunni" | "beratrax" | "concrete" | "cian" | "pendle" | "yei" | "termmax" | "filament" | "gammaswap" | "maha" | "tempest" | "uranium" | "holdstation" | "katana" | "punchswap" | "satlayer" | "puffer";
|
22
|
+
name: string;
|
23
|
+
tokens: {
|
24
|
+
chainId: number;
|
25
|
+
address: any;
|
26
|
+
}[];
|
27
|
+
depositUrl: string;
|
28
|
+
explorerAddress: any;
|
29
|
+
}>;
|
30
|
+
}
|
@@ -1,7 +1,24 @@
|
|
1
1
|
import { TokenService } from "@/modules/v4/token/token.service";
|
2
2
|
import { OpportunityAction } from "@db/api";
|
3
3
|
import { Aave__factory, ChainInteractionService, TokenInteractionService } from "@sdk";
|
4
|
-
export class
|
4
|
+
export class AaveMetadata {
|
5
|
+
/**
|
6
|
+
* @notice Protocol entity ID - must be defined in the corresponding file and created in DB
|
7
|
+
*/
|
8
|
+
mainProtocol;
|
9
|
+
/**
|
10
|
+
* @notice Protocol name - used to create the opportunity name
|
11
|
+
*/
|
12
|
+
protocolName;
|
13
|
+
/**
|
14
|
+
* @notice Function to generate the deposit URL for the opportunity
|
15
|
+
*/
|
16
|
+
depositUrl;
|
17
|
+
constructor(mainProtocol, protocolName, depositUrl) {
|
18
|
+
this.mainProtocol = mainProtocol;
|
19
|
+
this.protocolName = protocolName;
|
20
|
+
this.depositUrl = depositUrl;
|
21
|
+
}
|
5
22
|
async build(campaign, _opportunityIdentifier) {
|
6
23
|
const { params, computeChainId } = campaign;
|
7
24
|
const { targetToken } = params;
|
@@ -16,13 +33,13 @@ export class SuperlendMetadata {
|
|
16
33
|
: OpportunityAction.LEND;
|
17
34
|
return {
|
18
35
|
action,
|
19
|
-
mainProtocol:
|
20
|
-
name: `${action === OpportunityAction.BORROW ? "Borrow" : "Supply"} ${underlyingTokenSymbol} on
|
36
|
+
mainProtocol: this.mainProtocol,
|
37
|
+
name: `${action === OpportunityAction.BORROW ? "Borrow" : "Supply"} ${underlyingTokenSymbol} on ${this.protocolName}`,
|
21
38
|
tokens: [
|
22
39
|
{ chainId: computeChainId, address: targetToken },
|
23
40
|
{ chainId: computeChainId, address: underlyingToken },
|
24
41
|
],
|
25
|
-
depositUrl:
|
42
|
+
depositUrl: this.depositUrl(underlyingToken),
|
26
43
|
explorerAddress: params.targetToken,
|
27
44
|
};
|
28
45
|
}
|
package/dist/src/engine/implementations/Erc20/subTypes/implementations/{dlend → aave}/tvl.d.ts
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
import type { Erc20LikeCampaignEnum } from "@/engine/implementations/Erc20/subTypes";
|
2
2
|
import type { TVLBuilder, TVLData } from "@/engine/tvl/interface";
|
3
3
|
import { type CampaignParameters, type MerklChainId } from "@sdk";
|
4
|
-
export declare class
|
4
|
+
export declare class AaveTVLBuilder implements TVLBuilder<Erc20LikeCampaignEnum> {
|
5
5
|
build(computeChainId: MerklChainId, campaigns: CampaignParameters<Erc20LikeCampaignEnum>[]): Promise<TVLData<any>>;
|
6
6
|
}
|
package/dist/src/engine/implementations/Erc20/subTypes/implementations/{dlend → aave}/tvl.js
RENAMED
@@ -1,7 +1,7 @@
|
|
1
1
|
import { TokenService } from "@/modules/v4/token/token.service";
|
2
2
|
import { TvlType } from "@db/api";
|
3
3
|
import { AaveInterface, ChainInteractionService, ERC20Interface, bigIntToNumber, } from "@sdk";
|
4
|
-
export class
|
4
|
+
export class AaveTVLBuilder {
|
5
5
|
async build(computeChainId, campaigns) {
|
6
6
|
const tvls = [];
|
7
7
|
const firstRound = await ChainInteractionService(computeChainId).fetchAndDecodeObject(campaigns.flatMap(campaign => {
|
@@ -3,20 +3,20 @@ import { TokenService } from "@/modules/v4/token/token.service";
|
|
3
3
|
import { log } from "@/utils/logger";
|
4
4
|
import { engineDbClient } from "@db";
|
5
5
|
import { TvlType } from "@db/api";
|
6
|
-
import { BN2Number, ChainInteractionService, NETWORK_LABELS, } from "@sdk";
|
6
|
+
import { BN2Number, ChainInteractionService, NETWORK_LABELS, UniswapV4Addresses, UniswapV4StateViewInterface, getRawPriceFromSqrtRatioX96, getSqrtRatioAtTick, } from "@sdk";
|
7
7
|
/**
|
8
8
|
* Compute TVL
|
9
9
|
* @dev important: using the most recent state save with current prices
|
10
10
|
* it's only an estimate
|
11
11
|
*/
|
12
|
-
async function computeUniV4PoolTVLFromMostRecentStateSave(computeChainId, poolID) {
|
12
|
+
async function computeUniV4PoolTVLFromMostRecentStateSave(computeChainId, poolID, campaign) {
|
13
13
|
let stateSave;
|
14
14
|
let blockNumber;
|
15
15
|
let states = {};
|
16
16
|
// TEMPORARY: handle Gamma TVL
|
17
17
|
const nodesTVL = {};
|
18
|
+
const currentBlock = await ChainInteractionService(computeChainId).getBlockNumber();
|
18
19
|
try {
|
19
|
-
const currentBlock = await ChainInteractionService(computeChainId).getBlockNumber();
|
20
20
|
const mostRecentStateSave = await engineDbClient.stateSave.findFirst({
|
21
21
|
where: {
|
22
22
|
id: `UniswapV4_${computeChainId}_${poolID}`,
|
@@ -37,25 +37,57 @@ async function computeUniV4PoolTVLFromMostRecentStateSave(computeChainId, poolID
|
|
37
37
|
return { amount0: 0n, amount1: 0n, blockNumber: blockNumber ?? 0, nodesTVL };
|
38
38
|
}
|
39
39
|
const { fileName } = states;
|
40
|
-
//
|
40
|
+
// Root campaign info
|
41
|
+
const hasRulesOnPrice = !!campaign?.campaignParameters.lowerPriceBond || !!campaign?.campaignParameters.upperPriceBond;
|
42
|
+
let priceAtTick = 0n; // price in base 4
|
43
|
+
if (hasRulesOnPrice) {
|
44
|
+
const res = await ChainInteractionService(computeChainId).fetchArchiveState([
|
45
|
+
{
|
46
|
+
allowFailure: true,
|
47
|
+
callData: UniswapV4StateViewInterface.encodeFunctionData("getSlot0", [campaign.campaignParameters.poolId]),
|
48
|
+
target: UniswapV4Addresses[computeChainId].StateView,
|
49
|
+
},
|
50
|
+
], blockNumber ?? currentBlock);
|
51
|
+
const poolData = UniswapV4StateViewInterface.decodeFunctionResult("getSlot0", res[0].returnData);
|
52
|
+
const tick = poolData.tick;
|
53
|
+
const sqrtRatioAtTick = BigInt(getSqrtRatioAtTick(tick).toString());
|
54
|
+
priceAtTick = getRawPriceFromSqrtRatioX96(1, sqrtRatioAtTick, campaign.campaignParameters.decimalsCurrency0, campaign.campaignParameters.decimalsCurrency1);
|
55
|
+
}
|
56
|
+
// SubCampaigns info
|
41
57
|
const nodes = await engineDbClient.nodes.findMany({
|
42
58
|
where: { chainId: computeChainId, nodeType: "GammaUniV4" },
|
43
59
|
select: { nodeType: true, recipient: true },
|
44
60
|
});
|
45
|
-
// Bucket service
|
46
61
|
let amount0 = 0n;
|
47
62
|
let amount1 = 0n;
|
48
63
|
try {
|
64
|
+
// Bucket service
|
49
65
|
const bucket = new BucketService("merkl-production-states", "merkl-production");
|
50
66
|
const storedStates = JSON.parse(await bucket.pull(fileName));
|
51
|
-
for (const [_, { value, params
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
67
|
+
for (const [_, { value, params }] of Object.entries(storedStates)) {
|
68
|
+
// _ Handle rules
|
69
|
+
if (!!hasRulesOnPrice && priceAtTick > 0n) {
|
70
|
+
if (!!campaign.campaignParameters.lowerPriceBond) {
|
71
|
+
const lowerPriceBond = BigInt(campaign.campaignParameters.lowerPriceBond);
|
72
|
+
const sqrtRatioAtLowerTick = BigInt(getSqrtRatioAtTick(params.additional.tickLower).toString());
|
73
|
+
const priceAtLowerTick = getRawPriceFromSqrtRatioX96(1, sqrtRatioAtLowerTick, campaign.campaignParameters.decimalsCurrency0, campaign.campaignParameters.decimalsCurrency1);
|
74
|
+
if (priceAtLowerTick < lowerPriceBond)
|
75
|
+
continue;
|
76
|
+
}
|
77
|
+
if (!!campaign.campaignParameters.upperPriceBond) {
|
78
|
+
const upperPriceBond = BigInt(campaign.campaignParameters.upperPriceBond);
|
79
|
+
const sqrtRatioAtUpperTick = BigInt(getSqrtRatioAtTick(params.additional.tickUpper).toString());
|
80
|
+
const priceAtUpperTick = getRawPriceFromSqrtRatioX96(1, sqrtRatioAtUpperTick, campaign.campaignParameters.decimalsCurrency0, campaign.campaignParameters.decimalsCurrency1);
|
81
|
+
if (priceAtUpperTick > upperPriceBond)
|
82
|
+
continue;
|
83
|
+
}
|
84
|
+
}
|
85
|
+
// _ Handle subcampaigns TVL
|
86
|
+
// ----------------- TEMPORARY: handle Gamma TVL
|
87
|
+
if (nodes.map(node => node.recipient).includes(params.recipient)) {
|
88
|
+
const node = nodes.find(node => node.recipient === params.recipient);
|
57
89
|
if (!node) {
|
58
|
-
log.warn(`merklDynamic data - failed to find node ${
|
90
|
+
log.warn(`merklDynamic data - failed to find node ${params.recipient} for pool ${poolID}`);
|
59
91
|
continue;
|
60
92
|
}
|
61
93
|
if (!nodesTVL[node.nodeType]) {
|
@@ -63,7 +95,11 @@ async function computeUniV4PoolTVLFromMostRecentStateSave(computeChainId, poolID
|
|
63
95
|
}
|
64
96
|
nodesTVL[node.nodeType].amount0 += BigInt(value.amount0);
|
65
97
|
nodesTVL[node.nodeType].amount1 += BigInt(value.amount1);
|
98
|
+
// -----------------
|
66
99
|
}
|
100
|
+
// _ Add amounts for TVL
|
101
|
+
amount0 += BigInt(value.amount0);
|
102
|
+
amount1 += BigInt(value.amount1);
|
67
103
|
}
|
68
104
|
}
|
69
105
|
catch {
|
@@ -75,7 +111,7 @@ export class UniswapV4TVLBuilder {
|
|
75
111
|
async build(computeChainId, campaigns) {
|
76
112
|
const tvls = [];
|
77
113
|
for (const campaign of campaigns) {
|
78
|
-
const { amount0: poolBalanceToken0, amount1: poolBalanceToken1, nodesTVL, } = await computeUniV4PoolTVLFromMostRecentStateSave(computeChainId, campaign.campaignParameters.poolId);
|
114
|
+
const { amount0: poolBalanceToken0, amount1: poolBalanceToken1, nodesTVL, } = await computeUniV4PoolTVLFromMostRecentStateSave(computeChainId, campaign.campaignParameters.poolId, campaign);
|
79
115
|
const token0Id = TokenService.hashId({
|
80
116
|
chainId: computeChainId,
|
81
117
|
address: campaign.campaignParameters.currency0,
|