@stake-dao/reader 0.1.0 → 0.1.2

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 (210) hide show
  1. package/dist/esm/batches/buildYearnStrats.js +39 -0
  2. package/dist/esm/batches/buildYearnStrats.js.map +1 -0
  3. package/dist/esm/batches/curveStrats.js +4 -6
  4. package/dist/esm/batches/curveStrats.js.map +1 -1
  5. package/dist/esm/batches/fetchYearnGauges.js +76 -0
  6. package/dist/esm/batches/fetchYearnGauges.js.map +1 -0
  7. package/dist/esm/batches/index.js +2 -0
  8. package/dist/esm/batches/index.js.map +1 -1
  9. package/dist/esm/index.js +2 -0
  10. package/dist/esm/index.js.map +1 -1
  11. package/dist/esm/lockers/abis/MulticallLockers.json +591 -0
  12. package/dist/esm/lockers/fetch/index.js +306 -0
  13. package/dist/esm/lockers/fetch/index.js.map +1 -0
  14. package/dist/esm/lockers/utils/cakeLockerAirdrop.js +46 -0
  15. package/dist/esm/lockers/utils/cakeLockerAirdrop.js.map +1 -0
  16. package/dist/esm/lockers/utils/callsForLockers/depositorCalls.js +20 -0
  17. package/dist/esm/lockers/utils/callsForLockers/depositorCalls.js.map +1 -0
  18. package/dist/esm/lockers/utils/callsForLockers/feeCalls.js +94 -0
  19. package/dist/esm/lockers/utils/callsForLockers/feeCalls.js.map +1 -0
  20. package/dist/esm/lockers/utils/callsForLockers/gaugeCalls.js +6 -0
  21. package/dist/esm/lockers/utils/callsForLockers/gaugeCalls.js.map +1 -0
  22. package/dist/esm/lockers/utils/callsForLockers/gaugeControllerCalls.js +8 -0
  23. package/dist/esm/lockers/utils/callsForLockers/gaugeControllerCalls.js.map +1 -0
  24. package/dist/esm/lockers/utils/callsForLockers/index.js +29 -0
  25. package/dist/esm/lockers/utils/callsForLockers/index.js.map +1 -0
  26. package/dist/esm/lockers/utils/callsForLockers/pegCalls.js +38 -0
  27. package/dist/esm/lockers/utils/callsForLockers/pegCalls.js.map +1 -0
  28. package/dist/esm/lockers/utils/callsForLockers/veCalls.js +26 -0
  29. package/dist/esm/lockers/utils/callsForLockers/veCalls.js.map +1 -0
  30. package/dist/esm/lockers/utils/callsForLockers/veSdtCalls.js +14 -0
  31. package/dist/esm/lockers/utils/callsForLockers/veSdtCalls.js.map +1 -0
  32. package/dist/esm/lockers/utils/endpoints.js +23 -0
  33. package/dist/esm/lockers/utils/endpoints.js.map +1 -0
  34. package/dist/esm/lockers/utils/getBribesRewardsData.js +46 -0
  35. package/dist/esm/lockers/utils/getBribesRewardsData.js.map +1 -0
  36. package/dist/esm/lockers/utils/getCherriesLeaderBoard.js +22 -0
  37. package/dist/esm/lockers/utils/getCherriesLeaderBoard.js.map +1 -0
  38. package/dist/esm/lockers/utils/getFees.js +30 -0
  39. package/dist/esm/lockers/utils/getFees.js.map +1 -0
  40. package/dist/esm/lockers/utils/getHttpCalls.js +44 -0
  41. package/dist/esm/lockers/utils/getHttpCalls.js.map +1 -0
  42. package/dist/esm/lockers/utils/getSdtInflationData.js +38 -0
  43. package/dist/esm/lockers/utils/getSdtInflationData.js.map +1 -0
  44. package/dist/esm/lockers/utils/index.js +157 -0
  45. package/dist/esm/lockers/utils/index.js.map +1 -0
  46. package/dist/esm/lockers/utils/substractFees.js +22 -0
  47. package/dist/esm/lockers/utils/substractFees.js.map +1 -0
  48. package/dist/esm/strategies/curve/build.js +10 -7
  49. package/dist/esm/strategies/curve/build.js.map +1 -1
  50. package/dist/esm/strategies/curve/fetch/curveApiData/abi.js +1 -1
  51. package/dist/esm/strategies/curve/fetch/curveApiData/abi.js.map +1 -1
  52. package/dist/esm/strategies/curve/fetch/curveApiData/bytecode.js +3 -3
  53. package/dist/esm/strategies/curve/fetch/curveApiData/bytecode.js.map +1 -1
  54. package/dist/esm/strategies/curve/fetch/curveApiData/config.js +1 -1
  55. package/dist/esm/strategies/curve/fetch/curveApiData/getCurveApiData.js +3 -6
  56. package/dist/esm/strategies/curve/fetch/curveApiData/getCurveApiData.js.map +1 -1
  57. package/dist/esm/strategies/curve/fetch/curveApiData/getGaugesWeights.js +1 -0
  58. package/dist/esm/strategies/curve/fetch/curveApiData/getGaugesWeights.js.map +1 -1
  59. package/dist/esm/strategies/curve/fetch/getStratsWithApr.js +26 -58
  60. package/dist/esm/strategies/curve/fetch/getStratsWithApr.js.map +1 -1
  61. package/dist/esm/strategies/curve/fetch/index.js +7 -23
  62. package/dist/esm/strategies/curve/fetch/index.js.map +1 -1
  63. package/dist/esm/strategies/curve/httpCalls.js +8 -24
  64. package/dist/esm/strategies/curve/httpCalls.js.map +1 -1
  65. package/dist/esm/strategies/utils/abis/MulticallYearnStratsAbi.json +107 -0
  66. package/dist/esm/strategies/{curve/fetch → utils}/getAprBreakdown.js +18 -8
  67. package/dist/esm/strategies/utils/getAprBreakdown.js.map +1 -0
  68. package/dist/esm/strategies/utils/index.js +1 -0
  69. package/dist/esm/strategies/utils/index.js.map +1 -1
  70. package/dist/esm/strategies/utils/sdt.js +17 -0
  71. package/dist/esm/strategies/utils/sdt.js.map +1 -1
  72. package/dist/esm/strategies/yearn/build.js +97 -0
  73. package/dist/esm/strategies/yearn/build.js.map +1 -0
  74. package/dist/esm/strategies/yearn/fetch/computeYearnApr.js +28 -0
  75. package/dist/esm/strategies/yearn/fetch/computeYearnApr.js.map +1 -0
  76. package/dist/esm/strategies/yearn/fetch/fetchAllYearnGauges.js +61 -0
  77. package/dist/esm/strategies/yearn/fetch/fetchAllYearnGauges.js.map +1 -0
  78. package/dist/esm/strategies/yearn/fetch/index.js +169 -0
  79. package/dist/esm/strategies/yearn/fetch/index.js.map +1 -0
  80. package/dist/esm/tsconfig.build.tsbuildinfo +1 -1
  81. package/dist/esm/utils.js +33 -1
  82. package/dist/esm/utils.js.map +1 -1
  83. package/dist/types/batches/buildYearnStrats.d.ts +4 -0
  84. package/dist/types/batches/buildYearnStrats.d.ts.map +1 -0
  85. package/dist/types/batches/curveStrats.d.ts.map +1 -1
  86. package/dist/types/batches/fetchYearnGauges.d.ts +4 -0
  87. package/dist/types/batches/fetchYearnGauges.d.ts.map +1 -0
  88. package/dist/types/batches/index.d.ts +2 -0
  89. package/dist/types/batches/index.d.ts.map +1 -1
  90. package/dist/types/index.d.ts +2 -0
  91. package/dist/types/index.d.ts.map +1 -1
  92. package/dist/types/lockers/fetch/index.d.ts +11 -0
  93. package/dist/types/lockers/fetch/index.d.ts.map +1 -0
  94. package/dist/types/lockers/utils/cakeLockerAirdrop.d.ts +8 -0
  95. package/dist/types/lockers/utils/cakeLockerAirdrop.d.ts.map +1 -0
  96. package/dist/types/lockers/utils/callsForLockers/depositorCalls.d.ts +3 -0
  97. package/dist/types/lockers/utils/callsForLockers/depositorCalls.d.ts.map +1 -0
  98. package/dist/types/lockers/utils/callsForLockers/feeCalls.d.ts +11 -0
  99. package/dist/types/lockers/utils/callsForLockers/feeCalls.d.ts.map +1 -0
  100. package/dist/types/lockers/utils/callsForLockers/gaugeCalls.d.ts +6 -0
  101. package/dist/types/lockers/utils/callsForLockers/gaugeCalls.d.ts.map +1 -0
  102. package/dist/types/lockers/utils/callsForLockers/gaugeControllerCalls.d.ts +11 -0
  103. package/dist/types/lockers/utils/callsForLockers/gaugeControllerCalls.d.ts.map +1 -0
  104. package/dist/types/lockers/utils/callsForLockers/index.d.ts +3 -0
  105. package/dist/types/lockers/utils/callsForLockers/index.d.ts.map +1 -0
  106. package/dist/types/lockers/utils/callsForLockers/pegCalls.d.ts +15 -0
  107. package/dist/types/lockers/utils/callsForLockers/pegCalls.d.ts.map +1 -0
  108. package/dist/types/lockers/utils/callsForLockers/veCalls.d.ts +3 -0
  109. package/dist/types/lockers/utils/callsForLockers/veCalls.d.ts.map +1 -0
  110. package/dist/types/lockers/utils/callsForLockers/veSdtCalls.d.ts +11 -0
  111. package/dist/types/lockers/utils/callsForLockers/veSdtCalls.d.ts.map +1 -0
  112. package/dist/types/lockers/utils/endpoints.d.ts +3 -0
  113. package/dist/types/lockers/utils/endpoints.d.ts.map +1 -0
  114. package/dist/types/lockers/utils/getBribesRewardsData.d.ts +18 -0
  115. package/dist/types/lockers/utils/getBribesRewardsData.d.ts.map +1 -0
  116. package/dist/types/lockers/utils/getCherriesLeaderBoard.d.ts +2 -0
  117. package/dist/types/lockers/utils/getCherriesLeaderBoard.d.ts.map +1 -0
  118. package/dist/types/lockers/utils/getFees.d.ts +4 -0
  119. package/dist/types/lockers/utils/getFees.d.ts.map +1 -0
  120. package/dist/types/lockers/utils/getHttpCalls.d.ts +11 -0
  121. package/dist/types/lockers/utils/getHttpCalls.d.ts.map +1 -0
  122. package/dist/types/lockers/utils/getSdtInflationData.d.ts +8 -0
  123. package/dist/types/lockers/utils/getSdtInflationData.d.ts.map +1 -0
  124. package/dist/types/lockers/utils/index.d.ts +30 -0
  125. package/dist/types/lockers/utils/index.d.ts.map +1 -0
  126. package/dist/types/lockers/utils/substractFees.d.ts +3 -0
  127. package/dist/types/lockers/utils/substractFees.d.ts.map +1 -0
  128. package/dist/types/strategies/curve/build.d.ts +2 -31
  129. package/dist/types/strategies/curve/build.d.ts.map +1 -1
  130. package/dist/types/strategies/curve/fetch/curveApiData/abi.d.ts.map +1 -1
  131. package/dist/types/strategies/curve/fetch/curveApiData/bytecode.d.ts +1 -1
  132. package/dist/types/strategies/curve/fetch/curveApiData/bytecode.d.ts.map +1 -1
  133. package/dist/types/strategies/curve/fetch/curveApiData/config.d.ts +1 -1
  134. package/dist/types/strategies/curve/fetch/curveApiData/getCurveApiData.d.ts.map +1 -1
  135. package/dist/types/strategies/curve/fetch/curveApiData/getGaugesWeights.d.ts +1 -0
  136. package/dist/types/strategies/curve/fetch/curveApiData/getGaugesWeights.d.ts.map +1 -1
  137. package/dist/types/strategies/curve/fetch/getStratsWithApr.d.ts +0 -4
  138. package/dist/types/strategies/curve/fetch/getStratsWithApr.d.ts.map +1 -1
  139. package/dist/types/strategies/curve/fetch/index.d.ts +2 -7
  140. package/dist/types/strategies/curve/fetch/index.d.ts.map +1 -1
  141. package/dist/types/strategies/curve/httpCalls.d.ts +3 -6
  142. package/dist/types/strategies/curve/httpCalls.d.ts.map +1 -1
  143. package/dist/types/strategies/types.d.ts +49 -6
  144. package/dist/types/strategies/types.d.ts.map +1 -1
  145. package/dist/types/strategies/utils/getAprBreakdown.d.ts +15 -0
  146. package/dist/types/strategies/utils/getAprBreakdown.d.ts.map +1 -0
  147. package/dist/types/strategies/utils/index.d.ts +1 -0
  148. package/dist/types/strategies/utils/index.d.ts.map +1 -1
  149. package/dist/types/strategies/utils/sdt.d.ts +1 -0
  150. package/dist/types/strategies/utils/sdt.d.ts.map +1 -1
  151. package/dist/types/strategies/yearn/build.d.ts +8 -0
  152. package/dist/types/strategies/yearn/build.d.ts.map +1 -0
  153. package/dist/types/strategies/yearn/fetch/computeYearnApr.d.ts +9 -0
  154. package/dist/types/strategies/yearn/fetch/computeYearnApr.d.ts.map +1 -0
  155. package/dist/types/strategies/yearn/fetch/fetchAllYearnGauges.d.ts +2 -0
  156. package/dist/types/strategies/yearn/fetch/fetchAllYearnGauges.d.ts.map +1 -0
  157. package/dist/types/strategies/yearn/fetch/index.d.ts +5 -0
  158. package/dist/types/strategies/yearn/fetch/index.d.ts.map +1 -0
  159. package/dist/types/utils.d.ts +5 -0
  160. package/dist/types/utils.d.ts.map +1 -1
  161. package/package.json +4 -3
  162. package/src/batches/buildYearnStrats.ts +41 -0
  163. package/src/batches/curveStrats.ts +4 -6
  164. package/src/batches/fetchYearnGauges.ts +78 -0
  165. package/src/batches/index.ts +2 -0
  166. package/src/index.ts +2 -0
  167. package/src/lockers/fetch/index.ts +407 -0
  168. package/src/lockers/utils/cakeLockerAirdrop.ts +73 -0
  169. package/src/lockers/utils/callsForLockers/depositorCalls.ts +25 -0
  170. package/src/lockers/utils/callsForLockers/feeCalls.ts +118 -0
  171. package/src/lockers/utils/callsForLockers/gaugeCalls.ts +6 -0
  172. package/src/lockers/utils/callsForLockers/gaugeControllerCalls.ts +8 -0
  173. package/src/lockers/utils/callsForLockers/index.ts +44 -0
  174. package/src/lockers/utils/callsForLockers/pegCalls.ts +40 -0
  175. package/src/lockers/utils/callsForLockers/veCalls.ts +31 -0
  176. package/src/lockers/utils/callsForLockers/veSdtCalls.ts +15 -0
  177. package/src/lockers/utils/endpoints.ts +24 -0
  178. package/src/lockers/utils/getBribesRewardsData.ts +64 -0
  179. package/src/lockers/utils/getCherriesLeaderBoard.ts +34 -0
  180. package/src/lockers/utils/getFees.ts +34 -0
  181. package/src/lockers/utils/getHttpCalls.ts +55 -0
  182. package/src/lockers/utils/getSdtInflationData.ts +54 -0
  183. package/src/lockers/utils/index.ts +200 -0
  184. package/src/lockers/utils/substractFees.ts +26 -0
  185. package/src/strategies/curve/build.ts +49 -44
  186. package/src/strategies/curve/fetch/curveApiData/abi.ts +1 -1
  187. package/src/strategies/curve/fetch/curveApiData/bytecode.ts +3 -3
  188. package/src/strategies/curve/fetch/curveApiData/config.ts +1 -1
  189. package/src/strategies/curve/fetch/curveApiData/getCurveApiData.ts +2 -2
  190. package/src/strategies/curve/fetch/curveApiData/getGaugesWeights.ts +2 -0
  191. package/src/strategies/curve/fetch/getStratsWithApr.ts +27 -81
  192. package/src/strategies/curve/fetch/index.ts +10 -29
  193. package/src/strategies/curve/httpCalls.ts +8 -24
  194. package/src/strategies/types.ts +52 -6
  195. package/src/strategies/{curve/fetch → utils}/getAprBreakdown.ts +26 -9
  196. package/src/strategies/utils/index.ts +1 -0
  197. package/src/strategies/utils/sdt.ts +24 -0
  198. package/src/strategies/yearn/build.ts +156 -0
  199. package/src/strategies/yearn/fetch/computeYearnApr.ts +47 -0
  200. package/src/strategies/yearn/fetch/fetchAllYearnGauges.ts +78 -0
  201. package/src/strategies/yearn/fetch/index.ts +225 -0
  202. package/src/utils.ts +43 -1
  203. package/dist/esm/strategies/curve/fetch/getAprBreakdown.js.map +0 -1
  204. package/dist/esm/strategies/curve/fetch/types.js +0 -2
  205. package/dist/esm/strategies/curve/fetch/types.js.map +0 -1
  206. package/dist/types/strategies/curve/fetch/getAprBreakdown.d.ts +0 -17
  207. package/dist/types/strategies/curve/fetch/getAprBreakdown.d.ts.map +0 -1
  208. package/dist/types/strategies/curve/fetch/types.d.ts +0 -11
  209. package/dist/types/strategies/curve/fetch/types.d.ts.map +0 -1
  210. package/src/strategies/curve/fetch/types.ts +0 -11
