@stake-dao/reader 0.4.52 → 0.4.54

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.
Files changed (56) hide show
  1. package/dist/esm/index.js +4 -1
  2. package/dist/esm/index.js.map +1 -1
  3. package/dist/esm/prices.js +16 -5
  4. package/dist/esm/prices.js.map +1 -1
  5. package/dist/esm/strategies/curve/fetch/index.js +3 -1
  6. package/dist/esm/strategies/curve/fetch/index.js.map +1 -1
  7. package/dist/esm/strategies/curve/points.js +8 -0
  8. package/dist/esm/strategies/curve/points.js.map +1 -0
  9. package/dist/esm/strategies/passive/fetch.js +3 -3
  10. package/dist/esm/strategies/passive/fetch.js.map +1 -1
  11. package/dist/esm/strategies/pendle/fetch.js +2 -1
  12. package/dist/esm/strategies/pendle/fetch.js.map +1 -1
  13. package/dist/esm/strategies/pendle/pendlePoints.js +1 -48
  14. package/dist/esm/strategies/pendle/pendlePoints.js.map +1 -1
  15. package/dist/esm/strategies/stakeDao/fetch.js +107 -0
  16. package/dist/esm/strategies/stakeDao/fetch.js.map +1 -0
  17. package/dist/esm/tsconfig.build.tsbuildinfo +1 -1
  18. package/dist/esm/utils/snapshot.js +92 -0
  19. package/dist/esm/utils/snapshot.js.map +1 -0
  20. package/dist/esm/votemarket/curve/config.js +1 -0
  21. package/dist/esm/votemarket/curve/config.js.map +1 -1
  22. package/dist/esm/votemarket/curve/fetchSnapshotUserData.js +2 -2
  23. package/dist/esm/votemarket/curve/fetchSnapshotUserData.js.map +1 -1
  24. package/dist/esm/votemarket/curve/fetchUserVlCvxClaimable.js +9 -15
  25. package/dist/esm/votemarket/curve/fetchUserVlCvxClaimable.js.map +1 -1
  26. package/dist/types/index.d.ts +3 -1
  27. package/dist/types/index.d.ts.map +1 -1
  28. package/dist/types/prices.d.ts +1 -0
  29. package/dist/types/prices.d.ts.map +1 -1
  30. package/dist/types/strategies/curve/fetch/index.d.ts.map +1 -1
  31. package/dist/types/strategies/curve/points.d.ts +20 -0
  32. package/dist/types/strategies/curve/points.d.ts.map +1 -0
  33. package/dist/types/strategies/pendle/fetch.d.ts +1 -0
  34. package/dist/types/strategies/pendle/fetch.d.ts.map +1 -1
  35. package/dist/types/strategies/pendle/pendlePoints.d.ts +1 -57
  36. package/dist/types/strategies/pendle/pendlePoints.d.ts.map +1 -1
  37. package/dist/types/strategies/stakeDao/fetch.d.ts +78 -0
  38. package/dist/types/strategies/stakeDao/fetch.d.ts.map +1 -0
  39. package/dist/types/utils/snapshot.d.ts +8 -0
  40. package/dist/types/utils/snapshot.d.ts.map +1 -0
  41. package/dist/types/votemarket/curve/config.d.ts +1 -0
  42. package/dist/types/votemarket/curve/config.d.ts.map +1 -1
  43. package/dist/types/votemarket/curve/fetchUserVlCvxClaimable.d.ts.map +1 -1
  44. package/package.json +2 -3
  45. package/src/index.ts +5 -1
  46. package/src/prices.ts +18 -5
  47. package/src/strategies/curve/fetch/index.ts +3 -1
  48. package/src/strategies/curve/points.ts +8 -0
  49. package/src/strategies/passive/fetch.ts +3 -3
  50. package/src/strategies/pendle/fetch.ts +2 -1
  51. package/src/strategies/pendle/pendlePoints.ts +1 -48
  52. package/src/strategies/stakeDao/fetch.ts +128 -0
  53. package/src/utils/snapshot.ts +116 -0
  54. package/src/votemarket/curve/config.ts +1 -0
  55. package/src/votemarket/curve/fetchSnapshotUserData.ts +3 -3
  56. package/src/votemarket/curve/fetchUserVlCvxClaimable.ts +12 -19
