@merkl/api 0.20.151 → 0.20.153

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.
@@ -0,0 +1,2 @@
1
+ import { Erc20SubType } from "@/engine/implementations/Erc20/subTypes";
2
+ export declare function getTypeFromTreasuryAddress(address: string): Erc20SubType;
@@ -0,0 +1,10 @@
1
+ import { Erc20SubType } from "@/engine/implementations/Erc20/subTypes";
2
+ const treasuryAddresses = {
3
+ "0x3E965117A51186e41c2BB58b729A1e518A715e5F": Erc20SubType.gearbox, // Gearbox ETH Treasury
4
+ };
5
+ export function getTypeFromTreasuryAddress(address) {
6
+ if (treasuryAddresses[address]) {
7
+ return treasuryAddresses[address];
8
+ }
9
+ return Erc20SubType.unknown;
10
+ }
@@ -1,10 +1,11 @@
1
1
  import { getTypeFromFactoryAddress } from "@/engine/deprecated/erc20SubTypeProcessors/helpers/factoryFinder";
2
2
  import { getTypeFromAddressChain } from "@/engine/deprecated/erc20SubTypeProcessors/helpers/hardcoded";
3
3
  import { getTypeFromOwnerAddress } from "@/engine/deprecated/erc20SubTypeProcessors/helpers/ownerFinder";
4
+ import { getTypeFromTreasuryAddress } from "@/engine/deprecated/erc20SubTypeProcessors/helpers/treasuryFinder";
4
5
  import { processNamingConditionsInOrder } from "@/engine/deprecated/erc20SubTypeProcessors/subtypesRound1";
5
6
  import { Erc20SubType } from "@/engine/implementations/Erc20/subTypes";
6
7
  import { decodeReturnValue } from "@/utils/decodeCalls";
7
- import { BalancerPoolInterface, BalancerV3StablePoolInterface, ChainInteractionService, ERC20Interface, EnzymeInterface, FactoryInterface, LayerBankERC20Interface, MetamorphoInterface, } from "@sdk";
8
+ import { BalancerPoolInterface, BalancerV3StablePoolInterface, ChainInteractionService, ERC20Interface, EnzymeInterface, FactoryInterface, IonPoolInterface, LayerBankERC20Interface, MetamorphoInterface, } from "@sdk";
8
9
  /**
9
10
  * @notice Compute the subtypes of the campaigns
10
11
  * @warning
@@ -12,7 +13,7 @@ import { BalancerPoolInterface, BalancerV3StablePoolInterface, ChainInteractionS
12
13
  */