@@ -0,0 +1,47 @@
1
+ import { formatUnits } from 'viem'
2
+
3
+ import { ONE_YEAR, STRAT_FEES } from '@stake-dao/constants'
4
+
5
+ export const computeYearnApr = (args: {
6
+ rawTotalAssets: bigint
7
+ rawRewardRate: bigint
8
+ rawPricePerShare: bigint
9
+ dYfiPrice: number
10
+ strat: any
11
+ yearnApiData: any
12
+ }) => {
13
+ const { rawTotalAssets, rawRewardRate, rawPricePerShare, dYfiPrice, strat, yearnApiData } = args
14
+
15
+ const yearnStratApiData = yearnApiData.find(
16
+ (element) => element.address.toLowerCase() === strat.lpToken.address.toLowerCase(),
17
+ )
18
+
19
+ const underlyingAprLpPriceInUsd = yearnStratApiData ? yearnStratApiData.tvl.price : 0
20
+ const lpPriceInUsd = underlyingAprLpPriceInUsd * Number(formatUnits(rawPricePerShare, strat.lpToken.decimals))
21
+
22
+ const vaultMonthlyApr = yearnStratApiData ? yearnStratApiData.apr.points.monthAgo : 0
23
+ const vaultWeeklyApr = yearnStratApiData ? yearnStratApiData.apr.points.weekAgo : 0
24
+ const underlyingApr = (vaultMonthlyApr === 0 ? vaultWeeklyApr : vaultMonthlyApr) * 100
25
+
26
+ const totalAssets = Number(formatUnits(rawTotalAssets, strat.gaugeToken.decimals))
27
+
28
+ const rewardScale = (strat.gaugeToken.version === 2 ? 36 : 18) + (18 - strat.lpToken.decimals)
29
+ const rewardRate = Number(formatUnits(rawRewardRate, rewardScale))
30
+
31
+ const maxApr =
32
+ lpPriceInUsd > 0 && rewardRate > 0 && totalAssets > 0
33
+ ? (rewardRate * dYfiPrice * ONE_YEAR) / totalAssets / lpPriceInUsd
34
+ : 0
35
+ const minApr = maxApr / 10
36
+
37
+ const coins = strat.underlyingCoins && strat.underlyingCoins.length > 0 ? strat.underlyingCoins : strat.coins
38
+
39
+ return {
40
+ ...strat,
41
+ name: coins.reduce((res: string, current) => `${res}/${current.symbol}`, '').slice(1),
42
+ lpPriceInUsd,
43
+ underlyingApr,
44
+ minApr: minApr * (100 - STRAT_FEES),
45
+ maxApr: maxApr * (100 - STRAT_FEES),
46
+ }
47
+ }
@@ -0,0 +1,78 @@
1
+ import { chunk } from 'lodash-es'
2
+ import { encodeAbiParameters, parseAbiParameters } from 'viem'
3
+
4
+ import { contracts } from '@stake-dao/constants'
5
+ import { fetchYearnGauges } from '../../../batches/index.js'
6
+ import { batchJsonRpc, multicall } from '../../../utils.js'
7
+ import multicallYearnStratsAbi from '../../utils/abis/MulticallYearnStratsAbi.json'
8
+ import { computeYearnApr } from './computeYearnApr.js'
9
+
10
+ const SKIP = '8'
11
+
12
+ const normalizeTokenInfo = (rawData: { decimals: bigint; name: string; symbol: string; tokenAddress: string }) => ({
13
+ name: rawData.name,
14
+ symbol: rawData.symbol,
15
+ address: rawData.tokenAddress,
16
+ decimals: Number(rawData.decimals),
17
+ })
18
+
19
+ const calls = (tokenAddress: string, gaugeAddress: string) => [
20
+ { address: gaugeAddress, name: 'totalAssets' },
21
+ { address: gaugeAddress, name: 'rewardRate' },
22
+ { address: tokenAddress, name: 'pricePerShare' },
23
+ ]
24
+
25
+ export const fetchAllYearnGauges = async (
26
+ provider: any,
27
+ rpc: string,
28
+ chainId: number,
29
+ yearnApiData: any[],
30
+ dYfiPrice: number,
31
+ ) => {
32
+ const stratsCalls: any[] = []
33
+ const inputData = encodeAbiParameters(parseAbiParameters(fetchYearnGauges.inputType![chainId]!) as any, [
34
+ contracts.yearnGaugeRegistry![chainId]!,
35
+ SKIP,
36
+ ])
37
+
38
+ const decodedPromises = await batchJsonRpc({
39
+ calls: [fetchYearnGauges.bytecode[chainId]!.concat(inputData.slice(2))],
40
+ outputTypeAbi: fetchYearnGauges.outputType![chainId]!,
41
+ rpc,
42
+ parse: false,
43
+ callsKey: `Fetch all Yearn gauges chainId : ${chainId}`,
44
+ })
45
+ const decodedResult = decodedPromises[0]?.yearnStrats || []
46
+
47
+ const notDeployedStrats = decodedResult.map((raw) => {
48
+ const coins = raw.coins.map((c) => normalizeTokenInfo(c))
49
+ stratsCalls.push(...calls(raw.lpToken.tokenAddress, raw.gaugeAddress))
50
+
51
+ return {
52
+ protocol: 'yearn',
53
+ chainId,
54
+ gaugeAddress: raw.gaugeAddress,
55
+ lpToken: normalizeTokenInfo(raw.lpToken),
56
+ gaugeToken: { ...normalizeTokenInfo(raw.gaugeToken), version: Number(raw.gaugeVersion) },
57
+ coins,
58
+ underlyingCoins: coins,
59
+ rewards: [],
60
+ underlyingReward: normalizeTokenInfo(raw.underlyingReward),
61
+ }
62
+ })
63
+
64
+ const rawData: any = await multicall(provider, stratsCalls, multicallYearnStratsAbi)
65
+ const chunkedRawData: any = chunk(rawData, calls('', '').length)
66
+ const parsedData = notDeployedStrats.map((s, index) =>
67
+ computeYearnApr({
68
+ rawTotalAssets: chunkedRawData[index][0].result,
69
+ rawRewardRate: chunkedRawData[index][1].result,
70
+ rawPricePerShare: chunkedRawData[index][2].result,
71
+ dYfiPrice,
72
+ strat: s,
73
+ yearnApiData,
74
+ }),
75
+ )
76
+
77
+ return parsedData
78
+ }
@@ -0,0 +1,225 @@
1
+ import { chunk } from 'lodash-es'
2
+ import { formatEther, formatUnits } from 'viem'
3
+
4
+ import { ONE_YEAR, yearnStrats } from '@stake-dao/constants'
5
+ import { equalTlc, multicall } from '../../../utils.js'
6
+ import { NEW_FACTORY_EXPLORER_EVENTS } from '../../curve/endpoints.js'
7
+ import multicallYearnStratsAbi from '../../utils/abis/MulticallYearnStratsAbi.json'
8
+ import { getBoost } from '../../utils/boost.js'
9
+ import { buildYearnStrategies } from '../build.js'
10
+ import { computeYearnApr } from './computeYearnApr.js'
11
+
12
+ import { contracts } from '@stake-dao/constants'
13
+ import type { Price } from '../../../prices.js'
14
+ import type { RewardsData, StrategyData } from '../../types.js'
15
+ import { getAprBreakdown } from '../../utils/getAprBreakdown.js'
16
+ import { type SdtEmissionData, decodeNewFactoryEvent, getSdtApr } from '../../utils/index.js'
17
+ import { fetchAllYearnGauges } from './fetchAllYearnGauges.js'
18
+
19
+ const globalCalls = [
20
+ { address: contracts.yearnStrategy![1]!, name: 'claimIncentiveFee' },
21
+ { address: contracts.yearnStrategy![1]!, name: 'protocolFeesPercent' },
22
+ { address: contracts.sdGaugeController![1]!, name: 'get_total_weight' },
23
+ ]
24
+
25
+ const calls = (
26
+ lockerAddress: string,
27
+ tokenAddress: string,
28
+ vaultAddress: string,
29
+ gaugeAddress: string,
30
+ sdGaugeAddress: string,
31
+ ) => [
32
+ { address: tokenAddress, name: 'balanceOf', params: [vaultAddress] },
33
+ { address: vaultAddress, name: 'totalSupply' },
34
+ { address: gaugeAddress, name: 'balanceOf', params: [lockerAddress] },
35
+ { address: gaugeAddress, name: 'nextBoostedBalanceOf', params: [lockerAddress] }, // working balance
36
+ { address: gaugeAddress, name: 'totalAssets' },
37
+ { address: gaugeAddress, name: 'rewardRate' },
38
+ { address: gaugeAddress, name: 'earned', params: [lockerAddress] },
39
+ { address: contracts.sdGaugeController![1]!, name: 'gauge_relative_weight', params: [sdGaugeAddress] },
40
+ { address: contracts.sdGaugeController![1]!, name: 'get_gauge_weight', params: [sdGaugeAddress] },
41
+ { address: sdGaugeAddress, name: 'working_supply' },
42
+ { address: sdGaugeAddress, name: 'totalSupply' },
43
+ { address: tokenAddress, name: 'pricePerShare' },
44
+ ]
45
+
46
+ const callsForRewards = (gauge: string, rewards: any[]) =>
47
+ rewards.map((r) => ({ address: gauge, name: 'reward_data', params: [r.address] }))
48
+
49
+ export const fetchYearn = async (
50
+ prices: Price[],
51
+ provider: any,
52
+ rpc: string,
53
+ explorerApiKey: string,
54
+ explorer: string,
55
+ chainId: number,
56
+ lastBlockNumber: number,
57
+ sdtEmissionData: SdtEmissionData,
58
+ ): Promise<StrategyData> => {
59
+ const dYfiPrice = prices.find((p) => p.symbol === 'dYFI')?.usdPrice || 0
60
+ const stratsCalls: any[] = []
61
+ const rewardsCalls: any[] = []
62
+
63
+ const httpCalls = [
64
+ // Etherscan Events
65
+ (
66
+ await fetch(
67
+ NEW_FACTORY_EXPLORER_EVENTS(explorerApiKey, explorer, contracts.yearnVaultFactory![chainId]!, lastBlockNumber),
68
+ )
69
+ ).json(),
70
+ // Yearn Api
71
+ (
72
+ await fetch(
73
+ 'https://ydevmon.ycorpo.com/vaults?hideAlways=true&orderBy=featuringScore&orderDirection=desc&strategiesDetails=withDetails&strategiesRisk=withRisk&strategiesCondition=inQueue&chainIDs=1&limit=2500',
74
+ )
75
+ ).json(),
76
+ multicall(provider, globalCalls, multicallYearnStratsAbi),
77
+ ]
78
+
79
+ const ethHttpResponses = (await Promise.allSettled(httpCalls)).map((result) =>
80
+ result.status === 'fulfilled' ? result.value : [],
81
+ )
82
+
83
+ const etherscanData = ethHttpResponses[0]
84
+ const yearnApiData = ethHttpResponses[1]
85
+ const yearnGlobalData = ethHttpResponses[2]
86
+
87
+ const yearnGaugesData = await fetchAllYearnGauges(provider, rpc, chainId, yearnApiData, dYfiPrice)
88
+
89
+ const newVaults = decodeNewFactoryEvent(etherscanData)
90
+ const vaults = yearnStrats.strats[chainId]!.concat(newVaults)
91
+
92
+ const strats: any[] = await buildYearnStrategies(provider, vaults, chainId)
93
+ for (const s of strats) {
94
+ stratsCalls.push(...calls(contracts.yearnLocker![1]!, s.lpToken.address, s.vault, s.gaugeAddress, s.sdGauge))
95
+ rewardsCalls.push(...callsForRewards(s.sdGauge, s.rewards))
96
+ }
97
+
98
+ const rawData: any = await multicall(provider, stratsCalls, multicallYearnStratsAbi)
99
+ const chunkedRawData: any = chunk(rawData, calls('', '', '', '', '').length)
100
+
101
+ const rewardsRawData: any = await multicall(provider, rewardsCalls, [
102
+ {
103
+ inputs: [{ internalType: 'address', token: 'account', type: 'address' }],
104
+ name: 'reward_data',
105
+ outputs: [
106
+ {
107
+ type: 'tuple',
108
+ name: 'coins',
109
+ components: [
110
+ { type: 'address', name: 'token' },
111
+ { type: 'address', name: 'distributor' },
112
+ { type: 'uint256', name: 'period_finish' },
113
+ { type: 'uint256', name: 'rate' },
114
+ { type: 'uint256', name: 'last_update' },
115
+ { type: 'uint256', name: 'integral' },
116
+ ],
117
+ },
118
+ ],
119
+ stateMutability: 'view',
120
+ type: 'function',
121
+ },
122
+ ])
123
+
124
+ const parsedData = strats.map((s, index) => {
125
+ const yearnGauge = computeYearnApr({
126
+ rawTotalAssets: chunkedRawData[index][4].result,
127
+ rawRewardRate: chunkedRawData[index][5].result,
128
+ rawPricePerShare: chunkedRawData[index][11].result,
129
+ dYfiPrice,
130
+ strat: s,
131
+ yearnApiData,
132
+ })
133
+ const boost = getBoost('yearn', chunkedRawData[index][2].result, chunkedRawData[index][3].result)
134
+
135
+ const lpPriceInUsd = yearnGauge.lpPriceInUsd
136
+ const underlyingApy = yearnGauge.underlyingApr
137
+ const minApr = yearnGauge.minApr
138
+ const maxApr = yearnGauge.maxApr
139
+
140
+ const sdGaugeTotalSupply = chunkedRawData[index][10].result
141
+ const tvl = Number(formatEther(sdGaugeTotalSupply)) * lpPriceInUsd
142
+
143
+ const rewardsData: RewardsData[] = s.rewards.map((rewardToken: any) => {
144
+ const fetchedRewardData = rewardsRawData.shift().result
145
+ const rewardPrice = prices.find((p: any) => equalTlc(p.address, rewardToken.address))
146
+
147
+ const periodFinish = Number(formatUnits(fetchedRewardData.period_finish, 0))
148
+ const streaming = periodFinish > Math.floor(Date.now() / 1000)
149
+
150
+ const rewardApr =
151
+ streaming && rewardPrice && tvl > 0
152
+ ? (Number(formatUnits(fetchedRewardData.rate * BigInt(ONE_YEAR), 18)) * rewardPrice.usdPrice) /
153
+ tvl /
154
+ (equalTlc(rewardToken.symbol, 'SDT') ? 2.5 : 1)
155
+ : 0
156
+
157
+ return {
158
+ token: rewardToken,
159
+ price: rewardPrice ? rewardPrice.usdPrice : 0,
160
+ apr: rewardApr * 100,
161
+ streaming,
162
+ periodFinish,
163
+ rate: formatUnits(fetchedRewardData.rate, 0),
164
+ lastUpdate: formatUnits(fetchedRewardData.last_update, 0),
165
+ claimablePendingRewards: rewardToken.symbol === 'dYFI' ? formatUnits(chunkedRawData[index][6].result, 0) : '0',
166
+ }
167
+ })
168
+
169
+ const sdGauge = {
170
+ address: s.sdGauge,
171
+ totalSupply: formatUnits(sdGaugeTotalSupply, 0),
172
+ relativeWeight: formatUnits(chunkedRawData[index][7].result, 0),
173
+ weight: formatUnits(chunkedRawData[index][8].result, 0),
174
+ futureWeight: formatUnits(chunkedRawData[index][9].result, 0), // TODO
175
+ workingSupply: formatUnits(chunkedRawData[index][9].result, 0),
176
+ }
177
+
178
+ const sdtApr = getSdtApr(rewardsData, sdtEmissionData, sdGauge, lpPriceInUsd, undefined)
179
+ const apr = getAprBreakdown(s, rewardsData, boost, sdtApr)
180
+
181
+ return {
182
+ key: s.key,
183
+ type: s.type,
184
+ protocol: s.protocol,
185
+ chainId,
186
+ vault: s.vault,
187
+ lpToken: s.lpToken,
188
+ gaugeAddress: s.gaugeAddress,
189
+ gaugeToken: s.gaugeToken,
190
+ coins: s.coins,
191
+ underlyingCoins: [],
192
+ sdGauge,
193
+ rewards: rewardsData,
194
+ name: s.coins.reduce((res: string, current) => `${res}/${current.symbol}`, '').slice(1),
195
+ tradingApy: 0,
196
+ underlyingApy,
197
+ gaugesProjectedApr: [],
198
+ minApr,
199
+ maxApr,
200
+ lpPriceInUsd,
201
+ tvl,
202
+ apr: { boost, ...apr },
203
+ vaultHoldings: formatUnits(chunkedRawData[index][0].result, 0),
204
+ totalSupply: formatUnits(chunkedRawData[index][1].result, 0),
205
+ strategyHoldings: formatUnits(chunkedRawData[index][2].result, 0),
206
+ workingBalance: formatUnits(chunkedRawData[index][3].result, 0),
207
+ vaultFees: { keeper: 0, accumulated: '0' },
208
+ }
209
+ })
210
+
211
+ const deployedStratsGauges = parsedData.map((s) => s.gaugeAddress)
212
+ const notDeployed = yearnGaugesData.filter(
213
+ (yg) => yg?.gaugeAddress && !deployedStratsGauges.includes(yg.gaugeAddress),
214
+ )
215
+
216
+ return {
217
+ global: {
218
+ totalGaugeWeights: formatUnits(yearnGlobalData[2].result, 0),
219
+ fees: { claimer: Number(yearnGlobalData[0].result) / 100, accumulator: 5, perf: 5, veSdt: 5 },
220
+ },
221
+ deployed: parsedData,
222
+ notDeployed,
223
+ fetched: true,
224
+ }
225
+ }
package/src/utils.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  import { tokens } from '@stake-dao/constants'
2
2
  import type { Token } from '@stake-dao/constants'
