@stake-dao/reader 0.4.97 → 0.4.98

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 (38) hide show
  1. package/dist/esm/index.js +1 -0
  2. package/dist/esm/index.js.map +1 -1
  3. package/dist/esm/number.js +64 -16
  4. package/dist/esm/number.js.map +1 -1
  5. package/dist/esm/strategies/curve/fetch/getOnlyboostData.js +6 -0
  6. package/dist/esm/strategies/curve/fetch/getOnlyboostData.js.map +1 -1
  7. package/dist/esm/strategies/curve/fetch/index.js +5 -10
  8. package/dist/esm/strategies/curve/fetch/index.js.map +1 -1
  9. package/dist/esm/strategies/curve/httpCalls.js +31 -35
  10. package/dist/esm/strategies/curve/httpCalls.js.map +1 -1
  11. package/dist/esm/strategies/v2/parse.js +174 -0
  12. package/dist/esm/strategies/v2/parse.js.map +1 -0
  13. package/dist/esm/votemarket/curve/fetchSnapshotUserData.js +2 -0
  14. package/dist/esm/votemarket/curve/fetchSnapshotUserData.js.map +1 -1
  15. package/dist/types/index.d.ts +1 -0
  16. package/dist/types/index.d.ts.map +1 -1
  17. package/dist/types/number.d.ts +17 -2
  18. package/dist/types/number.d.ts.map +1 -1
  19. package/dist/types/strategies/curve/fetch/getOnlyboostData.d.ts.map +1 -1
  20. package/dist/types/strategies/curve/fetch/index.d.ts +1 -2
  21. package/dist/types/strategies/curve/fetch/index.d.ts.map +1 -1
  22. package/dist/types/strategies/curve/httpCalls.d.ts +2 -2
  23. package/dist/types/strategies/curve/httpCalls.d.ts.map +1 -1
  24. package/dist/types/strategies/types.d.ts +2 -0
  25. package/dist/types/strategies/types.d.ts.map +1 -1
  26. package/dist/types/strategies/v2/parse.d.ts +51 -0
  27. package/dist/types/strategies/v2/parse.d.ts.map +1 -0
  28. package/dist/types/votemarket/curve/fetchSnapshotUserData.d.ts.map +1 -1
  29. package/package.json +3 -3
  30. package/src/index.ts +1 -0
  31. package/src/number.ts +77 -19
  32. package/src/strategies/curve/fetch/getOnlyboostData.ts +7 -0
  33. package/src/strategies/curve/fetch/index.ts +4 -15
  34. package/src/strategies/curve/httpCalls.ts +31 -48
  35. package/src/strategies/types.ts +2 -0
  36. package/src/strategies/v2/parse.ts +197 -0
  37. package/src/votemarket/curve/fetchSnapshotUserData.ts +2 -0
  38. package/dist/esm/tsconfig.build.tsbuildinfo +0 -1
