@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,26 @@
1
+ import type { BatchMetaData } from './types.js'
2
+
3
+ const commonBytecode =
4
+ '0x608060405234801561001057600080fd5b5060405161094a38038061094a8339818101604052810190610032919061051d565b60008151905060008167ffffffffffffffff8111156100545761005361037c565b5b60405190808252806020026020018201604052801561008d57816020015b61007a610314565b8152602001906001900390816100725790505b50905060005b828110156102e45760008482815181106100b0576100af610566565b5b6020026020010151905060008190508073ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa15801561010a573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906101339190610665565b84848151811061014657610145610566565b5b6020026020010151600001819052508073ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa1580156101a0573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906101c99190610665565b8484815181106101dc576101db610566565b5b602002602001015160200181905250818484815181106101ff576101fe610566565b5b60200260200101516040019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508073ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610288573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ac91906106e4565b8484815181106102bf576102be610566565b5b60200260200101516060018181525050505080806102dc90610740565b915050610093565b506000816040516020016102f89190610927565b6040516020818303038152906040529050602081018059038082f35b60405180608001604052806060815260200160608152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600081525090565b6000604051905090565b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6103b48261036b565b810181811067ffffffffffffffff821117156103d3576103d261037c565b5b80604052505050565b60006103e6610352565b90506103f282826103ab565b919050565b600067ffffffffffffffff8211156104125761041161037c565b5b602082029050602081019050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061045382610428565b9050919050565b61046381610448565b811461046e57600080fd5b50565b6000815190506104808161045a565b92915050565b6000610499610494846103f7565b6103dc565b905080838252602082019050602084028301858111156104bc576104bb610423565b5b835b818110156104e557806104d18882610471565b8452602084019350506020810190506104be565b5050509392505050565b600082601f83011261050457610503610366565b5b8151610514848260208601610486565b91505092915050565b6000602082840312156105335761053261035c565b5b600082015167ffffffffffffffff81111561055157610550610361565b5b61055d848285016104ef565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b600067ffffffffffffffff8211156105b5576105b461037c565b5b6105be8261036b565b9050602081019050919050565b60005b838110156105e95780820151818401526020810190506105ce565b60008484015250505050565b60006106086106038461059a565b6103dc565b90508281526020810184848401111561062457610623610595565b5b61062f8482856105cb565b509392505050565b600082601f83011261064c5761064b610366565b5b815161065c8482602086016105f5565b91505092915050565b60006020828403121561067b5761067a61035c565b5b600082015167ffffffffffffffff81111561069957610698610361565b5b6106a584828501610637565b91505092915050565b6000819050919050565b6106c1816106ae565b81146106cc57600080fd5b50565b6000815190506106de816106b8565b92915050565b6000602082840312156106fa576106f961035c565b5b6000610708848285016106cf565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061074b826106ae565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361077d5761077c610711565b5b600182019050919050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60006107db826107b4565b6107e581856107bf565b93506107f58185602086016105cb565b6107fe8161036b565b840191505092915050565b61081281610448565b82525050565b610821816106ae565b82525050565b6000608083016000830151848203600086015261084482826107d0565b9150506020830151848203602086015261085e82826107d0565b91505060408301516108736040860182610809565b5060608301516108866060860182610818565b508091505092915050565b600061089d8383610827565b905092915050565b6000602082019050919050565b60006108bd82610788565b6108c78185610793565b9350836020820285016108d9856107a4565b8060005b8581101561091557848403895281516108f68582610891565b9450610901836108a5565b925060208a019950506001810190506108dd565b50829750879550505050505092915050565b6000602082019050818103600083015261094181846108b2565b90509291505056fe'
5
+ const commonInputType = ['address[] inputs']
6
+ const commonOutputType = [
7
+ 'Erc20Data[] erc20data',
8
+ 'struct Erc20Data { string name; string symbol; address tokenAddress; uint256 decimals; }',
9
+ ]
10
+
11
+ const tokenData: BatchMetaData = {
12
+ bytecode: {
13
+ 1: commonBytecode,
14
+ 42161: commonBytecode,
15
+ },
16
+ inputType: {
17
+ 1: commonInputType,
18
+ 42161: commonInputType,
19
+ },
20
+ outputTypeHr: {
21
+ 1: commonOutputType,
22
+ 42161: commonOutputType,
23
+ },
24
+ }
25
+
26
+ export default tokenData
@@ -0,0 +1,14 @@
1
+ export type BatchMetaData = {
2
+ bytecode: {
3
+ [chainId: number]: `0x${string}`
4
+ }
5
+ inputType: {
6
+ [chainId: number]: string[]
7
+ }
8
+ outputType?: {
9
+ [chainId: number]: any[]
10
+ }
11
+ outputTypeHr: {
12
+ [chainId: number]: string[]
13
+ }
14
+ }
@@ -0,0 +1,2 @@
1
+ export const LLAMA_API_URL = 'https://coins.llama.fi'
2
+ export const AGNOSTIC_QUERY_URL = 'https://proxy.eu-02.agnostic.engineering/query'
package/src/index.ts ADDED
@@ -0,0 +1,7 @@
1
+ export { fetchCurve } from './strategies/curve/fetch/index.js'
2
+ export { fetchCurveBase } from './strategies/curve/fetch/curveApiData/getCurveApiData.js'
3
+ export { getGaugesWeights } from './strategies/curve/fetch/curveApiData/getGaugesWeights.js'
4
+ export { getGaugesFromRegistry } from './strategies/curve/fetch/curveApiData/getGaugesFromRegistry.js'
5
+ export { getPricesFromLlama, getPricesFromGeckoTerminal } from './prices.js'
6
+ export { fetchSdt } from './sdt/sdt.js'
7
+ export * from './strategies/utils/index.js'
package/src/number.ts ADDED
@@ -0,0 +1,51 @@
1
+ import { formatUnits } from 'viem'
2
+
3
+ export const getString = (data: any, nbDecimals = 2) => {
4
+ if (typeof data === 'string') {
5
+ return data
6
+ }
7
+ return data ? Number(data).toFixed(nbDecimals) : 0
8
+ }
9
+
10
+ export const getFixedNumber = (amount: string, reduce = false) => {
11
+ const earningsNumber = reduce ? Number(formatUnits(BigInt(amount), 18)) : Number(amount)
12
+ if (earningsNumber > 0 && earningsNumber < 1) {
13
+ const indexNotZero = earningsNumber.toString().match('[1-9]')
14
+ return indexNotZero?.index ? indexNotZero.index - 2 + 4 : 4
15
+ }
16
+ if (earningsNumber >= 1 && earningsNumber < 100) {
17
+ return 2
18
+ }
19
+ if (earningsNumber >= 100 && earningsNumber < 1000) {
20
+ return 2
21
+ }
22
+ return 0
23
+ }
24
+
25
+ export const fixed = (nb: string, decimals?: number) => {
26
+ const fixedTo = decimals ? decimals : getFixedNumber(nb)
27
+ return Number(nb).toLocaleString('en-US', {
28
+ minimumFractionDigits: fixedTo,
29
+ maximumFractionDigits: fixedTo,
30
+ })
31
+ }
32
+
33
+ export const formatUsd = (number: string | number) => {
34
+ const nb = typeof number === 'string' ? Number(number) : number
35
+
36
+ if (nb > 1000000000) {
37
+ return `${getString(nb / 1000000000, 2)}B`
38
+ }
39
+ if (nb > 1000000) {
40
+ return `${getString(nb / 1000000, 2)}M`
41
+ }
42
+ if (nb > 1000) {
43
+ return `${getString(nb / 1000, 2)}k`
44
+ }
45
+
46
+ return fixed(number.toString())
47
+ }
48
+
49
+ export const withTwoDec = (num: number) => {
50
+ return (Math.floor(num * 100) / 100).toFixed(2)
51
+ }
package/src/prices.ts ADDED
@@ -0,0 +1,86 @@
1
+ import { uniq } from 'lodash-es'
2
+
3
+ const LLAMA_API_URL = 'https://coins.llama.fi'
4
+ const GECKO_TERMINAL_API_URL = 'https://api.geckoterminal.com/api/v2'
5
+
6
+ export type Price = {
7
+ symbol: string
8
+ address: string
9
+ usdPrice: number
10
+ }
11
+
12
+ export const getLlamaTokenPrefix = (chainId = 1): string => {
13
+ switch (chainId) {
14
+ case 1:
15
+ return 'ethereum'
16
+ case 137:
17
+ return 'polygon'
18
+ case 42161:
19
+ return 'arbitrum'
20
+ case 56:
21
+ return 'bsc'
22
+ default:
23
+ return 'ethereum'
24
+ }
25
+ }
26
+
27
+ export const getPricesFromLlama = async (tokens: any[], chainId = 1, defaultErrorValue?: any): Promise<Price[]> => {
28
+ try {
29
+ const prefix: string = getLlamaTokenPrefix(chainId)
30
+
31
+ const httpArgs = uniq(tokens.map((t) => `${prefix}:${t.address}`)).toString()
32
+ const httpRequest = await (await fetch(`${LLAMA_API_URL}/prices/current/${httpArgs}`)).json()
33
+ const coinsData = httpRequest.coins
34
+
35
+ const parsedPrice = tokens.map((t) => {
36
+ return {
37
+ symbol: t.symbol,
38
+ address: t.address,
39
+ usdPrice: coinsData[`${prefix}:${t.address}`] ? coinsData[`${prefix}:${t.address}`].price : 0,
40
+ }
41
+ })
42
+
43
+ return parsedPrice
44
+ } catch (e) {
45
+ console.error(e)
46
+ return defaultErrorValue
47
+ }
48
+ }
49
+
50
+ export const getPricesFromCurve = async (chainId: number) => {
51
+ const prefix = getLlamaTokenPrefix(chainId)
52
+ const httpRequest = (await fetch(`https://prices.curve.fi/v1/usd_price/${prefix}`)).json()
53
+
54
+ return httpRequest
55
+ }
56
+
57
+ export const getPricesFromGeckoTerminal = async (tokens: any[], chainId = 1, defaultErrorValue?: any): Promise<any> => {
58
+ try {
59
+ let network: string
60
+ switch (chainId) {
61
+ case 1:
62
+ network = 'eth'
63
+ break
64
+ case 137:
65
+ network = 'polygon_pos'
66
+ break
67
+ case 42161:
68
+ network = 'arbitrum'
69
+ break
70
+ default:
71
+ network = 'eth'
72
+ break
73
+ }
74
+
75
+ const httpArgs = uniq(tokens).join(',')
76
+ const httpRequest = await (
77
+ await fetch(`${GECKO_TERMINAL_API_URL}/simple/networks/${network}/token_price/${httpArgs}`)
78
+ ).json()
79
+ const coinsData = httpRequest.data.attributes.token_prices
80
+
81
+ return coinsData
82
+ } catch (e) {
83
+ console.error(e)
84
+ return defaultErrorValue
85
+ }
86
+ }
package/src/sdt/sdt.ts ADDED
@@ -0,0 +1,110 @@
1
+ import { formatUnits, parseAbi, parseUnits } from 'viem'
2
+
3
+ import { ONE_DAY, type Token, contracts, tokenWithId } from '@stake-dao/constants'
4
+ import { Zero } from '../index.js'
5
+ import { type Price } from '../prices.js'
6
+ import { agnostic, multicall } from '../utils.js'
7
+ import veSdtAlternativeYields from './veSdtAlternativeYields.js'
8
+
9
+ const AGNOSTIC_QUERY = (timeLimit: number) => `
10
+ select
11
+ input_0_value_uint256 as time,
12
+ input_1_value_uint256 as tokens
13
+ from evm_events_ethereum_mainnet
14
+ where
15
+ address = '${contracts.veSdtFeeDistributor![1]!}' and
16
+ input_1_value_uint256 != '0' and
17
+ input_0_value_uint256 > '${timeLimit}' and
18
+ signature = 'CheckpointToken(uint256,uint256)'
19
+ ORDER BY time DESC
20
+ `
21
+
22
+ export const fetchSdt = async (prices: Price[], provider: any, agnosticKey?: string) => {
23
+ const sdtToken = tokenWithId('sdt') as Token
24
+ const frax3CrvToken = tokenWithId('frax3crv') as Token
25
+
26
+ const now = Math.ceil(new Date().getTime() / 1000)
27
+ const lastCheck = now - ONE_DAY * 28
28
+
29
+ let agnosticData: any[] | null = null
30
+ if (agnosticKey) {
31
+ const httpCalls = [await agnostic(AGNOSTIC_QUERY(lastCheck), agnosticKey)]
32
+ const httpResponses = (await Promise.allSettled(httpCalls))
33
+ .flatMap((d) => (d.status === 'fulfilled' ? d.value : d.reason))
34
+ .flat()
35
+ agnosticData = httpResponses[0]
36
+ }
37
+
38
+ const rawSdtData: any = await multicall(
39
+ provider,
40
+ [
41
+ { address: contracts.sdFrx3CrvVault![1]!, name: 'getPricePerFullShare' },
42
+ { address: sdtToken.address, name: 'balanceOf', params: [contracts.veSdt![1]!] },
43
+ { address: sdtToken.address, name: 'balanceOf', params: [contracts.vestedSdt![1]!] },
44
+ { address: sdtToken.address, name: 'totalSupply' },
45
+ { address: contracts.veSdt![1]!, name: 'totalSupply' },
46
+ {
47
+ address: contracts.veSdtBoostDelegation![1]!,
48
+ name: 'received_balance',
49
+ params: [contracts.voteBoosterStrategy![1]!],
50
+ },
51
+ { address: contracts.liquidLockersGaugeController![1]!, name: 'get_total_weight' },
52
+ { address: contracts.sdGaugeController![1]!, name: 'get_total_weight' },
53
+ ],
54
+ parseAbi([
55
+ 'function getPricePerFullShare() external view returns (uint256)',
56
+ 'function balanceOf(address user) external view returns (uint256)',
57
+ 'function totalSupply() external view returns (uint256)',
58
+ 'function received_balance(address user) external view returns (uint256)',
59
+ 'function get_total_weight() external view returns (uint256)',
60
+ ]),
61
+ )
62
+
63
+ const vaultRatio = rawSdtData[0].result
64
+ const lockedSdtBalance = rawSdtData[1].result
65
+ const vestedSdtBalance = rawSdtData[2].result
66
+ const sdtTotalSupply = rawSdtData[3].result
67
+ const veSdtTotalSupply = rawSdtData[4].result
68
+ const voteBoosterVeSdt = rawSdtData[5].result
69
+
70
+ const sdtPrice = prices?.find((p) => p.address.toLowerCase() === sdtToken.address.toLowerCase())?.usdPrice || 0
71
+ const frax3CrvPrice =
72
+ prices?.find((p) => p.address.toLowerCase() === frax3CrvToken.address.toLowerCase())?.usdPrice || 0
73
+
74
+ const lockedInUsd = parseUnits(`${sdtPrice}`, sdtToken.decimals) * lockedSdtBalance
75
+ const vestedInUsd = parseUnits(`${sdtPrice}`, sdtToken.decimals) * vestedSdtBalance
76
+ const percentLocked = parseUnits(formatUnits(lockedSdtBalance, 0), sdtToken.decimals) / sdtTotalSupply
77
+ const averageLock = (parseUnits(formatUnits(veSdtTotalSupply, 0), sdtToken.decimals) / lockedSdtBalance) * BigInt(4)
78
+
79
+ let rewardsAmount = Zero
80
+ let checkedWeek = now - ONE_DAY * 7
81
+
82
+ let apr = 0
83
+ if (agnosticData) {
84
+ while (lastCheck <= checkedWeek && rewardsAmount === Zero) {
85
+ const checkedWeekAgnostic = agnosticData ? agnosticData.filter((d: any) => checkedWeek < Number(d[0])) : null
86
+ rewardsAmount = checkedWeekAgnostic ? checkedWeekAgnostic.reduce((total, d) => total + BigInt(d[1]), Zero) : Zero
87
+ checkedWeek = checkedWeek - ONE_DAY * 7
88
+ }
89
+
90
+ apr =
91
+ ((frax3CrvPrice * Number(formatUnits(rewardsAmount, 18)) * 52) / Number(formatUnits(vestedInUsd, 18))) *
92
+ Number(vaultRatio)
93
+ }
94
+
95
+ const parsedData = {
96
+ alternativeYields: veSdtAlternativeYields,
97
+ veSdtTotalSupply: formatUnits(veSdtTotalSupply, 0),
98
+ locked: formatUnits(lockedSdtBalance, 0),
99
+ lockedInUsd: Number(formatUnits(lockedInUsd, sdtToken.decimals * 2)),
100
+ vestedInUsd: Number(formatUnits(vestedInUsd, sdtToken.decimals * 2)),
101
+ percentLocked: Number(formatUnits(percentLocked, 18)) * 100,
102
+ averageLockInYears: Number(formatUnits(averageLock, 18)),
103
+ apr: apr * 100,
104
+ voteBoosterVeSdt: Number(formatUnits(voteBoosterVeSdt, sdtToken.decimals)),
105
+ lockersTotalWeight: formatUnits(rawSdtData[6].result, 0),
106
+ stratsTotalWeight: formatUnits(rawSdtData[7].result, 0),
107
+ }
108
+
109
+ return parsedData
110
+ }
@@ -0,0 +1,19 @@
1
+ const veSdtAlternativeYields = {
2
+ wardenMarket: {
3
+ label: 'Market',
4
+ platform: 'Warden',
5
+ href: 'https://app.warden.vote/boosts/market/',
6
+ },
7
+ wardenPledge: {
8
+ label: 'Pledge',
9
+ platform: 'Warden',
10
+ href: 'https://app.warden.vote/boosts/pledge/',
11
+ },
12
+ asdcrvDelegation: {
13
+ label: 'asdCRV Delegation',
14
+ platform: 'Concentator',
15
+ href: 'https://concentrator.aladdin.club/#/vault',
16
+ },
17
+ }
18
+
19
+ export default veSdtAlternativeYields
@@ -0,0 +1,187 @@
1
+ import { chunk, remove, uniq } from 'lodash-es'
2
+ import { decodeAbiParameters, encodeAbiParameters, parseAbi, parseAbiParameters } from 'viem'
3
+
4
+ import { contract, tokens } from '@stake-dao/constants'
5
+ import type { FetchedToken, Token } from '@stake-dao/constants'
6
+ import { batchSdtGaugeRewards, batchTokenData } from '../../batches/index.js'
7
+ import { equalTlc, getTokenInfo } from '../../utils.js'
8
+
9
+ interface VaultAndLp {
10
+ vault: string
11
+ lpToken: string
12
+ }
13
+
14
+ export const buildCurveStrategies = async (
15
+ provider: any,
16
+ stratsList: VaultAndLp[],
17
+ chainId: number,
18
+ externalApisResult: any[],
19
+ ) => {
20
+ const tokensToFetch: string[] = []
21
+ const gaugesToFetch: string[] = []
22
+
23
+ const strats = stratsList.map((data) => {
24
+ const lpToken = data.lpToken
25
+ const curveApiData = externalApisResult.find((el) => equalTlc(el.lp, lpToken))
26
+
27
+ if (curveApiData) {
28
+ const isMetapool = curveApiData.isMetapool
29
+ const isLending = curveApiData.isLending
30
+
31
+ const coins: string[] = curveApiData.coins.map((c) => c.coinAddress)
32
+
33
+ let underlyingCoins: string[] = []
34
+ if (isMetapool || isLending) {
35
+ underlyingCoins = curveApiData.underlyingCoins
36
+ }
37
+
38
+ const gaugeAddress = curveApiData.gauge?.address || undefined
39
+
40
+ for (const coin of coins) tokensToFetch.push(coin)
41
+ for (const uCoin of underlyingCoins) tokensToFetch.push(uCoin)
42
+ tokensToFetch.push(lpToken)
43
+
44
+ if (typeof gaugeAddress === 'undefined') {
45
+ gaugesToFetch.push(data.vault)
46
+ }
47
+
48
+ return {
49
+ type: curveApiData.poolType,
50
+ key: `${curveApiData.poolType}-${curveApiData.id}`,
51
+ isMetapool,
52
+ isLending,
53
+ coins,
54
+ vault: data.vault,
55
+ lpToken,
56
+ gaugeAddress,
57
+ underlyingCoins,
58
+ }
59
+ }
60
+
61
+ return {
62
+ type: undefined,
63
+ key: undefined,
64
+ isMetapool: undefined,
65
+ isLending: undefined,
66
+ coins: [],
67
+ vault: data.vault,
68
+ lpToken,
69
+ gaugeAddress: undefined,
70
+ underlyingCoins: [],
71
+ }
72
+ })
73
+
74
+ // Fetch tokens infos
75
+ const inputArgsChunks = chunk(
76
+ remove(uniq(tokensToFetch), (t) => !tokens.find((token: Token) => token.address === t)),
77
+ 40,
78
+ )
79
+ const decodedPromise = await Promise.allSettled(
80
+ inputArgsChunks.map(async (inputArgs) => {
81
+ const inputData = encodeAbiParameters(parseAbiParameters(batchTokenData.inputType[chainId] || []) as any, [
82
+ inputArgs,
83
+ ])
84
+ const contractCreationCode = batchTokenData.bytecode[chainId]?.concat(inputData.slice(2))
85
+ const returnedData = await provider.call({
86
+ data: contractCreationCode,
87
+ })
88
+ return decodeAbiParameters(
89
+ parseAbiParameters(batchTokenData.outputTypeHr[chainId] || []) as any,
90
+ returnedData.data,
91
+ )
92
+ }),
93
+ )
94
+
95
+ const fetchedTokenData = decodedPromise.flatMap((d) => (d.status === 'fulfilled' ? d.value : [])).flat()
96
+
97
+ // Fetch Sdt Gauge rewards tokens infos
98
+ const sdtGaugeInputArgsChunks = chunk(
99
+ stratsList.map((data) => data.vault),
100
+ 20,
101
+ )
102
+ const sdtGaugedecodedPromise = await Promise.allSettled(
103
+ sdtGaugeInputArgsChunks.map(async (inputArgs) => {
104
+ const inputData = encodeAbiParameters(parseAbiParameters(batchSdtGaugeRewards.inputType[chainId] || []) as any, [
105
+ inputArgs,
106
+ ])
107
+ const contractCreationCode = batchSdtGaugeRewards.bytecode[chainId]?.concat(inputData.slice(2))
108
+ const returnedData = await provider.call({
109
+ data: contractCreationCode,
110
+ })
111
+ return decodeAbiParameters(
112
+ parseAbiParameters(batchSdtGaugeRewards.outputTypeHr[chainId] || []) as any,
113
+ returnedData.data,
114
+ )
115
+ }),
116
+ )
117
+ const fetchedSdtGaugeData = sdtGaugedecodedPromise.flatMap((d) => (d.status === 'fulfilled' ? d.value : [])).flat()
118
+
119
+ // Fetch Curve Lending Gauges
120
+ let curveLendingGauges: any[] = []
121
+ let curveLendingGaugesIndex = 0
122
+
123
+ if (chainId === 1) {
124
+ curveLendingGauges = await provider.multicall({
125
+ contracts: strats
126
+ .map((s) =>
127
+ s.isLending
128
+ ? {
129
+ abi: parseAbi(['function gauge_for_vault(address _vault) external view returns (address)']),
130
+ address: contract('curveOneWayLendingFactory', chainId),
131
+ functionName: 'gauge_for_vault',
132
+ args: [s.lpToken],
133
+ }
134
+ : undefined,
135
+ )
136
+ .filter(Boolean),
137
+ })
138
+ }
139
+
140
+ const stratsData = strats.map((s, index) => {
141
+ const coinsData = s.coins.map((c: string) =>
142
+ getTokenInfo(
143
+ fetchedTokenData.find((t) => equalTlc(t.tokenAddress, c)),
144
+ c,
145
+ chainId,
146
+ ),
147
+ )
148
+ const underlyingCoinsData = s.underlyingCoins.map((c: string) =>
149
+ getTokenInfo(
150
+ fetchedTokenData.find((t) => equalTlc(t.tokenAddress, c)),
151
+ c,
152
+ chainId,
153
+ ),
154
+ )
155
+ const stakeTokenData = getTokenInfo(
156
+ fetchedTokenData.find((t) => equalTlc(t.tokenAddress, s.lpToken)),
157
+ s.lpToken,
158
+ chainId,
159
+ )
160
+
161
+ let gaugeAddress: string = s.gaugeAddress
162
+ if (s.isLending) {
163
+ gaugeAddress = curveLendingGauges[curveLendingGaugesIndex]?.result
164
+ curveLendingGaugesIndex += 1
165
+ }
166
+
167
+ return {
168
+ key: s.key,
169
+ type: s.type,
170
+ protocol: 'curve',
171
+ chainId: chainId,
172
+ isMetapool: s.isMetapool,
173
+ isLending: s.isLending,
174
+ vault: s.vault,
175
+ lpToken: stakeTokenData,
176
+ gaugeAddress,
177
+ coins: coinsData,
178
+ underlyingCoins: underlyingCoinsData,
179
+ sdGauge: fetchedSdtGaugeData[index]?.gauge || undefined,
180
+ rewards: fetchedSdtGaugeData[index].rewards.map((tokenInfo: FetchedToken) =>
181
+ getTokenInfo(tokenInfo, tokenInfo.tokenAddress, chainId),
182
+ ),
183
+ }
184
+ })
185
+
186
+ return stratsData
187
+ }
@@ -0,0 +1,21 @@
1
+ export const FACTORY_EXPLORER_EVENTS = (
2
+ apiKey: string,
3
+ explorer: string,
4
+ contract: string,
5
+ fromBlock: number,
6
+ toBlock: number | 'latest' = 'latest',
7
+ ) =>
8
+ `https://api.${explorer}/api?module=logs&action=getLogs&address=${contract}&fromBlock=${fromBlock}&toBlock=${toBlock}&topic0=0x26ad9f07a47e389150a15677a365d64f42af0000b792c182ada6a3b5ab193a0b&apikey=${apiKey}`
9
+
10
+ export const NEW_FACTORY_EXPLORER_EVENTS = (
11
+ apiKey: string,
12
+ explorer: string,
13
+ contract: string,
14
+ fromBlock: number,
15
+ toBlock: number | 'latest' = 'latest',
16
+ ) =>
17
+ `https://api.${explorer}/api?module=logs&action=getLogs&address=${contract}&fromBlock=${fromBlock}&toBlock=${toBlock}&topic0=0x5f7560a5797edc6f72421362defa094d690eb9f7ced3cc5a5c13383502e4fcc5&apikey=${apiKey}`
18
+
19
+ export const CURVE_API_URL = 'https://api.curve.fi/api'
20
+ export const CONVEX_POOLS_URL = 'https://curve.convexfinance.com/api/curve/pools'
21
+ export const CONVEX_LENDING_VAULTS_URL = 'https://curve.convexfinance.com/api/curve/lending-vaults'
@@ -0,0 +1,81 @@
1
+ export const getCurveDataPoolsOutputTypeAbi = (isLending: boolean) => [
2
+ {
3
+ type: 'tuple[]',
4
+ name: 'returnData',
5
+ components: [
6
+ { type: 'uint256', name: 'id' },
7
+ { type: 'address', name: 'lp' },
8
+ { type: 'address', name: 'pool' },
9
+ { type: 'uint256', name: 'totalSupply' },
10
+ { type: 'address', name: 'gauge' },
11
+ { type: 'bool', name: 'isMetapool' },
12
+ {
13
+ type: 'tuple[]',
14
+ name: 'coins',
15
+ components: [
16
+ { type: 'address', name: 'coinAddress' },
17
+ { type: 'uint256', name: 'decimals' },
18
+ { type: 'uint256', name: 'balance' },
19
+ ],
20
+ },
21
+ { type: 'address[]', name: 'underlyingCoins' },
22
+ ...(isLending
23
+ ? [
24
+ {
25
+ type: 'tuple',
26
+ name: 'ext',
27
+ components: [
28
+ { type: 'uint256', name: 'pricePerShare' },
29
+ { type: 'uint256', name: 'lendApr' },
30
+ ],
31
+ },
32
+ ]
33
+ : []),
34
+ ],
35
+ },
36
+ ]
37
+
38
+ export const getCurveDataGaugesWeightsOutputTypeAbi = [
39
+ {
40
+ type: 'tuple[]',
41
+ name: 'returnData',
42
+ components: [
43
+ { type: 'address', name: 'gauge' },
44
+ { type: 'uint256', name: 'relativeWeight' },
45
+ { type: 'uint256', name: 'futureRelativeWeight' },
46
+ ],
47
+ },
48
+ ]
49
+
50
+ export const getCurveDataGaugesOutputTypeAbi = [
51
+ {
52
+ type: 'tuple[]',
53
+ name: 'returnData',
54
+ components: [
55
+ { type: 'address', name: 'gauge' },
56
+ { type: 'address', name: 'lpToken' },
57
+ { type: 'bool', name: 'isKilled' },
58
+ { type: 'uint256', name: 'inflationRate' },
59
+ { type: 'uint256', name: 'workingSupply' },
60
+ {
61
+ type: 'tuple[]',
62
+ name: 'rewards',
63
+ components: [
64
+ {
65
+ type: 'tuple',
66
+ name: 'token',
67
+ components: [
68
+ { type: 'address', name: 'tokenAddress' },
69
+ { type: 'string', name: 'name' },
70
+ { type: 'string', name: 'symbol' },
71
+ { type: 'uint256', name: 'decimals' },
72
+ ],
73
+ },
74
+ { type: 'address', name: 'distributor' },
75
+ { type: 'uint256', name: 'periodFinish' },
76
+ { type: 'uint256', name: 'rate' },
77
+ ],
78
+ },
79
+ ],
80
+ },
81
+ ]