@@ -3,7 +3,7 @@ import { formatUnits } from 'viem'
3
3
  import { ONE_YEAR, OneEther, Zero, curveStrats, mainnet, tokenWithId } from '@stake-dao/constants'
4
4
  import type { Price } from '../../../prices.js'
5
5
  import { type SdtEmissionData, getSdtApr } from '../../../sdt.js'
6
- import { equalTlc } from '../../../utils.js'
6
+ import { equalTlc, lc } from '../../../utils.js'
7
7
  import type {
8
8
  CurveGlobalData,
9
9
  OnlyBoostData,
@@ -18,6 +18,7 @@ import { getAprBreakdown } from '../../utils/getAprBreakdown.js'
18
18
  import { buildCurveStrategies } from '../build.js'
19
19
  import { getCurveHttpCalls } from '../httpCalls.js'
20
20
  import { getOnChainSdCurveData } from '../onChainCalls.js'
21
+ import curvePoints from '../points.js'
21
22
  import { BROKEN_VAULTS } from './curveApiData/config.js'
22
23
  import type { GaugesWeightsData } from './curveApiData/getGaugesWeights.js'
23
24
  import { getCvxApr } from './getCvxApr.js'
@@ -218,6 +219,7 @@ export const fetchCurve = async ({
218
219
  underlyingCoins: strat.underlyingCoins,
219
220
  sdGauge,
220
221
  lpPriceInUsd: strat.lpPriceInUsd,
222
+ points: curvePoints[lc(strat.lpToken.address)],
221
223
  streaming: rewardsData.some((r) => Number(r.periodFinish) > Math.floor(Date.now() / 1000)),
222
224
  tvl,
223
225
  apr: {
@@ -0,0 +1,8 @@
1
+ const curvePoints = {
2
+ '0x38de22a3175708d45e7c7c64cd78479c8b56f76e': [{ multiplier: 30, label: 'Resolv Points' }],
3
+ '0x4628f13651ead6793f8d838b34b8f8522fb0cc52': [{ multiplier: 30, label: 'Resolv Points' }],
4
+ '0xc907ba505c2e1cbc4658c395d4a2c7e6d2c32656': [{ multiplier: 30, label: 'Resolv Points' }],
5
+ '0x3ee841f47947fefbe510366e4bbb49e145484195': [{ multiplier: 30, label: 'Resolv Points' }],
6
+ }
7
+
8
+ export default curvePoints
@@ -1,11 +1,11 @@
1
1
  import { formatUnits } from 'viem'
2
2
 
3
- import multicallPassiveVaultsAbi from '../../abis/passiveVaultsMulticall.js'
4
3
  import { contract, passiveStrats } from '@stake-dao/constants'
5
- import { multicall } from '../../utils.js'
6
4
  import { mainnet } from 'viem/chains'
7
- import { getPassiveHttpCalls } from './httpCalls.js'
5
+ import multicallPassiveVaultsAbi from '../../abis/passiveVaultsMulticall.js'
6
+ import { multicall } from '../../utils.js'
8
7
  import { getBoost } from '../utils/boost.js'
8
+ import { getPassiveHttpCalls } from './httpCalls.js'
9
9
 
10
10
  interface TFetchPassive {
11
11
  provider: any
@@ -16,7 +16,7 @@ import {
16
16
  import multicallPendleStratsAbi from '../../abis/pendleVaultsMulticall.js'
17
17
  import { batchPendleStrats } from '../../bytecodes/index.js'
18
18
  import type { Price } from '../../prices.js'
19
- import { type Call, batchJsonRpc, equalTlc, multicall } from '../../utils.js'
19
+ import { type Call, batchJsonRpc, equalTlc, lc, multicall } from '../../utils.js'
20
20
  import { FACTORY_EXPLORER_EVENTS } from '../curve/endpoints.js'
21
21
  import type { RewardsData, SdtApr, ValidChainId, ValidExplorer } from '../types.js'
22
22
  import { getBoost } from '../utils/boost.js'
@@ -281,6 +281,7 @@ export const fetchPendle = async ({ prices, provider, rpc, explorerApiKey, explo
281
281
  lpToken: s.lpToken,
282
282
  coins: s.coins,
283
283
  syToken: s.syToken,
284
+ points: pendlePoints[lc(s.lpToken.address)],
284
285
  streaming: rewardsData.some((r) => Number(r.periodFinish) > Math.floor(Date.now() / 1000)),
285
286
  sdGauge,
286
287
  lpPriceInUsd,
@@ -1,71 +1,24 @@
1
1
  const pendlePoints = {
2
- '0x9c73879f795cefa1d5239de08d1b6aba2d2d1434': [{ multiplier: 30, label: 'Sats Multiplier' }],
3
- '0x19588f29f9402bb508007feadd415c875ee3f19f': [{ multiplier: 20, label: 'Sats Multiplier' }],
4
2
  '0x90c98ab215498b72abfec04c651e2e496ba364c0': [
5
3
  { multiplier: 20, label: 'Sats Multiplier' },
6
4
  { multiplier: 2, label: 'Zircuit Multiplier' },
7
5
  ],
8
- '0x107a2e3cd2bb9a32b9ee2e4d51143149f8367eba': [{ multiplier: 20, label: 'Sats Multiplier' }],
9
- '0x7d372819240d14fb477f17b964f95f33beb4c704': [
10
- { multiplier: 3, label: 'Ether.fi Multiplier' },
11
- { multiplier: 1, label: 'EigenLayer Multiplier' },
12
- ],
13
- '0xf32e58f92e60f4b0a37a69b95d642a471365eae8': [
14
- { multiplier: 2, label: 'Ether.fi Multiplier' },
15
- { multiplier: 1, label: 'EigenLayer Multiplier' },
16
- ],
17
6
  '0xe26d7f9409581f606242300fbfe63f56789f2169': [
18
7
  { multiplier: 3, label: 'Ether.fi Multiplier' },
19
8
  { multiplier: 2, label: 'Zircuit Multiplier' },
20
9
  { multiplier: 1, label: 'EigenLayer Multiplier' },
21
10
  ],
22
- '0xd8f12bcde578c653014f27379a6114f67f0e445f': [
23
- { multiplier: 4, label: 'Renzo Multiplier' },
24
- { multiplier: 1, label: 'EigenLayer Multiplier' },
25
- ],
26
11
  '0xd7e0809998693fd87e81d51de1619fd0ee658031': [
27
12
  { multiplier: 1, label: 'Renzo Multiplier' },
28
13
  { multiplier: 2, label: 'Zircuit Multiplier' },
29
14
  { multiplier: 1, label: 'EigenLayer Multiplier' },
30
15
  ],
31
- '0x4f43c77872db6ba177c270986cd30c3381af37ee': [
32
- { multiplier: 2, label: 'Kelp Multiplier' },
33
- { multiplier: 1, label: 'EigenLayer Multiplier' },
34
- ],
35
16
  '0x445d25a1c31445fb29e65d12da8e0eea38174176': [
36
17
  { multiplier: 2, label: 'Kelp Multiplier' },
37
18
  { multiplier: 2, label: 'Zircuit Multiplier' },
38
19
  { multiplier: 1, label: 'EigenLayer Multiplier' },
39
20
  ],
40
- '0xa9355a5d306c67027c54de0e5a72df76befa5694': [
41
- { multiplier: 4.5, label: 'Swell Multiplier' },
42
- { multiplier: 1, label: 'EigenLayer Multiplier' },
43
- ],
44
- '0x38100a480dbed278b0fe57ba80a75498a7dc5bb1': [
45
- { multiplier: 5, label: 'Bedrock Multiplier' },
46
- { multiplier: 1, label: 'EigenLayer Multiplier' },
47
- ],
48
- '0x17be998a578fd97687b24e83954fec86dc20c979': [
49
- { multiplier: 1.25, label: 'Puffer Multiplier' },
50
- { multiplier: 1, label: 'EigenLayer Multiplier' },
51
- ],
52
- '0xd1d7d99764f8a52aff007b7831cc02748b2013b5': [{ multiplier: 20, label: 'Sats Multiplier' }],
53
- '0xa54fc268101c8b97de19ef3141d34751a11996b2': [
54
- { multiplier: 2, label: 'Puffer Multiplier' },
55
- { multiplier: 1, label: 'EigenLayer Multiplier' },
56
- ],
57
- '0xbae2df4dfcd0c613018d6056a40077f2d1eff28a': [
58
- { multiplier: 5, label: 'Bedrock Multiplier' },
59
- { multiplier: 1, label: 'EigenLayer Multiplier' },
60
- ],
61
- '0xc8edd52d0502aa8b4d5c77361d4b3d300e8fc81c': [
62
- { multiplier: 2, label: 'Ether.fi Multiplier' },
63
- { multiplier: 1, label: 'EigenLayer Multiplier' },
64
- ],
65
- '0xcdbd5ff3e03b6828db9c32e2131a60aba5137901': [
66
- { multiplier: 4, label: 'Renzo Multiplier' },
67
- { multiplier: 1, label: 'EigenLayer Multiplier' },
68
- ],
21
+ '0x353d0b2efb5b3a7987fb06d30ad6160522d08426': [{ multiplier: 15, label: 'Resolv Points' }],
69
22
  }
70
23
 
71
24
  export default pendlePoints
@@ -0,0 +1,128 @@
1
+ import { contract, stakeDaoStrats } from '@stake-dao/constants'
2
+ import { formatUnits, parseAbi, zeroAddress } from 'viem'
3
+ import type { Price } from '../../prices.js'
4
+ import { multicall } from '../../utils.js'
5
+ import getAverageYearlyRewards from '../../utils/getAverageYearlyRewards.js'
6
+
7
+ const baseQueryParams = {
8
+ module: 'logs',
9
+ action: 'getLogs',
10
+ fromBlock: `${20061000}`,
11
+ address: '0xCe00aD8DF94D8C365dc415B84963aA37A06bE923',
12
+ topic0: '0x4882c2b96bd65ac9234537053e19a51399df7ee5f67f5f20256bfff49f7389a5',
13
+ }
14
+
15
+ interface TFetchStakeDao {
16
+ provider: any
17
+ chainId: number
18
+ lockers: any[]
19
+ prices: Price[]
20
+ explorerApiKey: string
21
+ }
22
+
23
+ export const fetchStakeDao = async ({ provider, chainId, lockers, prices, explorerApiKey }: TFetchStakeDao) => {
24
+ let amountPerYear = 0
25
+
26
+ try {
27
+ const queryParams = { ...baseQueryParams, chainid: `${chainId}`, apikey: explorerApiKey }
28
+ const url = `https://api.etherscan.io/v2/api?${new URLSearchParams(queryParams)}`
29
+
30
+ const rawEventsData = await (await fetch(url)).json()
31
+ amountPerYear = await getAverageYearlyRewards(rawEventsData, 5)
32
+ } catch {
33
+ amountPerYear = 0
34
+ }
35
+
36
+ const rawData: any = await multicall(
37
+ provider,
38
+ [
39
+ {
40
+ address: contract('veSdtBoostDelegation'),
41
+ name: 'received_balance',
42
+ params: [contract('voteBoosterStrategy')],
43
+ },
44
+ ],
45
+ parseAbi(['function received_balance(address user) external view returns (uint256)']),
46
+ )
47
+
48
+ const parsedData = stakeDaoStrats.strats.map((s, index) => {
49
+ const locker = lockers.find((l) => l.id === s.lockerId)
50
+ const boost = locker.voteBooster?.boost || 0
51
+ const lpPriceInUsd = prices.find((p) => p.symbol === 'SDT')?.usdPrice || 0
52
+
53
+ const totalSupply = rawData[index].result
54
+ const tvl = lpPriceInUsd * Number(formatUnits(totalSupply, 18))
55
+
56
+ const currentApr = ((amountPerYear * lpPriceInUsd) / tvl) * 100
57
+ const projectedApr = locker?.rewards ? locker.rewards.reduce((total, r) => (total += r.apr), 0) : 0
58
+
59
+ return {
60
+ key: s.key,
61
+ name: s.name,
62
+ subname: s.subname,
63
+ type: s.type,
64
+ protocol: s.protocol,
65
+ chainId: s.chainId,
66
+ vault: s.vault,
67
+ lpToken: s.lpToken,
68
+ coins: s.coins,
69
+ underlyingCoins: s.underlyingCoins,
70
+ vSdToken: s.vSdToken,
71
+ lpPriceInUsd,
72
+ streaming: amountPerYear > 0,
73
+ tvl,
74
+ apr: {
75
+ boost,
76
+ current: {
77
+ total: currentApr,
78
+ details: [
79
+ {
80
+ label: 'SDT',
81
+ value: [currentApr],
82
+ },
83
+ ],
84
+ },
85
+ projected: {
86
+ total: projectedApr,
87
+ details: [
88
+ {
89
+ label: 'SDT',
90
+ value: [projectedApr],
91
+ },
92
+ ],
93
+ },
94
+ },
95
+ rewards: s.rewards.map((r) => {
96
+ return {
97
+ token: {
98
+ name: r!.name,
99
+ decimals: r!.decimals,
100
+ symbol: r!.symbol,
101
+ address: r!.address,
102
+ },
103
+ distributor: zeroAddress,
104
+ periodFinish: '0',
105
+ rate: '0',
106
+ lastUpdate: '0',
107
+ integral: '0',
108
+ claimablePendingRewards: '0',
109
+ }
110
+ }),
111
+ // Base APR data
112
+ tradingApy: 0,
113
+ minApr: projectedApr,
114
+ maxApr: projectedApr,
115
+ // Raw data
116
+ totalSupply: formatUnits(totalSupply, 0),
117
+ }
118
+ })
119
+
120
+ return {
121
+ global: {
122
+ fees: { accumulator: 0, perf: 0, veSdt: 0, claimer: 0 },
123
+ },
124
+ deployed: parsedData,
125
+ notDeployed: [],
126
+ fetched: true,
127
+ }
128
+ }
@@ -0,0 +1,116 @@
1
+ import { isAddress, zeroAddress } from 'viem'
2
+
3
+ interface Strategy {
4
+ name: string
5
+ network?: string
6
+ params: any
7
+ }
8
+
9
+ const DEFAULT_SCORE_API_URL = 'https://score.snapshot.org'
10
+
11
+ const NETWORKS = {
12
+ 1: { key: '1', name: 'Ethereum', start: 7929876 },
13
+ 10: { key: '10', name: 'Optimism', start: 657806 },
14
+ 56: { key: '56', name: 'BNB Smart Chain', start: 461230 },
15
+ 100: { key: '100', name: 'Gnosis Chain', start: 4108192 },
16
+ 137: { key: '137', name: 'Polygon PoS', start: 9834491 },
17
+ 146: { key: '146', name: 'Sonic', start: 60 },
18
+ 250: { key: '250', name: 'Fantom Opera', start: 2497732 },
19
+ 252: { key: '252', name: 'Fraxtal', start: 1 },
20
+ 324: { key: '324', name: 'zkSync Era', start: 3908235 },
21
+ 8453: { key: '8453', name: 'Base', start: 5022 },
22
+ 42161: { key: '42161', name: 'Arbitrum One', start: 256508 },
23
+ 42220: { key: '42220', name: 'Celo', start: 6599803 },
24
+ 43114: { key: '43114', name: 'Avalanche', start: 536483 },
25
+ 59144: { key: '59144', name: 'Linea', start: 42 },
26
+ 81457: { key: '81457', name: 'Blast', start: 88189 },
27
+ }
28
+
29
+ const inputError = (message: string) => Promise.reject(new Error(message))
30
+
31
+ function isValidNetwork(network: string) {
32
+ return !!NETWORKS[network]
33
+ }
34
+
35
+ function isValidAddress(address: string) {
36
+ return isAddress(address) && address !== zeroAddress
37
+ }
38
+
39
+ function isValidSnapshot(snapshot: number | string, network: string) {
40
+ return snapshot === 'latest' || (typeof snapshot === 'number' && snapshot >= NETWORKS[network].start)
41
+ }
42
+
43
+ const parseScoreAPIResponse = async (res: any) => {
44
+ let data: any = await res.text()
45
+
46
+ try {
47
+ data = JSON.parse(data)
48
+ } catch (_e: any) {
49
+ return Promise.reject({
50
+ code: res.status || 500,
51
+ message: 'Failed to parse response from score API',
52
+ data,
53
+ })
54
+ }
55
+
56
+ if (data.error) return Promise.reject(data.error)
57
+ return data
58
+ }
59
+
60
+ export const getSnapshotScores = async (
61
+ space: string,
62
+ strategies: Strategy[],
63
+ network: string,
64
+ addresses: string[],
65
+ snapshot: number | string = 'latest',
66
+ options: any = {},
67
+ ) => {
68
+ if (!Array.isArray(addresses)) {
69
+ return inputError('addresses should be an array of addresses')
70
+ }
71
+ if (addresses.length === 0) {
72
+ return inputError('addresses can not be empty')
73
+ }
74
+ const invalidAddress = addresses.find((address) => !isValidAddress(address))
75
+ if (invalidAddress) {
76
+ return inputError(`Invalid address: ${invalidAddress}`)
77
+ }
78
+ if (!isValidNetwork(network)) {
79
+ return inputError(`Invalid network: ${network}`)
80
+ }
81
+ const invalidStrategy = strategies.find((strategy) => strategy.network && !isValidNetwork(strategy.network))
82
+ if (invalidStrategy) {
83
+ return inputError(`Invalid network (${invalidStrategy.network}) in strategy ${invalidStrategy.name}`)
84
+ }
85
+ if (!isValidSnapshot(snapshot, network)) {
86
+ return inputError(
87
+ `Snapshot (${snapshot}) must be 'latest' or greater than network start block (${NETWORKS[network].start})`,
88
+ )
89
+ }
90
+
91
+ const url = `${DEFAULT_SCORE_API_URL}/api/scores`
92
+ const headers = { Accept: 'application/json', 'Content-Type': 'application/json' }
93
+
94
+ try {
95
+ const params = {
96
+ space,
97
+ network,
98
+ snapshot,
99
+ strategies,
100
+ addresses,
101
+ }
102
+ const res = await fetch(url, {
103
+ method: 'POST',
104
+ headers,
105
+ body: JSON.stringify({ params }),
106
+ })
107
+ const response = await parseScoreAPIResponse(res)
108
+
109
+ return options.returnValue === 'all' ? response.result : response.result[options.returnValue || 'scores']
110
+ } catch (e: any) {
111
+ if (e.errno) {
112
+ return Promise.reject({ code: e.errno, message: e.toString(), data: '' })
113
+ }
114
+ return Promise.reject(e)
115
+ }
116
+ }
@@ -6,6 +6,7 @@ export const GAUGES_METADATA_CHUNK_SIZE = {
6
6
  10: 10,
7
7
  100: 10,
8
8
  137: 10,
9
+ 146: 10,
9
10
  250: 10,
10
11
  252: 10,
11
12
  8453: 10,
@@ -1,8 +1,8 @@
1
- import snapshot from '@snapshot-labs/snapshot.js'
2
1
  import { gql } from 'graphql-request'
3
2
  import { isAddress } from 'viem'
4
3
  import { SNAPSHOT_HUB } from '../../endpoints.js'
5
4
  import { graphql } from '../../utils.js'
5
+ import { getSnapshotScores } from '../../utils/snapshot.js'
6
6
 
7
7
  interface SnapshotProposal {
8
8
  id: string
@@ -114,8 +114,8 @@ export const fetchSnapshotUserData = async (
114
114
  let vp = 0
115
115
  const userVotes = {}
116
116
  if (isAddress(userAddress)) {
117
- const fetchedVp = await (snapshot as any).utils.getScores(
118
- spaces[i],
117
+ const fetchedVp = await getSnapshotScores(
118
+ spaces[i]!,
119
119
  proposal.space.strategies,
120
120
  '1',
121
121
  [userAddress],
@@ -1,4 +1,4 @@
1
- import { ONE_WEEK, Zero, contract, tokenWithAddress } from '@stake-dao/constants'
1
+ import { Zero, contract, tokenWithAddress } from '@stake-dao/constants'
2
2
  import { type Address, formatUnits, parseAbi } from 'viem'
3
3
  import { mainnet } from 'viem/chains'
4
4
  import { GH_STAKE_DAO_BOUNTIES_REPORT } from '../../endpoints.js'
@@ -18,14 +18,14 @@ type UnknownToken = {
18
18
  chainId: number
19
19
  }
20
20
 
21
- const getMerkleData = async (epoch: number) => {
21
+ const getMerkleData = async () => {
22
22
  const [delegators, nonDelegators] = await Promise.all([
23
23
  fetch(
24
- `${GH_STAKE_DAO_BOUNTIES_REPORT}/refs/heads/main/bounties-reports/${epoch}/vlCVX/merkle_data_delegators.json`,
25
- ).then((res) => res.json()),
26
- fetch(
27
- `${GH_STAKE_DAO_BOUNTIES_REPORT}/refs/heads/main/bounties-reports/${epoch}/vlCVX/merkle_data_non_delegators.json`,
24
+ `${GH_STAKE_DAO_BOUNTIES_REPORT}/refs/heads/main/bounties-reports/latest/vlCVX/vlcvx_merkle_delegators.json`,
28
25
  ).then((res) => res.json()),
26
+ fetch(`${GH_STAKE_DAO_BOUNTIES_REPORT}/refs/heads/main/bounties-reports/latest/vlCVX/vlcvx_merkle.json`).then(
27
+ (res) => res.json(),
28
+ ),
29
29
  ])
30
30
 
31
31
  return { delegators, nonDelegators }
@@ -112,23 +112,16 @@ const getParsedData = (
112
112
  const ZERO_ROOT = '0x0000000000000000000000000000000000000000000000000000000000000000'
113
113
 
114
114
  export const fetchUserVlCvxClaimable = async (provider: any, rpc: Rpcs, user: string) => {
115
- const nowEpoch = Math.floor(Date.now() / 1000 / ONE_WEEK) * ONE_WEEK
116
- const prevEpoch = nowEpoch - ONE_WEEK
117
-
118
115
  const { delegatorRoot, nonDelegatorRoot } = await getMerkleRoots(provider)
119
116
 
120
117
  let vlCvxClaimable: any
121
118
 
122
- // Try current week, then previous week if needed
123
- for (const epoch of [nowEpoch, prevEpoch]) {
124
- try {
125
- const merkleData = await getMerkleData(epoch)
126
- if (validateMerkleRoots(delegatorRoot, nonDelegatorRoot, merkleData)) {
127
- vlCvxClaimable = merkleData
128
- break
129
- }
130
- } catch {}
131
- }
119
+ try {
120
+ const merkleData = await getMerkleData()
121
+ if (validateMerkleRoots(delegatorRoot, nonDelegatorRoot, merkleData)) {
122
+ vlCvxClaimable = merkleData
123
+ }
124
+ } catch {}
132
125
 
133
126
  if (!vlCvxClaimable) {
134
127
  throw new Error('Could not find valid merkle data')