@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,206 @@
1
+ import { ONE_WEEK, ONE_YEAR, contracts, mainnet } from '@stake-dao/constants'
2
+ import { LOCKERS_MASTERCHEF_PID } from '@stake-dao/constants'
3
+ import { STRATEGIES_MASTERCHEF_PID } from '@stake-dao/constants'
4
+ import { ETH_SECONDS_PER_BLOCK } from '@stake-dao/constants'
5
+ import { formatUnits, parseAbi, parseEther, parseUnits } from 'viem'
6
+ import { multicall } from '../../utils.js'
7
+ import type { RewardsData, SdtApr } from '../types.js'
8
+ import { OneEther, Zero } from './index.js'
9
+
10
+ export type SdtEmissionData = {
11
+ lockersSdtPerBlock: bigint
12
+ lockersSdtPerSecond: bigint
13
+ stratsSdtPerBlock: bigint
14
+ stratsSdtPerSecond: bigint
15
+ }
16
+
17
+ const simulateUserWorkingBalance = (
18
+ adjustedBalanceOf: bigint,
19
+ veSDTTotalSupply: bigint,
20
+ userAmountLP: bigint,
21
+ totalAmountLP: bigint,
22
+ currentUserWorkingBalance: bigint,
23
+ currentWorkingSupply: bigint,
24
+ ): {
25
+ newUserWorkingBalance: bigint
26
+ newWorkingSupply: bigint
27
+ } => {
28
+ const voting_balance = adjustedBalanceOf
29
+ const voting_total = veSDTTotalSupply
30
+
31
+ let lim = (userAmountLP * BigInt(40)) / BigInt(100)
32
+ if (voting_total > 0) {
33
+ lim += (((totalAmountLP * voting_balance) / voting_total) * BigInt(60)) / BigInt(100)
34
+ }
35
+
36
+ if (userAmountLP < lim) {
37
+ lim = userAmountLP
38
+ }
39
+
40
+ const _working_supply = currentWorkingSupply + lim - currentUserWorkingBalance
41
+
42
+ return {
43
+ newUserWorkingBalance: lim,
44
+ newWorkingSupply: _working_supply,
45
+ }
46
+ }
47
+
48
+ export const calculateSDTRangeApr = (
49
+ sdtRateInput: bigint,
50
+ periodFinish: number,
51
+ workingBalance: string,
52
+ workingSupply: string,
53
+ depositBalance: bigint,
54
+ adjustedBalanceOf: string,
55
+ votingEscrowTotalSupply: string,
56
+ gaugeTotalSupply: string,
57
+ sdtPrice: number,
58
+ lpPrice: number,
59
+ ) => {
60
+ // Assign rate is needed
61
+ const sdtRate = periodFinish === 0 || Date.now() / 1000 > periodFinish ? Zero : sdtRateInput
62
+
63
+ let workingBalanceToUse = parseUnits(workingBalance, 0)
64
+ let workingSupplyToUse = parseUnits(workingSupply, 0)
65
+ let stakedAmountToUse = BigInt(depositBalance)
66
+ let realStakedAmount = (stakedAmountToUse * BigInt(4)) / BigInt(10)
67
+ const isSimulated = stakedAmountToUse <= 0
68
+
69
+ if (isSimulated) {
70
+ // Simulation with 1 LP
71
+ stakedAmountToUse = parseUnits('1', 18)
72
+ realStakedAmount = (stakedAmountToUse * BigInt(4)) / BigInt(10)
73
+
74
+ const simu = simulateUserWorkingBalance(
75
+ parseUnits(adjustedBalanceOf, 0),
76
+ parseUnits(votingEscrowTotalSupply, 0),
77
+ stakedAmountToUse,
78
+ parseUnits(gaugeTotalSupply, 0) + stakedAmountToUse,
79
+ workingBalanceToUse,
80
+ workingSupplyToUse,
81
+ )
82
+
83
+ workingBalanceToUse = simu.newUserWorkingBalance
84
+ workingSupplyToUse = simu.newWorkingSupply
85
+ }
86
+
87
+ let sdtUserApr =
88
+ ((Number.parseFloat(formatUnits(sdtRate, 18)) *
89
+ Number.parseFloat(formatUnits(workingBalanceToUse, 18)) *
90
+ sdtPrice *
91
+ ONE_YEAR) /
92
+ (Number.parseFloat(formatUnits(workingSupplyToUse, 18)) *
93
+ Number.parseFloat(formatUnits(stakedAmountToUse, 18)) *
94
+ lpPrice)) *
95
+ 100
96
+
97
+ if (Number.isNaN(sdtUserApr)) sdtUserApr = 0
98
+
99
+ let sdtBoost =
100
+ (BigInt(depositBalance) > 0 || isSimulated) && realStakedAmount > Zero
101
+ ? Number.parseFloat(formatUnits(parseEther(formatUnits(workingBalanceToUse, 0)) / realStakedAmount, 18))
102
+ : 1
103
+
104
+ const sdtMinApr = sdtUserApr / sdtBoost
105
+ const sdtMaxApr = sdtMinApr * 2.5
106
+ if (isSimulated) {
107
+ // Reset user apr + boost to minimum because we used only data to simulate the position and calculate the SDT apr range
108
+ sdtUserApr = sdtMinApr
109
+ sdtBoost = 1
110
+ }
111
+
112
+ return {
113
+ sdtMinApr,
114
+ sdtMaxApr,
115
+ sdtBoost,
116
+ sdtUserApr,
117
+ }
118
+ }
119
+
120
+ export const getSdtInflationData = async (provider: any, chainId: number): Promise<SdtEmissionData | undefined> => {
121
+ if (chainId === mainnet.id) {
122
+ const rawSdtMasterchefData = await multicall(
123
+ provider,
124
+ [
125
+ { address: contracts.sdtMasterchef![1]!, name: 'sdtPerBlock' },
126
+ { address: contracts.sdtMasterchef![1]!, name: 'totalAllocPoint' },
127
+ { address: contracts.sdtMasterchef![1]!, name: 'poolInfo', params: [LOCKERS_MASTERCHEF_PID] },
128
+ { address: contracts.sdtMasterchef![1]!, name: 'poolInfo', params: [STRATEGIES_MASTERCHEF_PID] },
129
+ ],
130
+ parseAbi([
131
+ 'function sdtPerBlock() view returns (uint256)',
132
+ 'function totalAllocPoint() view returns (uint256)',
133
+ 'function poolInfo(uint256 pid) view returns (address,uint256,uint256,uint256)',
134
+ ]),
135
+ )
136
+
137
+ const sdtPerBlock = rawSdtMasterchefData[0].result
138
+ const totalAllocPoint = rawSdtMasterchefData[1].result
139
+ const lockerPoolInfo = rawSdtMasterchefData[2].result
140
+ const stratPoolInfo = rawSdtMasterchefData[3].result
141
+
142
+ const lockersAllocPoint = lockerPoolInfo[1] as bigint
143
+ const stratsAllocPoint = stratPoolInfo[1] as bigint
144
+
145
+ const lockersSdtPerBlock = (lockersAllocPoint * sdtPerBlock) / totalAllocPoint
146
+ const lockersSdtPerSecond = BigInt(lockersSdtPerBlock) / BigInt(ETH_SECONDS_PER_BLOCK)
147
+
148
+ const stratsSdtPerBlock = (stratsAllocPoint * sdtPerBlock) / totalAllocPoint
149
+ const stratsSdtPerSecond = BigInt(stratsSdtPerBlock) / BigInt(ETH_SECONDS_PER_BLOCK)
150
+
151
+ return {
152
+ lockersSdtPerBlock,
153
+ lockersSdtPerSecond,
154
+ stratsSdtPerBlock,
155
+ stratsSdtPerSecond,
156
+ }
157
+ }
158
+
159
+ return undefined
160
+ }
161
+
162
+ export const computeSdtApr = (
163
+ sdtEmissionData: SdtEmissionData,
164
+ sdtRewards: RewardsData,
165
+ userData: any,
166
+ sdGauge: any,
167
+ lpPriceInUsd: number,
168
+ ): SdtApr => {
169
+ const futureRate = (sdtEmissionData.stratsSdtPerSecond * BigInt(sdGauge.futureWeight)) / OneEther
170
+
171
+ const sdtRangeApr = calculateSDTRangeApr(
172
+ BigInt(sdtRewards.rate),
173
+ sdtRewards.periodFinish,
174
+ userData?.workingBalance || '0',
175
+ sdGauge.workingSupply,
176
+ BigInt(userData?.depositBalance || '0'),
177
+ userData?.sdtAprData.adjustedBalanceOf || '0',
178
+ userData?.sdtAprData.votingEscrowTotalSupply || '0',
179
+ sdGauge.totalSupply,
180
+ sdtRewards.price,
181
+ lpPriceInUsd,
182
+ )
183
+
184
+ const futurSdtRangeApr = calculateSDTRangeApr(
185
+ futureRate,
186
+ Math.floor(Date.now() / 1000) + ONE_WEEK,
187
+ userData?.workingBalance || '0',
188
+ sdGauge.workingSupply,
189
+ BigInt(userData?.depositBalance || '0'),
190
+ userData?.sdtAprData.adjustedBalanceOf || '0',
191
+ userData?.sdtAprData.votingEscrowTotalSupply || '0',
192
+ sdGauge.totalSupply,
193
+ sdtRewards.price,
194
+ lpPriceInUsd,
195
+ )
196
+
197
+ return {
198
+ sdtUserApr: sdtRangeApr?.sdtUserApr || 0,
199
+ sdtFuturUserApr: futurSdtRangeApr?.sdtUserApr || 0,
200
+ sdtMinApr: sdtRangeApr?.sdtMinApr || 0,
201
+ sdtFuturMinApr: futurSdtRangeApr?.sdtMinApr || 0,
202
+ sdtMaxApr: sdtRangeApr?.sdtMaxApr || 0,
203
+ sdtFuturMaxApr: futurSdtRangeApr?.sdtMaxApr || 0,
204
+ sdtBoost: sdtRangeApr?.sdtBoost || 1,
205
+ }
206
+ }
package/src/utils.ts ADDED
@@ -0,0 +1,171 @@
1
+ import { tokens } from '@stake-dao/constants'
2
+ import type { Token } from '@stake-dao/constants'
3
+ import { decodeAbiParameters, parseAbiParameters } from 'viem'
4
+ import { AGNOSTIC_QUERY_URL } from './endpoints.js'
5
+ import { withTwoDec } from './number.js'
6
+
7
+ export const isProtocolToken = (protocol: string, tokenSymbol: string) =>
8
+ (protocol === 'curve' && tokenSymbol === 'CRV') ||
9
+ (protocol === 'balancer' && tokenSymbol === 'BAL') ||
10
+ (protocol === 'angle' && tokenSymbol === 'ANGLE') ||
11
+ (protocol === 'pendle' && tokenSymbol === 'PENDLE') ||
12
+ (protocol === 'yearn' && tokenSymbol === 'dYFI') ||
13
+ (protocol === 'pancakeswap' && tokenSymbol === 'CAKE')
14
+
15
+ export const getBreakdownLabel = (strat: any, reward: any, isFuturSDT: boolean, boost: number, sdtApr: any) => {
16
+ switch (reward.token.symbol) {
17
+ case 'SDT':
18
+ return `${reward.token.symbol} APR${
19
+ sdtApr?.sdtBoost
20
+ ? ` (${withTwoDec(isFuturSDT ? sdtApr.sdtFuturMinApr : sdtApr.sdtMinApr)}% → ${withTwoDec(
21
+ isFuturSDT ? sdtApr.sdtFuturMaxApr : sdtApr.sdtMaxApr,
22
+ )}% | Your boost : ${sdtApr.sdtBoost.toFixed(2)}x)`
23
+ : ''
24
+ }`
25
+ default:
26
+ return `${reward.token.symbol} APR${
27
+ isProtocolToken(strat.protocol, reward.token.symbol) ? ` (incl. ${boost.toFixed(2)}x boost)` : ''
28
+ }`
29
+ }
30
+ }
31
+
32
+ export const equalTlc = (addressOne: string, addressTwo: string): boolean =>
33
+ addressOne.toLowerCase() === addressTwo.toLowerCase()
34
+
35
+ export const getTokenInfo = (
36
+ coinData: any,
37
+ address: string,
38
+ chainId: number = 1,
39
+ ): { name: string; symbol: string; address: string; decimals: number } | Token => {
40
+ if (coinData) {
41
+ return {
42
+ name: coinData.name,
43
+ symbol: coinData.symbol,
44
+ address: coinData.tokenAddress,
45
+ decimals: Number(coinData.decimals),
46
+ }
47
+ }
48
+
49
+ const tokenObj = tokens.find((t: Token) => t.chainId === chainId && t.address === address)!
50
+ return {
51
+ name: tokenObj.name,
52
+ symbol: tokenObj.symbol,
53
+ address: tokenObj.address,
54
+ decimals: tokenObj.decimals,
55
+ }
56
+ }
57
+
58
+ export const projectWorkingBalance = (veBalance: bigint, veTotal: bigint, balance: bigint, totalSupply: bigint) => {
59
+ const TOKENLESS_PRODUCTION = BigInt(40)
60
+ const DENOMINATOR = BigInt(100)
61
+
62
+ const derived = (balance * TOKENLESS_PRODUCTION) / DENOMINATOR
63
+ const adjusted = (((totalSupply * veBalance) / veTotal) * (DENOMINATOR - TOKENLESS_PRODUCTION)) / DENOMINATOR
64
+
65
+ // Math.min for BigInt
66
+ return [balance, derived + adjusted].reduce((m, e) => (e < m ? e : m))
67
+ }
68
+
69
+ interface RpcCallArgs {
70
+ to: string
71
+ data: string
72
+ }
73
+
74
+ export const rpcCall = async (rpc: string, params: RpcCallArgs[]) => {
75
+ const request = (
76
+ await fetch(rpc, {
77
+ method: 'POST',
78
+ headers: { 'Content-Type': 'application/json' },
79
+ body: JSON.stringify(
80
+ params.map((param, index) => ({
81
+ id: index,
82
+ jsonrpc: '2.0',
83
+ method: 'eth_call',
84
+ params: [{ to: param.to, data: param.data }, 'latest'],
85
+ })),
86
+ ),
87
+ })
88
+ ).json()
89
+
90
+ return request
91
+ }
92
+
93
+ interface BatchJsonRpcArgs {
94
+ rpc: string
95
+ calls: string[]
96
+ outputTypeAbi: any | any[]
97
+ parse?: boolean
98
+ callsKey?: string
99
+ }
100
+
101
+ export const batchJsonRpc = async (args: BatchJsonRpcArgs) => {
102
+ const { rpc, calls, outputTypeAbi, parse = true, callsKey = '' } = args
103
+
104
+ const rpcRequests = await (
105
+ await fetch(rpc, {
106
+ method: 'POST',
107
+ headers: { 'Content-Type': 'application/json' },
108
+ body: JSON.stringify(
109
+ calls.map((calldata, index) => ({
110
+ id: index,
111
+ jsonrpc: '2.0',
112
+ method: 'eth_call',
113
+ params: [{ data: calldata }, 'latest'],
114
+ })),
115
+ ),
116
+ })
117
+ ).json()
118
+
119
+ const rpcResults = rpcRequests.map((res: any, index: number) => {
120
+ const isError = Object.keys(res).includes('error')
121
+ const abi = Array.isArray(outputTypeAbi[0]) ? outputTypeAbi[index] : outputTypeAbi
122
+ const status = isError ? 'error' : 'fulfilled'
123
+ const value = isError
124
+ ? `${callsKey} call index ${index}: code ${res.error.code}\n${res.error.message}`
125
+ : decodeAbiParameters(parse ? (parseAbiParameters(abi) as any) : abi, res.result)
126
+
127
+ if (isError) {
128
+ console.error(value)
129
+ }
130
+
131
+ return { status, value }
132
+ })
133
+
134
+ return rpcResults.flatMap((r) => (r.status === 'fulfilled' ? r.value[0] : []))
135
+ }
136
+
137
+ export interface Call {
138
+ address: string // Address of the contract
139
+ name: string // Function name on the contract (example: balanceOf)
140
+ params?: any[] // Function params
141
+ }
142
+
143
+ export const multicall = async (provider: any, calls: Call[], abi: readonly any[]) => {
144
+ const contracts = calls.map((c) => ({
145
+ address: c.address as `0x${string}`,
146
+ abi,
147
+ functionName: c.name,
148
+ args: c.params ? c.params : [],
149
+ }))
150
+
151
+ const results = await provider.multicall({ contracts, batchSize: 10_240 })
152
+
153
+ return results
154
+ }
155
+
156
+ export const agnostic = async (query: string, apiKey: string, defaultErrorValue?: any): Promise<any> => {
157
+ try {
158
+ const response = await fetch(AGNOSTIC_QUERY_URL, {
159
+ body: query,
160
+ method: 'POST',
161
+ headers: {
162
+ Authorization: apiKey,
163
+ },
164
+ })
165
+ const data = await response.json()
166
+ return data.rows
167
+ } catch (e) {
168
+ console.error(e)
169
+ return defaultErrorValue
170
+ }
171
+ }