13
14
  export const detectSubType = async (chainId, campaigns) => {
14
15
  // 1. Do a generic multicall per campaign to see which functions are supported
15
- const callsPerCampaign = 7;
16
+ const callsPerCampaign = 8;
16
17
  const calls = [];
17
18
  for (const [index, campaign] of campaigns.entries()) {
18
19
  const { targetToken } = campaign.campaignParameters;
@@ -44,6 +45,10 @@ export const detectSubType = async (chainId, campaigns) => {
44
45
  allowFailure: true,
45
46
  callData: BalancerV3StablePoolInterface.encodeFunctionData("getVault"),
46
47
  target: targetToken,
48
+ }, {
49
+ allowFailure: true,
50
+ callData: IonPoolInterface.encodeFunctionData("treasury"),
51
+ target: targetToken,
47
52
  });
48
53
  if (calls.length !== callsPerCampaign * (index + 1))
49
54
  throw new Error("computeSubTypes: calls.length !== callsPerCampaign * index");
@@ -63,6 +68,7 @@ export const detectSubType = async (chainId, campaigns) => {
63
68
  creator: callResult[index + 4].returnData,
64
69
  owner: callResult[index + 5].returnData,
65
70
  vault: callResult[index + 6].returnData,
71
+ treasury: callResult[index + 7].returnData,
66
72
  };
67
73
  // Get erc20SubType from factory address
68
74
  try {
@@ -74,6 +80,16 @@ export const detectSubType = async (chainId, campaigns) => {
74
80
  }
75
81
  }
76
82
  catch { }
83
+ // Get erc20SubType from treasury address
84
+ try {
85
+ const treasury = decodeReturnValue(values.treasury, "treasury");
86
+ const type = getTypeFromTreasuryAddress(treasury);
87
+ if (type !== Erc20SubType.unknown) {
88
+ res.push(type);
89
+ continue;
90
+ }
91
+ }
92
+ catch { }
77
93
  // Get erc20SubType from owner address
78
94
  try {
79
95
  const owner = decodeReturnValue(values.owner, "owner");
@@ -5,6 +5,7 @@ export declare class DynamicDataService {
5
5
  *
6
6
  * @dev The list must ONLY contain campaigns of the same type and the same computeChainId
7
7
  */
8
+ static checkValidUpdate(opportunityId: string, newApr: number): Promise<boolean>;
8
9
  static update(chainId: ChainId, type: CampaignType, campaigns: CampaignParameters<CampaignType>[], dryRun?: boolean): Promise<unknown[]>;
9
10
  /**
10
11
  * @dev Test function used to create mock ERC20 static campaigns and check tvl and metadata
@@ -14,7 +14,7 @@ import bigintToString from "@/utils/bigintToString";
14
14
  import { log } from "@/utils/logger";
15
15
  import { parseDistributionType } from "@/utils/parseDistributionType";
16
16
  import { AprType, DistributionType } from "@db/api";
17
- import { Campaign as CampaignType, DAY, NETWORK_LABELS, bigIntToNumber, } from "@sdk";
17
+ import { Campaign as CampaignType, DAY, HOUR, NETWORK_LABELS, bigIntToNumber, } from "@sdk";
18
18
  import moment from "moment";
19
19
  export class DynamicDataService {
20
20
  /**
@@ -22,6 +22,16 @@ export class DynamicDataService {
22
22
  *
23
23
  * @dev The list must ONLY contain campaigns of the same type and the same computeChainId
24
24
  */
25
+ static async checkValidUpdate(opportunityId, newApr) {
26
+ const previousRecords = await OpportunityRepository.findUnique(opportunityId);
27
+ const previousApr = previousRecords?.apr;
28
+ const lastUpdate = previousRecords?.AprRecords.reduce((acc, record) => Math.max(acc, Number(record.timestamp)), 0);
29
+ if (previousApr && lastUpdate && moment.now() / 1000 - lastUpdate < HOUR) {
30
+ if (newApr / previousApr < 0.5 || newApr / previousApr > 2)
31
+ return false;
32
+ }
33
+ return true;
34
+ }
25
35
  static async update(chainId, type, campaigns, dryRun = false) {
26
36
  // 1 - Safety check
27
37
  for (const campaign of campaigns) {
@@ -172,7 +182,9 @@ export class DynamicDataService {
172
182
  if (!dryRun) {
173
183
  for (const update of updates) {
174
184
  try {
175
- await OpportunityRepository.updateDynamicData(update.opportunityId, update.apr, update.tvl, update.dailyRewards);
185
+ if (await DynamicDataService.checkValidUpdate(update.opportunityId, update.apr.cumulated)) {
186
+ await OpportunityRepository.updateDynamicData(update.opportunityId, update.apr, update.tvl, update.dailyRewards);
187
+ }
176
188
  }
177
189
  catch (err) {
178
190
  throw new HttpError("Failed to update dynamic data", 500, {
@@ -211,7 +223,9 @@ export class DynamicDataService {
211
223
  });
212
224
  try {
213
225
  if (!dryRun)
214
- await OpportunityRepository.updateDynamicData(opportunityId, apr, tvl, dailyRewards);
226
+ if (await DynamicDataService.checkValidUpdate(opportunityId, apr.cumulated)) {
227
+ await OpportunityRepository.updateDynamicData(opportunityId, apr, tvl, dailyRewards);
228
+ }
215
229
  }
216
230
  catch (err) {
217
231
  log.error(`failed to update dynamic data for ${opportunityId}`, err);
@@ -221,7 +221,7 @@ export class RewardService {
221
221
  if (!lastTreeRewardsBreakdown)
222
222
  continue;
223
223
  breakdown.claimed = lastTreeRewardsBreakdown.amount;
224
- await RewardRepository.updateBreakdownClaimed(user, tokenId, breakdown.campaignId, breakdown.reason, breakdown.amount);
224
+ await RewardRepository.updateBreakdownClaimed(user, tokenId, breakdown.campaignId, breakdown.reason, breakdown.claimed);
225
225
  }
226
226
  }
227
227
  }
@@ -1,5 +1,5 @@
1
1
  import { Erc20SubType } from "@/engine/implementations/Erc20/subTypes";
2
- import { AaveInterface, AccountantWithRateProvidersInterface, AuraInterface, AuraOperatorInterface, BalancerGaugeInterface, BalancerPoolInterface, BalancerV3StablePoolInterface, BalancerVaultInterface, BeefyInterface, BunniV2HubInterface, BunniV2TokenInterface, CPMMGammaPoolMainInterface, CompoundInterface, CurveInterface, CurveLPTokenInterface, CurveStableSwapNGInterface, DefutureVaultInterface, ERC20Interface, ERC4626Interface, EnzymeInterface, EulerInterface, FactoryInterface, FluidInterface, FraxlendInterface, GearboxVaultInterface, HourglassERC20TBTInterface, HourglassVedaLockDepositorV2Interface, IonicInterface, LPManagerHelperInterface, LPManagerInterface, LayerBankERC20Interface, LayerBankInterface, LendleInterface, MaverickBPLensInterface, MetamorphoInterface, MoonwellInterface, OneInchStakingInterface, PendleInterface, PendleYTInterface, RadiantInterface, RfxInterface, RswEthStrategyInterface, SpectraYTInterface, StabilityVaultInterface, SturdyInterface, SymetricAmbientStrategyInterface, SyncSwapClassicPoolInterface, TorosInterface, UniswapV2PoolInterface, UniswapV3PoolInterface, VePufferInterface, ZFStableLPINterface, ZFStableSwapThreePoolInterface, } from "@sdk";
2
+ import { AaveInterface, AccountantWithRateProvidersInterface, AuraInterface, AuraOperatorInterface, BalancerGaugeInterface, BalancerPoolInterface, BalancerV3StablePoolInterface, BalancerVaultInterface, BeefyInterface, BunniV2HubInterface, BunniV2TokenInterface, CPMMGammaPoolMainInterface, CompoundInterface, CurveInterface, CurveLPTokenInterface, CurveStableSwapNGInterface, DefutureVaultInterface, ERC20Interface, ERC4626Interface, EnzymeInterface, EulerInterface, FactoryInterface, FluidInterface, FraxlendInterface, GearboxVaultInterface, HourglassERC20TBTInterface, HourglassVedaLockDepositorV2Interface, IonPoolInterface, IonicInterface, LPManagerHelperInterface, LPManagerInterface, LayerBankERC20Interface, LayerBankInterface, LendleInterface, MaverickBPLensInterface, MetamorphoInterface, MoonwellInterface, OneInchStakingInterface, PendleInterface, PendleYTInterface, RadiantInterface, RfxInterface, RswEthStrategyInterface, SpectraYTInterface, StabilityVaultInterface, SturdyInterface, SymetricAmbientStrategyInterface, SyncSwapClassicPoolInterface, TorosInterface, UniswapV2PoolInterface, UniswapV3PoolInterface, VePufferInterface, ZFStableLPINterface, ZFStableSwapThreePoolInterface, } from "@sdk";
3
3
  import { BigNumber } from "ethers";
4
4
  export function decodeCall(calls, index, key, type) {
5
5
  const returnData = calls[index];
@@ -7,6 +7,8 @@ export function decodeCall(calls, index, key, type) {
7
7
  }
8
8
  export function decodeReturnValue(returnData, key, type) {
9
9
  switch (key) {
10
+ case "treasury":
11
+ return IonPoolInterface.decodeFunctionResult("treasury", returnData)[0];
10
12
  case "sqrtPriceX96":
11
13
  return UniswapV3PoolInterface.decodeFunctionResult("slot0", returnData)[0];
12
14
  case "tokens":