@stake-dao/reader 0.1.1 → 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 (191) 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/getStratsWithApr.js +1 -1
  51. package/dist/esm/strategies/curve/fetch/getStratsWithApr.js.map +1 -1
  52. package/dist/esm/strategies/curve/fetch/index.js +4 -17
  53. package/dist/esm/strategies/curve/fetch/index.js.map +1 -1
  54. package/dist/esm/strategies/curve/httpCalls.js +3 -1
  55. package/dist/esm/strategies/curve/httpCalls.js.map +1 -1
  56. package/dist/esm/strategies/utils/abis/MulticallYearnStratsAbi.json +107 -0
  57. package/dist/esm/strategies/{curve/fetch → utils}/getAprBreakdown.js +17 -7
  58. package/dist/esm/strategies/utils/getAprBreakdown.js.map +1 -0
  59. package/dist/esm/strategies/utils/index.js +1 -0
  60. package/dist/esm/strategies/utils/index.js.map +1 -1
  61. package/dist/esm/strategies/utils/sdt.js +17 -0
  62. package/dist/esm/strategies/utils/sdt.js.map +1 -1
  63. package/dist/esm/strategies/yearn/build.js +97 -0
  64. package/dist/esm/strategies/yearn/build.js.map +1 -0
  65. package/dist/esm/strategies/yearn/fetch/computeYearnApr.js +28 -0
  66. package/dist/esm/strategies/yearn/fetch/computeYearnApr.js.map +1 -0
  67. package/dist/esm/strategies/yearn/fetch/fetchAllYearnGauges.js +61 -0
  68. package/dist/esm/strategies/yearn/fetch/fetchAllYearnGauges.js.map +1 -0
  69. package/dist/esm/strategies/yearn/fetch/index.js +169 -0
  70. package/dist/esm/strategies/yearn/fetch/index.js.map +1 -0
  71. package/dist/esm/tsconfig.build.tsbuildinfo +1 -1
  72. package/dist/esm/utils.js +33 -1
  73. package/dist/esm/utils.js.map +1 -1
  74. package/dist/types/batches/buildYearnStrats.d.ts +4 -0
  75. package/dist/types/batches/buildYearnStrats.d.ts.map +1 -0
  76. package/dist/types/batches/curveStrats.d.ts.map +1 -1
  77. package/dist/types/batches/fetchYearnGauges.d.ts +4 -0
  78. package/dist/types/batches/fetchYearnGauges.d.ts.map +1 -0
  79. package/dist/types/batches/index.d.ts +2 -0
  80. package/dist/types/batches/index.d.ts.map +1 -1
  81. package/dist/types/index.d.ts +2 -0
  82. package/dist/types/index.d.ts.map +1 -1
  83. package/dist/types/lockers/fetch/index.d.ts +11 -0
  84. package/dist/types/lockers/fetch/index.d.ts.map +1 -0
  85. package/dist/types/lockers/utils/cakeLockerAirdrop.d.ts +8 -0
  86. package/dist/types/lockers/utils/cakeLockerAirdrop.d.ts.map +1 -0
  87. package/dist/types/lockers/utils/callsForLockers/depositorCalls.d.ts +3 -0
  88. package/dist/types/lockers/utils/callsForLockers/depositorCalls.d.ts.map +1 -0
  89. package/dist/types/lockers/utils/callsForLockers/feeCalls.d.ts +11 -0
  90. package/dist/types/lockers/utils/callsForLockers/feeCalls.d.ts.map +1 -0
  91. package/dist/types/lockers/utils/callsForLockers/gaugeCalls.d.ts +6 -0
  92. package/dist/types/lockers/utils/callsForLockers/gaugeCalls.d.ts.map +1 -0
  93. package/dist/types/lockers/utils/callsForLockers/gaugeControllerCalls.d.ts +11 -0
  94. package/dist/types/lockers/utils/callsForLockers/gaugeControllerCalls.d.ts.map +1 -0
  95. package/dist/types/lockers/utils/callsForLockers/index.d.ts +3 -0
  96. package/dist/types/lockers/utils/callsForLockers/index.d.ts.map +1 -0
  97. package/dist/types/lockers/utils/callsForLockers/pegCalls.d.ts +15 -0
  98. package/dist/types/lockers/utils/callsForLockers/pegCalls.d.ts.map +1 -0
  99. package/dist/types/lockers/utils/callsForLockers/veCalls.d.ts +3 -0
  100. package/dist/types/lockers/utils/callsForLockers/veCalls.d.ts.map +1 -0
  101. package/dist/types/lockers/utils/callsForLockers/veSdtCalls.d.ts +11 -0
  102. package/dist/types/lockers/utils/callsForLockers/veSdtCalls.d.ts.map +1 -0
  103. package/dist/types/lockers/utils/endpoints.d.ts +3 -0
  104. package/dist/types/lockers/utils/endpoints.d.ts.map +1 -0
  105. package/dist/types/lockers/utils/getBribesRewardsData.d.ts +18 -0
  106. package/dist/types/lockers/utils/getBribesRewardsData.d.ts.map +1 -0
  107. package/dist/types/lockers/utils/getCherriesLeaderBoard.d.ts +2 -0
  108. package/dist/types/lockers/utils/getCherriesLeaderBoard.d.ts.map +1 -0
  109. package/dist/types/lockers/utils/getFees.d.ts +4 -0
  110. package/dist/types/lockers/utils/getFees.d.ts.map +1 -0
  111. package/dist/types/lockers/utils/getHttpCalls.d.ts +11 -0
  112. package/dist/types/lockers/utils/getHttpCalls.d.ts.map +1 -0
  113. package/dist/types/lockers/utils/getSdtInflationData.d.ts +8 -0
  114. package/dist/types/lockers/utils/getSdtInflationData.d.ts.map +1 -0
  115. package/dist/types/lockers/utils/index.d.ts +30 -0
  116. package/dist/types/lockers/utils/index.d.ts.map +1 -0
  117. package/dist/types/lockers/utils/substractFees.d.ts +3 -0
  118. package/dist/types/lockers/utils/substractFees.d.ts.map +1 -0
  119. package/dist/types/prices.d.ts.map +1 -1
  120. package/dist/types/strategies/curve/build.d.ts +2 -31
  121. package/dist/types/strategies/curve/build.d.ts.map +1 -1
  122. package/dist/types/strategies/curve/endpoints.d.ts +2 -2
  123. package/dist/types/strategies/curve/fetch/curveApiData/getGaugesFromRegistry.d.ts.map +1 -1
  124. package/dist/types/strategies/curve/fetch/curveApiData/getGaugesWeights.d.ts.map +1 -1
  125. package/dist/types/strategies/curve/fetch/index.d.ts +2 -7
  126. package/dist/types/strategies/curve/fetch/index.d.ts.map +1 -1
  127. package/dist/types/strategies/curve/httpCalls.d.ts.map +1 -1
  128. package/dist/types/strategies/types.d.ts +49 -6
  129. package/dist/types/strategies/types.d.ts.map +1 -1
  130. package/dist/types/strategies/utils/getAprBreakdown.d.ts +15 -0
  131. package/dist/types/strategies/utils/getAprBreakdown.d.ts.map +1 -0
  132. package/dist/types/strategies/utils/index.d.ts +1 -0
  133. package/dist/types/strategies/utils/index.d.ts.map +1 -1
  134. package/dist/types/strategies/utils/promise.d.ts.map +1 -1
  135. package/dist/types/strategies/utils/sdt.d.ts +1 -0
  136. package/dist/types/strategies/utils/sdt.d.ts.map +1 -1
  137. package/dist/types/strategies/yearn/build.d.ts +8 -0
  138. package/dist/types/strategies/yearn/build.d.ts.map +1 -0
  139. package/dist/types/strategies/yearn/fetch/computeYearnApr.d.ts +9 -0
  140. package/dist/types/strategies/yearn/fetch/computeYearnApr.d.ts.map +1 -0
  141. package/dist/types/strategies/yearn/fetch/fetchAllYearnGauges.d.ts +2 -0
  142. package/dist/types/strategies/yearn/fetch/fetchAllYearnGauges.d.ts.map +1 -0
  143. package/dist/types/strategies/yearn/fetch/index.d.ts +5 -0
  144. package/dist/types/strategies/yearn/fetch/index.d.ts.map +1 -0
  145. package/dist/types/utils.d.ts +5 -0
  146. package/dist/types/utils.d.ts.map +1 -1
  147. package/package.json +3 -2
  148. package/src/batches/buildYearnStrats.ts +41 -0
  149. package/src/batches/curveStrats.ts +4 -6
  150. package/src/batches/fetchYearnGauges.ts +78 -0
  151. package/src/batches/index.ts +2 -0
  152. package/src/index.ts +2 -0
  153. package/src/lockers/fetch/index.ts +407 -0
  154. package/src/lockers/utils/cakeLockerAirdrop.ts +73 -0
  155. package/src/lockers/utils/callsForLockers/depositorCalls.ts +25 -0
  156. package/src/lockers/utils/callsForLockers/feeCalls.ts +118 -0
  157. package/src/lockers/utils/callsForLockers/gaugeCalls.ts +6 -0
  158. package/src/lockers/utils/callsForLockers/gaugeControllerCalls.ts +8 -0
  159. package/src/lockers/utils/callsForLockers/index.ts +44 -0
  160. package/src/lockers/utils/callsForLockers/pegCalls.ts +40 -0
  161. package/src/lockers/utils/callsForLockers/veCalls.ts +31 -0
  162. package/src/lockers/utils/callsForLockers/veSdtCalls.ts +15 -0
  163. package/src/lockers/utils/endpoints.ts +24 -0
  164. package/src/lockers/utils/getBribesRewardsData.ts +64 -0
  165. package/src/lockers/utils/getCherriesLeaderBoard.ts +34 -0
  166. package/src/lockers/utils/getFees.ts +34 -0
  167. package/src/lockers/utils/getHttpCalls.ts +55 -0
  168. package/src/lockers/utils/getSdtInflationData.ts +54 -0
  169. package/src/lockers/utils/index.ts +200 -0
  170. package/src/lockers/utils/substractFees.ts +26 -0
  171. package/src/strategies/curve/build.ts +49 -44
  172. package/src/strategies/curve/fetch/getStratsWithApr.ts +1 -1
  173. package/src/strategies/curve/fetch/index.ts +12 -22
  174. package/src/strategies/curve/httpCalls.ts +3 -1
  175. package/src/strategies/types.ts +52 -6
  176. package/src/strategies/{curve/fetch → utils}/getAprBreakdown.ts +25 -8
  177. package/src/strategies/utils/index.ts +1 -0
  178. package/src/strategies/utils/sdt.ts +24 -0
  179. package/src/strategies/yearn/build.ts +156 -0
  180. package/src/strategies/yearn/fetch/computeYearnApr.ts +47 -0
  181. package/src/strategies/yearn/fetch/fetchAllYearnGauges.ts +78 -0
  182. package/src/strategies/yearn/fetch/index.ts +225 -0
  183. package/src/utils.ts +43 -1
  184. package/dist/esm/strategies/curve/fetch/getAprBreakdown.js.map +0 -1
  185. package/dist/esm/strategies/curve/fetch/types.js +0 -2
  186. package/dist/esm/strategies/curve/fetch/types.js.map +0 -1
  187. package/dist/types/strategies/curve/fetch/getAprBreakdown.d.ts +0 -17
  188. package/dist/types/strategies/curve/fetch/getAprBreakdown.d.ts.map +0 -1
  189. package/dist/types/strategies/curve/fetch/types.d.ts +0 -11
  190. package/dist/types/strategies/curve/fetch/types.d.ts.map +0 -1
  191. package/src/strategies/curve/fetch/types.ts +0 -11
