@stake-dao/reader 0.1.0

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 (182) hide show
  1. package/dist/esm/batches/curveStrats.js +163 -0
  2. package/dist/esm/batches/curveStrats.js.map +1 -0
  3. package/dist/esm/batches/index.js +4 -0
  4. package/dist/esm/batches/index.js.map +1 -0
  5. package/dist/esm/batches/sdtGaugeRewards.js +22 -0
  6. package/dist/esm/batches/sdtGaugeRewards.js.map +1 -0
  7. package/dist/esm/batches/tokenData.js +22 -0
  8. package/dist/esm/batches/tokenData.js.map +1 -0
  9. package/dist/esm/batches/types.js +2 -0
  10. package/dist/esm/batches/types.js.map +1 -0
  11. package/dist/esm/endpoints.js +3 -0
  12. package/dist/esm/endpoints.js.map +1 -0
  13. package/dist/esm/index.js +8 -0
  14. package/dist/esm/index.js.map +1 -0
  15. package/dist/esm/number.js +45 -0
  16. package/dist/esm/number.js.map +1 -0
  17. package/dist/esm/prices.js +70 -0
  18. package/dist/esm/prices.js.map +1 -0
  19. package/dist/esm/sdt/sdt.js +92 -0
  20. package/dist/esm/sdt/sdt.js.map +1 -0
  21. package/dist/esm/sdt/veSdtAlternativeYields.js +19 -0
  22. package/dist/esm/sdt/veSdtAlternativeYields.js.map +1 -0
  23. package/dist/esm/strategies/curve/build.js +123 -0
  24. package/dist/esm/strategies/curve/build.js.map +1 -0
  25. package/dist/esm/strategies/curve/endpoints.js +6 -0
  26. package/dist/esm/strategies/curve/endpoints.js.map +1 -0
  27. package/dist/esm/strategies/curve/fetch/curveApiData/abi.js +80 -0
  28. package/dist/esm/strategies/curve/fetch/curveApiData/abi.js.map +1 -0
  29. package/dist/esm/strategies/curve/fetch/curveApiData/bytecode.js +24 -0
  30. package/dist/esm/strategies/curve/fetch/curveApiData/bytecode.js.map +1 -0
  31. package/dist/esm/strategies/curve/fetch/curveApiData/config.js +47 -0
  32. package/dist/esm/strategies/curve/fetch/curveApiData/config.js.map +1 -0
  33. package/dist/esm/strategies/curve/fetch/curveApiData/getCurveApiData.js +172 -0
  34. package/dist/esm/strategies/curve/fetch/curveApiData/getCurveApiData.js.map +1 -0
  35. package/dist/esm/strategies/curve/fetch/curveApiData/getGaugesFromRegistry.js +33 -0
  36. package/dist/esm/strategies/curve/fetch/curveApiData/getGaugesFromRegistry.js.map +1 -0
  37. package/dist/esm/strategies/curve/fetch/curveApiData/getGaugesWeights.js +36 -0
  38. package/dist/esm/strategies/curve/fetch/curveApiData/getGaugesWeights.js.map +1 -0
  39. package/dist/esm/strategies/curve/fetch/curveApiData/getPoolsFromRegistries.ts.js +26 -0
  40. package/dist/esm/strategies/curve/fetch/curveApiData/getPoolsFromRegistries.ts.js.map +1 -0
  41. package/dist/esm/strategies/curve/fetch/curveApiData/getRegistries.js +20 -0
  42. package/dist/esm/strategies/curve/fetch/curveApiData/getRegistries.js.map +1 -0
  43. package/dist/esm/strategies/curve/fetch/getAprBreakdown.js +73 -0
  44. package/dist/esm/strategies/curve/fetch/getAprBreakdown.js.map +1 -0
  45. package/dist/esm/strategies/curve/fetch/getCvxApr.js +33 -0
  46. package/dist/esm/strategies/curve/fetch/getCvxApr.js.map +1 -0
  47. package/dist/esm/strategies/curve/fetch/getOnlyboostData.js +63 -0
  48. package/dist/esm/strategies/curve/fetch/getOnlyboostData.js.map +1 -0
  49. package/dist/esm/strategies/curve/fetch/getStratsWithApr.js +88 -0
  50. package/dist/esm/strategies/curve/fetch/getStratsWithApr.js.map +1 -0
  51. package/dist/esm/strategies/curve/fetch/index.js +209 -0
  52. package/dist/esm/strategies/curve/fetch/index.js.map +1 -0
  53. package/dist/esm/strategies/curve/fetch/types.js +2 -0
  54. package/dist/esm/strategies/curve/fetch/types.js.map +1 -0
  55. package/dist/esm/strategies/curve/httpCalls.js +80 -0
  56. package/dist/esm/strategies/curve/httpCalls.js.map +1 -0
  57. package/dist/esm/strategies/curve/onChainCalls.js +28 -0
  58. package/dist/esm/strategies/curve/onChainCalls.js.map +1 -0
  59. package/dist/esm/strategies/types.js +2 -0
  60. package/dist/esm/strategies/types.js.map +1 -0
  61. package/dist/esm/strategies/utils/boost.js +30 -0
  62. package/dist/esm/strategies/utils/boost.js.map +1 -0
  63. package/dist/esm/strategies/utils/decodeEtherscanFactoryEvent.js +40 -0
  64. package/dist/esm/strategies/utils/decodeEtherscanFactoryEvent.js.map +1 -0
  65. package/dist/esm/strategies/utils/index.js +7 -0
  66. package/dist/esm/strategies/utils/index.js.map +1 -0
  67. package/dist/esm/strategies/utils/promise.js +10 -0
  68. package/dist/esm/strategies/utils/promise.js.map +1 -0
  69. package/dist/esm/strategies/utils/sdt.js +112 -0
  70. package/dist/esm/strategies/utils/sdt.js.map +1 -0
  71. package/dist/esm/tsconfig.build.tsbuildinfo +1 -0
  72. package/dist/esm/utils.js +113 -0
  73. package/dist/esm/utils.js.map +1 -0
  74. package/dist/types/batches/curveStrats.d.ts +4 -0
  75. package/dist/types/batches/curveStrats.d.ts.map +1 -0
  76. package/dist/types/batches/index.d.ts +4 -0
  77. package/dist/types/batches/index.d.ts.map +1 -0
  78. package/dist/types/batches/sdtGaugeRewards.d.ts +4 -0
  79. package/dist/types/batches/sdtGaugeRewards.d.ts.map +1 -0
  80. package/dist/types/batches/tokenData.d.ts +4 -0
  81. package/dist/types/batches/tokenData.d.ts.map +1 -0
  82. package/dist/types/batches/types.d.ts +15 -0
  83. package/dist/types/batches/types.d.ts.map +1 -0
  84. package/dist/types/endpoints.d.ts +3 -0
  85. package/dist/types/endpoints.d.ts.map +1 -0
  86. package/dist/types/index.d.ts +8 -0
  87. package/dist/types/index.d.ts.map +1 -0
  88. package/dist/types/number.d.ts +6 -0
  89. package/dist/types/number.d.ts.map +1 -0
  90. package/dist/types/prices.d.ts +10 -0
  91. package/dist/types/prices.d.ts.map +1 -0
  92. package/dist/types/sdt/sdt.d.ts +31 -0
  93. package/dist/types/sdt/sdt.d.ts.map +1 -0
  94. package/dist/types/sdt/veSdtAlternativeYields.d.ts +19 -0
  95. package/dist/types/sdt/veSdtAlternativeYields.d.ts.map +1 -0
  96. package/dist/types/strategies/curve/build.d.ts +37 -0
  97. package/dist/types/strategies/curve/build.d.ts.map +1 -0
  98. package/dist/types/strategies/curve/endpoints.d.ts +6 -0
  99. package/dist/types/strategies/curve/endpoints.d.ts.map +1 -0
  100. package/dist/types/strategies/curve/fetch/curveApiData/abi.d.ts +49 -0
  101. package/dist/types/strategies/curve/fetch/curveApiData/abi.d.ts.map +1 -0
  102. package/dist/types/strategies/curve/fetch/curveApiData/bytecode.d.ts +8 -0
  103. package/dist/types/strategies/curve/fetch/curveApiData/bytecode.d.ts.map +1 -0
  104. package/dist/types/strategies/curve/fetch/curveApiData/config.d.ts +34 -0
  105. package/dist/types/strategies/curve/fetch/curveApiData/config.d.ts.map +1 -0
  106. package/dist/types/strategies/curve/fetch/curveApiData/getCurveApiData.d.ts +3 -0
  107. package/dist/types/strategies/curve/fetch/curveApiData/getCurveApiData.d.ts.map +1 -0
  108. package/dist/types/strategies/curve/fetch/curveApiData/getGaugesFromRegistry.d.ts +2 -0
  109. package/dist/types/strategies/curve/fetch/curveApiData/getGaugesFromRegistry.d.ts.map +1 -0
  110. package/dist/types/strategies/curve/fetch/curveApiData/getGaugesWeights.d.ts +11 -0
  111. package/dist/types/strategies/curve/fetch/curveApiData/getGaugesWeights.d.ts.map +1 -0
  112. package/dist/types/strategies/curve/fetch/curveApiData/getPoolsFromRegistries.ts.d.ts +2 -0
  113. package/dist/types/strategies/curve/fetch/curveApiData/getPoolsFromRegistries.ts.d.ts.map +1 -0
  114. package/dist/types/strategies/curve/fetch/curveApiData/getRegistries.d.ts +5 -0
  115. package/dist/types/strategies/curve/fetch/curveApiData/getRegistries.d.ts.map +1 -0
  116. package/dist/types/strategies/curve/fetch/getAprBreakdown.d.ts +17 -0
  117. package/dist/types/strategies/curve/fetch/getAprBreakdown.d.ts.map +1 -0
  118. package/dist/types/strategies/curve/fetch/getCvxApr.d.ts +3 -0
  119. package/dist/types/strategies/curve/fetch/getCvxApr.d.ts.map +1 -0
  120. package/dist/types/strategies/curve/fetch/getOnlyboostData.d.ts +4 -0
  121. package/dist/types/strategies/curve/fetch/getOnlyboostData.d.ts.map +1 -0
  122. package/dist/types/strategies/curve/fetch/getStratsWithApr.d.ts +9 -0
  123. package/dist/types/strategies/curve/fetch/getStratsWithApr.d.ts.map +1 -0
  124. package/dist/types/strategies/curve/fetch/index.d.ts +10 -0
  125. package/dist/types/strategies/curve/fetch/index.d.ts.map +1 -0
  126. package/dist/types/strategies/curve/fetch/types.d.ts +11 -0
  127. package/dist/types/strategies/curve/fetch/types.d.ts.map +1 -0
  128. package/dist/types/strategies/curve/httpCalls.d.ts +18 -0
  129. package/dist/types/strategies/curve/httpCalls.d.ts.map +1 -0
  130. package/dist/types/strategies/curve/onChainCalls.d.ts +2 -0
  131. package/dist/types/strategies/curve/onChainCalls.d.ts.map +1 -0
  132. package/dist/types/strategies/types.d.ts +130 -0
  133. package/dist/types/strategies/types.d.ts.map +1 -0
  134. package/dist/types/strategies/utils/boost.d.ts +2 -0
  135. package/dist/types/strategies/utils/boost.d.ts.map +1 -0
  136. package/dist/types/strategies/utils/decodeEtherscanFactoryEvent.d.ts +4 -0
  137. package/dist/types/strategies/utils/decodeEtherscanFactoryEvent.d.ts.map +1 -0
  138. package/dist/types/strategies/utils/index.d.ts +6 -0
  139. package/dist/types/strategies/utils/index.d.ts.map +1 -0
  140. package/dist/types/strategies/utils/promise.d.ts +2 -0
  141. package/dist/types/strategies/utils/promise.d.ts.map +1 -0
  142. package/dist/types/strategies/utils/sdt.d.ts +16 -0
  143. package/dist/types/strategies/utils/sdt.d.ts.map +1 -0
  144. package/dist/types/utils.d.ts +33 -0
  145. package/dist/types/utils.d.ts.map +1 -0
  146. package/package.json +54 -0
  147. package/src/batches/curveStrats.ts +166 -0
  148. package/src/batches/index.ts +3 -0
  149. package/src/batches/sdtGaugeRewards.ts +26 -0
  150. package/src/batches/tokenData.ts +26 -0
  151. package/src/batches/types.ts +14 -0
  152. package/src/endpoints.ts +2 -0
  153. package/src/index.ts +7 -0
  154. package/src/number.ts +51 -0
  155. package/src/prices.ts +86 -0
  156. package/src/sdt/sdt.ts +110 -0
  157. package/src/sdt/veSdtAlternativeYields.ts +19 -0
  158. package/src/strategies/curve/build.ts +187 -0
  159. package/src/strategies/curve/endpoints.ts +21 -0
  160. package/src/strategies/curve/fetch/curveApiData/abi.ts +81 -0
  161. package/src/strategies/curve/fetch/curveApiData/bytecode.ts +43 -0
  162. package/src/strategies/curve/fetch/curveApiData/config.ts +56 -0
  163. package/src/strategies/curve/fetch/curveApiData/getCurveApiData.ts +207 -0
  164. package/src/strategies/curve/fetch/curveApiData/getGaugesFromRegistry.ts +41 -0
  165. package/src/strategies/curve/fetch/curveApiData/getGaugesWeights.ts +52 -0
  166. package/src/strategies/curve/fetch/curveApiData/getPoolsFromRegistries.ts.ts +36 -0
  167. package/src/strategies/curve/fetch/curveApiData/getRegistries.ts +25 -0
  168. package/src/strategies/curve/fetch/getAprBreakdown.ts +98 -0
  169. package/src/strategies/curve/fetch/getCvxApr.ts +49 -0
  170. package/src/strategies/curve/fetch/getOnlyboostData.ts +100 -0
  171. package/src/strategies/curve/fetch/getStratsWithApr.ts +118 -0
  172. package/src/strategies/curve/fetch/index.ts +276 -0
  173. package/src/strategies/curve/fetch/types.ts +11 -0
  174. package/src/strategies/curve/httpCalls.ts +117 -0
  175. package/src/strategies/curve/onChainCalls.ts +36 -0
  176. package/src/strategies/types.ts +137 -0
  177. package/src/strategies/utils/boost.ts +41 -0
  178. package/src/strategies/utils/decodeEtherscanFactoryEvent.ts +42 -0
  179. package/src/strategies/utils/index.ts +8 -0
  180. package/src/strategies/utils/promise.ts +10 -0
  181. package/src/strategies/utils/sdt.ts +206 -0
  182. package/src/utils.ts +171 -0
