@stake-dao/reader 0.4.112 → 0.5.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 (193) hide show
  1. package/dist/esm/abis/lockersMulticall.js +30 -2
  2. package/dist/esm/abis/lockersMulticall.js.map +1 -1
  3. package/dist/esm/index.js +2 -1
  4. package/dist/esm/index.js.map +1 -1
  5. package/dist/esm/lockers/fetch/index.js +53 -224
  6. package/dist/esm/lockers/fetch/index.js.map +1 -1
  7. package/dist/esm/lockers/fetch/parse.js +174 -0
  8. package/dist/esm/lockers/fetch/parse.js.map +1 -0
  9. package/dist/esm/lockers/fetch/protocols/angle.js +136 -0
  10. package/dist/esm/lockers/fetch/protocols/angle.js.map +1 -0
  11. package/dist/esm/lockers/fetch/protocols/balancer.js +172 -0
  12. package/dist/esm/lockers/fetch/protocols/balancer.js.map +1 -0
  13. package/dist/esm/lockers/fetch/protocols/blackpool.js +130 -0
  14. package/dist/esm/lockers/fetch/protocols/blackpool.js.map +1 -0
  15. package/dist/esm/lockers/fetch/protocols/curve.js +204 -0
  16. package/dist/esm/lockers/fetch/protocols/curve.js.map +1 -0
  17. package/dist/esm/lockers/fetch/protocols/frax-fpis.js +121 -0
  18. package/dist/esm/lockers/fetch/protocols/frax-fpis.js.map +1 -0
  19. package/dist/esm/lockers/fetch/protocols/frax-fxs.js +169 -0
  20. package/dist/esm/lockers/fetch/protocols/frax-fxs.js.map +1 -0
  21. package/dist/esm/lockers/fetch/protocols/fxn.js +131 -0
  22. package/dist/esm/lockers/fetch/protocols/fxn.js.map +1 -0
  23. package/dist/esm/lockers/fetch/protocols/maverick.js +172 -0
  24. package/dist/esm/lockers/fetch/protocols/maverick.js.map +1 -0
  25. package/dist/esm/lockers/fetch/protocols/pancakeswap.js +128 -0
  26. package/dist/esm/lockers/fetch/protocols/pancakeswap.js.map +1 -0
  27. package/dist/esm/lockers/fetch/protocols/pendle.js +144 -0
  28. package/dist/esm/lockers/fetch/protocols/pendle.js.map +1 -0
  29. package/dist/esm/lockers/fetch/protocols/spectra.js +133 -0
  30. package/dist/esm/lockers/fetch/protocols/spectra.js.map +1 -0
  31. package/dist/esm/lockers/fetch/protocols/yearn.js +138 -0
  32. package/dist/esm/lockers/fetch/protocols/yearn.js.map +1 -0
  33. package/dist/esm/lockers/fetch/protocols/yieldbasis.js +131 -0
  34. package/dist/esm/lockers/fetch/protocols/yieldbasis.js.map +1 -0
  35. package/dist/esm/lockers/fetch/protocols/yieldnest.js +135 -0
  36. package/dist/esm/lockers/fetch/protocols/yieldnest.js.map +1 -0
  37. package/dist/esm/lockers/fetch/protocols/zerolend.js +124 -0
  38. package/dist/esm/lockers/fetch/protocols/zerolend.js.map +1 -0
  39. package/dist/esm/lockers/fetch/static.js +33 -0
  40. package/dist/esm/lockers/fetch/static.js.map +1 -0
  41. package/dist/esm/lockers/fetch/types.js +2 -0
  42. package/dist/esm/lockers/fetch/types.js.map +1 -0
  43. package/dist/esm/lockers/utils/callsForLockers/pegCalls.js.map +1 -1
  44. package/dist/esm/lockers/utils/getBribesRewardsData.js +11 -9
  45. package/dist/esm/lockers/utils/getBribesRewardsData.js.map +1 -1
  46. package/dist/esm/lockers/utils/substractFees.js +1 -2
  47. package/dist/esm/lockers/utils/substractFees.js.map +1 -1
  48. package/dist/esm/strategies/curve/fetch/getOnlyboostData.js +8 -3
  49. package/dist/esm/strategies/curve/fetch/getOnlyboostData.js.map +1 -1
  50. package/dist/esm/strategies/curve/fetch/index.js +1 -1
  51. package/dist/esm/strategies/curve/fetch/index.js.map +1 -1
  52. package/dist/esm/strategies/v2/parse.js +5 -3
  53. package/dist/esm/strategies/v2/parse.js.map +1 -1
  54. package/dist/esm/utils.js +5 -0
  55. package/dist/esm/utils.js.map +1 -1
  56. package/dist/types/abis/lockersMulticall.d.ts +1 -1
  57. package/dist/types/abis/lockersMulticall.d.ts.map +1 -1
  58. package/dist/types/index.d.ts +2 -1
  59. package/dist/types/index.d.ts.map +1 -1
  60. package/dist/types/lockers/fetch/index.d.ts +5 -99
  61. package/dist/types/lockers/fetch/index.d.ts.map +1 -1
  62. package/dist/types/lockers/fetch/parse.d.ts +52 -0
  63. package/dist/types/lockers/fetch/parse.d.ts.map +1 -0
  64. package/dist/types/lockers/fetch/protocols/angle.d.ts +9 -0
  65. package/dist/types/lockers/fetch/protocols/angle.d.ts.map +1 -0
  66. package/dist/types/lockers/fetch/protocols/balancer.d.ts +9 -0
  67. package/dist/types/lockers/fetch/protocols/balancer.d.ts.map +1 -0
  68. package/dist/types/lockers/fetch/protocols/blackpool.d.ts +9 -0
  69. package/dist/types/lockers/fetch/protocols/blackpool.d.ts.map +1 -0
  70. package/dist/types/lockers/fetch/protocols/curve.d.ts +9 -0
  71. package/dist/types/lockers/fetch/protocols/curve.d.ts.map +1 -0
  72. package/dist/types/lockers/fetch/protocols/frax-fpis.d.ts +9 -0
  73. package/dist/types/lockers/fetch/protocols/frax-fpis.d.ts.map +1 -0
  74. package/dist/types/lockers/fetch/protocols/frax-fxs.d.ts +9 -0
  75. package/dist/types/lockers/fetch/protocols/frax-fxs.d.ts.map +1 -0
  76. package/dist/types/lockers/fetch/protocols/fxn.d.ts +9 -0
  77. package/dist/types/lockers/fetch/protocols/fxn.d.ts.map +1 -0
  78. package/dist/types/lockers/fetch/protocols/maverick.d.ts +9 -0
  79. package/dist/types/lockers/fetch/protocols/maverick.d.ts.map +1 -0
  80. package/dist/types/lockers/fetch/protocols/pancakeswap.d.ts +9 -0
  81. package/dist/types/lockers/fetch/protocols/pancakeswap.d.ts.map +1 -0
  82. package/dist/types/lockers/fetch/protocols/pendle.d.ts +9 -0
  83. package/dist/types/lockers/fetch/protocols/pendle.d.ts.map +1 -0
  84. package/dist/types/lockers/fetch/protocols/spectra.d.ts +9 -0
  85. package/dist/types/lockers/fetch/protocols/spectra.d.ts.map +1 -0
  86. package/dist/types/lockers/fetch/protocols/yearn.d.ts +9 -0
  87. package/dist/types/lockers/fetch/protocols/yearn.d.ts.map +1 -0
  88. package/dist/types/lockers/fetch/protocols/yieldbasis.d.ts +9 -0
  89. package/dist/types/lockers/fetch/protocols/yieldbasis.d.ts.map +1 -0
  90. package/dist/types/lockers/fetch/protocols/yieldnest.d.ts +9 -0
  91. package/dist/types/lockers/fetch/protocols/yieldnest.d.ts.map +1 -0
  92. package/dist/types/lockers/fetch/protocols/zerolend.d.ts +9 -0
  93. package/dist/types/lockers/fetch/protocols/zerolend.d.ts.map +1 -0
  94. package/dist/types/lockers/fetch/static.d.ts +3 -0
  95. package/dist/types/lockers/fetch/static.d.ts.map +1 -0
  96. package/dist/types/lockers/fetch/types.d.ts +105 -0
  97. package/dist/types/lockers/fetch/types.d.ts.map +1 -0
  98. package/dist/types/lockers/utils/callsForLockers/pegCalls.d.ts +1 -1
  99. package/dist/types/lockers/utils/callsForLockers/pegCalls.d.ts.map +1 -1
  100. package/dist/types/lockers/utils/getBribesRewardsData.d.ts +1 -0
  101. package/dist/types/lockers/utils/getBribesRewardsData.d.ts.map +1 -1
  102. package/dist/types/lockers/utils/substractFees.d.ts.map +1 -1
  103. package/dist/types/strategies/curve/fetch/getOnlyboostData.d.ts +1 -1
  104. package/dist/types/strategies/curve/fetch/getOnlyboostData.d.ts.map +1 -1
  105. package/dist/types/strategies/curve/fetch/index.d.ts.map +1 -1
  106. package/dist/types/strategies/stakeDao/fetch.d.ts +1 -1
  107. package/dist/types/strategies/v2/parse.d.ts.map +1 -1
  108. package/dist/types/utils.d.ts +1 -0
  109. package/dist/types/utils.d.ts.map +1 -1
  110. package/package.json +2 -2
  111. package/src/abis/lockersMulticall.ts +30 -2
  112. package/src/index.ts +2 -1
  113. package/src/lockers/fetch/index.ts +65 -329
  114. package/src/lockers/fetch/parse.ts +258 -0
  115. package/src/lockers/fetch/protocols/angle.ts +157 -0
  116. package/src/lockers/fetch/protocols/balancer.ts +195 -0
  117. package/src/lockers/fetch/protocols/blackpool.ts +151 -0
  118. package/src/lockers/fetch/protocols/curve.ts +229 -0
  119. package/src/lockers/fetch/protocols/frax-fpis.ts +139 -0
  120. package/src/lockers/fetch/protocols/frax-fxs.ts +193 -0
  121. package/src/lockers/fetch/protocols/fxn.ts +152 -0
  122. package/src/lockers/fetch/protocols/maverick.ts +193 -0
  123. package/src/lockers/fetch/protocols/pancakeswap.ts +149 -0
  124. package/src/lockers/fetch/protocols/pendle.ts +165 -0
  125. package/src/lockers/fetch/protocols/spectra.ts +154 -0
  126. package/src/lockers/fetch/protocols/yearn.ts +159 -0
  127. package/src/lockers/fetch/protocols/yieldbasis.ts +152 -0
  128. package/src/lockers/fetch/protocols/yieldnest.ts +157 -0
  129. package/src/lockers/fetch/protocols/zerolend.ts +144 -0
  130. package/src/lockers/fetch/static.ts +35 -0
  131. package/src/lockers/fetch/types.ts +112 -0
  132. package/src/lockers/utils/callsForLockers/pegCalls.ts +2 -1
  133. package/src/lockers/utils/getBribesRewardsData.ts +12 -11
  134. package/src/lockers/utils/substractFees.ts +1 -2
  135. package/src/strategies/curve/fetch/getOnlyboostData.ts +11 -2
  136. package/src/strategies/curve/fetch/index.ts +2 -0
  137. package/src/strategies/v2/parse.ts +10 -4
  138. package/src/utils.ts +5 -0
  139. package/dist/esm/lockers/fetch/parseBoost.js +0 -36
  140. package/dist/esm/lockers/fetch/parseBoost.js.map +0 -1
  141. package/dist/esm/lockers/fetch/parsePeg.js +0 -18
  142. package/dist/esm/lockers/fetch/parsePeg.js.map +0 -1
  143. package/dist/esm/lockers/fetch/parseVoteBoosterData.js +0 -28
  144. package/dist/esm/lockers/fetch/parseVoteBoosterData.js.map +0 -1
  145. package/dist/esm/lockers/utils/callsForLockers/depositorCalls.js +0 -24
  146. package/dist/esm/lockers/utils/callsForLockers/depositorCalls.js.map +0 -1
  147. package/dist/esm/lockers/utils/callsForLockers/feeCalls.js +0 -97
  148. package/dist/esm/lockers/utils/callsForLockers/feeCalls.js.map +0 -1
  149. package/dist/esm/lockers/utils/callsForLockers/gaugeCalls.js +0 -9
  150. package/dist/esm/lockers/utils/callsForLockers/gaugeCalls.js.map +0 -1
  151. package/dist/esm/lockers/utils/callsForLockers/index.js +0 -34
  152. package/dist/esm/lockers/utils/callsForLockers/index.js.map +0 -1
  153. package/dist/esm/lockers/utils/callsForLockers/veBoosts.js +0 -17
  154. package/dist/esm/lockers/utils/callsForLockers/veBoosts.js.map +0 -1
  155. package/dist/esm/lockers/utils/callsForLockers/veCalls.js +0 -33
  156. package/dist/esm/lockers/utils/callsForLockers/veCalls.js.map +0 -1
  157. package/dist/esm/lockers/utils/callsForLockers/veSdtCalls.js +0 -14
  158. package/dist/esm/lockers/utils/callsForLockers/veSdtCalls.js.map +0 -1
  159. package/dist/esm/lockers/utils/getFees.js +0 -27
  160. package/dist/esm/lockers/utils/getFees.js.map +0 -1
  161. package/dist/types/lockers/fetch/parseBoost.d.ts +0 -4
  162. package/dist/types/lockers/fetch/parseBoost.d.ts.map +0 -1
  163. package/dist/types/lockers/fetch/parsePeg.d.ts +0 -3
  164. package/dist/types/lockers/fetch/parsePeg.d.ts.map +0 -1
  165. package/dist/types/lockers/fetch/parseVoteBoosterData.d.ts +0 -13
  166. package/dist/types/lockers/fetch/parseVoteBoosterData.d.ts.map +0 -1
  167. package/dist/types/lockers/utils/callsForLockers/depositorCalls.d.ts +0 -4
  168. package/dist/types/lockers/utils/callsForLockers/depositorCalls.d.ts.map +0 -1
  169. package/dist/types/lockers/utils/callsForLockers/feeCalls.d.ts +0 -13
  170. package/dist/types/lockers/utils/callsForLockers/feeCalls.d.ts.map +0 -1
  171. package/dist/types/lockers/utils/callsForLockers/gaugeCalls.d.ts +0 -6
  172. package/dist/types/lockers/utils/callsForLockers/gaugeCalls.d.ts.map +0 -1
  173. package/dist/types/lockers/utils/callsForLockers/index.d.ts +0 -8
  174. package/dist/types/lockers/utils/callsForLockers/index.d.ts.map +0 -1
  175. package/dist/types/lockers/utils/callsForLockers/veBoosts.d.ts +0 -7
  176. package/dist/types/lockers/utils/callsForLockers/veBoosts.d.ts.map +0 -1
  177. package/dist/types/lockers/utils/callsForLockers/veCalls.d.ts +0 -4
  178. package/dist/types/lockers/utils/callsForLockers/veCalls.d.ts.map +0 -1
  179. package/dist/types/lockers/utils/callsForLockers/veSdtCalls.d.ts +0 -11
  180. package/dist/types/lockers/utils/callsForLockers/veSdtCalls.d.ts.map +0 -1
  181. package/dist/types/lockers/utils/getFees.d.ts +0 -4
  182. package/dist/types/lockers/utils/getFees.d.ts.map +0 -1
  183. package/src/lockers/fetch/parseBoost.ts +0 -46
  184. package/src/lockers/fetch/parsePeg.ts +0 -22
  185. package/src/lockers/fetch/parseVoteBoosterData.ts +0 -34
  186. package/src/lockers/utils/callsForLockers/depositorCalls.ts +0 -30
  187. package/src/lockers/utils/callsForLockers/feeCalls.ts +0 -124
  188. package/src/lockers/utils/callsForLockers/gaugeCalls.ts +0 -10
  189. package/src/lockers/utils/callsForLockers/index.ts +0 -51
  190. package/src/lockers/utils/callsForLockers/veBoosts.ts +0 -28
  191. package/src/lockers/utils/callsForLockers/veCalls.ts +0 -44
  192. package/src/lockers/utils/callsForLockers/veSdtCalls.ts +0 -15
  193. package/src/lockers/utils/getFees.ts +0 -31