3
- import { decodeAbiParameters, parseAbiParameters } from 'viem'
3
+ import { request } from 'graphql-request'
4
+ import { groupBy } from 'lodash-es'
5
+ import { http, createPublicClient, decodeAbiParameters, extractChain, parseAbiParameters } from 'viem'
6
+ import * as viemChains from 'viem/chains'
4
7
  import { AGNOSTIC_QUERY_URL } from './endpoints.js'
5
8
  import { withTwoDec } from './number.js'
6
9
 
@@ -169,3 +172,42 @@ export const agnostic = async (query: string, apiKey: string, defaultErrorValue?
169
172
  return defaultErrorValue
170
173
  }
171
174
  }
175
+
176
+ export const graphql = async (url: string, query: string, params?: any, defaultErrorValue?: any): Promise<any> => {
177
+ try {
178
+ return await request(url, query, params)
179
+ } catch (e) {
180
+ console.error(e)
181
+ return defaultErrorValue
182
+ }
183
+ }
184
+
185
+ export interface MultiChainCall extends Call {
186
+ chainId: number
187
+ }
188
+
189
+ export const multichainMulticall = async (calls: MultiChainCall[], abi: readonly any[]) => {
190
+ const callsPerChain = groupBy(calls, (call) => call.chainId)
191
+
192
+ const chains = Object.keys(callsPerChain)
193
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
194
+ const parsedCallsPerChain = chains.map((chainId) => callsPerChain[chainId]!.map(({ chainId, ...call }) => call))
195
+
196
+ const promises = await Promise.allSettled(
197
+ chains.map(async (chainId, index) => {
198
+ const provider = createPublicClient({
199
+ chain: extractChain({
200
+ chains: Object.values(viemChains) as any,
201
+ id: Number(chainId),
202
+ }),
203
+ transport: http(),
204
+ })
205
+ return await multicall(provider, parsedCallsPerChain[index]!, abi)
206
+ }),
207
+ )
208
+ const promisesValues = promises.map((p) => (p.status === 'fulfilled' ? p.value : p.reason))
209
+
210
+ const res = {}
211
+ chains.forEach((chainId, index) => (res[chainId] = promisesValues[index]))
212
+ return res
213
+ }
@@ -1 +0,0 @@
1
- {"version":3,"file":"getAprBreakdown.js","sourceRoot":"","sources":["../../../../../src/strategies/curve/fetch/getAprBreakdown.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../src/strategies/curve/fetch/types.ts"],"names":[],"mappings":""}
@@ -1,17 +0,0 @@
1
- import type { RewardsData } from '../../types.js';
2
- type Breakdown = {
3
- label: string;
4
- value: number[];
5
- };
6
- export declare const getAprBreakdown: (strat: any, rewardsData: RewardsData[], boost: number, cvxApr: number, sdtApr: any) => {
7
- current: {
8
- total: number;
9
- details: Breakdown[];
10
- };
11
- projected: {
12
- total: any;
13
- details: any[];
14
- };
15
- };
16
- export {};
17
- //# sourceMappingURL=getAprBreakdown.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"getAprBreakdown.d.ts","sourceRoot":"","sources":["../../../../../src/strategies/curve/fetch/getAprBreakdown.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAEjD,KAAK,SAAS,GAAG;IACf,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,EAAE,CAAA;CAChB,CAAA;AAED,eAAO,MAAM,eAAe,UAAW,GAAG,eAAe,WAAW,EAAE,SAAS,MAAM,UAAU,MAAM,UAAU,GAAG;;;;;;;;;CAyFjH,CAAA"}
@@ -1,11 +0,0 @@
1
- import type { Fees } from '../../types.js';
2
- export type StratGlobalData = {
3
- totalGaugeWeights: string;
4
- nextEffectiveTimestamp: string;
5
- cvxTotalSupply: string;
6
- veCrvTotalSupply: string;
7
- stakeDaoVeBoost: string;
8
- convexVeBoost: string;
9
- fees: Fees;
10
- };
11
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../src/strategies/curve/fetch/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAA;AAE1C,MAAM,MAAM,eAAe,GAAG;IAC5B,iBAAiB,EAAE,MAAM,CAAA;IACzB,sBAAsB,EAAE,MAAM,CAAA;IAC9B,cAAc,EAAE,MAAM,CAAA;IACtB,gBAAgB,EAAE,MAAM,CAAA;IACxB,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;IACrB,IAAI,EAAE,IAAI,CAAA;CACX,CAAA"}
@@ -1,11 +0,0 @@
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
- }