1
+ const sdk = require ( '@defillama/sdk' ) ;
2
+ const superagent = require ( 'superagent' ) ;
3
+
4
+ const BOLD_TOKEN = '0x9cf12ccd6020b6888e4d4c4e4c7aca33c1eb91f8' ;
5
+
6
+ const YSYBOLD_BRANCH = {
7
+ activePool : '0xb87e1e1c4cc2decada13025a8dc8a94bdb77fb63' ,
8
+ defaultPool : '0x27f539ec3fa3e548e10d4ac883534eba891bb212' ,
9
+ stabilityPool : '0x83e5bde77d7477ecd972e338541b90af57675536' ,
10
+ borrowerOperations : '0x57bd20ae68f845b35b76fe6e0239c9929eb48469' ,
11
+ collToken : '0x23346b04a7f55b8760e5860aa5a77383d63491cd' . toLowerCase ( ) ,
12
+ symbol : 'YSYBOLD'
13
+ }
14
+
15
+ const SCRVUSD_BRANCH = {
16
+ activePool : '0x244c422663328233a5d1bd5045ff943ba97d046e' ,
17
+ defaultPool : '0xc20a51f66c917feff80d1e089199f727060c0369' ,
18
+ stabilityPool : '0xd48dc7cddc481f596bd9a97755c7ac696ad4ea87' ,
19
+ borrowerOperations : '0x9e601005deaaee8294c686e28e1affd04cc13830' ,
20
+ collToken : '0x0655977feb2f289a4ab78af67bab0d17aab84367' . toLowerCase ( ) ,
21
+ symbol : 'SCRVUSD'
22
+ }
23
+
24
+ const SUSDS_BRANCH = {
25
+ activePool : '0x08eaafd8fbb12cf12d6765e80c5b0ff8490c232d' ,
26
+ defaultPool : '0xfab7396e2a6a3364e02ed26d2f80a354aa923b88' ,
27
+ stabilityPool : '0xb571781cedf07257d60d6b252a3d8b24150ded97' ,
28
+ borrowerOperations : '0x336d9c5ecb9d6ce79c8c077d35426e714969b41d' ,
29
+ collToken : '0xa3931d71877c0e7a3148cb7eb4463524fec27fbd' . toLowerCase ( ) ,
30
+ symbol : 'SUSDS'
31
+ }
32
+
33
+ const SFRXUSD_BRANCH = {
34
+ activePool : '0x20f29569566020d8e49c9843033c370772a93774' ,
35
+ defaultPool : '0xfe6f765e77fd8f17ec3a985ac36c3c3ea92c946d' ,
36
+ stabilityPool : '0x446f358e3a927cc68f342141d78aa2d1c54e18f0' ,
37
+ borrowerOperations : '0x2538cd346429ea59902e02448bb7a7c098e4554e' ,
38
+ collToken : '0xcf62f905562626cfcdd2261162a51fd02fc9c5b6' . toLowerCase ( ) ,
39
+ symbol : 'SFRXUSD'
40
+ }
41
+
42
+ const TBTC_BRANCH = {
43
+ activePool : '0xb00d1d5dfd72a440b8c04a5f7b5bc3c8159a7f44' ,
44
+ defaultPool : '0x254a6a3e172a81d5825122403e1bc4d47f264a07' ,
45
+ stabilityPool : '0x545a7ddfd863bd7ea0bfc689125169598085f75e' ,
46
+ borrowerOperations : '0xda9af112edfd837eebc1780433481426a52556e0' ,
47
+ collToken : '0x18084fba666a33d37592fa2633fd49a74dd93a88' . toLowerCase ( ) ,
48
+ symbol : 'TBTC'
49
+ }
50
+
51
+ const WBTC_BRANCH = {
52
+ activePool : '0xf507e264d507ef64a72aeaf4cc8c270d008fc48a' ,
53
+ defaultPool : '0x01e37634cbd25ec7ffe680ece5eec178ff51ef2d' ,
54
+ stabilityPool : '0x922faa141e95e43a9deeab8dade3ac8d4a32ad5c' ,
55
+ borrowerOperations : '0x664507f1445657d36d8064663653b7810971f411' ,
56
+ collToken : '0xe065bc161b90c9c4bba2de7f1e194b70a3267c47' . toLowerCase ( ) ,
57
+ symbol : 'WBTC'
58
+ }
59
+
60
+ const branches = [ YSYBOLD_BRANCH , SCRVUSD_BRANCH , SUSDS_BRANCH , SFRXUSD_BRANCH , TBTC_BRANCH , WBTC_BRANCH ] ;
61
+
62
+ const SP_YIELD_SPLIT = 0.75 ;
63
+
64
+ const ABIS = {
65
+ getTotalBoldDeposits : {
66
+ inputs : [ ] ,
67
+ name : 'getTotalBoldDeposits' ,
68
+ outputs : [
69
+ {
70
+ internalType : 'uint256' ,
71
+ name : 'totalBoldDeposits' ,
72
+ type : 'uint256' ,
73
+ } ,
74
+ ] ,
75
+ stateMutability : 'view' ,
76
+ type : 'function' ,
77
+ } ,
78
+ getCollBalance : {
79
+ inputs : [ ] ,
80
+ name : 'getCollBalance' ,
81
+ outputs : [
82
+ {
83
+ internalType : 'uint256' ,
84
+ name : 'collBalance' ,
85
+ type : 'uint256' ,
86
+ } ,
87
+ ] ,
88
+ stateMutability : 'view' ,
89
+ type : 'function' ,
90
+ } ,
91
+ getBoldDebt : {
92
+ inputs : [ ] ,
93
+ name : 'getBoldDebt' ,
94
+ outputs : [
95
+ {
96
+ internalType : 'uint256' ,
97
+ name : 'boldDebt' ,
98
+ type : 'uint256' ,
99
+ } ,
100
+ ] ,
101
+ stateMutability : 'view' ,
102
+ type : 'function' ,
103
+ } ,
104
+ getMCR : {
105
+ inputs : [ ] ,
106
+ name : 'MCR' ,
107
+ outputs : [ { internalType : 'uint256' , name : '' , type : 'uint256' } ] ,
108
+ stateMutability : 'view' ,
109
+ type : 'function' ,
110
+ } ,
111
+ getNewApproxAvgInterestRateFromTroveChange : {
112
+ inputs : [
113
+ {
114
+ components : [
115
+ {
116
+ internalType : 'uint256' ,
117
+ name : 'appliedRedistBoldDebtGain' ,
118
+ type : 'uint256' ,
119
+ } ,
120
+ {
121
+ internalType : 'uint256' ,
122
+ name : 'appliedRedistCollGain' ,
123
+ type : 'uint256' ,
124
+ } ,
125
+ {
126
+ internalType : 'uint256' ,
127
+ name : 'collIncrease' ,
128
+ type : 'uint256' ,
129
+ } ,
130
+ {
131
+ internalType : 'uint256' ,
132
+ name : 'collDecrease' ,
133
+ type : 'uint256' ,
134
+ } ,
135
+ {
136
+ internalType : 'uint256' ,
137
+ name : 'debtIncrease' ,
138
+ type : 'uint256' ,
139
+ } ,
140
+ {
141
+ internalType : 'uint256' ,
142
+ name : 'debtDecrease' ,
143
+ type : 'uint256' ,
144
+ } ,
145
+ {
146
+ internalType : 'uint256' ,
147
+ name : 'newWeightedRecordedDebt' ,
148
+ type : 'uint256' ,
149
+ } ,
150
+ {
151
+ internalType : 'uint256' ,
152
+ name : 'oldWeightedRecordedDebt' ,
153
+ type : 'uint256' ,
154
+ } ,
155
+ {
156
+ internalType : 'uint256' ,
157
+ name : 'upfrontFee' ,
158
+ type : 'uint256' ,
159
+ } ,
160
+ {
161
+ internalType : 'uint256' ,
162
+ name : 'batchAccruedManagementFee' ,
163
+ type : 'uint256' ,
164
+ } ,
165
+ {
166
+ internalType : 'uint256' ,
167
+ name : 'newWeightedRecordedBatchManagementFee' ,
168
+ type : 'uint256' ,
169
+ } ,
170
+ {
171
+ internalType : 'uint256' ,
172
+ name : 'oldWeightedRecordedBatchManagementFee' ,
173
+ type : 'uint256' ,
174
+ } ,
175
+ ] ,
176
+ internalType : 'struct TroveChange' ,
177
+ name : '_troveChange' ,
178
+ type : 'tuple' ,
179
+ } ,
180
+ ] ,
181
+ name : 'getNewApproxAvgInterestRateFromTroveChange' ,
182
+ outputs : [
183
+ {
184
+ internalType : 'uint256' ,
185
+ name : '' ,
186
+ type : 'uint256' ,
187
+ } ,
188
+ ] ,
189
+ stateMutability : 'view' ,
190
+ type : 'function' ,
191
+ }
192
+ } ;
193
+
194
+ const getSPSupplyAndApy = async ( spAddr , avgBranchInterestRate , branchBoldSupply ) => {
195
+ const spSupply = ( await sdk . api . abi . call ( {
196
+ target : spAddr ,
197
+ abi : ABIS . getTotalBoldDeposits ,
198
+ chain : 'ethereum' ,
199
+ } ) ) . output / 1e18 ;
200
+
201
+ // Yield is the branch interest rate amplifyed by ratio of branch supply to the BOLD in the SP
202
+ const spApy = avgBranchInterestRate * SP_YIELD_SPLIT * branchBoldSupply / spSupply ;
203
+
204
+ return [ spSupply , spApy ] ;
205
+ }
206
+
207
+ const getPrices = async ( addresses ) => {
208
+ const req = addresses . map ( ( address ) => `ethereum:${ address } ` ) . join ( ',' ) . toLowerCase ( ) ;
209
+ const prices = ( await superagent . get ( `https://coins.llama.fi/prices/current/${ req } ` ) ) . body . coins ;
210
+
211
+ const pricesObj = Object . fromEntries (
212
+ Object . entries ( prices ) . map ( ( [ address , priceData ] ) => [ address . split ( ':' ) [ 1 ] . toLowerCase ( ) , priceData . price ] )
213
+ ) ;
214
+
215
+ return pricesObj ;
216
+ }
217
+
218
+ const getBranchColl = async ( collPools ) => {
219
+ const results = await sdk . api . abi . multiCall ( {
220
+ calls : collPools . map ( ( poolAddr ) => ( {
221
+ target : poolAddr ,
222
+ params : [ ] ,
223
+ } ) ) ,
224
+ abi : ABIS . getCollBalance ,
225
+ chain : 'ethereum' ,
226
+ } ) ;
227
+
228
+ const totalColl = results . output . map ( x => Number ( x . output ) ) . reduce ( ( a , b ) => a + b ) ;
229
+ return totalColl / 1e18 ;
230
+ }
231
+
232
+ const getBranchDebt = async ( debtPools ) => {
233
+ const results = await sdk . api . abi . multiCall ( {
234
+ calls : debtPools . map ( ( poolAddr ) => ( {
235
+ target : poolAddr ,
236
+ params : [ ] ,
237
+ } ) ) ,
238
+ abi : ABIS . getBoldDebt ,
239
+ chain : 'ethereum' ,
240
+ } ) ;
241
+
242
+ const totalDebt = results . output . map ( x => Number ( x . output ) ) . reduce ( ( a , b ) => a + b ) ;
243
+ return totalDebt / 1e18 ;
244
+ }
245
+
246
+ const getLTV = async ( borrowerOpsAddr ) => {
247
+ const res = ( await sdk . api . abi . call ( {
248
+ target : borrowerOpsAddr ,
249
+ abi : ABIS . getMCR ,
250
+ chain : 'ethereum' ,
251
+ } )
252
+ ) ;
253
+
254
+ return 1 / ( res . output / 1e18 ) ;
255
+ }
256
+
257
+ const getNewApproxAvgInterestRateFromTroveChange = async ( activePoolAddr ) => {
258
+ const res = await sdk . api . abi . call ( {
259
+ target : activePoolAddr ,
260
+ abi : ABIS . getNewApproxAvgInterestRateFromTroveChange ,
261
+ params : [
262
+ [ 0 , // appliedRedistBoldDebtGain
263
+ 0 , // appliedRedistCollGain
264
+ 0 , // collIncrease
265
+ 0 , // collDecrease
266
+ 0 , // debtIncrease
267
+ 0 , // debtDecrease
268
+ 0 , // newWeightedRecordedDebt
269
+ 0 , // oldWeightedRecordedDebt
270
+ 0 , // upfrontFee
271
+ 0 , // batchAccruedManagementFee
272
+ 0 , // newWeightedRecordedBatchManagementFee
273
+ 0 ] // oldWeightedRecordedBatchManagementFee
274
+ ] ,
275
+ chain : 'ethereum' ,
276
+ } ) ;
277
+
278
+ // convert from 18 decimals and make percentage
279
+ return res . output / 1e16 ;
280
+ }
281
+
282
+ const main = async ( ) => {
283
+ const prices = await getPrices (
284
+ [ YSYBOLD_BRANCH . collToken ,
285
+ SCRVUSD_BRANCH . collToken ,
286
+ SUSDS_BRANCH . collToken ,
287
+ SFRXUSD_BRANCH . collToken ,
288
+ TBTC_BRANCH . collToken ,
289
+ '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599' , // WBTC - collToken is wrapper
290
+ BOLD_TOKEN
291
+ ]
292
+ ) ;
293
+
294
+ YSYBOLD_BRANCH . price = prices [ YSYBOLD_BRANCH . collToken ] ;
295
+ SCRVUSD_BRANCH . price = prices [ SCRVUSD_BRANCH . collToken ] ;
296
+ SUSDS_BRANCH . price = prices [ SUSDS_BRANCH . collToken ] ;
297
+ SFRXUSD_BRANCH . price = prices [ SFRXUSD_BRANCH . collToken ] ;
298
+ TBTC_BRANCH . price = prices [ TBTC_BRANCH . collToken ] ;
299
+ WBTC_BRANCH . price = prices [ '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599' ] ; // WBTC
300
+
301
+ const pools = [ ] ;
302
+
303
+ for ( const branch of branches ) {
304
+ const collPools = [ branch . activePool , branch . defaultPool ] ;
305
+
306
+ const totalColl = await getBranchColl ( collPools ) ;
307
+ const totalCollUsd = totalColl * branch . price
308
+
309
+ const ltv = await getLTV ( branch . borrowerOperations ) ;
310
+ const borrowApy = await getNewApproxAvgInterestRateFromTroveChange ( branch . activePool ) ;
311
+
312
+ const totalDebt = await getBranchDebt ( collPools ) ;
313
+ const totalDebtUsd = totalDebt * prices [ BOLD_TOKEN ] ;
314
+
315
+ const [ spSupply , spApy ] = await getSPSupplyAndApy ( branch . stabilityPool , borrowApy , totalDebt ) ;
316
+ const spSupplyUsd = spSupply * prices [ BOLD_TOKEN ] ;
317
+
318
+ const spPool =
319
+ {
320
+ pool : branch . stabilityPool ,
321
+ project : 'asymmetry-usdaf' ,
322
+ symbol : 'USDaf' ,
323
+ chain : 'ethereum' ,
324
+ apy : spApy ,
325
+ tvlUsd : spSupplyUsd ,
326
+ underlyingTokens : [ BOLD_TOKEN ] ,
327
+ rewardTokens : [ BOLD_TOKEN , branch . collToken ] ,
328
+ poolMeta : `${ branch . symbol } Stability Pool`
329
+ }
330
+
331
+ const borrowPool =
332
+ {
333
+ pool : branch . activePool ,
334
+ project : 'asymmetry-usdaf' ,
335
+ symbol : branch . symbol ,
336
+ chain : 'ethereum' ,
337
+ apy : 0 ,
338
+ tvlUsd : totalCollUsd ,
339
+ apyBaseBorrow : borrowApy ,
340
+ totalSupplyUsd : totalCollUsd ,
341
+ totalBorrowUsd : totalDebtUsd ,
342
+ ltv : ltv ,
343
+ mintedCoin : 'USDaf' ,
344
+ underlyingTokens : [ branch . collToken ] ,
345
+ }
346
+
347
+ pools . push ( spPool , borrowPool ) ;
348
+ } ;
349
+
350
+ return pools ;
351
+ }
352
+
353
+ module . exports = {
354
+ timetravel : false ,
355
+ apy : main ,
356
+ url : 'https://usdaf.asymmetry.finance/' ,
357
+ } ;
0 commit comments