@@ -0,0 +1,276 @@
1
+ import { formatUnits } from 'viem'
2
+
3
+ import { ONE_YEAR, curveStrats, mainnet, tokenWithId } from '@stake-dao/constants'
4
+ import { equalTlc } from '../../../utils.js'
5
+ import type { OnlyBoostData, RewardsData, SdtApr } from '../../types.js'
6
+ import { getBoost } from '../../utils/boost.js'
7
+ import decodeEtherscanFactoryEvent, { decodeNewFactoryEvent } from '../../utils/decodeEtherscanFactoryEvent.js'
8
+ import { OneEther, Zero } from '../../utils/index.js'
9
+ import { type SdtEmissionData, computeSdtApr } from '../../utils/sdt.js'
10
+ import { buildCurveStrategies } from '../build.js'
11
+ import { getCurveHttpCalls } from '../httpCalls.js'
12
+ import { getOnChainSdCurveData } from '../onChainCalls.js'
13
+ import type { GaugesWeightsData } from './curveApiData/getGaugesWeights.js'
14
+ import { getAprBreakdown } from './getAprBreakdown.js'
15
+ import { getCvxApr } from './getCvxApr.js'
16
+ import getOnlyboostData from './getOnlyboostData.js'
17
+ import { getCurveLendingWithApr, getCurveStratsWithApr } from './getStratsWithApr.js'
18
+ import type { StratGlobalData } from './types.js'
19
+
20
+ export const fetchCurve = async (
21
+ prices: any, // TODO Type
22
+ provider: any,
23
+ rpc: string,
24
+ explorerApiKey: string,
25
+ explorer: string,
26
+ chainId: number,
27
+ lastBlockNumber: number,
28
+ sdtEmissionData: SdtEmissionData,
29
+ gaugesWeights: GaugesWeightsData,
30
+ ) => {
31
+ const apisData = await getCurveHttpCalls(explorerApiKey, explorer, rpc, chainId, lastBlockNumber, gaugesWeights)
32
+
33
+ const newVaultAndLp =
34
+ chainId === mainnet.id
35
+ ? decodeNewFactoryEvent(apisData.explorerData)
36
+ : decodeEtherscanFactoryEvent(apisData.explorerData)
37
+
38
+ const allVaultAndLp = curveStrats.strats[chainId]!.concat(newVaultAndLp)
39
+
40
+ const strats: any[] = await buildCurveStrategies(provider, allVaultAndLp, chainId, apisData.curveApiData)
41
+
42
+ const { curveStratsWithApr, curveStratsDataCalls } = getCurveStratsWithApr(chainId, strats, apisData)
43
+ const { curveLendingWithApr, curveLendingDataCalls } = await getCurveLendingWithApr(
44
+ provider,
45
+ chainId,
46
+ strats,
47
+ apisData,
48
+ )
49
+
50
+ const stratsWithApr = [...curveStratsWithApr, ...curveLendingWithApr]
51
+ const stratsDataCalls = [...curveStratsDataCalls, ...curveLendingDataCalls]
52
+
53
+ const decodedPromise = await getOnChainSdCurveData(chainId, rpc, stratsDataCalls)
54
+
55
+ const global: StratGlobalData = {
56
+ totalGaugeWeights: '0',
57
+ nextEffectiveTimestamp: '0',
58
+ cvxTotalSupply: '0',
59
+ veCrvTotalSupply: '0',
60
+ stakeDaoVeBoost: '0',
61
+ convexVeBoost: '0',
62
+ fees: {
63
+ veSdt: 0,
64
+ perf: 0,
65
+ accumulator: 0,
66
+ claimer: 0,
67
+ },
68
+ }
69
+
70
+ // TODO stratsData type
71
+ let stratsData: any[] = []
72
+
73
+ const crv = tokenWithId('crv', chainId)
74
+ decodedPromise.forEach((d: any, index: number) => {
75
+ if (index === 0 && chainId === mainnet.id) {
76
+ global.totalGaugeWeights = formatUnits(d.totalGaugeWeights, 0)
77
+ global.nextEffectiveTimestamp = formatUnits(d.nextEffectiveTimestamp, 0)
78
+ global.cvxTotalSupply = formatUnits(d.cvxTotalSupply, 0)
79
+ global.veCrvTotalSupply = formatUnits(d.veCrvTotalSupply, 0)
80
+ global.stakeDaoVeBoost = formatUnits(d.stakeDaoVeBoost, 0)
81
+ global.convexVeBoost = formatUnits(d.convexVeBoost, 0)
82
+
83
+ global.fees = {
84
+ veSdt: 5,
85
+ perf: 2,
86
+ accumulator: 8,
87
+ claimer: Number(d.claimerFee) / 100,
88
+ }
89
+ }
90
+ const parsedData = d.curveStratsData.map((v: any) => {
91
+ const strat = stratsWithApr.find((s) => equalTlc(s.vault, v.vault))
92
+
93
+ let onlyboost: OnlyBoostData = {} as OnlyBoostData
94
+ let totalSupply = '0'
95
+ let boost = 2.5
96
+
97
+ if (chainId === mainnet.id && v.onlyboost.active) {
98
+ onlyboost = getOnlyboostData(
99
+ v.onlyboost,
100
+ global.stakeDaoVeBoost,
101
+ global.convexVeBoost,
102
+ global.veCrvTotalSupply,
103
+ v.curveGaugeTotalSupply,
104
+ v.strategyHoldings,
105
+ v.workingBalance,
106
+ v.totalSupply,
107
+ strat.lpPriceInUsd,
108
+ )
109
+ totalSupply = onlyboost.totalSupply
110
+ boost = onlyboost.boost
111
+ } else {
112
+ totalSupply = formatUnits(v.totalSupply, 0)
113
+ boost = getBoost('curve', v.strategyHoldings, v.workingBalance)
114
+ }
115
+
116
+ const tvl = Number(formatUnits(BigInt(totalSupply), 18)) * strat.lpPriceInUsd
117
+
118
+ const sdGauge = {
119
+ address: strat.sdGauge,
120
+ totalSupply: formatUnits(v.sdGaugeTotalSupply, 0),
121
+ ...(chainId === mainnet.id
122
+ ? {
123
+ relativeWeight: formatUnits(v.gaugeRelativeWeight, 0),
124
+ weight: formatUnits(v.gaugeWeight, 0),
125
+ futureWeight:
126
+ BigInt(global.totalGaugeWeights) > 0
127
+ ? formatUnits(((v.gaugeWeight as bigint) * OneEther * OneEther) / BigInt(global.totalGaugeWeights), 0)
128
+ : '0',
129
+ workingSupply: formatUnits(v.sdWorkingSupply, 0),
130
+ }
131
+ : { relativeWeight: '0', weight: '0', futureWeight: '0', workingSupply: '0' }),
132
+ }
133
+
134
+ const rewardsData: RewardsData[] = v.rewardsData.map((r: any, rewardIndex: number) => {
135
+ const rewardToken = strat.rewards[rewardIndex]
136
+ const rewardPrice = prices.find((p: any) => equalTlc(p.symbol, rewardToken.symbol))
137
+
138
+ const periodFinish = Number(formatUnits(r.period_finish, 0))
139
+ const streaming = periodFinish > Math.floor(Date.now() / 1000)
140
+
141
+ const rewardApr =
142
+ streaming && rewardPrice && tvl > 0
143
+ ? (Number(formatUnits(r.rate * BigInt(ONE_YEAR), 18)) * rewardPrice.usdPrice) /
144
+ tvl /
145
+ (equalTlc(rewardToken.symbol, 'SDT') ? 2.5 : 1)
146
+ : 0
147
+
148
+ return {
149
+ token: rewardToken,
150
+ price: rewardPrice ? rewardPrice.usdPrice : 0,
151
+ apr: rewardApr,
152
+ streaming,
153
+ periodFinish,
154
+ rate: formatUnits(r.rate, 0),
155
+ lastUpdate: formatUnits(r.last_update, 0),
156
+ claimablePendingRewards: equalTlc(v.rewardsTokens[rewardIndex], crv?.address!)
157
+ ? formatUnits(v.claimablePendingRewards, 0)
158
+ : formatUnits(
159
+ v.claimableData.find((c: any) => c.token === v.rewardsTokens[rewardIndex])?.claimable || Zero,
160
+ 0,
161
+ ),
162
+ }
163
+ })
164
+
165
+ let sdtApr: SdtApr = {
166
+ sdtUserApr: 0,
167
+ sdtFuturUserApr: 0,
168
+ sdtMinApr: 0,
169
+ sdtFuturMinApr: 0,
170
+ sdtMaxApr: 0,
171
+ sdtFuturMaxApr: 0,
172
+ sdtBoost: 1,
173
+ }
174
+ const sdtRewards = rewardsData.find((r) => r.token.symbol === 'SDT')
175
+ if (sdtRewards) {
176
+ sdtApr = computeSdtApr(sdtEmissionData, sdtRewards, undefined, sdGauge, strat.lpPriceInUsd)
177
+ }
178
+
179
+ let convexCrvProjectedApr = 0
180
+ let cvxApr = 0
181
+
182
+ if (onlyboost.active) {
183
+ convexCrvProjectedApr = onlyboost.convex.boost * strat.minApr
184
+ cvxApr =
185
+ onlyboost.active && onlyboost.convex.tvl > 0
186
+ ? getCvxApr(
187
+ onlyboost.convex.tvl,
188
+ tvl,
189
+ convexCrvProjectedApr,
190
+ global.cvxTotalSupply,
191
+ prices.find((p: any) => equalTlc(p.symbol, 'CVX'))?.usdPrice || 0,
192
+ )
193
+ : 0
194
+ }
195
+
196
+ const apr = getAprBreakdown(strat, rewardsData, boost, cvxApr, sdtApr)
197
+
198
+ return {
199
+ ...strat,
200
+ tvl,
201
+ apr: {
202
+ boost,
203
+ ...apr,
204
+ ...(onlyboost?.active
205
+ ? {
206
+ onlyboost: {
207
+ convex: {
208
+ projected: {
209
+ baseToken: strat.minApr ? onlyboost.convex.boost * strat.minApr : undefined,
210
+ },
211
+ },
212
+ optimal: {
213
+ projected: {
214
+ baseToken: strat.minApr ? onlyboost.optimalBoost * strat.minApr : undefined,
215
+ },
216
+ },
217
+ },
218
+ }
219
+ : {}),
220
+ },
221
+ sdtApr,
222
+ rewards: rewardsData,
223
+
224
+ vaultHoldings: formatUnits(v.vaultHoldings, 0),
225
+ totalSupply,
226
+ strategyHoldings: formatUnits(v.strategyHoldings, 0),
227
+ workingBalance: formatUnits(v.workingBalance, 0),
228
+ workingSupplyStaked: formatUnits(v.workingSupplyStaked, 0),
229
+ sdGauge,
230
+ vaultFees:
231
+ chainId === mainnet.id
232
+ ? {
233
+ keeper: Number(v.keeperFee) / 100,
234
+ accumulated: formatUnits(v.accumulatedFees, 0),
235
+ }
236
+ : { keeper: 0, accumulated: '0' },
237
+ // onlyboost
238
+ ...(chainId === mainnet.id && onlyboost?.active ? { onlyboost } : {}),
239
+ }
240
+ })
241
+ stratsData = stratsData.concat(parsedData)
242
+ })
243
+
244
+ // const deployedStratsGauges = stratsData.map((s) => s.gaugeAddress)
245
+
246
+ // const notDeployedStrats = apisData.curveApiData
247
+ // .flatMap((d) => d.value)
248
+ // .filter(
249
+ // (curvePool) =>
250
+ // curvePool?.gaugeAddress &&
251
+ // !deployedStratsGauges.includes(curvePool.gaugeAddress) &&
252
+ // ((curvePool.gaugeCrvApy &&
253
+ // curvePool.gaugeCrvApy.length > 1 &&
254
+ // curvePool.gaugeCrvApy[1] !== null &&
255
+ // curvePool.gaugeCrvApy[1] > 0) ||
256
+ // (curvePool.gaugeRewards && curvePool.gaugeRewards.length > 0)),
257
+ // )
258
+ // .map((s) => ({
259
+ // ...s,
260
+ // protocol: 'curve',
261
+ // chainId,
262
+ // convexPool:
263
+ // chainId === 1
264
+ // ? apisData.convexPools.find(
265
+ // (pool: any) => pool.lpTokenAddress.toLowerCase() === s.lpTokenAddress.toLowerCase(),
266
+ // )?.convexPoolData || undefined
267
+ // : undefined,
268
+ // }))
269
+
270
+ return {
271
+ global,
272
+ deployed: stratsData,
273
+ notDeployed: [],
274
+ fetched: true,
275
+ }
276
+ }
@@ -0,0 +1,11 @@
1
+ import type { Fees } from '../../types.js'
2
+
3
+ export type StratGlobalData = {
4
+ totalGaugeWeights: string
5
+ nextEffectiveTimestamp: string
6
+ cvxTotalSupply: string
7
+ veCrvTotalSupply: string
8
+ stakeDaoVeBoost: string
9
+ convexVeBoost: string
10
+ fees: Fees
11
+ }
@@ -0,0 +1,117 @@
1
+ import { contract } from '@stake-dao/constants'
2
+ import {
3
+ CONVEX_LENDING_VAULTS_URL,
4
+ CONVEX_POOLS_URL,
5
+ CURVE_API_URL,
6
+ FACTORY_EXPLORER_EVENTS,
7
+ NEW_FACTORY_EXPLORER_EVENTS,
8
+ } from './endpoints.js'
9
+ import { fetchCurveBase } from './fetch/curveApiData/getCurveApiData.js'
10
+ import { type GaugesWeightsData } from './fetch/curveApiData/getGaugesWeights.js'
11
+
12
+ export const getCurveHttpCalls = async (
13
+ explorerApiKey: string,
14
+ explorer: string,
15
+ rpc: string,
16
+ chainId: number,
17
+ lastBlockNumber: number,
18
+ gaugesWeights: GaugesWeightsData,
19
+ ) => {
20
+ switch (chainId) {
21
+ case 1: {
22
+ const ethHttpCalls = [
23
+ // Etherscan Events
24
+ (
25
+ await fetch(
26
+ NEW_FACTORY_EXPLORER_EVENTS(
27
+ explorerApiKey,
28
+ explorer,
29
+ contract('curveVaultFactory', chainId),
30
+ lastBlockNumber,
31
+ ),
32
+ )
33
+ ).json(),
34
+ // Curve Data (replace APIs calls)
35
+ fetchCurveBase(rpc, chainId, gaugesWeights.gauges),
36
+ // Curve Trading Apy API
37
+ (await fetch(`${CURVE_API_URL}/getSubgraphData/ethereum`)).json(),
38
+ // Convex API for OnlyBoost
39
+ (await fetch(CONVEX_POOLS_URL)).json(),
40
+ (await fetch(CONVEX_LENDING_VAULTS_URL)).json(),
41
+ ]
42
+
43
+ const ethHttpResponses = (await Promise.allSettled(ethHttpCalls)).map((result) =>
44
+ result.status === 'fulfilled' ? result.value : result.reason,
45
+ )
46
+
47
+ const etherscanData = ethHttpResponses[0]
48
+ const ethCurveData = ethHttpResponses[1]
49
+ const ethCurveSubgraph = ethHttpResponses[2].success ? ethHttpResponses[2].data.poolList : undefined
50
+ const convexPools = ethHttpResponses[3].pools
51
+ const convexLendingVaults = ethHttpResponses[4].lendingVaults
52
+
53
+ return {
54
+ explorerData: etherscanData,
55
+ curveSubgraphData: ethCurveSubgraph,
56
+ convexPools,
57
+ convexLendingVaults,
58
+ curveApiData: ethCurveData,
59
+ }
60
+ }
61
+ case 42161: {
62
+ const arbitrumHttpCalls = [
63
+ // Etherscan Events
64
+ (
65
+ await fetch(
66
+ FACTORY_EXPLORER_EVENTS(explorerApiKey, explorer, contract('curveVaultFactory', chainId), lastBlockNumber),
67
+ )
68
+ ).json(),
69
+ // Curve Apis
70
+ (await fetch(`${CURVE_API_URL}/getPools/arbitrum/factory`)).json(),
71
+ (await fetch(`${CURVE_API_URL}/getPools/arbitrum/main`)).json(),
72
+ (await fetch(`${CURVE_API_URL}/getPools/arbitrum/crypto`)).json(),
73
+ (await fetch(`${CURVE_API_URL}/getPools/arbitrum/factory-stable-ng`)).json(),
74
+ (await fetch(`${CURVE_API_URL}/getPools/arbitrum/factory-tricrypto`)).json(),
75
+ (await fetch(`${CURVE_API_URL}/getSubgraphData/arbitrum`)).json(),
76
+ ]
77
+
78
+ const arbitrumHttpResponses = (await Promise.allSettled(arbitrumHttpCalls)).map((result) =>
79
+ result.status === 'fulfilled' ? result.value : result.reason,
80
+ )
81
+
82
+ const arbiscanData = arbitrumHttpResponses[0]
83
+ const arbitrumCurveFactory = arbitrumHttpResponses[1].success ? arbitrumHttpResponses[1].data.poolData : undefined
84
+ const arbitrumCurveMain = arbitrumHttpResponses[2].success ? arbitrumHttpResponses[2].data.poolData : undefined
85
+ const arbitrumCurveCrypto = arbitrumHttpResponses[3].success ? arbitrumHttpResponses[3].data.poolData : undefined
86
+ const arbitrumCurveFactoryStableNg = arbitrumHttpResponses[4].success
87
+ ? arbitrumHttpResponses[4].data.poolData
88
+ : undefined
89
+ const arbitrumCurveFactoryTriCrypto = arbitrumHttpResponses[5].success
90
+ ? arbitrumHttpResponses[5].data.poolData
91
+ : undefined
92
+ const arbitrumCurveSubgraph = arbitrumHttpResponses[6].success
93
+ ? arbitrumHttpResponses[6].data.poolList
94
+ : undefined
95
+
96
+ return {
97
+ explorerData: arbiscanData,
98
+ curveSubgraphData: arbitrumCurveSubgraph,
99
+ convexPools: [],
100
+ curveApiData: [
101
+ { type: 'factory-tricrypto', value: arbitrumCurveFactoryTriCrypto },
102
+ { type: 'factory', value: arbitrumCurveFactory },
103
+ { type: 'main', value: arbitrumCurveMain },
104
+ { type: 'crypto', value: arbitrumCurveCrypto },
105
+ { type: 'factory-stable-ng', value: arbitrumCurveFactoryStableNg },
106
+ ],
107
+ }
108
+ }
109
+ }
110
+
111
+ return {
112
+ explorerData: undefined,
113
+ curveSubgraphData: undefined,
114
+ convexPools: [],
115
+ curveApiData: [],
116
+ }
117
+ }
@@ -0,0 +1,36 @@
1
+ import { contract, mainnet } from '@stake-dao/constants'
2
+ import { chunk } from 'lodash-es'
3
+ import { encodeAbiParameters, parseAbiParameters } from 'viem'
4
+ import { batchCurveStrats } from '../../batches/index.js'
5
+ import { batchJsonRpc } from '../../utils.js'
6
+
7
+ export const getOnChainSdCurveData = async (chainId: number, rpc: string, calls: any[]) => {
8
+ const inputArgsChunks = chunk(calls, 12)
9
+
10
+ const allContractCreationCodes: string[] = inputArgsChunks.map((inputArgs) => {
11
+ const inputParams =
12
+ chainId === mainnet.id
13
+ ? [
14
+ contract('convexProxyFactory', chainId),
15
+ contract('curveStrategy', chainId),
16
+ contract('sdGaugeController', chainId),
17
+ inputArgs,
18
+ ]
19
+ : [contract('curveStratsFeeRegistry', chainId), inputArgs]
20
+
21
+ const inputData = encodeAbiParameters(
22
+ parseAbiParameters(batchCurveStrats.inputType[chainId] || []) as any,
23
+ inputParams,
24
+ )
25
+ return batchCurveStrats.bytecode[chainId]?.concat(inputData.slice(2)) as string
26
+ })
27
+
28
+ const decodedPromise = await batchJsonRpc({
29
+ rpc,
30
+ calls: allContractCreationCodes,
31
+ outputTypeAbi: batchCurveStrats.outputType ? batchCurveStrats.outputType[chainId] : [],
32
+ parse: false,
33
+ })
34
+
35
+ return decodedPromise
36
+ }
@@ -0,0 +1,137 @@
1
+ export type Coin = {
2
+ name: string
3
+ symbol: string
4
+ address: string
5
+ decimals: number
6
+ }
7
+
8
+ export type AprDetail = {
9
+ total: number
10
+ details: {
11
+ label: string
12
+ value: number[]
13
+ }[]
14
+ }
15
+
16
+ export type OnlyBoostAprDetail = {
17
+ projected: {
18
+ baseToken: number
19
+ }
20
+ }
21
+
22
+ export type OnlyBoostProtocolData = {
23
+ tvl: number
24
+ supply: string
25
+ boost: number
26
+ optimal: {
27
+ supply: string
28
+ boost: number
29
+ share: number
30
+ }
31
+ claimable?: {
32
+ token: string
33
+ claimable: string
34
+ }[]
35
+ }
36
+
37
+ export type OnlyBoostData = {
38
+ active: boolean
39
+ implementations: {
40
+ key: string
41
+ address: string
42
+ }[]
43
+ totalSupply: string
44
+ boost: number
45
+ optimalBoost: number
46
+ stakeDao: OnlyBoostProtocolData
47
+ convex: OnlyBoostProtocolData
48
+ }
49
+
50
+ export type SdGauge = {
51
+ address: string
52
+ totalSupply: string
53
+ relativeWeight: string
54
+ weight: string
55
+ futureWeight: string
56
+ workingSupply: string
57
+ }
58
+
59
+ export type Fees = {
60
+ veSdt: number
61
+ perf: number
62
+ accumulator: number
63
+ claimer: number
64
+ }
65
+
66
+ export type VaultFees = {
67
+ keeper: number
68
+ accumulated: number
69
+ }
70
+
71
+ export type SdtApr = {
72
+ sdtUserApr: number
73
+ sdtFuturUserApr: number
74
+ sdtMinApr: number
75
+ sdtFuturMinApr: number
76
+ sdtMaxApr: number
77
+ sdtFuturMaxApr: number
78
+ sdtBoost: number
79
+ }
80
+
81
+ export type RewardsData = {
82
+ token: Coin
83
+ price: number
84
+ apr: number
85
+ streaming: boolean
86
+ periodFinish: number
87
+ rate: string
88
+ lastUpdate: string
89
+ claimablePendingRewards: string
90
+ }
91
+
92
+ export type Strategy = {
93
+ key: string
94
+ type: string
95
+ protocol: string
96
+ chainId: number
97
+ isMetapool: boolean
98
+ isLending: boolean
99
+ vault: string
100
+ lpToken: Coin
101
+ gaugeAddress: string
102
+ coins: Coin[]
103
+ underlyingCoins?: Coin[]
104
+ rewards: RewardsData[]
105
+ name: string
106
+ minApr: number
107
+ maxApr: number
108
+ lpPriceInUsd: number
109
+ convexPool?: {
110
+ id: number
111
+ token: string
112
+ gauge: string
113
+ crvRewards: string
114
+ stash: string
115
+ shutdown: boolean
116
+ usdTotal: number
117
+ }
118
+ tvl: number
119
+ apr: {
120
+ boost: number
121
+ current: AprDetail
122
+ projected: AprDetail
123
+ onlyboost: {
124
+ convex: OnlyBoostAprDetail
125
+ optimal: OnlyBoostAprDetail
126
+ }
127
+ }
128
+ sdtApr: SdtApr
129
+ vaultHoldings: string
130
+ totalSupply: string
131
+ strategyHoldings: string
132
+ workingBalance: string
133
+ workingSupplyStaked: string
134
+ sdGauge: SdGauge
135
+ vaultFees: VaultFees
136
+ onlyboost?: OnlyBoostData | { active: boolean }
137
+ }
@@ -0,0 +1,41 @@
1
+ import { formatUnits } from 'viem'
2
+ import { OneEther, Zero } from './index.js'
3
+
4
+ export const getBoost = (protocol: string, strategyHoldings: bigint, workingBalance: bigint): number => {
5
+ switch (protocol) {
6
+ case 'curve':
7
+ return Number(
8
+ strategyHoldings > Zero
9
+ ? formatUnits((workingBalance * OneEther) / ((strategyHoldings * BigInt(4)) / BigInt(10)), 18)
10
+ : '2.5',
11
+ )
12
+ case 'balancer':
13
+ return Number(
14
+ strategyHoldings > Zero
15
+ ? formatUnits((workingBalance * OneEther) / ((strategyHoldings * BigInt(4)) / BigInt(10)), 18)
16
+ : '1',
17
+ )
18
+ case 'angle':
19
+ return Number(
20
+ strategyHoldings > Zero
21
+ ? formatUnits((workingBalance * OneEther) / ((strategyHoldings * BigInt(4)) / BigInt(10)), 18)
22
+ : '1',
23
+ )
24
+ case 'pendle':
25
+ return Number(
26
+ strategyHoldings > Zero
27
+ ? formatUnits((workingBalance * OneEther) / ((strategyHoldings * BigInt(4)) / BigInt(10)), 18)
28
+ : '2.5',
29
+ )
30
+ case 'yearn':
31
+ return Number(
32
+ strategyHoldings > Zero
33
+ ? Math.min(1, Number(formatUnits((workingBalance * OneEther) / strategyHoldings, 18))) * 10
34
+ : '10',
35
+ )
36
+ default:
37
+ break
38
+ }
39
+
40
+ return 0
41
+ }
@@ -0,0 +1,42 @@
1
+ import { decodeEventLog, parseAbiItem } from 'viem'
2
+
3
+ const decodeEtherscanFactoryEvent = (explorerData: any, onlyVault: boolean = false) => {
4
+ return explorerData.status === '1' && explorerData.result
5
+ ? explorerData.result.map((event: any) => {
6
+ const decodedData = decodeEventLog({
7
+ abi: [
8
+ parseAbiItem('event VaultDeployed(address proxy, address lpToken, address impl)'),
9
+ ...(onlyVault ? [] : [parseAbiItem('event GaugeDeployed(address proxy, address lpToken, address impl)')]),
10
+ ],
11
+ data: event.data,
12
+ topics: event.topics,
13
+ })
14
+ return {
15
+ vault: decodedData.args.proxy,
16
+ lpToken: decodedData.args.lpToken,
17
+ }
18
+ })
19
+ : []
20
+ }
21
+
22
+ export const decodeNewFactoryEvent = (explorerData: any) => {
23
+ return explorerData.status === '1' && explorerData.result
24
+ ? explorerData.result.map((event: any) => {
25
+ const decodedData = decodeEventLog({
26
+ abi: [
27
+ parseAbiItem('event PoolDeployed(address vault, address rewardDistributor, address token, address gauge)'),
28
+ ],
29
+ data: event.data,
30
+ topics: event.topics,
31
+ })
32
+ return {
33
+ vault: decodedData.args.vault,
34
+ sdGauge: decodedData.args.rewardDistributor,
35
+ lpToken: decodedData.args.token,
36
+ gauge: decodedData.args.gauge,
37
+ }
38
+ })
39
+ : []
40
+ }
41
+
42
+ export default decodeEtherscanFactoryEvent
@@ -0,0 +1,8 @@
1
+ import { parseEther } from 'viem'
2
+
3
+ export const Zero = BigInt(0)
4
+ export const OneEther = parseEther('1')
5
+
6
+ export * from './boost.js'
7
+ export * from './decodeEtherscanFactoryEvent.js'
8
+ export * from './sdt.js'
@@ -0,0 +1,10 @@
1
+ export const handlePromise = async (promises: Promise<any>[], key: string) => {
2
+ const promisesResults = await Promise.allSettled(promises)
3
+
4
+ return promisesResults.map((pr, index) => {
5
+ if (pr.status === 'rejected') {
6
+ throw Error(`${key}: promise error index ${index}\n${pr.reason}`)
7
+ }
8
+ return pr.value
9
+ })
10
+ }