@@ -0,0 +1,197 @@
1
+ import { getOnlyboostData } from '@stake-dao/reader'
2
+ import { formatUnits, zeroAddress } from 'viem'
3
+ import { arbitrum, base, fraxtal, mainnet, optimism, sonic } from 'viem/chains'
4
+ import { withTwoDec } from '../../number.js'
5
+ import { equalTlc } from '../../utils.js'
6
+
7
+ const V2_FEES = 17
8
+
9
+ const parseAsset = (asset) => ({
10
+ id: asset.id,
11
+ name: asset.name,
12
+ symbol: asset.symbol,
13
+ address: asset.address,
14
+ decimals: asset.decimals,
15
+ })
16
+
17
+ const baseTokens = {
18
+ curve: {
19
+ [mainnet.id]: '0xD533a949740bb3306d119CC777fa900bA034cd52',
20
+ [sonic.id]: '0x5Af79133999f7908953E94b7A5CF367740Ebee35',
21
+ [fraxtal.id]: '0x331B9182088e2A7d6D3Fe4742AbA1fB231aEcc56',
22
+ [arbitrum.id]: '0x11cDb42B0EB46D95f990BeDD4695A6e3fA034978',
23
+ [base.id]: '0x8Ee73c484A26e0A5df2Ee2a4960B789967dd0415',
24
+ [optimism.id]: '0x0994206dfE8De6Ec6920FF4D779B0d950605Fb53',
25
+ },
26
+ balancer: {
27
+ [mainnet.id]: '0xba100000625a3754423978a60c9317c58a424e3D',
28
+ },
29
+ yearn: {
30
+ [mainnet.id]: '0x41252E8691e964f7DE35156B68493bAb6797a275',
31
+ },
32
+ pendle: {
33
+ [mainnet.id]: '0x808507121B80c02388fAd14726482e061B8da827',
34
+ },
35
+ }
36
+
37
+ export const parseV2Strats = (global: any, rawStrats: any[], extra: any) => {
38
+ try {
39
+ return rawStrats.map((s) => {
40
+ const isLending = s.asset.name.startsWith('Llamalend')
41
+
42
+ const lpToken = parseAsset(s.asset)
43
+ const coins = s.asset.components.map((c) => parseAsset(c.childAsset))
44
+
45
+ let name = coins.map((c) => c.symbol).join('/')
46
+ if (name.length > 26 || lpToken?.name?.startsWith('CrossCurve')) name = lpToken.symbol
47
+ if (isLending) name = s.asset.name
48
+
49
+ const lpPriceInUsd =
50
+ Number(s.gauge.totalSupply) > 0
51
+ ? Number(s.gauge.totalSupplyUSD) / Number(formatUnits(BigInt(s.gauge.totalSupply || '0'), 18))
52
+ : 0
53
+
54
+ const compoundedYieldKey = isLending ? 'LENDING_INTEREST' : 'TRADING_FEES'
55
+ const tradingApy = (s.gauge.aprDetails.find((el) => el.yieldType === compoundedYieldKey)?.aprUSD || 0) * 100
56
+ const otherRewards = s.gauge.aprDetails.filter((el) => el.yieldType !== compoundedYieldKey && el.asset)
57
+ const merklRewards = (extra?.merklApi || [])
58
+ .filter((r) => equalTlc(r.explorerAddress, lpToken?.address))
59
+ .map((r) => ({
60
+ token: parseAsset(r.rewardsRecord.breakdowns[0]?.token),
61
+ aprInToken: r.apr / r.rewardsRecord.breakdowns[0]?.token.price || 1,
62
+ apr: r.apr,
63
+ streaming: true,
64
+ periodFinish: 2000000000,
65
+ yieldType: 'OFFCHAIN',
66
+ }))
67
+
68
+ const rewards = otherRewards
69
+ .map((r) => ({
70
+ token: parseAsset(r.asset),
71
+ aprInToken: r.apr,
72
+ apr: Number(r.aprUSD) * 100,
73
+ streaming: true,
74
+ periodFinish: 2000000000,
75
+ yieldType: r.yieldType,
76
+ }))
77
+ .concat(merklRewards)
78
+ .sort((a, b) => {
79
+ if (a.token.address === baseTokens.curve[s.chainId]) return -1
80
+ if (b.token.address === baseTokens.curve[s.chainId]) return 1
81
+ return 0
82
+ })
83
+
84
+ const metadata: any = {}
85
+ for (const m of s.gauge.metadata) metadata[m.key] = m.value
86
+
87
+ // Current
88
+ const totalSupply = BigInt(s.totalSupply)
89
+ const convexSupply = BigInt(s.sidecarBalance)
90
+ const stakeDaoSupply = totalSupply - convexSupply
91
+
92
+ // Optimal
93
+ const stakeDaoOptSupply =
94
+ totalSupply > BigInt(metadata.optimalDepositBalance || '0')
95
+ ? BigInt(metadata.optimalDepositBalance || '0')
96
+ : totalSupply
97
+ const convexOptSupply = totalSupply - stakeDaoOptSupply
98
+
99
+ const useVeBoost = s.chainId === mainnet.id && s.gauge?.address !== '0xd8b712d29381748dB89c36BCa0138d7c75866ddF' // MIM/3crv
100
+
101
+ const onlyboost = getOnlyboostData(
102
+ {
103
+ active: s.sidecar !== zeroAddress,
104
+ convexImpl: s.sidecar,
105
+ totalSupply,
106
+ convexSupply,
107
+ stakeDaoSupply,
108
+ convexStrategyHoldings: BigInt(metadata.convexTotalSupply || '0'),
109
+ convexWorkingBalance: BigInt(metadata.workingBalanceConvex || '0'),
110
+ convexOptSupply,
111
+ stakeDaoOptSupply,
112
+ claimableData: [],
113
+ },
114
+ global[useVeBoost ? 'stakeDaoVeBoost' : 'stakeDaoVeBalance'],
115
+ global[useVeBoost ? 'convexVeBoost' : 'convexVeBalance'],
116
+ global.veCrvTotalSupply,
117
+ BigInt(s.gauge.totalSupply),
118
+ stakeDaoSupply,
119
+ BigInt(metadata.workingBalance || '0'),
120
+ totalSupply,
121
+ lpPriceInUsd,
122
+ )
123
+
124
+ const boost = onlyboost.boost
125
+ const baseReward = rewards[0]
126
+ const maxApr = baseReward?.apr || 0
127
+ const baseRewardApr = (maxApr / 2.5) * boost * ((100 - V2_FEES) / 100)
128
+
129
+ let baseRewardAdded = false
130
+ const aprDetails = [{ label: isLending ? 'Lending' : 'Trading Fees (APY)', value: [tradingApy] }]
131
+
132
+ for (const r of rewards) {
133
+ if (baseReward && r.token.symbol === baseReward.token.symbol && !baseRewardAdded) {
134
+ aprDetails.push({
135
+ label: `${r.token.symbol} APR (incl. ${withTwoDec(boost)}x boost)`,
136
+ value: [baseRewardApr || 0],
137
+ })
138
+
139
+ baseRewardAdded = true
140
+ } else {
141
+ aprDetails.push({ label: `${r.token.symbol} APR`, value: [r.apr || 0] })
142
+ }
143
+ }
144
+
145
+ let aprTotal = aprDetails.reduce((total, x) => {
146
+ for (const v of x.value) total += v
147
+ return total
148
+ }, 0)
149
+ if (aprTotal > 1e18) aprTotal = 2727
150
+
151
+ return {
152
+ key: s.id,
153
+ isLending,
154
+ name,
155
+ type: 'factory-stable-ng',
156
+ version: 2,
157
+ protocol: 'curve',
158
+ chainId: s.chainId,
159
+ vault: s.address,
160
+ lpToken,
161
+ gaugeAddress: s.gauge.address,
162
+ gauge: {
163
+ address: s.gauge.address,
164
+ totalSupply: s.gauge.totalSupply,
165
+ totalSupplyUsd: s.gauge.totalSupplyUSD,
166
+ extraRewards: [],
167
+ },
168
+ coins,
169
+ underlyingCoins: [],
170
+ lpPriceInUsd,
171
+ streaming: true,
172
+ tvl: Number(s.totalSupplyUSD),
173
+ apr: {
174
+ boost,
175
+ current: { total: aprTotal, details: aprDetails },
176
+ },
177
+ rewards,
178
+ tradingApy,
179
+ minApr: maxApr / 2.5,
180
+ maxApr,
181
+ totalSupply: s.totalSupply,
182
+ workingBalance: metadata?.workingBalance || '0',
183
+ onlyboost,
184
+ convexPool:
185
+ metadata.pid && metadata.convexBaseRewardPool
186
+ ? {
187
+ id: Number(metadata.pid),
188
+ crvRewards: metadata.convexBaseRewardPool,
189
+ }
190
+ : undefined,
191
+ }
192
+ })
193
+ } catch (e) {
194
+ console.error(e)
195
+ return []
196
+ }
197
+ }
@@ -94,6 +94,8 @@ export const getStakeDaoSnapshotSpace = (protocolId: string): string | undefined
94
94
  return 'sdfxn.eth'
95
95
  case 'balancer':
96
96
  return 'sdbal.eth'
97
+ case 'pendle':
98
+ return 'sdpendle.eth'
97
99
  default:
98
100
  return undefined
99
101
  }