@@ -0,0 +1,407 @@
1
+ import { formatUnits, parseAbi, parseUnits, zeroAddress } from 'viem'
2
+ import { mainnet } from 'viem/chains'
3
+
4
+ import { ONE_YEAR, lockers, tokenWithId } from '@stake-dao/constants'
5
+ import { delegationWithId } from '@stake-dao/constants'
6
+ import { OneEther, Zero } from '../../index.js'
7
+ import { type Price } from '../../prices.js'
8
+ import { type Call, multicall } from '../../utils.js'
9
+ import { lockedAmountCallSideChain } from '../utils/index.js'
10
+
11
+ import { type MultiChainCall, multichainMulticall } from '../../utils.js'
12
+ import lockersMulticallAbi from '../abis/MulticallLockers.json'
13
+ import { getCherriesLeaderBoard } from '../utils/getCherriesLeaderBoard.js'
14
+
15
+ import { extractFees, feeCalls } from '../utils/callsForLockers/feeCalls.js'
16
+ import callsForLockers from '../utils/callsForLockers/index.js'
17
+ import getBribesRewardsData from '../utils/getBribesRewardsData.js'
18
+ import getFees from '../utils/getFees.js'
19
+ import getHttpCalls from '../utils/getHttpCalls.js'
20
+ import getSdtInflationData from '../utils/getSdtInflationData.js'
21
+ import substractFees from '../utils/substractFees.js'
22
+
23
+ const callsForRewards = (gauge: string, rewards: any[]) =>
24
+ rewards.map((r) => ({ address: gauge, name: 'reward_data', params: [r.address] }))
25
+
26
+ const callsForLockersSideChains = (lockerId: any, sideChains: any[]) => {
27
+ return sideChains.reduce((acc, value) => {
28
+ return acc.concat([
29
+ lockedAmountCallSideChain(lockerId, value.veToken, value.locker, value.chainId),
30
+ { address: value.veToken, name: 'balanceOf', params: [value.locker], chainId: value.chainId },
31
+ { address: value.veToken, name: 'totalSupply', chainId: value.chainId },
32
+ ])
33
+ }, [])
34
+ }
35
+
36
+ export const fetchLockers = async (provider: any, chainId: number, prices: Price[]) => {
37
+ const chainLockers = lockers.filter((l) => l.chainId === chainId)
38
+
39
+ const httpCalls = await getHttpCalls(chainId)
40
+
41
+ const lockersCalls: Call[] = []
42
+ const lockersRewardsCalls: Call[] = []
43
+ const lockersFeeCalls: Call[] = []
44
+ const lockersSideChainsCalls: MultiChainCall[] = []
45
+
46
+ for (const locker of chainLockers) {
47
+ lockersCalls.push(
48
+ ...callsForLockers(
49
+ locker.id,
50
+ locker.token!.address,
51
+ locker.sdToken!.address,
52
+ locker.extensions.veToken,
53
+ locker.extensions.depositor,
54
+ locker.extensions.gaugeController,
55
+ locker.extensions.gauge,
56
+ locker.extensions.locker,
57
+ locker.extensions.pool,
58
+ locker.pegCalculator,
59
+ locker.extensions.secondaryMarket,
60
+ locker.extensions.voteBooster,
61
+ ),
62
+ )
63
+ lockersRewardsCalls.push(...callsForRewards(locker.extensions.gauge, locker.rewards))
64
+ if (locker.extensions.sideChains) {
65
+ lockersSideChainsCalls.push(...callsForLockersSideChains(locker.id, locker.extensions.sideChains))
66
+ }
67
+
68
+ // Add fee calls into another array
69
+ // We will concat it with #lockersRewardsCalls to do only one multicall, the concat will push all fee calls at the end
70
+ lockersFeeCalls.push(...feeCalls(locker.id, locker.extensions.accumulator))
71
+ }
72
+
73
+ const [rawLockersData, rawLockersSideChainData] = (
74
+ await Promise.allSettled([
75
+ multicall(provider, lockersCalls.concat(lockersFeeCalls), lockersMulticallAbi),
76
+ multichainMulticall(lockersSideChainsCalls, lockersMulticallAbi),
77
+ ])
78
+ ).map((result) => (result.status === 'fulfilled' ? result.value : result.reason))
79
+
80
+ const lockersFees = extractFees(chainLockers, rawLockersData)
81
+
82
+ const [sdtInflationData, rawLockersRewardsData]: any = await Promise.all([
83
+ getSdtInflationData(provider),
84
+ multicall(
85
+ provider,
86
+ lockersRewardsCalls,
87
+ parseAbi([
88
+ 'function reward_data(address) external view returns (address,address,uint256,uint256,uint256,uint256)',
89
+ ]),
90
+ ),
91
+ ])
92
+
93
+ const lockerData = chainLockers.map(async (locker) => {
94
+ const lockerCallsLength = callsForLockers(
95
+ locker.id,
96
+ locker.token!.address,
97
+ locker.sdToken!.address,
98
+ locker.extensions.veToken,
99
+ locker.extensions.depositor,
100
+ locker.extensions.gaugeController,
101
+ locker.extensions.gauge,
102
+ locker.extensions.locker,
103
+ locker.extensions.pool,
104
+ locker.pegCalculator,
105
+ locker.extensions.secondaryMarket,
106
+ locker.extensions.voteBooster,
107
+ ).length
108
+ const chunkedRawLockersData = rawLockersData.splice(0, lockerCallsLength)
109
+
110
+ let gaugeRelativeWeight = '0'
111
+ let gaugeTotalWeight = '0'
112
+ let gaugeWeight = '0'
113
+ let nextEffectiveTimestamp = '0'
114
+
115
+ let airdropGraph: any = undefined
116
+ if (locker.id === 'cake') {
117
+ airdropGraph = await getCherriesLeaderBoard()
118
+ }
119
+
120
+ const lockerFee = lockersFees.find((l) => l.lockerId === locker.id)
121
+ const fees = getFees(locker, lockerFee)
122
+
123
+ const tokenLocked = formatUnits(chunkedRawLockersData[0].result[0], 0)
124
+ const veBalanceOfLockerBN = chunkedRawLockersData[1].result
125
+ const veBalanceOfLocker = formatUnits(veBalanceOfLockerBN, locker.token!.decimals)
126
+ const totalTokenLocked = formatUnits(chunkedRawLockersData[2].result, 0)
127
+ const veTotalSupplyBN = chunkedRawLockersData[3].result
128
+ const veTotalSupply = formatUnits(veTotalSupplyBN, locker.token!.decimals)
129
+ const lockIncentive = formatUnits(chunkedRawLockersData[4].result, 0)
130
+ const incentiveAmountInToken = formatUnits(chunkedRawLockersData[5].result, 0)
131
+ if (chainId === mainnet.id) {
132
+ gaugeRelativeWeight = formatUnits(chunkedRawLockersData[6].result, 0)
133
+ gaugeTotalWeight = formatUnits(chunkedRawLockersData[7].result, 0)
134
+ gaugeWeight = formatUnits(chunkedRawLockersData[8].result, 0)
135
+ nextEffectiveTimestamp = formatUnits(chunkedRawLockersData[9].result, 0)
136
+ }
137
+
138
+ const totalSupplyStakedStr =
139
+ locker.extensions.gauge !== zeroAddress ? formatUnits(chunkedRawLockersData[10].result, 0) : '0'
140
+ const totalSupplyStaked =
141
+ locker.extensions.gauge !== zeroAddress
142
+ ? formatUnits(chunkedRawLockersData[10].result, locker.token!.decimals)
143
+ : '0'
144
+
145
+ const gaugeWorkingSupplyStr =
146
+ locker.chainId === mainnet.id && locker.extensions.gauge !== zeroAddress
147
+ ? formatUnits(chunkedRawLockersData[11].result, 0)
148
+ : '0'
149
+ const gaugeWorkingSupply =
150
+ locker.chainId === mainnet.id && locker.extensions.gauge !== zeroAddress
151
+ ? formatUnits(chunkedRawLockersData[11].result, locker.token!.decimals)
152
+ : '0'
153
+ const amountTokenNotLock = formatUnits(chunkedRawLockersData[12].result, 0)
154
+ const veSdtTotalSupply = chainId === mainnet.id ? chunkedRawLockersData[13].result : '0'
155
+
156
+ const voteBoosterBalance = locker.extensions.voteBooster
157
+ ? {
158
+ token: formatUnits(chunkedRawLockersData[14].result, locker.token!.decimals),
159
+ sdToken: formatUnits(chunkedRawLockersData[15].result, locker.sdToken!.decimals),
160
+ staked:
161
+ locker.extensions.gauge !== zeroAddress
162
+ ? formatUnits(chunkedRawLockersData[16].result, locker.sdToken!.decimals)
163
+ : '0',
164
+ working:
165
+ locker.chainId === mainnet.id && locker.extensions.gauge !== zeroAddress
166
+ ? formatUnits(chunkedRawLockersData[17].result, locker.sdToken!.decimals)
167
+ : '0',
168
+ }
169
+ : undefined
170
+
171
+ const voteBoosterBoost = locker.extensions.voteBooster
172
+ ? Number(voteBoosterBalance!.working) > 0 && Number(voteBoosterBalance!.staked) > 0
173
+ ? Number(voteBoosterBalance!.working) / (Number(voteBoosterBalance!.staked) * 0.4)
174
+ : 1
175
+ : undefined
176
+
177
+ const voteBooster = locker.extensions.voteBooster
178
+ ? { balance: voteBoosterBalance, boost: voteBoosterBoost }
179
+ : undefined
180
+
181
+ const rawPeg =
182
+ locker.extensions.pool !== zeroAddress
183
+ ? chunkedRawLockersData[locker.extensions.voteBooster ? 18 : 14].result
184
+ : undefined
185
+ const veTokenRate =
186
+ locker.id === 'mav' ? formatUnits(chunkedRawLockersData[15].result[0], locker.token!.decimals) : '4'
187
+
188
+ const futureWeight =
189
+ BigInt(gaugeTotalWeight) > Zero ? (BigInt(gaugeWeight) * OneEther * OneEther) / BigInt(gaugeTotalWeight) : Zero
190
+
191
+ const sideChains = locker.extensions.sideChains?.map((sideChain) => {
192
+ const tokenLocked = rawLockersSideChainData[sideChain.chainId].shift().result
193
+ return {
194
+ ...sideChain,
195
+ tokenLocked: formatUnits(locker.id === 'mav' ? tokenLocked[0] : tokenLocked, 0),
196
+ veBalanceOfLocker: formatUnits(rawLockersSideChainData[sideChain.chainId].shift().result, 0),
197
+ veTotalSupply: formatUnits(rawLockersSideChainData[sideChain.chainId].shift().result, locker.token!.decimals),
198
+ }
199
+ })
200
+
201
+ let parsedPeg = rawPeg
202
+ switch (locker.id) {
203
+ case 'bal': {
204
+ parsedPeg = rawPeg[1] * BigInt(-1)
205
+ break
206
+ }
207
+ case 'cake': {
208
+ parsedPeg = rawPeg[0]
209
+ break
210
+ }
211
+ }
212
+ const peg =
213
+ rawPeg && parsedPeg ? formatUnits(parsedPeg / parseUnits(locker.pegCalculator.basedOn.toString(), 0), 18) : '-'
214
+
215
+ const tokenPrice = prices.find((p) => p.address === locker.token!.address)
216
+ const tokenPriceInUsd = tokenPrice ? tokenPrice.usdPrice : 0
217
+ const sdTokenPriceInUsd = peg !== '-' ? tokenPriceInUsd * Number(peg) : tokenPriceInUsd
218
+
219
+ const tvl = totalSupplyStaked ? Number(totalSupplyStaked) * sdTokenPriceInUsd : undefined
220
+
221
+ // Rewards APR
222
+ const rewardsData = locker.rewards.map((r) => {
223
+ const rawData = rawLockersRewardsData.shift().result
224
+ const rewardPrice = prices.find((p) => p.address === r.address)?.usdPrice || 0
225
+
226
+ const periodFinish = rawData ? rawData[2] : Zero
227
+ const isFinished = Math.floor(Date.now() / 1000) > Number(periodFinish)
228
+
229
+ const rate = rawData ? rawData[3] : Zero
230
+ const oneYearRate = rate * BigInt(ONE_YEAR)
231
+ const oneYearRewardInUsd = parseUnits(`${rewardPrice}`, locker.token!.decimals) * oneYearRate
232
+
233
+ let maxApr = 0
234
+ switch (locker.id) {
235
+ case 'mav': {
236
+ const MAV_AIRDROP = 10_000_000
237
+ const veMavBalanceOfLocker =
238
+ Number(veBalanceOfLocker) + sideChains?.reduce((acc, value) => acc + Number(value.veBalanceOfLocker), 0)
239
+ const veMavTotalSupply =
240
+ Number(veTotalSupply) + sideChains?.reduce((acc, value) => acc + Number(value.veTotalSupply), 0)
241
+
242
+ const mavAirdropStakeDaoShare = MAV_AIRDROP * (veMavBalanceOfLocker / veMavTotalSupply)
243
+ const airdropPerSdMav = mavAirdropStakeDaoShare / (veMavBalanceOfLocker / Number(veTokenRate))
244
+
245
+ maxApr = airdropPerSdMav
246
+ break
247
+ }
248
+ default: {
249
+ if (isFinished) {
250
+ maxApr = 0
251
+ } else {
252
+ maxApr =
253
+ rewardPrice && (tvl || 0) > 0
254
+ ? ((Number(formatUnits(oneYearRate, r.decimals)) * rewardPrice) / tvl!) * 100
255
+ : 0
256
+ }
257
+ break
258
+ }
259
+ }
260
+
261
+ // Remove fees from APR
262
+ maxApr = substractFees(locker.id, maxApr, lockerFee)
263
+ if (r.id === 'sdt' && locker.id !== 'cake') {
264
+ maxApr = isFinished ? 0 : maxApr
265
+ }
266
+ const minApr = maxApr / (locker.id !== 'cake' && r.address === tokenWithId('sdt')!.address ? 2.5 : 1)
267
+
268
+ let futureMinApr = minApr
269
+ let futureMaxApr = maxApr
270
+
271
+ if (r.id === 'sdt' && locker.id !== 'cake') {
272
+ const futureRate = (sdtInflationData.lockersSdtPerSecond * futureWeight) / OneEther
273
+ const futureOneYearRate = futureRate * BigInt(ONE_YEAR)
274
+ const futureOneYearRewardInUsd = rewardPrice * Number(formatUnits(futureOneYearRate, locker.token!.decimals))
275
+
276
+ futureMaxApr = rewardPrice && (tvl || 0) > 0 ? (futureOneYearRewardInUsd / tvl!) * 100 : 0
277
+ futureMinApr = futureMaxApr / 2.5
278
+ }
279
+
280
+ return {
281
+ token: r.address,
282
+ distributor: rawData ? rawData[1] : zeroAddress,
283
+ periodFinish: formatUnits(periodFinish, 0),
284
+ rate: formatUnits(rate, 0),
285
+ oneYearRate: formatUnits(oneYearRate, 0),
286
+ oneYearRewardInUsd: formatUnits(oneYearRewardInUsd, 0),
287
+ lastUpdate: rawData ? Number(formatUnits(rawData[4], 0)) : 0,
288
+ integral: rawData ? formatUnits(rawData[5], 0) : '0',
289
+ minApr: minApr,
290
+ maxApr: maxApr,
291
+ futureMinApr,
292
+ futureMaxApr,
293
+ rewardPrice,
294
+ isFinished,
295
+ isAirdrop: r.isAirdrop,
296
+ }
297
+ })
298
+
299
+ let bribeMinApr = 0
300
+ let bribeMaxApr = 0
301
+ let bribeRewards: any = undefined
302
+
303
+ if (chainId === mainnet.id) {
304
+ const data = getBribesRewardsData(
305
+ locker,
306
+ httpCalls?.bribesData,
307
+ veSdtTotalSupply,
308
+ totalSupplyStaked,
309
+ veBalanceOfLocker,
310
+ gaugeWorkingSupply,
311
+ )
312
+
313
+ bribeMinApr = data.bribeMinApr
314
+ bribeMaxApr = data.bribeMaxApr
315
+ bribeRewards = data.bribeRewards
316
+ } else if (locker.id === 'cake') {
317
+ const apr =
318
+ (httpCalls?.bribesData?.[delegationWithId('cake')!] || 0) *
319
+ (Number.parseFloat(veBalanceOfLocker) / Number.parseFloat(totalSupplyStaked))
320
+ bribeMinApr = apr
321
+ bribeMaxApr = apr
322
+ bribeRewards = {
323
+ bribeMinApr: apr,
324
+ bribeMaxApr: apr,
325
+ bribeAverageApr: apr,
326
+ average: apr,
327
+ minBoost: 0,
328
+ maxBoost: 0,
329
+ hideBoostTab: true,
330
+ token: 'sdcake',
331
+ }
332
+ }
333
+
334
+ // Total APR
335
+ const minRewardsAprs = rewardsData.reduce((x, y) => x + y.minApr, 0) + bribeMinApr
336
+ const maxRewardsAprs = rewardsData.reduce((x, y) => x + y.maxApr, 0) + bribeMaxApr
337
+
338
+ // Streaming status
339
+ const streaming = rewardsData.some((r) => !r.isFinished)
340
+ const alternativeYields = JSON.parse(JSON.stringify(locker.alternativeYields || {})) // parse and stringify to avoid extensible issue
341
+ if (httpCalls?.cvgAprs?.[locker.extensions.gauge]) {
342
+ alternativeYields.convergenceSdToken = {
343
+ label: locker.sdToken!.symbol,
344
+ platform: 'Convergence',
345
+ href: 'https://app.cvg.finance/',
346
+ apr: httpCalls.cvgAprs[locker.extensions.gauge].totalApr,
347
+ }
348
+ }
349
+
350
+ if (httpCalls?.cvgAprs?.[locker.extensions.strategyGauge!]) {
351
+ alternativeYields[`convergence${locker.sdToken!.symbol}Pool`] = {
352
+ label: `${locker.sdToken!.symbol}/${locker.token!.symbol}`,
353
+ platform: 'Convergence',
354
+ href: 'https://app.cvg.finance/',
355
+ apr: httpCalls.cvgAprs[locker.extensions.strategyGauge!].totalApr,
356
+ }
357
+ }
358
+
359
+ return {
360
+ ...locker,
361
+ fees,
362
+ tokenLocked: tokenLocked,
363
+ veBalanceOfLocker: formatUnits(veBalanceOfLockerBN, 0),
364
+ totalTokenLocked: totalTokenLocked,
365
+ veTotalSupply: formatUnits(veTotalSupplyBN, 0),
366
+ lockIncentive: lockIncentive,
367
+ incentiveAmountInToken: incentiveAmountInToken,
368
+ gaugeRelativeWeight: gaugeRelativeWeight,
369
+ gaugeTotalWeight: gaugeTotalWeight,
370
+ gaugeWeight: gaugeWeight,
371
+ futureWeight: formatUnits(futureWeight, 16),
372
+ gaugeWorkingSupply: gaugeWorkingSupplyStr,
373
+ nextEffectiveTimestamp: nextEffectiveTimestamp,
374
+ totalSupplyStaked: totalSupplyStakedStr,
375
+ amountTokenNotLock: amountTokenNotLock,
376
+ rewardsData,
377
+ bribeRewards,
378
+ apr: [minRewardsAprs, maxRewardsAprs],
379
+ streaming,
380
+ veTokenRate,
381
+ tvl,
382
+ peg,
383
+ tokenPriceInUsd,
384
+ sdTokenPriceInUsd,
385
+ voteBooster,
386
+ alternativeYields,
387
+ extensions: {
388
+ ...locker.extensions,
389
+ sideChains,
390
+ ...(locker.id === 'cake' ? { airdropGraph } : {}),
391
+ },
392
+ }
393
+ })
394
+
395
+ return {
396
+ parsed: (await Promise.allSettled(lockerData)).map((r) => (r.status === 'fulfilled' ? r.value : r.reason)),
397
+ sdt:
398
+ chainId === mainnet.id
399
+ ? {
400
+ lockersSdtPerBlock: formatUnits(sdtInflationData.lockersSdtPerBlock, 18),
401
+ lockersSdtPerSecond: formatUnits(sdtInflationData.lockersSdtPerSecond, 18),
402
+ stratsSdtPerBlock: formatUnits(sdtInflationData.stratsSdtPerBlock, 18),
403
+ stratsSdtPerSecond: formatUnits(sdtInflationData.stratsSdtPerSecond, 18),
404
+ }
405
+ : undefined,
406
+ }
407
+ }
@@ -0,0 +1,73 @@
1
+ import { Zero } from '../../index.js'
2
+
3
+ const THREE_M_MULTIPLIER = BigInt(10)
4
+ const TEN_M_MULTIPLIER = BigInt(8)
5
+ const TWENTY_FIVE_M_MULTIPLIER = BigInt(5)
6
+ const FIFTY_M_MULTIPLIER = BigInt(3)
7
+
8
+ export const computeRatePoints = (
9
+ rate: bigint,
10
+ timestampStart: bigint,
11
+ timestampEnd: bigint,
12
+ global: {
13
+ threeMTimestamp: bigint
14
+ tenMTimestamp: bigint
15
+ twentyFiveMTimestamp: bigint
16
+ fiftyMTimestamp: bigint
17
+ },
18
+ basePoints: bigint = Zero,
19
+ ): bigint => {
20
+ if (global.fiftyMTimestamp > Zero && timestampStart >= global.fiftyMTimestamp) {
21
+ return basePoints + rate * (timestampEnd - timestampStart)
22
+ }
23
+ if (global.twentyFiveMTimestamp > Zero && timestampStart >= global.twentyFiveMTimestamp) {
24
+ if (global.fiftyMTimestamp > Zero && timestampEnd >= global.fiftyMTimestamp) {
25
+ const checkpointPoints = basePoints + FIFTY_M_MULTIPLIER * rate * (global.fiftyMTimestamp - timestampStart)
26
+ return computeRatePoints(rate, global.fiftyMTimestamp, timestampEnd, global, checkpointPoints)
27
+ }
28
+ return basePoints + FIFTY_M_MULTIPLIER * rate * (timestampEnd - timestampStart)
29
+ }
30
+ if (global.tenMTimestamp > Zero && timestampStart >= global.tenMTimestamp) {
31
+ if (global.twentyFiveMTimestamp > Zero && timestampEnd >= global.twentyFiveMTimestamp) {
32
+ const checkpointPoints =
33
+ basePoints + TWENTY_FIVE_M_MULTIPLIER * rate * (global.twentyFiveMTimestamp - timestampStart)
34
+ return computeRatePoints(rate, global.twentyFiveMTimestamp, timestampEnd, global, checkpointPoints)
35
+ }
36
+ return basePoints + TWENTY_FIVE_M_MULTIPLIER * rate * (timestampEnd - timestampStart)
37
+ }
38
+ if (global.threeMTimestamp > Zero && timestampStart >= global.threeMTimestamp) {
39
+ if (global.tenMTimestamp > Zero && timestampEnd >= global.tenMTimestamp) {
40
+ const checkpointPoints = basePoints + TEN_M_MULTIPLIER * rate * (global.tenMTimestamp - timestampStart)
41
+ return computeRatePoints(rate, global.tenMTimestamp, timestampEnd, global, checkpointPoints)
42
+ }
43
+ return basePoints + TEN_M_MULTIPLIER * rate * (timestampEnd - timestampStart)
44
+ }
45
+ if (global.threeMTimestamp > Zero && timestampEnd >= global.threeMTimestamp) {
46
+ const checkpointPoints = basePoints + THREE_M_MULTIPLIER * rate * (global.threeMTimestamp - timestampStart)
47
+ return computeRatePoints(rate, global.threeMTimestamp, timestampEnd, global, checkpointPoints)
48
+ }
49
+ return basePoints + THREE_M_MULTIPLIER * rate * (timestampEnd - timestampStart)
50
+ }
51
+
52
+ export const getUpdatedPointsAmount = (
53
+ userRate: bigint,
54
+ userLastUpdate: number,
55
+ userLastPoints: bigint,
56
+ airdropGraph: any,
57
+ timestamp?: number,
58
+ ) => {
59
+ const now = timestamp ? timestamp : Math.floor(Date.now() / 1000)
60
+
61
+ return computeRatePoints(
62
+ userRate,
63
+ BigInt(userLastUpdate),
64
+ BigInt(now),
65
+ {
66
+ threeMTimestamp: BigInt(airdropGraph.threeMTimestamp),
67
+ tenMTimestamp: BigInt(airdropGraph.tenMTimestamp),
68
+ twentyFiveMTimestamp: BigInt(airdropGraph.twentyFiveMTimestamp),
69
+ fiftyMTimestamp: BigInt(airdropGraph.fiftyMTimestamp),
70
+ },
71
+ userLastPoints,
72
+ )
73
+ }
@@ -0,0 +1,25 @@
1
+ import { lockerWithId } from '@stake-dao/constants'
2
+
3
+ const depositorCalls = (depositor: string, locker: string) => {
4
+ const calls: any[] = []
5
+
6
+ if (
7
+ [
8
+ lockerWithId('crv')!.extensions.locker,
9
+ lockerWithId('mav')!.extensions.locker,
10
+ lockerWithId('cake', 56)!.extensions.locker,
11
+ lockerWithId('fxn')!.extensions.locker,
12
+ lockerWithId('yfi')!.extensions.locker,
13
+ ].includes(locker)
14
+ ) {
15
+ calls.push({ address: depositor, name: 'lockIncentivePercent' })
16
+ } else {
17
+ calls.push({ address: depositor, name: 'lockIncentive' })
18
+ }
19
+
20
+ calls.push({ address: depositor, name: 'incentiveToken' })
21
+
22
+ return calls
23
+ }
24
+
25
+ export default depositorCalls
@@ -0,0 +1,118 @@
1
+ import { zeroAddress } from 'viem'
2
+
3
+ import { Zero } from '../../../index.js'
4
+
5
+ export const feeCalls = (lockerId: string, accumulatorAddress: string) => {
6
+ const calls: any[] = []
7
+
8
+ if (accumulatorAddress === zeroAddress || lockerId === 'mav') {
9
+ return calls
10
+ }
11
+
12
+ // Harvester fees
13
+ calls.push({ address: accumulatorAddress, name: 'claimerFee', params: [] })
14
+
15
+ // Treasury
16
+ if (['crv', 'cake', 'yfi', 'pendle', 'fpis'].includes(lockerId)) {
17
+ calls.push({ address: accumulatorAddress, name: 'daoFee', params: [] })
18
+ }
19
+
20
+ switch (lockerId) {
21
+ case 'crv':
22
+ calls.push({ address: accumulatorAddress, name: 'liquidityFee', params: [] })
23
+ break
24
+ case 'cake':
25
+ case 'yfi':
26
+ calls.push({ address: accumulatorAddress, name: 'liquidityFee', params: [] })
27
+ break
28
+ case 'pendle':
29
+ calls.push({ address: accumulatorAddress, name: 'bountyFee', params: [] })
30
+ break
31
+ case 'fpis':
32
+ calls.push({ address: accumulatorAddress, name: 'bribeFee', params: [] })
33
+ break
34
+ case 'apw':
35
+ case 'bpt':
36
+ calls.push({ address: accumulatorAddress, name: 'lockerFee', params: [] })
37
+ break
38
+ }
39
+
40
+ return calls
41
+ }
42
+
43
+ export interface ILockerFee {
44
+ lockerId: string
45
+ claimerFee: bigint
46
+ daoFee: bigint
47
+ bountyFee: bigint
48
+ liquidityFee: bigint
49
+ lockerFee: bigint
50
+ }
51
+
52
+ export const extractFees = (lockers: any, feesData: any): ILockerFee[] => {
53
+ const results: ILockerFee[] = []
54
+
55
+ // We reverse it because all fee calls was pushed in the locker array order
56
+ // It's easier to get back fees with the pop function
57
+ // And we slice it because the reverse modify the original array
58
+ const lockersReverse = lockers.slice().reverse()
59
+
60
+ for (const locker of lockersReverse) {
61
+ if (locker.extensions.accumulator === zeroAddress || locker.id === 'mav') {
62
+ const claimerFee = locker.fees.find((f) => f.key === 'claimerFee')
63
+ const daoFee = locker.fees.find((f) => f.key === 'daoFee')
64
+ const bountyFee = locker.fees.find((f) => f.key === 'bountyFee')
65
+ const liquidityFee = locker.fees.find((f) => f.key === 'liquidityFee')
66
+ const lockerFee = locker.fees.find((f) => f.key === 'lockerFee')
67
+
68
+ results.push({
69
+ lockerId: locker.id,
70
+ claimerFee: claimerFee ? BigInt(claimerFee.value * 100) : Zero,
71
+ daoFee: daoFee ? BigInt(daoFee.value * 100) : Zero,
72
+ bountyFee: bountyFee ? BigInt(bountyFee.value * 100) : Zero,
73
+ liquidityFee: liquidityFee ? BigInt(liquidityFee.value * 100) : Zero,
74
+ lockerFee: lockerFee ? BigInt(lockerFee.value * 100) : Zero,
75
+ })
76
+ continue
77
+ }
78
+
79
+ let daoFee = Zero
80
+ let bountyFee = Zero
81
+ let liquidityFee = Zero
82
+ let lockerFee = Zero
83
+
84
+ switch (locker.id) {
85
+ case 'crv':
86
+ liquidityFee = BigInt(feesData.pop()?.result)
87
+ daoFee = BigInt(feesData.pop()?.result)
88
+ break
89
+ case 'cake':
90
+ case 'yfi':
91
+ liquidityFee = BigInt(feesData.pop()?.result)
92
+ daoFee = BigInt(feesData.pop()?.result)
93
+ break
94
+ case 'pendle':
95
+ case 'fpis':
96
+ bountyFee = BigInt(feesData.pop()?.result)
97
+ daoFee = BigInt(feesData.pop()?.result)
98
+ break
99
+ case 'apw':
100
+ case 'bpt':
101
+ lockerFee = BigInt(feesData.pop()?.result)
102
+ break
103
+ }
104
+
105
+ const claimerFee = BigInt(feesData.pop()?.result)
106
+
107
+ results.push({
108
+ lockerId: locker.id,
109
+ claimerFee,
110
+ daoFee,
111
+ bountyFee,
112
+ liquidityFee,
113
+ lockerFee,
114
+ })
115
+ }
116
+
117
+ return results
118
+ }
@@ -0,0 +1,6 @@
1
+ const gaugeCalls = (gauge: string) => [
2
+ { address: gauge, name: 'totalSupply' },
3
+ { address: gauge, name: 'working_supply' },
4
+ ]
5
+
6
+ export default gaugeCalls
@@ -0,0 +1,8 @@
1
+ const gaugeControllerCalls = (gaugeController: string, gauge: string) => [
2
+ { address: gaugeController, name: 'gauge_relative_weight', params: [gauge] },
3
+ { address: gaugeController, name: 'get_total_weight' },
4
+ { address: gaugeController, name: 'get_gauge_weight', params: [gauge] },
5
+ { address: gaugeController, name: 'time_total' },
6
+ ]
7
+
8
+ export default gaugeControllerCalls
@@ -0,0 +1,44 @@
1
+ import { FOUR_YEAR } from '@stake-dao/constants'
2
+ import { OneEther } from '../../../index.js'
3
+
4
+ import depositorCalls from './depositorCalls.js'
5
+ import gaugeCalls from './gaugeCalls.js'
6
+ import gaugeControllerCalls from './gaugeControllerCalls.js'
7
+ import pegCalls from './pegCalls.js'
8
+ import veCalls from './veCalls.js'
9
+ import veSdtCalls from './veSdtCalls.js'
10
+
11
+ const callsForLockers = (
12
+ lockerId: string,
13
+ token: string,
14
+ sdToken: string,
15
+ votingEscrow: string,
16
+ depositor: string,
17
+ gaugeController: string,
18
+ gauge: string,
19
+ locker: string,
20
+ pool: string,
21
+ pegInfo: any,
22
+ secondaryMarket: string,
23
+ voteBooster: any,
24
+ ) => [
25
+ ...veCalls(lockerId, votingEscrow, locker, token),
26
+ ...depositorCalls(depositor, locker),
27
+ ...gaugeControllerCalls(gaugeController, gauge),
28
+ ...gaugeCalls(gauge),
29
+ // Token
30
+ { address: token, name: 'balanceOf', params: [depositor] },
31
+ ...veSdtCalls(voteBooster, token, sdToken, gauge),
32
+ pegCalls(secondaryMarket, pool, pegInfo, sdToken, token),
33
+ ...(lockerId === 'mav'
34
+ ? [
35
+ {
36
+ address: votingEscrow,
37
+ name: 'previewPoints',
38
+ params: [OneEther, FOUR_YEAR],
39
+ },
40
+ ]
41
+ : []),
42
+ ]
43
+
44
+ export default callsForLockers