@@ -0,0 +1,193 @@
1
+ import { One, STAKE_DAO_ASSETS_BASE_URL, Zero, tokenWithId } from '@stake-dao/constants'
2
+ import { formatUnits, parseUnits } from 'viem'
3
+ import lockersMulticallAbi from '../../../abis/lockersMulticall.js'
4
+ import { STAKE_DAO_API } from '../../../endpoints.js'
5
+ import { type Call, getRes, multicall, multichainMulticall } from '../../../utils.js'
6
+ import { parse, parsePeg } from '../parse.js'
7
+ import type { Locker } from '../types.js'
8
+
9
+ export const locker: Locker = {
10
+ id: 'fxs',
11
+ symbol: 'FXS',
12
+ protocol: 'Frax',
13
+ protocolDescription:
14
+ 'The Frax Protocol issues innovative, decentralized stablecoins and contains subprotocols to support them.',
15
+ website: 'https://frax.finance/',
16
+ logoUrl: `${STAKE_DAO_ASSETS_BASE_URL}/assets/archive/fxs.svg`,
17
+ chainId: 252,
18
+ rgb: '0, 0, 0',
19
+ token: tokenWithId('wfrax', 252)!,
20
+ sdToken: tokenWithId('sdfxs', 252)!,
21
+ rewards: [
22
+ { ...tokenWithId('wfrax', 252)!, distribution: 'streamed', origin: 'native.fxs' },
23
+ { ...tokenWithId('sdfxs', 252)!, distribution: 'distributed', origin: 'bounties' },
24
+ ],
25
+ delegation: ['sdfxs.eth'],
26
+ modules: {
27
+ depositor: '0x453369Ba22CEb6c3Eccd3029b911F590C3AD92d2',
28
+ locker: '0x26aCff2adc9104FE1c26c958dC4C9a5180840c35',
29
+ veToken: '0x007FD070a7E1B0fA1364044a373Ac1339bAD89CF',
30
+ gauge: '0x12992595328E52267c95e45B1a97014D6Ddf8683',
31
+ accumulator: '0xe3dE095C1A48D2dcBefBA8f4109d9CD4d124A0D4',
32
+ },
33
+ secondaryMarket: {
34
+ label: 'Curve',
35
+ poolKey: 'factory-stable-ng-27',
36
+ vaultKey: '252-0xD90725436f2D8fE152132394b2985dd5cd4dC197',
37
+ pool: '0x3df1658e3e76d14ef3c4d410829ea7575bb83b9b',
38
+ pools: ['0x3df1658e3e76d14ef3c4d410829ea7575bb83b9b'],
39
+ pegBase: 1000,
40
+ },
41
+ alternativeYields: {
42
+ sdFxsFxsStakeDao: {
43
+ label: 'sdFXS/FXS',
44
+ platform: 'Stake DAO',
45
+ href: '/yield?search=0xD90725436f2D8fE152132394b2985dd5cd4dC197',
46
+ },
47
+ },
48
+ fees: [
49
+ {
50
+ label: { key: 'liquidity', variable: 'sdFXS/FXS' },
51
+ value: 10,
52
+ key: 'liquidityFee',
53
+ },
54
+ {
55
+ label: { key: 'treasury' },
56
+ value: 5,
57
+ key: 'daoFee',
58
+ },
59
+ {
60
+ label: { key: 'harvesterOn', variable: 'FXS' },
61
+ value: 0.1,
62
+ key: 'claimerFee',
63
+ },
64
+ ],
65
+ extensions: {
66
+ coingeckoBaseSlug: 'frax-share',
67
+ sideChains: [
68
+ {
69
+ chainId: 1,
70
+ locker: '0xCd3a267DE09196C48bbB1d9e842D7D7645cE448f',
71
+ gauge: '0xF3C6e8fbB946260e8c2a55d48a5e01C82fD63106',
72
+ veToken: '0xc8418aF6358FFddA74e09Ca9CC3Fe03Ca6aDC5b0',
73
+ depositor: '0x0000000000000000000000000000000000000000',
74
+ sdToken: '0x402F878BDd1f5C66FdAF0fabaBcF74741B68ac36',
75
+ token: '0x3432B6A60D23Ca0dFCa7761B7ab56459D9C964D0',
76
+ accumulator: '0xAB8a21516465D9Fc57c621f57eCAB838c1910BD6',
77
+ rewards: [{ ...tokenWithId('fxs', 1)!, distribution: 'streamed', origin: 'native.common' }],
78
+ },
79
+ ],
80
+ },
81
+ }
82
+
83
+ const fraxFxsLocker = async ({ provider, common, prices }: { provider; common; prices }) => {
84
+ const token = locker.token.address
85
+ const sdToken = locker.sdToken.address
86
+
87
+ const gauge = locker.modules.gauge
88
+ const depositor = locker.modules.depositor
89
+ const votingEscrow = locker.modules.veToken
90
+ const lockerAddress = locker.modules.locker
91
+
92
+ const secondaryMarket = locker.secondaryMarket!
93
+ const rewards = locker.rewards
94
+
95
+ const sidechains = locker.extensions.sideChains!
96
+
97
+ const pegBase = parseUnits(secondaryMarket?.pegBase?.toString() || '1', 18)
98
+
99
+ const format = (value: bigint) => formatUnits(value, locker.token.decimals)
100
+ const formatRes = (value: any) => format(getRes(value))
101
+
102
+ const calls: Call[] = [
103
+ /*********************************************************************************
104
+ *** Voting Escrow
105
+ *********************************************************************************/
106
+
107
+ // Token locked by the Locker
108
+ { address: votingEscrow, name: 'balanceOfLockedFxs', params: [lockerAddress] },
109
+ // veToken Balance of the Locker
110
+ { address: votingEscrow, name: 'balanceOf', params: [lockerAddress] },
111
+ // Total token locked
112
+ { address: votingEscrow, name: 'supply' },
113
+ // Total veToken supply
114
+ { address: votingEscrow, name: 'totalSupply' },
115
+
116
+ /*********************************************************************************
117
+ *** Gauge
118
+ *********************************************************************************/
119
+
120
+ // Total sdToken staked
121
+ { address: gauge, name: 'totalSupply' },
122
+
123
+ /*********************************************************************************
124
+ *** Token & sdToken
125
+ *********************************************************************************/
126
+
127
+ // Token balance not locked
128
+ { address: token, name: 'balanceOf', params: [depositor] },
129
+ // sdToken in secondary market pool
130
+ { address: sdToken, name: 'balanceOf', params: [secondaryMarket.pool] },
131
+
132
+ /*********************************************************************************
133
+ *** Peg
134
+ *********************************************************************************/
135
+
136
+ // Return amount when swapping {pegBase} sdToken to token -> get_dy(int128,int128,uint256)
137
+ { address: secondaryMarket.pool, name: '0x5e0d443f', params: [One, Zero, pegBase] },
138
+
139
+ /*********************************************************************************
140
+ *** Rewards
141
+ *********************************************************************************/
142
+
143
+ // Streaming status for each reward token
144
+ ...rewards.map((r) => ({ address: gauge, name: 'reward_data', params: [r.address] })),
145
+ ]
146
+
147
+ /*********************************************************************************
148
+ *** Sidechains
149
+ *********************************************************************************/
150
+ const sidechainsCalls = sidechains.reduce((acc, value) => {
151
+ return acc.concat([
152
+ { address: value.veToken, name: 'locked', params: [value.locker], chainId: value.chainId },
153
+ { address: value.veToken, name: 'balanceOf', params: [value.locker], chainId: value.chainId },
154
+ { address: value.veToken, name: 'totalSupply', chainId: value.chainId },
155
+ ])
156
+ }, [] as any)
157
+
158
+ const [res, sidechainsRes, sdfxsData] = await Promise.all([
159
+ multicall(provider, calls, lockersMulticallAbi(locker.id, locker.chainId)),
160
+ multichainMulticall(sidechainsCalls, lockersMulticallAbi()),
161
+ fetch(`${STAKE_DAO_API}/main/api/lockers/sdfxs-working-supply.json`).then((res) => res.json()),
162
+ ])
163
+
164
+ const raw = {
165
+ tokenLocked: formatRes(res.shift()),
166
+ veBalanceOfLocker: formatRes(res.shift()),
167
+ totalTokenLocked: formatRes(res.shift()),
168
+ veTotalSupply: formatRes(res.shift()),
169
+ totalSupplyStaked: formatRes(res.shift()),
170
+ gaugeWorkingSupply: '0',
171
+ amountTokenNotLock: formatRes(res.shift()),
172
+ sdTokenInPool: formatRes(res.shift()),
173
+ peg: getRes(res.shift()),
174
+ rewards: rewards.map(() => getRes(res.shift())),
175
+ veTokenRate: '4',
176
+ _workingSupply: '0',
177
+ _veBalanceOfLocker: '0',
178
+ sidechains: sidechains.map((s) => ({
179
+ tokenLocked: format(getRes(sidechainsRes[s.chainId].shift())[0]),
180
+ veBalanceOfLocker: formatRes(sidechainsRes[s.chainId].shift()),
181
+ veTotalSupply: formatRes(sidechainsRes[s.chainId].shift()),
182
+ })),
183
+ }
184
+
185
+ raw.gaugeWorkingSupply = raw.totalSupplyStaked
186
+ raw.peg = parsePeg(locker, raw.peg)
187
+ raw._workingSupply = sdfxsData.working_supply.toString()
188
+ raw._veBalanceOfLocker = (sdfxsData.veBalance * 4).toString()
189
+
190
+ return parse({ locker, common, prices, raw })
191
+ }
192
+
193
+ export default fraxFxsLocker
@@ -0,0 +1,152 @@
1
+ import { One, STAKE_DAO_ASSETS_BASE_URL, Zero, tokenWithId } from '@stake-dao/constants'
2
+ import { formatUnits, parseUnits } from 'viem'
3
+ import lockersMulticallAbi from '../../../abis/lockersMulticall.js'
4
+ import { type Call, getRes, multicall } from '../../../utils.js'
5
+ import { parse, parsePeg } from '../parse.js'
6
+ import type { Locker } from '../types.js'
7
+
8
+ export const locker: Locker = {
9
+ id: 'fxn',
10
+ symbol: 'FXN',
11
+ protocol: 'f(x) Protocol',
12
+ protocolDescription:
13
+ 'f(x) splits ETH into a mix of low-volatility “floating stablecoins” called fETH and high volatility “leveraged ETH” tokens called xETH.',
14
+ website: 'https://fx.aladdin.club/',
15
+ logoUrl: `${STAKE_DAO_ASSETS_BASE_URL}/assets/archive/fxn.svg`,
16
+ chainId: 1,
17
+ rgb: '86, 61, 250',
18
+ token: tokenWithId('fxn')!,
19
+ sdToken: tokenWithId('sdfxn')!,
20
+ rewards: [
21
+ { ...tokenWithId('sdt')!, distribution: 'streamed', origin: 'sdtEmission' },
22
+ { ...tokenWithId('wsteth')!, distribution: 'streamed', origin: 'native.fxn' },
23
+ { ...tokenWithId('sdfxn')!, distribution: 'distributed', origin: 'bounties' },
24
+ ],
25
+ delegation: ['sdfxn.eth'],
26
+ modules: {
27
+ depositor: '0x7995192bE61EA0B28ce14183DDA51eDF78F1c7AB',
28
+ locker: '0x75736518075a01034fa72D675D36a47e9B06B2Fb',
29
+ veToken: '0xEC6B8A3F3605B083F7044C0F31f2cac0caf1d469',
30
+ gauge: '0xbcfE5c47129253C6B8a9A00565B3358b488D42E0',
31
+ accumulator: '0x23ab5100acaFF53d00ad92BB8Df75a72e7a3Bc4a',
32
+ },
33
+ secondaryMarket: {
34
+ label: 'Curve',
35
+ poolKey: 'factory-v2-359',
36
+ vaultKey: '',
37
+ pool: '0x28Ca243dc0aC075dD012fCf9375C25D18A844d96',
38
+ pools: ['0x28Ca243dc0aC075dD012fCf9375C25D18A844d96'],
39
+ pegBase: 50,
40
+ },
41
+ fees: [
42
+ {
43
+ label: { key: 'liquidity', variable: 'sdFXN/FXN' },
44
+ value: 10,
45
+ key: 'liquidityFee',
46
+ },
47
+ {
48
+ label: { key: 'treasury' },
49
+ value: 5,
50
+ key: 'daoFee',
51
+ },
52
+ {
53
+ label: { key: 'harvester' },
54
+ value: 0.5,
55
+ key: 'claimerFee',
56
+ },
57
+ ],
58
+ extensions: {
59
+ coingeckoBaseSlug: 'fxn-token',
60
+ },
61
+ }
62
+
63
+ const fxnLocker = async ({ provider, common, prices }: { provider; common; prices }) => {
64
+ const token = locker.token.address
65
+ const sdToken = locker.sdToken.address
66
+
67
+ const gauge = locker.modules.gauge
68
+ const depositor = locker.modules.depositor
69
+ const votingEscrow = locker.modules.veToken
70
+ const lockerAddress = locker.modules.locker
71
+
72
+ const secondaryMarket = locker.secondaryMarket!
73
+ const rewards = locker.rewards
74
+
75
+ const pegBase = parseUnits(secondaryMarket?.pegBase?.toString() || '1', 18)
76
+
77
+ const format = (value: bigint) => formatUnits(value, locker.token.decimals)
78
+ const formatRes = (value: any) => format(getRes(value))
79
+
80
+ const calls: Call[] = [
81
+ /*********************************************************************************
82
+ *** Voting Escrow
83
+ *********************************************************************************/
84
+
85
+ // Token locked by the Locker
86
+ { address: votingEscrow, name: 'locked', params: [lockerAddress] },
87
+ // veToken Balance of the Locker
88
+ { address: votingEscrow, name: 'balanceOf', params: [lockerAddress] },
89
+ // Total token locked
90
+ { address: votingEscrow, name: 'supply' },
91
+ // Total veToken supply
92
+ { address: votingEscrow, name: 'totalSupply' },
93
+
94
+ /*********************************************************************************
95
+ *** Gauge
96
+ *********************************************************************************/
97
+
98
+ // Total sdToken staked
99
+ { address: gauge, name: 'totalSupply' },
100
+ // Gauge working supply
101
+ { address: gauge, name: 'working_supply' },
102
+
103
+ /*********************************************************************************
104
+ *** Token & sdToken
105
+ *********************************************************************************/
106
+
107
+ // Token balance not locked
108
+ { address: token, name: 'balanceOf', params: [depositor] },
109
+ // sdToken in secondary market pool
110
+ { address: sdToken, name: 'balanceOf', params: [secondaryMarket.pool] },
111
+
112
+ /*********************************************************************************
113
+ *** Peg
114
+ *********************************************************************************/
115
+
116
+ // Return amount when swapping {pegBase} sdToken to token -> get_dy(int128,int128,uint256)
117
+ { address: secondaryMarket.pool, name: '0x5e0d443f', params: [One, Zero, pegBase] },
118
+
119
+ /*********************************************************************************
120
+ *** Rewards
121
+ *********************************************************************************/
122
+
123
+ // Streaming status for each reward token
124
+ ...rewards.map((r) => ({ address: gauge, name: 'reward_data', params: [r.address] })),
125
+ ]
126
+
127
+ const res = await multicall(provider, calls, lockersMulticallAbi(locker.id, locker.chainId))
128
+ const raw = {
129
+ tokenLocked: getRes(res.shift()),
130
+ veBalanceOfLocker: formatRes(res.shift()),
131
+ totalTokenLocked: formatRes(res.shift()),
132
+ veTotalSupply: formatRes(res.shift()),
133
+ totalSupplyStaked: formatRes(res.shift()),
134
+ gaugeWorkingSupply: formatRes(res.shift()),
135
+ amountTokenNotLock: formatRes(res.shift()),
136
+ sdTokenInPool: formatRes(res.shift()),
137
+ peg: getRes(res.shift()),
138
+ rewards: rewards.map(() => getRes(res.shift())),
139
+ veTokenRate: '4',
140
+ _workingSupply: '0',
141
+ _veBalanceOfLocker: '0',
142
+ }
143
+
144
+ raw.tokenLocked = format(raw.tokenLocked[0])
145
+ raw.peg = parsePeg(locker, raw.peg)
146
+ raw._workingSupply = raw.gaugeWorkingSupply
147
+ raw._veBalanceOfLocker = raw.veBalanceOfLocker
148
+
149
+ return parse({ locker, common, prices, raw })
150
+ }
151
+
152
+ export default fxnLocker
@@ -0,0 +1,193 @@
1
+ import { FOUR_YEAR, OneEther, STAKE_DAO_ASSETS_BASE_URL, tokenWithId } from '@stake-dao/constants'
2
+ import { formatUnits } from 'viem'
3
+ import lockersMulticallAbi from '../../../abis/lockersMulticall.js'
4
+ import { type Call, getRes, multicall, multichainMulticall } from '../../../utils.js'
5
+ import { parse } from '../parse.js'
6
+ import type { Locker } from '../types.js'
7
+
8
+ export const locker: Locker = {
9
+ id: 'mav',
10
+ symbol: 'MAV',
11
+ protocol: 'Maverick',
12
+ protocolDescription:
13
+ 'Maverick Protocol offers an infrastructure for DeFi, built for traders, liquidity providers, DAO treasuries, and developers.',
14
+ website: 'https://www.mav.xyz/',
15
+ logoUrl: `${STAKE_DAO_ASSETS_BASE_URL}/assets/archive/mav.svg`,
16
+ chainId: 1,
17
+ rgb: '100, 0, 255',
18
+ token: tokenWithId('mav')!,
19
+ sdToken: tokenWithId('sdmav')!,
20
+ rewards: [],
21
+ delegation: ['sdmav.eth'],
22
+ modules: {
23
+ depositor: '0x177Eaa1A7c26da6Dc84c0cC3F9AE6Fd0A470E7Ec',
24
+ locker: '0xdBD6170396ECE3DCd51195950A2dF7F7635F9e38',
25
+ veToken: '0x4949Ac21d5b2A0cCd303C20425eeb29DCcba66D8',
26
+ gauge: '0x5B75C60D45BfB053f91B5a9eAe22519DFaa37BB6',
27
+ accumulator: '0x0000000000000000000000000000000000000000',
28
+ },
29
+ secondaryMarket: {
30
+ label: 'Maverick',
31
+ poolKey: '0x10463ad648d59a3dadcef626dcec4197fd0b550f',
32
+ vaultKey: '',
33
+ pool: '0x10463ad648d59a3dAdceF626dCec4197FD0B550f',
34
+ pools: ['0x10463ad648d59a3dAdceF626dCec4197FD0B550f'],
35
+ router: '0xbBF1EE38152E9D8e3470Dc47947eAa65DcA94913',
36
+ pegBase: 1,
37
+ },
38
+ fees: [
39
+ {
40
+ label: { key: 'liquidity', variable: 'sdMAV/MAV' },
41
+ value: 10,
42
+ key: 'liquidityFee',
43
+ static: true,
44
+ },
45
+ {
46
+ label: { key: 'treasury' },
47
+ value: 5,
48
+ key: 'daoFee',
49
+ static: true,
50
+ },
51
+ {
52
+ label: { key: 'harvester' },
53
+ value: 0.1,
54
+ key: 'claimerFee',
55
+ static: true,
56
+ },
57
+ ],
58
+ extensions: {
59
+ coingeckoBaseSlug: 'maverick-protocol',
60
+ sideChains: [
61
+ {
62
+ chainId: 324,
63
+ locker: '0xb908EB86C9427269EC85C83bd812A2265778Da3e',
64
+ veToken: '0x7EDcB053d4598a145DdaF5260cf89A32263a2807',
65
+ depositor: '0x5b3b63E8313e7c68F88E4A12c86dC319ba75fC98',
66
+ sdToken: '0x8E6d4c0088b5B41BdDb126f355Ef278Ac5B5974C',
67
+ token: '0x787c09494ec8bcb24dcaf8659e7d5d69979ee508',
68
+ },
69
+ {
70
+ chainId: 56,
71
+ locker: '0xC6973841dC130597dF3Cb8bE2F57440d856FD7C4',
72
+ veToken: '0xE6108f1869d37E5076a56168C66A1607EdB10819',
73
+ depositor: '0xC5CCc20f6A4CD65fda979A2E292DBCF2C450C067',
74
+ sdToken: '0x75289388d50364c3013583d97bd70cED0e183e32',
75
+ token: '0xd691d9a68c887bdf34da8c36f63487333acfd103',
76
+ },
77
+ {
78
+ chainId: 8453,
79
+ locker: '0xC5CCc20f6A4CD65fda979A2E292DBCF2C450C067',
80
+ veToken: '0xFcCB5263148fbF11d58433aF6FeeFF0Cc49E0EA5',
81
+ depositor: '0xb30807324354379233FC6F7716C0510BbBD88487',
82
+ sdToken: '0x75289388d50364c3013583d97bd70cED0e183e32',
83
+ token: '0x64b88c73A5DfA78D1713fE1b4c69a22d7E0faAa7',
84
+ },
85
+ ],
86
+ },
87
+ }
88
+
89
+ const maverickLocker = async ({ provider, common, prices }: { provider; common; prices }) => {
90
+ const token = locker.token.address
91
+ const sdToken = locker.sdToken.address
92
+
93
+ const gauge = locker.modules.gauge
94
+ const depositor = locker.modules.depositor
95
+ const votingEscrow = locker.modules.veToken
96
+ const lockerAddress = locker.modules.locker
97
+
98
+ const secondaryMarket = locker.secondaryMarket!
99
+ const rewards = locker.rewards
100
+
101
+ const sidechains = locker.extensions.sideChains!
102
+
103
+ const format = (value: bigint) => formatUnits(value, locker.token.decimals)
104
+ const formatRes = (value: any) => format(getRes(value))
105
+
106
+ const calls: Call[] = [
107
+ /*********************************************************************************
108
+ *** Voting Escrow
109
+ *********************************************************************************/
110
+
111
+ // Token locked by the Locker
112
+ { address: votingEscrow, name: 'lockups', params: [lockerAddress, 0] },
113
+ // veToken Balance of the Locker
114
+ { address: votingEscrow, name: 'balanceOf', params: [lockerAddress] },
115
+ // Total token locked
116
+ { address: token, name: 'balanceOf', params: [votingEscrow] },
117
+ // Total veToken supply
118
+ { address: votingEscrow, name: 'totalSupply' },
119
+ // veToken rate
120
+ { address: votingEscrow, name: 'previewPoints', params: [OneEther, FOUR_YEAR] },
121
+
122
+ /*********************************************************************************
123
+ *** Gauge
124
+ *********************************************************************************/
125
+
126
+ // Total sdToken staked
127
+ { address: gauge, name: 'totalSupply' },
128
+ // Gauge working supply
129
+ { address: gauge, name: 'working_supply' },
130
+
131
+ /*********************************************************************************
132
+ *** Token & sdToken
133
+ *********************************************************************************/
134
+
135
+ // Token balance not locked
136
+ { address: token, name: 'balanceOf', params: [depositor] },
137
+ // sdToken in secondary market pool
138
+ { address: sdToken, name: 'balanceOf', params: [secondaryMarket.pool] },
139
+
140
+ /*********************************************************************************
141
+ *** Rewards
142
+ *********************************************************************************/
143
+
144
+ // Streaming status for each reward token
145
+ ...rewards.map((r) => ({ address: gauge, name: 'reward_data', params: [r.address] })),
146
+ ]
147
+
148
+ /*********************************************************************************
149
+ *** Sidechains
150
+ *********************************************************************************/
151
+ const sidechainsCalls = sidechains.reduce((acc, value) => {
152
+ return acc.concat([
153
+ { address: value.veToken, name: 'lockups', params: [value.locker, 0], chainId: value.chainId },
154
+ { address: value.veToken, name: 'balanceOf', params: [value.locker], chainId: value.chainId },
155
+ { address: value.veToken, name: 'totalSupply', chainId: value.chainId },
156
+ ])
157
+ }, [] as any)
158
+
159
+ const [res, sidechainsRes] = await Promise.all([
160
+ multicall(provider, calls, lockersMulticallAbi(locker.id, locker.chainId)),
161
+ multichainMulticall(sidechainsCalls, lockersMulticallAbi()),
162
+ ])
163
+
164
+ const raw = {
165
+ tokenLocked: getRes(res.shift()),
166
+ veBalanceOfLocker: formatRes(res.shift()),
167
+ totalTokenLocked: formatRes(res.shift()),
168
+ veTotalSupply: formatRes(res.shift()),
169
+ veTokenRate: getRes(res.shift()),
170
+ totalSupplyStaked: formatRes(res.shift()),
171
+ gaugeWorkingSupply: formatRes(res.shift()),
172
+ amountTokenNotLock: formatRes(res.shift()),
173
+ sdTokenInPool: formatRes(res.shift()),
174
+ peg: '-',
175
+ rewards: rewards.map(() => getRes(res.shift())),
176
+ _workingSupply: '0',
177
+ _veBalanceOfLocker: '0',
178
+ sidechains: sidechains.map((s) => ({
179
+ tokenLocked: format(getRes(sidechainsRes[s.chainId].shift())[0]),
180
+ veBalanceOfLocker: formatRes(sidechainsRes[s.chainId].shift()),
181
+ veTotalSupply: formatRes(sidechainsRes[s.chainId].shift()),
182
+ })),
183
+ }
184
+
185
+ raw.tokenLocked = format(raw.tokenLocked[0])
186
+ raw.veTokenRate = format(raw.veTokenRate[0])
187
+ raw._workingSupply = raw.gaugeWorkingSupply
188
+ raw._veBalanceOfLocker = raw.veBalanceOfLocker
189
+
190
+ return parse({ locker, common, prices, raw })
191
+ }
192
+
193
+ export default maverickLocker
@@ -0,0 +1,149 @@
1
+ import { One, STAKE_DAO_ASSETS_BASE_URL, Zero, tokenWithId } from '@stake-dao/constants'
2
+ import { formatUnits, parseUnits } from 'viem'
3
+ import lockersMulticallAbi from '../../../abis/lockersMulticall.js'
4
+ import { STAKE_DAO_API } from '../../../endpoints.js'
5
+ import { type Call, getRes, multicall } from '../../../utils.js'
6
+ import { parse, parsePeg } from '../parse.js'
7
+ import type { Locker } from '../types.js'
8
+
9
+ export const locker: Locker = {
10
+ id: 'cake',
11
+ symbol: 'CAKE',
12
+ protocol: 'PancakeSwap',
13
+ protocolDescription: 'PancakeSwap is the leading decentralized exchange on BNB Smart Chain.',
14
+ website: 'https://pancakeswap.finance/',
15
+ logoUrl: `${STAKE_DAO_ASSETS_BASE_URL}/assets/archive/cake.svg`,
16
+ chainId: 56,
17
+ rgb: '31, 199, 212',
18
+ token: tokenWithId('cake', 56)!,
19
+ sdToken: tokenWithId('sdcake', 56)!,
20
+ rewards: [
21
+ { ...tokenWithId('cake', 56)!, distribution: 'streamed', origin: 'native.pancakeswap' },
22
+ { ...tokenWithId('sdcake', 56)!, distribution: 'distributed', origin: 'bounties' },
23
+ ],
24
+ delegation: ['sdcake.eth'],
25
+ modules: {
26
+ depositor: '0x0000000000000000000000000000000000000000',
27
+ locker: '0x1e6f87a9ddf744af31157d8daa1e3025648d042d',
28
+ veToken: '0x5692DB8177a81A6c6afc8084C2976C9933EC1bAB',
29
+ gauge: '0xE2496134149e6CD3f3A577C2B08A6f54fC23e6e4',
30
+ accumulator: '0xAA14AD0AD8B48406Baf2473692901e47430414F5',
31
+ redeem: '0xD1Aa72713ccB1FE2983141EC176F1181F98E4908',
32
+ },
33
+ secondaryMarket: {
34
+ label: 'PancakeSwap',
35
+ poolKey: '',
36
+ vaultKey: '',
37
+ pool: '0xb8204D31379A9B317CD61C833406C972F58ecCbC',
38
+ pools: ['0xb8204D31379A9B317CD61C833406C972F58ecCbC', '0x8A876Ca851063e0252654CA6368a5B2280f51c32'],
39
+ router: '0x13f4EA83D0bd40E75C8222255bc855a974568Dd4',
40
+ pegBase: 3000,
41
+ },
42
+ fees: [
43
+ {
44
+ label: { key: 'liquidity', variable: 'sdCAKE/CAKE' },
45
+ value: 10,
46
+ key: 'liquidityFee',
47
+ },
48
+ {
49
+ label: { key: 'treasury' },
50
+ value: 5,
51
+ key: 'daoFee',
52
+ },
53
+ ],
54
+ extensions: {
55
+ coingeckoBaseSlug: 'pancakeswap',
56
+ },
57
+ }
58
+
59
+ const pancakeswapLocker = async ({ provider, common, prices }: { provider; common; prices }) => {
60
+ const token = locker.token.address
61
+ const sdToken = locker.sdToken.address
62
+
63
+ const gauge = locker.modules.gauge
64
+ const depositor = locker.modules.depositor
65
+ const votingEscrow = locker.modules.veToken
66
+ const lockerAddress = locker.modules.locker
67
+
68
+ const secondaryMarket = locker.secondaryMarket!
69
+ const rewards = locker.rewards
70
+
71
+ const pegBase = parseUnits(secondaryMarket?.pegBase?.toString() || '1', 18)
72
+
73
+ const format = (value: bigint) => formatUnits(value, locker.token.decimals)
74
+ const formatRes = (value: any) => format(getRes(value))
75
+
76
+ const calls: Call[] = [
77
+ /*********************************************************************************
78
+ *** Voting Escrow
79
+ *********************************************************************************/
80
+
81
+ // Token locked by the Locker
82
+ { address: votingEscrow, name: 'locks', params: [lockerAddress] },
83
+ // veToken Balance of the Locker
84
+ { address: votingEscrow, name: 'balanceOf', params: [lockerAddress] },
85
+ // Total token locked
86
+ { address: token, name: 'balanceOf', params: [votingEscrow] },
87
+ // Total veToken supply
88
+ { address: votingEscrow, name: 'totalSupply' },
89
+
90
+ /*********************************************************************************
91
+ *** Gauge
92
+ *********************************************************************************/
93
+
94
+ // Total sdToken staked
95
+ { address: gauge, name: 'totalSupply' },
96
+
97
+ /*********************************************************************************
98
+ *** Token & sdToken
99
+ *********************************************************************************/
100
+
101
+ // Token balance not locked
102
+ { address: token, name: 'balanceOf', params: [depositor] },
103
+ // sdToken in secondary market pool
104
+ { address: sdToken, name: 'balanceOf', params: [secondaryMarket.pool] },
105
+
106
+ /*********************************************************************************
107
+ *** Peg
108
+ *********************************************************************************/
109
+
110
+ // Return amount when swapping {pegBase} sdToken to token -> get_dy(uint256,uint256,uint256)
111
+ { address: secondaryMarket.pool, name: '0x556d6e9f', params: [One, Zero, pegBase] },
112
+
113
+ /*********************************************************************************
114
+ *** Rewards
115
+ *********************************************************************************/
116
+
117
+ // Streaming status for each reward token
118
+ ...rewards.map((r) => ({ address: gauge, name: 'reward_data', params: [r.address] })),
119
+ ]
120
+
121
+ const [res, sdcakeData] = await Promise.all([
122
+ multicall(provider, calls, lockersMulticallAbi(locker.id, locker.chainId)),
123
+ fetch(`${STAKE_DAO_API}/main/api/lockers/sdcake-working-supply.json`).then((res) => res.json()),
124
+ ])
125
+
126
+ const raw = {
127
+ tokenLocked: getRes(res.shift()),
128
+ veBalanceOfLocker: formatRes(res.shift()),
129
+ totalTokenLocked: formatRes(res.shift()),
130
+ veTotalSupply: formatRes(res.shift()),
131
+ totalSupplyStaked: formatRes(res.shift()),
132
+ gaugeWorkingSupply: '0',
133
+ amountTokenNotLock: formatRes(res.shift()),
134
+ sdTokenInPool: formatRes(res.shift()),
135
+ peg: getRes(res.shift()),
136
+ rewards: rewards.map(() => getRes(res.shift())),
137
+ veTokenRate: '4',
138
+ _workingSupply: sdcakeData.working_supply.toString(),
139
+ _veBalanceOfLocker: sdcakeData.total_user_votes.toString(),
140
+ }
141
+
142
+ raw.tokenLocked = format(raw.tokenLocked[0])
143
+ raw.gaugeWorkingSupply = raw.totalSupplyStaked
144
+ raw.peg = parsePeg(locker, raw.peg)
145
+
146
+ return parse({ locker, common, prices, raw })
147
+ }
148
+
149
+ export default pancakeswapLocker