@panoptic-eng/sdk 1.0.5 → 1.0.6
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.
- package/LICENSE +21 -0
- package/dist/cow/index.d.ts +5 -0
- package/dist/cow/index.js +5 -0
- package/dist/cow/types.d.ts +4 -0
- package/dist/cow/types.js +0 -0
- package/dist/cow-Dy-Cd09v.js +1405 -0
- package/dist/cow-Dy-Cd09v.js.map +1 -0
- package/dist/index-BuJcj5aO.d.ts +275 -0
- package/dist/index-BuJcj5aO.d.ts.map +1 -0
- package/dist/index-DVMjZi1E.d.ts +1801 -0
- package/dist/index-DVMjZi1E.d.ts.map +1 -0
- package/dist/index.d.ts +4222 -2177
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2345 -5532
- package/dist/index.js.map +1 -1
- package/dist/irm-CBrX8bjH.js +2375 -0
- package/dist/irm-CBrX8bjH.js.map +1 -0
- package/dist/irm-CGykVo3q.d.ts +32 -0
- package/dist/irm-CGykVo3q.d.ts.map +1 -0
- package/dist/irm-zWjtffWA.d.ts +85 -0
- package/dist/irm-zWjtffWA.d.ts.map +1 -0
- package/dist/panoptic/v2/index.d.ts +3972 -4004
- package/dist/panoptic/v2/index.d.ts.map +1 -1
- package/dist/panoptic/v2/index.js +7074 -9212
- package/dist/panoptic/v2/index.js.map +1 -1
- package/dist/panoptic/v2/types/index.d.ts +3 -0
- package/dist/panoptic/v2/types/index.js +0 -0
- package/dist/{rates-D-7EWaPS.js → position-FxaZi608.js} +7246 -5375
- package/dist/position-FxaZi608.js.map +1 -0
- package/dist/router-gzYGM1OO.js +1012 -0
- package/dist/router-gzYGM1OO.js.map +1 -0
- package/dist/types-BQejAFnu.d.ts +245 -0
- package/dist/types-BQejAFnu.d.ts.map +1 -0
- package/dist/types-CRvvn2ce.d.ts +128 -0
- package/dist/types-CRvvn2ce.d.ts.map +1 -0
- package/dist/uniswap/index.d.ts +291 -0
- package/dist/uniswap/index.d.ts.map +1 -0
- package/dist/uniswap/index.js +5 -0
- package/dist/writes-CVCD6Ers.js +4302 -0
- package/dist/writes-CVCD6Ers.js.map +1 -0
- package/package.json +17 -5
- package/dist/rates-BQ91Bbn6.d.ts +0 -38
- package/dist/rates-BQ91Bbn6.d.ts.map +0 -1
- package/dist/rates-D-7EWaPS.js.map +0 -1
|
@@ -0,0 +1,2375 @@
|
|
|
1
|
+
import { MulticallNoDataError, MulticallResultFailedError, MulticallResultMissingError, PanopticValidationError, collateralTrackerV2Abi, decodeLeftRightUnsigned, getBlockMeta, getPool$1 as getPool, getPositions, panopticPoolV2Abi, riskEngineAbi, tickToSqrtPriceX96$1 as tickToSqrtPriceX96 } from "./position-FxaZi608.js";
|
|
2
|
+
import { decodeFunctionResult, encodeFunctionData } from "viem";
|
|
3
|
+
import { call } from "viem/actions";
|
|
4
|
+
|
|
5
|
+
//#region src/abis/multicall3.ts
|
|
6
|
+
const Multicall3Abi = [
|
|
7
|
+
{
|
|
8
|
+
inputs: [{
|
|
9
|
+
components: [{
|
|
10
|
+
internalType: "address",
|
|
11
|
+
name: "target",
|
|
12
|
+
type: "address"
|
|
13
|
+
}, {
|
|
14
|
+
internalType: "bytes",
|
|
15
|
+
name: "callData",
|
|
16
|
+
type: "bytes"
|
|
17
|
+
}],
|
|
18
|
+
internalType: "struct Multicall3.Call[]",
|
|
19
|
+
name: "calls",
|
|
20
|
+
type: "tuple[]"
|
|
21
|
+
}],
|
|
22
|
+
name: "aggregate",
|
|
23
|
+
outputs: [{
|
|
24
|
+
internalType: "uint256",
|
|
25
|
+
name: "blockNumber",
|
|
26
|
+
type: "uint256"
|
|
27
|
+
}, {
|
|
28
|
+
internalType: "bytes[]",
|
|
29
|
+
name: "returnData",
|
|
30
|
+
type: "bytes[]"
|
|
31
|
+
}],
|
|
32
|
+
stateMutability: "payable",
|
|
33
|
+
type: "function"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
inputs: [{
|
|
37
|
+
components: [
|
|
38
|
+
{
|
|
39
|
+
internalType: "address",
|
|
40
|
+
name: "target",
|
|
41
|
+
type: "address"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
internalType: "bool",
|
|
45
|
+
name: "allowFailure",
|
|
46
|
+
type: "bool"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
internalType: "bytes",
|
|
50
|
+
name: "callData",
|
|
51
|
+
type: "bytes"
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
internalType: "struct Multicall3.Call3[]",
|
|
55
|
+
name: "calls",
|
|
56
|
+
type: "tuple[]"
|
|
57
|
+
}],
|
|
58
|
+
name: "aggregate3",
|
|
59
|
+
outputs: [{
|
|
60
|
+
components: [{
|
|
61
|
+
internalType: "bool",
|
|
62
|
+
name: "success",
|
|
63
|
+
type: "bool"
|
|
64
|
+
}, {
|
|
65
|
+
internalType: "bytes",
|
|
66
|
+
name: "returnData",
|
|
67
|
+
type: "bytes"
|
|
68
|
+
}],
|
|
69
|
+
internalType: "struct Multicall3.Result[]",
|
|
70
|
+
name: "returnData",
|
|
71
|
+
type: "tuple[]"
|
|
72
|
+
}],
|
|
73
|
+
stateMutability: "payable",
|
|
74
|
+
type: "function"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
inputs: [{
|
|
78
|
+
components: [
|
|
79
|
+
{
|
|
80
|
+
internalType: "address",
|
|
81
|
+
name: "target",
|
|
82
|
+
type: "address"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
internalType: "bool",
|
|
86
|
+
name: "allowFailure",
|
|
87
|
+
type: "bool"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
internalType: "uint256",
|
|
91
|
+
name: "value",
|
|
92
|
+
type: "uint256"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
internalType: "bytes",
|
|
96
|
+
name: "callData",
|
|
97
|
+
type: "bytes"
|
|
98
|
+
}
|
|
99
|
+
],
|
|
100
|
+
internalType: "struct Multicall3.Call3Value[]",
|
|
101
|
+
name: "calls",
|
|
102
|
+
type: "tuple[]"
|
|
103
|
+
}],
|
|
104
|
+
name: "aggregate3Value",
|
|
105
|
+
outputs: [{
|
|
106
|
+
components: [{
|
|
107
|
+
internalType: "bool",
|
|
108
|
+
name: "success",
|
|
109
|
+
type: "bool"
|
|
110
|
+
}, {
|
|
111
|
+
internalType: "bytes",
|
|
112
|
+
name: "returnData",
|
|
113
|
+
type: "bytes"
|
|
114
|
+
}],
|
|
115
|
+
internalType: "struct Multicall3.Result[]",
|
|
116
|
+
name: "returnData",
|
|
117
|
+
type: "tuple[]"
|
|
118
|
+
}],
|
|
119
|
+
stateMutability: "payable",
|
|
120
|
+
type: "function"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
inputs: [{
|
|
124
|
+
components: [{
|
|
125
|
+
internalType: "address",
|
|
126
|
+
name: "target",
|
|
127
|
+
type: "address"
|
|
128
|
+
}, {
|
|
129
|
+
internalType: "bytes",
|
|
130
|
+
name: "callData",
|
|
131
|
+
type: "bytes"
|
|
132
|
+
}],
|
|
133
|
+
internalType: "struct Multicall3.Call[]",
|
|
134
|
+
name: "calls",
|
|
135
|
+
type: "tuple[]"
|
|
136
|
+
}],
|
|
137
|
+
name: "blockAndAggregate",
|
|
138
|
+
outputs: [
|
|
139
|
+
{
|
|
140
|
+
internalType: "uint256",
|
|
141
|
+
name: "blockNumber",
|
|
142
|
+
type: "uint256"
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
internalType: "bytes32",
|
|
146
|
+
name: "blockHash",
|
|
147
|
+
type: "bytes32"
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
components: [{
|
|
151
|
+
internalType: "bool",
|
|
152
|
+
name: "success",
|
|
153
|
+
type: "bool"
|
|
154
|
+
}, {
|
|
155
|
+
internalType: "bytes",
|
|
156
|
+
name: "returnData",
|
|
157
|
+
type: "bytes"
|
|
158
|
+
}],
|
|
159
|
+
internalType: "struct Multicall3.Result[]",
|
|
160
|
+
name: "returnData",
|
|
161
|
+
type: "tuple[]"
|
|
162
|
+
}
|
|
163
|
+
],
|
|
164
|
+
stateMutability: "payable",
|
|
165
|
+
type: "function"
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
inputs: [],
|
|
169
|
+
name: "getBasefee",
|
|
170
|
+
outputs: [{
|
|
171
|
+
internalType: "uint256",
|
|
172
|
+
name: "basefee",
|
|
173
|
+
type: "uint256"
|
|
174
|
+
}],
|
|
175
|
+
stateMutability: "view",
|
|
176
|
+
type: "function"
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
inputs: [{
|
|
180
|
+
internalType: "uint256",
|
|
181
|
+
name: "blockNumber",
|
|
182
|
+
type: "uint256"
|
|
183
|
+
}],
|
|
184
|
+
name: "getBlockHash",
|
|
185
|
+
outputs: [{
|
|
186
|
+
internalType: "bytes32",
|
|
187
|
+
name: "blockHash",
|
|
188
|
+
type: "bytes32"
|
|
189
|
+
}],
|
|
190
|
+
stateMutability: "view",
|
|
191
|
+
type: "function"
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
inputs: [],
|
|
195
|
+
name: "getBlockNumber",
|
|
196
|
+
outputs: [{
|
|
197
|
+
internalType: "uint256",
|
|
198
|
+
name: "blockNumber",
|
|
199
|
+
type: "uint256"
|
|
200
|
+
}],
|
|
201
|
+
stateMutability: "view",
|
|
202
|
+
type: "function"
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
inputs: [],
|
|
206
|
+
name: "getChainId",
|
|
207
|
+
outputs: [{
|
|
208
|
+
internalType: "uint256",
|
|
209
|
+
name: "chainid",
|
|
210
|
+
type: "uint256"
|
|
211
|
+
}],
|
|
212
|
+
stateMutability: "view",
|
|
213
|
+
type: "function"
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
inputs: [],
|
|
217
|
+
name: "getCurrentBlockCoinbase",
|
|
218
|
+
outputs: [{
|
|
219
|
+
internalType: "address",
|
|
220
|
+
name: "coinbase",
|
|
221
|
+
type: "address"
|
|
222
|
+
}],
|
|
223
|
+
stateMutability: "view",
|
|
224
|
+
type: "function"
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
inputs: [],
|
|
228
|
+
name: "getCurrentBlockDifficulty",
|
|
229
|
+
outputs: [{
|
|
230
|
+
internalType: "uint256",
|
|
231
|
+
name: "difficulty",
|
|
232
|
+
type: "uint256"
|
|
233
|
+
}],
|
|
234
|
+
stateMutability: "view",
|
|
235
|
+
type: "function"
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
inputs: [],
|
|
239
|
+
name: "getCurrentBlockGasLimit",
|
|
240
|
+
outputs: [{
|
|
241
|
+
internalType: "uint256",
|
|
242
|
+
name: "gaslimit",
|
|
243
|
+
type: "uint256"
|
|
244
|
+
}],
|
|
245
|
+
stateMutability: "view",
|
|
246
|
+
type: "function"
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
inputs: [],
|
|
250
|
+
name: "getCurrentBlockTimestamp",
|
|
251
|
+
outputs: [{
|
|
252
|
+
internalType: "uint256",
|
|
253
|
+
name: "timestamp",
|
|
254
|
+
type: "uint256"
|
|
255
|
+
}],
|
|
256
|
+
stateMutability: "view",
|
|
257
|
+
type: "function"
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
inputs: [{
|
|
261
|
+
internalType: "address",
|
|
262
|
+
name: "addr",
|
|
263
|
+
type: "address"
|
|
264
|
+
}],
|
|
265
|
+
name: "getEthBalance",
|
|
266
|
+
outputs: [{
|
|
267
|
+
internalType: "uint256",
|
|
268
|
+
name: "balance",
|
|
269
|
+
type: "uint256"
|
|
270
|
+
}],
|
|
271
|
+
stateMutability: "view",
|
|
272
|
+
type: "function"
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
inputs: [],
|
|
276
|
+
name: "getLastBlockHash",
|
|
277
|
+
outputs: [{
|
|
278
|
+
internalType: "bytes32",
|
|
279
|
+
name: "blockHash",
|
|
280
|
+
type: "bytes32"
|
|
281
|
+
}],
|
|
282
|
+
stateMutability: "view",
|
|
283
|
+
type: "function"
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
inputs: [{
|
|
287
|
+
internalType: "bool",
|
|
288
|
+
name: "requireSuccess",
|
|
289
|
+
type: "bool"
|
|
290
|
+
}, {
|
|
291
|
+
components: [{
|
|
292
|
+
internalType: "address",
|
|
293
|
+
name: "target",
|
|
294
|
+
type: "address"
|
|
295
|
+
}, {
|
|
296
|
+
internalType: "bytes",
|
|
297
|
+
name: "callData",
|
|
298
|
+
type: "bytes"
|
|
299
|
+
}],
|
|
300
|
+
internalType: "struct Multicall3.Call[]",
|
|
301
|
+
name: "calls",
|
|
302
|
+
type: "tuple[]"
|
|
303
|
+
}],
|
|
304
|
+
name: "tryAggregate",
|
|
305
|
+
outputs: [{
|
|
306
|
+
components: [{
|
|
307
|
+
internalType: "bool",
|
|
308
|
+
name: "success",
|
|
309
|
+
type: "bool"
|
|
310
|
+
}, {
|
|
311
|
+
internalType: "bytes",
|
|
312
|
+
name: "returnData",
|
|
313
|
+
type: "bytes"
|
|
314
|
+
}],
|
|
315
|
+
internalType: "struct Multicall3.Result[]",
|
|
316
|
+
name: "returnData",
|
|
317
|
+
type: "tuple[]"
|
|
318
|
+
}],
|
|
319
|
+
stateMutability: "payable",
|
|
320
|
+
type: "function"
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
inputs: [{
|
|
324
|
+
internalType: "bool",
|
|
325
|
+
name: "requireSuccess",
|
|
326
|
+
type: "bool"
|
|
327
|
+
}, {
|
|
328
|
+
components: [{
|
|
329
|
+
internalType: "address",
|
|
330
|
+
name: "target",
|
|
331
|
+
type: "address"
|
|
332
|
+
}, {
|
|
333
|
+
internalType: "bytes",
|
|
334
|
+
name: "callData",
|
|
335
|
+
type: "bytes"
|
|
336
|
+
}],
|
|
337
|
+
internalType: "struct Multicall3.Call[]",
|
|
338
|
+
name: "calls",
|
|
339
|
+
type: "tuple[]"
|
|
340
|
+
}],
|
|
341
|
+
name: "tryBlockAndAggregate",
|
|
342
|
+
outputs: [
|
|
343
|
+
{
|
|
344
|
+
internalType: "uint256",
|
|
345
|
+
name: "blockNumber",
|
|
346
|
+
type: "uint256"
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
internalType: "bytes32",
|
|
350
|
+
name: "blockHash",
|
|
351
|
+
type: "bytes32"
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
components: [{
|
|
355
|
+
internalType: "bool",
|
|
356
|
+
name: "success",
|
|
357
|
+
type: "bool"
|
|
358
|
+
}, {
|
|
359
|
+
internalType: "bytes",
|
|
360
|
+
name: "returnData",
|
|
361
|
+
type: "bytes"
|
|
362
|
+
}],
|
|
363
|
+
internalType: "struct Multicall3.Result[]",
|
|
364
|
+
name: "returnData",
|
|
365
|
+
type: "tuple[]"
|
|
366
|
+
}
|
|
367
|
+
],
|
|
368
|
+
stateMutability: "payable",
|
|
369
|
+
type: "function"
|
|
370
|
+
}
|
|
371
|
+
];
|
|
372
|
+
|
|
373
|
+
//#endregion
|
|
374
|
+
//#region src/panoptic/v2/abis/panopticQuery.ts
|
|
375
|
+
/**
|
|
376
|
+
* PanopticQuery contract ABI
|
|
377
|
+
* Auto-generated from PanopticQuery.json
|
|
378
|
+
* @module abis/panopticQuery
|
|
379
|
+
*/
|
|
380
|
+
const panopticQueryAbi = [
|
|
381
|
+
{
|
|
382
|
+
type: "constructor",
|
|
383
|
+
inputs: [{
|
|
384
|
+
name: "SFPM_",
|
|
385
|
+
type: "address",
|
|
386
|
+
internalType: "contract ISemiFungiblePositionManager"
|
|
387
|
+
}],
|
|
388
|
+
stateMutability: "payable"
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
type: "function",
|
|
392
|
+
name: "checkCollateral",
|
|
393
|
+
inputs: [
|
|
394
|
+
{
|
|
395
|
+
name: "pool",
|
|
396
|
+
type: "address",
|
|
397
|
+
internalType: "contract PanopticPool"
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
name: "account",
|
|
401
|
+
type: "address",
|
|
402
|
+
internalType: "address"
|
|
403
|
+
},
|
|
404
|
+
{
|
|
405
|
+
name: "positionIdList",
|
|
406
|
+
type: "uint256[]",
|
|
407
|
+
internalType: "TokenId[]"
|
|
408
|
+
}
|
|
409
|
+
],
|
|
410
|
+
outputs: [
|
|
411
|
+
{
|
|
412
|
+
name: "collateralBalances0",
|
|
413
|
+
type: "uint256[4]",
|
|
414
|
+
internalType: "uint256[4]"
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
name: "requiredCollaterals0",
|
|
418
|
+
type: "uint256[4]",
|
|
419
|
+
internalType: "uint256[4]"
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
name: "collateralBalances1",
|
|
423
|
+
type: "uint256[4]",
|
|
424
|
+
internalType: "uint256[4]"
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
name: "requiredCollaterals1",
|
|
428
|
+
type: "uint256[4]",
|
|
429
|
+
internalType: "uint256[4]"
|
|
430
|
+
}
|
|
431
|
+
],
|
|
432
|
+
stateMutability: "view"
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
type: "function",
|
|
436
|
+
name: "checkCollateral",
|
|
437
|
+
inputs: [
|
|
438
|
+
{
|
|
439
|
+
name: "pool",
|
|
440
|
+
type: "address",
|
|
441
|
+
internalType: "contract PanopticPool"
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
name: "account",
|
|
445
|
+
type: "address",
|
|
446
|
+
internalType: "address"
|
|
447
|
+
},
|
|
448
|
+
{
|
|
449
|
+
name: "positionIdList",
|
|
450
|
+
type: "uint256[]",
|
|
451
|
+
internalType: "TokenId[]"
|
|
452
|
+
},
|
|
453
|
+
{
|
|
454
|
+
name: "atTick",
|
|
455
|
+
type: "int24",
|
|
456
|
+
internalType: "int24"
|
|
457
|
+
}
|
|
458
|
+
],
|
|
459
|
+
outputs: [{
|
|
460
|
+
name: "balancesAndRequired",
|
|
461
|
+
type: "uint256[4]",
|
|
462
|
+
internalType: "uint256[4]"
|
|
463
|
+
}],
|
|
464
|
+
stateMutability: "view"
|
|
465
|
+
},
|
|
466
|
+
{
|
|
467
|
+
type: "function",
|
|
468
|
+
name: "checkCollateralListOutput",
|
|
469
|
+
inputs: [
|
|
470
|
+
{
|
|
471
|
+
name: "pool",
|
|
472
|
+
type: "address",
|
|
473
|
+
internalType: "contract PanopticPool"
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
name: "account",
|
|
477
|
+
type: "address",
|
|
478
|
+
internalType: "address"
|
|
479
|
+
},
|
|
480
|
+
{
|
|
481
|
+
name: "positionIdList",
|
|
482
|
+
type: "uint256[]",
|
|
483
|
+
internalType: "TokenId[]"
|
|
484
|
+
}
|
|
485
|
+
],
|
|
486
|
+
outputs: [
|
|
487
|
+
{
|
|
488
|
+
name: "",
|
|
489
|
+
type: "uint256[2][]",
|
|
490
|
+
internalType: "uint256[2][]"
|
|
491
|
+
},
|
|
492
|
+
{
|
|
493
|
+
name: "",
|
|
494
|
+
type: "int256[]",
|
|
495
|
+
internalType: "int256[]"
|
|
496
|
+
},
|
|
497
|
+
{
|
|
498
|
+
name: "",
|
|
499
|
+
type: "int24[]",
|
|
500
|
+
internalType: "int24[]"
|
|
501
|
+
}
|
|
502
|
+
],
|
|
503
|
+
stateMutability: "view"
|
|
504
|
+
},
|
|
505
|
+
{
|
|
506
|
+
type: "function",
|
|
507
|
+
name: "computeMedianObservedPrice",
|
|
508
|
+
inputs: [
|
|
509
|
+
{
|
|
510
|
+
name: "univ3pool",
|
|
511
|
+
type: "address",
|
|
512
|
+
internalType: "contract IUniswapV3Pool"
|
|
513
|
+
},
|
|
514
|
+
{
|
|
515
|
+
name: "cardinality",
|
|
516
|
+
type: "uint256",
|
|
517
|
+
internalType: "uint256"
|
|
518
|
+
},
|
|
519
|
+
{
|
|
520
|
+
name: "period",
|
|
521
|
+
type: "uint256",
|
|
522
|
+
internalType: "uint256"
|
|
523
|
+
}
|
|
524
|
+
],
|
|
525
|
+
outputs: [{
|
|
526
|
+
name: "medianTick",
|
|
527
|
+
type: "int24",
|
|
528
|
+
internalType: "int24"
|
|
529
|
+
}],
|
|
530
|
+
stateMutability: "view"
|
|
531
|
+
},
|
|
532
|
+
{
|
|
533
|
+
type: "function",
|
|
534
|
+
name: "getChunkData",
|
|
535
|
+
inputs: [{
|
|
536
|
+
name: "pool",
|
|
537
|
+
type: "address",
|
|
538
|
+
internalType: "contract PanopticPool"
|
|
539
|
+
}, {
|
|
540
|
+
name: "positionIdList",
|
|
541
|
+
type: "uint256[]",
|
|
542
|
+
internalType: "TokenId[]"
|
|
543
|
+
}],
|
|
544
|
+
outputs: [{
|
|
545
|
+
name: "",
|
|
546
|
+
type: "uint256[2][4][]",
|
|
547
|
+
internalType: "uint256[2][4][]"
|
|
548
|
+
}],
|
|
549
|
+
stateMutability: "view"
|
|
550
|
+
},
|
|
551
|
+
{
|
|
552
|
+
type: "function",
|
|
553
|
+
name: "scanChunks",
|
|
554
|
+
inputs: [
|
|
555
|
+
{
|
|
556
|
+
name: "pool",
|
|
557
|
+
type: "address",
|
|
558
|
+
internalType: "contract PanopticPool"
|
|
559
|
+
},
|
|
560
|
+
{
|
|
561
|
+
name: "tickLower",
|
|
562
|
+
type: "int24",
|
|
563
|
+
internalType: "int24"
|
|
564
|
+
},
|
|
565
|
+
{
|
|
566
|
+
name: "tickUpper",
|
|
567
|
+
type: "int24",
|
|
568
|
+
internalType: "int24"
|
|
569
|
+
},
|
|
570
|
+
{
|
|
571
|
+
name: "width",
|
|
572
|
+
type: "int24",
|
|
573
|
+
internalType: "int24"
|
|
574
|
+
}
|
|
575
|
+
],
|
|
576
|
+
outputs: [
|
|
577
|
+
{
|
|
578
|
+
name: "strikes",
|
|
579
|
+
type: "int24[]",
|
|
580
|
+
internalType: "int24[]"
|
|
581
|
+
},
|
|
582
|
+
{
|
|
583
|
+
name: "netLiquidities",
|
|
584
|
+
type: "uint128[2][]",
|
|
585
|
+
internalType: "uint128[2][]"
|
|
586
|
+
},
|
|
587
|
+
{
|
|
588
|
+
name: "removedLiquidities",
|
|
589
|
+
type: "uint128[2][]",
|
|
590
|
+
internalType: "uint128[2][]"
|
|
591
|
+
},
|
|
592
|
+
{
|
|
593
|
+
name: "settledTokens",
|
|
594
|
+
type: "uint256[2][]",
|
|
595
|
+
internalType: "LeftRightUnsigned[2][]"
|
|
596
|
+
}
|
|
597
|
+
],
|
|
598
|
+
stateMutability: "view"
|
|
599
|
+
},
|
|
600
|
+
{
|
|
601
|
+
type: "function",
|
|
602
|
+
name: "getLiquidationPrices",
|
|
603
|
+
inputs: [
|
|
604
|
+
{
|
|
605
|
+
name: "pool",
|
|
606
|
+
type: "address",
|
|
607
|
+
internalType: "contract PanopticPool"
|
|
608
|
+
},
|
|
609
|
+
{
|
|
610
|
+
name: "account",
|
|
611
|
+
type: "address",
|
|
612
|
+
internalType: "address"
|
|
613
|
+
},
|
|
614
|
+
{
|
|
615
|
+
name: "positionIdList",
|
|
616
|
+
type: "uint256[]",
|
|
617
|
+
internalType: "TokenId[]"
|
|
618
|
+
}
|
|
619
|
+
],
|
|
620
|
+
outputs: [{
|
|
621
|
+
name: "liquidationPriceDown",
|
|
622
|
+
type: "int24",
|
|
623
|
+
internalType: "int24"
|
|
624
|
+
}, {
|
|
625
|
+
name: "liquidationPriceUp",
|
|
626
|
+
type: "int24",
|
|
627
|
+
internalType: "int24"
|
|
628
|
+
}],
|
|
629
|
+
stateMutability: "view"
|
|
630
|
+
},
|
|
631
|
+
{
|
|
632
|
+
type: "function",
|
|
633
|
+
name: "getMaxPositionSizeBounds",
|
|
634
|
+
inputs: [
|
|
635
|
+
{
|
|
636
|
+
name: "pool",
|
|
637
|
+
type: "address",
|
|
638
|
+
internalType: "contract PanopticPool"
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
name: "existingPositionIds",
|
|
642
|
+
type: "uint256[]",
|
|
643
|
+
internalType: "TokenId[]"
|
|
644
|
+
},
|
|
645
|
+
{
|
|
646
|
+
name: "account",
|
|
647
|
+
type: "address",
|
|
648
|
+
internalType: "address"
|
|
649
|
+
},
|
|
650
|
+
{
|
|
651
|
+
name: "tokenId",
|
|
652
|
+
type: "uint256",
|
|
653
|
+
internalType: "TokenId"
|
|
654
|
+
}
|
|
655
|
+
],
|
|
656
|
+
outputs: [{
|
|
657
|
+
name: "maxSizeAtMinUtil",
|
|
658
|
+
type: "uint128",
|
|
659
|
+
internalType: "uint128"
|
|
660
|
+
}, {
|
|
661
|
+
name: "maxSizeAtMaxUtil",
|
|
662
|
+
type: "uint128",
|
|
663
|
+
internalType: "uint128"
|
|
664
|
+
}],
|
|
665
|
+
stateMutability: "view"
|
|
666
|
+
},
|
|
667
|
+
{
|
|
668
|
+
type: "function",
|
|
669
|
+
name: "getNetLiquidationValue",
|
|
670
|
+
inputs: [
|
|
671
|
+
{
|
|
672
|
+
name: "pool",
|
|
673
|
+
type: "address",
|
|
674
|
+
internalType: "contract PanopticPool"
|
|
675
|
+
},
|
|
676
|
+
{
|
|
677
|
+
name: "account",
|
|
678
|
+
type: "address",
|
|
679
|
+
internalType: "address"
|
|
680
|
+
},
|
|
681
|
+
{
|
|
682
|
+
name: "includePendingPremium",
|
|
683
|
+
type: "bool",
|
|
684
|
+
internalType: "bool"
|
|
685
|
+
},
|
|
686
|
+
{
|
|
687
|
+
name: "positionIdList",
|
|
688
|
+
type: "uint256[]",
|
|
689
|
+
internalType: "TokenId[]"
|
|
690
|
+
},
|
|
691
|
+
{
|
|
692
|
+
name: "atTicks",
|
|
693
|
+
type: "int24[]",
|
|
694
|
+
internalType: "int24[]"
|
|
695
|
+
}
|
|
696
|
+
],
|
|
697
|
+
outputs: [{
|
|
698
|
+
name: "value0",
|
|
699
|
+
type: "int256[]",
|
|
700
|
+
internalType: "int256[]"
|
|
701
|
+
}, {
|
|
702
|
+
name: "value1",
|
|
703
|
+
type: "int256[]",
|
|
704
|
+
internalType: "int256[]"
|
|
705
|
+
}],
|
|
706
|
+
stateMutability: "view"
|
|
707
|
+
},
|
|
708
|
+
{
|
|
709
|
+
type: "function",
|
|
710
|
+
name: "getNetLiquidationValue",
|
|
711
|
+
inputs: [
|
|
712
|
+
{
|
|
713
|
+
name: "pool",
|
|
714
|
+
type: "address",
|
|
715
|
+
internalType: "contract PanopticPool"
|
|
716
|
+
},
|
|
717
|
+
{
|
|
718
|
+
name: "account",
|
|
719
|
+
type: "address",
|
|
720
|
+
internalType: "address"
|
|
721
|
+
},
|
|
722
|
+
{
|
|
723
|
+
name: "includePendingPremium",
|
|
724
|
+
type: "bool",
|
|
725
|
+
internalType: "bool"
|
|
726
|
+
},
|
|
727
|
+
{
|
|
728
|
+
name: "positionIdList",
|
|
729
|
+
type: "uint256[]",
|
|
730
|
+
internalType: "TokenId[]"
|
|
731
|
+
},
|
|
732
|
+
{
|
|
733
|
+
name: "atTick",
|
|
734
|
+
type: "int24",
|
|
735
|
+
internalType: "int24"
|
|
736
|
+
}
|
|
737
|
+
],
|
|
738
|
+
outputs: [{
|
|
739
|
+
name: "value0",
|
|
740
|
+
type: "int256",
|
|
741
|
+
internalType: "int256"
|
|
742
|
+
}, {
|
|
743
|
+
name: "value1",
|
|
744
|
+
type: "int256",
|
|
745
|
+
internalType: "int256"
|
|
746
|
+
}],
|
|
747
|
+
stateMutability: "view"
|
|
748
|
+
},
|
|
749
|
+
{
|
|
750
|
+
type: "function",
|
|
751
|
+
name: "getPortfolioValue",
|
|
752
|
+
inputs: [
|
|
753
|
+
{
|
|
754
|
+
name: "pool",
|
|
755
|
+
type: "address",
|
|
756
|
+
internalType: "contract PanopticPool"
|
|
757
|
+
},
|
|
758
|
+
{
|
|
759
|
+
name: "account",
|
|
760
|
+
type: "address",
|
|
761
|
+
internalType: "address"
|
|
762
|
+
},
|
|
763
|
+
{
|
|
764
|
+
name: "atTick",
|
|
765
|
+
type: "int24",
|
|
766
|
+
internalType: "int24"
|
|
767
|
+
},
|
|
768
|
+
{
|
|
769
|
+
name: "positionIdList",
|
|
770
|
+
type: "uint256[]",
|
|
771
|
+
internalType: "TokenId[]"
|
|
772
|
+
}
|
|
773
|
+
],
|
|
774
|
+
outputs: [{
|
|
775
|
+
name: "value0",
|
|
776
|
+
type: "int256",
|
|
777
|
+
internalType: "int256"
|
|
778
|
+
}, {
|
|
779
|
+
name: "value1",
|
|
780
|
+
type: "int256",
|
|
781
|
+
internalType: "int256"
|
|
782
|
+
}],
|
|
783
|
+
stateMutability: "view"
|
|
784
|
+
},
|
|
785
|
+
{
|
|
786
|
+
type: "function",
|
|
787
|
+
name: "getRequiredBase",
|
|
788
|
+
inputs: [
|
|
789
|
+
{
|
|
790
|
+
name: "pool",
|
|
791
|
+
type: "address",
|
|
792
|
+
internalType: "contract PanopticPool"
|
|
793
|
+
},
|
|
794
|
+
{
|
|
795
|
+
name: "tokenId",
|
|
796
|
+
type: "uint256",
|
|
797
|
+
internalType: "TokenId"
|
|
798
|
+
},
|
|
799
|
+
{
|
|
800
|
+
name: "atTick",
|
|
801
|
+
type: "int24",
|
|
802
|
+
internalType: "int24"
|
|
803
|
+
}
|
|
804
|
+
],
|
|
805
|
+
outputs: [{
|
|
806
|
+
name: "",
|
|
807
|
+
type: "uint256",
|
|
808
|
+
internalType: "uint256"
|
|
809
|
+
}],
|
|
810
|
+
stateMutability: "view"
|
|
811
|
+
},
|
|
812
|
+
{
|
|
813
|
+
type: "function",
|
|
814
|
+
name: "getTickNets",
|
|
815
|
+
inputs: [
|
|
816
|
+
{
|
|
817
|
+
name: "pool",
|
|
818
|
+
type: "address",
|
|
819
|
+
internalType: "contract PanopticPool"
|
|
820
|
+
},
|
|
821
|
+
{
|
|
822
|
+
name: "startTick",
|
|
823
|
+
type: "int24",
|
|
824
|
+
internalType: "int24"
|
|
825
|
+
},
|
|
826
|
+
{
|
|
827
|
+
name: "nTicks",
|
|
828
|
+
type: "uint256",
|
|
829
|
+
internalType: "uint256"
|
|
830
|
+
}
|
|
831
|
+
],
|
|
832
|
+
outputs: [{
|
|
833
|
+
name: "tickData",
|
|
834
|
+
type: "int256[]",
|
|
835
|
+
internalType: "int256[]"
|
|
836
|
+
}, {
|
|
837
|
+
name: "liquidityNets",
|
|
838
|
+
type: "int256[]",
|
|
839
|
+
internalType: "int256[]"
|
|
840
|
+
}],
|
|
841
|
+
stateMutability: "view"
|
|
842
|
+
},
|
|
843
|
+
{
|
|
844
|
+
type: "function",
|
|
845
|
+
name: "getTickNetsV3",
|
|
846
|
+
inputs: [
|
|
847
|
+
{
|
|
848
|
+
name: "univ3pool",
|
|
849
|
+
type: "address",
|
|
850
|
+
internalType: "contract IUniswapV3Pool"
|
|
851
|
+
},
|
|
852
|
+
{
|
|
853
|
+
name: "startTick",
|
|
854
|
+
type: "int24",
|
|
855
|
+
internalType: "int24"
|
|
856
|
+
},
|
|
857
|
+
{
|
|
858
|
+
name: "nTicks",
|
|
859
|
+
type: "uint256",
|
|
860
|
+
internalType: "uint256"
|
|
861
|
+
}
|
|
862
|
+
],
|
|
863
|
+
outputs: [{
|
|
864
|
+
name: "tickData",
|
|
865
|
+
type: "int256[]",
|
|
866
|
+
internalType: "int256[]"
|
|
867
|
+
}, {
|
|
868
|
+
name: "liquidityNets",
|
|
869
|
+
type: "int256[]",
|
|
870
|
+
internalType: "int256[]"
|
|
871
|
+
}],
|
|
872
|
+
stateMutability: "view"
|
|
873
|
+
},
|
|
874
|
+
{
|
|
875
|
+
type: "function",
|
|
876
|
+
name: "getTickNetsV4",
|
|
877
|
+
inputs: [
|
|
878
|
+
{
|
|
879
|
+
name: "manager",
|
|
880
|
+
type: "address",
|
|
881
|
+
internalType: "contract IPoolManager"
|
|
882
|
+
},
|
|
883
|
+
{
|
|
884
|
+
name: "poolId",
|
|
885
|
+
type: "bytes32",
|
|
886
|
+
internalType: "PoolId"
|
|
887
|
+
},
|
|
888
|
+
{
|
|
889
|
+
name: "tickSpacing",
|
|
890
|
+
type: "int24",
|
|
891
|
+
internalType: "int24"
|
|
892
|
+
},
|
|
893
|
+
{
|
|
894
|
+
name: "startTick",
|
|
895
|
+
type: "int24",
|
|
896
|
+
internalType: "int24"
|
|
897
|
+
},
|
|
898
|
+
{
|
|
899
|
+
name: "nTicks",
|
|
900
|
+
type: "uint256",
|
|
901
|
+
internalType: "uint256"
|
|
902
|
+
}
|
|
903
|
+
],
|
|
904
|
+
outputs: [{
|
|
905
|
+
name: "tickData",
|
|
906
|
+
type: "int256[]",
|
|
907
|
+
internalType: "int256[]"
|
|
908
|
+
}, {
|
|
909
|
+
name: "liquidityNets",
|
|
910
|
+
type: "int256[]",
|
|
911
|
+
internalType: "int256[]"
|
|
912
|
+
}],
|
|
913
|
+
stateMutability: "view"
|
|
914
|
+
},
|
|
915
|
+
{
|
|
916
|
+
type: "function",
|
|
917
|
+
name: "isAccountSolvent",
|
|
918
|
+
inputs: [
|
|
919
|
+
{
|
|
920
|
+
name: "pool",
|
|
921
|
+
type: "address",
|
|
922
|
+
internalType: "contract PanopticPool"
|
|
923
|
+
},
|
|
924
|
+
{
|
|
925
|
+
name: "account",
|
|
926
|
+
type: "address",
|
|
927
|
+
internalType: "address"
|
|
928
|
+
},
|
|
929
|
+
{
|
|
930
|
+
name: "positionIdList",
|
|
931
|
+
type: "uint256[]",
|
|
932
|
+
internalType: "TokenId[]"
|
|
933
|
+
},
|
|
934
|
+
{
|
|
935
|
+
name: "atTick",
|
|
936
|
+
type: "int24",
|
|
937
|
+
internalType: "int24"
|
|
938
|
+
}
|
|
939
|
+
],
|
|
940
|
+
outputs: [{
|
|
941
|
+
name: "",
|
|
942
|
+
type: "bool",
|
|
943
|
+
internalType: "bool"
|
|
944
|
+
}],
|
|
945
|
+
stateMutability: "view"
|
|
946
|
+
},
|
|
947
|
+
{
|
|
948
|
+
type: "function",
|
|
949
|
+
name: "optimizeRiskPartners",
|
|
950
|
+
inputs: [
|
|
951
|
+
{
|
|
952
|
+
name: "pool",
|
|
953
|
+
type: "address",
|
|
954
|
+
internalType: "contract PanopticPool"
|
|
955
|
+
},
|
|
956
|
+
{
|
|
957
|
+
name: "atTick",
|
|
958
|
+
type: "int24",
|
|
959
|
+
internalType: "int24"
|
|
960
|
+
},
|
|
961
|
+
{
|
|
962
|
+
name: "tokenId",
|
|
963
|
+
type: "uint256",
|
|
964
|
+
internalType: "TokenId"
|
|
965
|
+
}
|
|
966
|
+
],
|
|
967
|
+
outputs: [{
|
|
968
|
+
name: "",
|
|
969
|
+
type: "uint256",
|
|
970
|
+
internalType: "TokenId"
|
|
971
|
+
}],
|
|
972
|
+
stateMutability: "view"
|
|
973
|
+
},
|
|
974
|
+
{
|
|
975
|
+
type: "function",
|
|
976
|
+
name: "twapFilter",
|
|
977
|
+
inputs: [{
|
|
978
|
+
name: "univ3pool",
|
|
979
|
+
type: "address",
|
|
980
|
+
internalType: "contract IUniswapV3Pool"
|
|
981
|
+
}, {
|
|
982
|
+
name: "twapWindow",
|
|
983
|
+
type: "uint32",
|
|
984
|
+
internalType: "uint32"
|
|
985
|
+
}],
|
|
986
|
+
outputs: [{
|
|
987
|
+
name: "",
|
|
988
|
+
type: "int24",
|
|
989
|
+
internalType: "int24"
|
|
990
|
+
}],
|
|
991
|
+
stateMutability: "view"
|
|
992
|
+
},
|
|
993
|
+
{
|
|
994
|
+
type: "function",
|
|
995
|
+
name: "validateTokenId",
|
|
996
|
+
inputs: [{
|
|
997
|
+
name: "self",
|
|
998
|
+
type: "uint256",
|
|
999
|
+
internalType: "TokenId"
|
|
1000
|
+
}],
|
|
1001
|
+
outputs: [],
|
|
1002
|
+
stateMutability: "pure"
|
|
1003
|
+
},
|
|
1004
|
+
{
|
|
1005
|
+
type: "error",
|
|
1006
|
+
name: "CastingError",
|
|
1007
|
+
inputs: []
|
|
1008
|
+
},
|
|
1009
|
+
{
|
|
1010
|
+
type: "error",
|
|
1011
|
+
name: "InvalidTick",
|
|
1012
|
+
inputs: []
|
|
1013
|
+
},
|
|
1014
|
+
{
|
|
1015
|
+
type: "error",
|
|
1016
|
+
name: "InvalidTokenIdParameter",
|
|
1017
|
+
inputs: [{
|
|
1018
|
+
name: "parameterType",
|
|
1019
|
+
type: "uint256",
|
|
1020
|
+
internalType: "uint256"
|
|
1021
|
+
}]
|
|
1022
|
+
},
|
|
1023
|
+
{
|
|
1024
|
+
type: "error",
|
|
1025
|
+
name: "LiquidityTooHigh",
|
|
1026
|
+
inputs: []
|
|
1027
|
+
},
|
|
1028
|
+
{
|
|
1029
|
+
type: "error",
|
|
1030
|
+
name: "UnderOverFlow",
|
|
1031
|
+
inputs: []
|
|
1032
|
+
}
|
|
1033
|
+
];
|
|
1034
|
+
|
|
1035
|
+
//#endregion
|
|
1036
|
+
//#region src/panoptic/v2/reads/multicallBlock.ts
|
|
1037
|
+
const MULTICALL3_ADDRESS = "0xcA11bde05977b3631167028862bE2a173976CA11";
|
|
1038
|
+
function hasCall(client) {
|
|
1039
|
+
return "call" in client && typeof client.call === "function";
|
|
1040
|
+
}
|
|
1041
|
+
function requireResult(results, index, label) {
|
|
1042
|
+
const result = results[index];
|
|
1043
|
+
if (result === void 0) throw new MulticallResultMissingError(label, index);
|
|
1044
|
+
if (!result.success) throw new MulticallResultFailedError(label, index);
|
|
1045
|
+
return result;
|
|
1046
|
+
}
|
|
1047
|
+
function requireReturnData(results, index, label) {
|
|
1048
|
+
return requireResult(results, index, label).returnData;
|
|
1049
|
+
}
|
|
1050
|
+
async function readBlockAndAggregate({ client, calls, blockNumber }) {
|
|
1051
|
+
const aggregateCalls = [...calls, {
|
|
1052
|
+
target: MULTICALL3_ADDRESS,
|
|
1053
|
+
callData: encodeFunctionData({
|
|
1054
|
+
abi: Multicall3Abi,
|
|
1055
|
+
functionName: "getCurrentBlockTimestamp"
|
|
1056
|
+
})
|
|
1057
|
+
}];
|
|
1058
|
+
const data = encodeFunctionData({
|
|
1059
|
+
abi: Multicall3Abi,
|
|
1060
|
+
functionName: "blockAndAggregate",
|
|
1061
|
+
args: [aggregateCalls]
|
|
1062
|
+
});
|
|
1063
|
+
const parameters = {
|
|
1064
|
+
to: MULTICALL3_ADDRESS,
|
|
1065
|
+
data,
|
|
1066
|
+
blockNumber
|
|
1067
|
+
};
|
|
1068
|
+
const response = hasCall(client) ? await client.call(parameters) : await call(client, parameters);
|
|
1069
|
+
if (response.data === void 0) throw new MulticallNoDataError("blockAndAggregate");
|
|
1070
|
+
const aggregateResult = decodeFunctionResult({
|
|
1071
|
+
abi: Multicall3Abi,
|
|
1072
|
+
functionName: "blockAndAggregate",
|
|
1073
|
+
data: response.data
|
|
1074
|
+
});
|
|
1075
|
+
const [aggregateBlockNumber, blockHash, rawResults] = aggregateResult;
|
|
1076
|
+
const timestampResult = requireReturnData(rawResults, calls.length, "Multicall3.getCurrentBlockTimestamp");
|
|
1077
|
+
const blockTimestamp = decodeFunctionResult({
|
|
1078
|
+
abi: Multicall3Abi,
|
|
1079
|
+
functionName: "getCurrentBlockTimestamp",
|
|
1080
|
+
data: timestampResult
|
|
1081
|
+
});
|
|
1082
|
+
return {
|
|
1083
|
+
_meta: {
|
|
1084
|
+
blockNumber: aggregateBlockNumber,
|
|
1085
|
+
blockHash,
|
|
1086
|
+
blockTimestamp
|
|
1087
|
+
},
|
|
1088
|
+
results: rawResults.slice(0, calls.length)
|
|
1089
|
+
};
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
//#endregion
|
|
1093
|
+
//#region src/panoptic/v2/reads/checks.ts
|
|
1094
|
+
const FP96 = 1n << 96n;
|
|
1095
|
+
const Q128 = 1n << 128n;
|
|
1096
|
+
function convert0to1(amount, sqrtPriceX96) {
|
|
1097
|
+
if (sqrtPriceX96 < Q128) return amount * sqrtPriceX96 * sqrtPriceX96 >> 192n;
|
|
1098
|
+
const sp2Hi = sqrtPriceX96 * sqrtPriceX96 >> 64n;
|
|
1099
|
+
return amount * sp2Hi >> 128n;
|
|
1100
|
+
}
|
|
1101
|
+
function convert1to0(amount, sqrtPriceX96) {
|
|
1102
|
+
if (sqrtPriceX96 < Q128) {
|
|
1103
|
+
const denom = sqrtPriceX96 * sqrtPriceX96;
|
|
1104
|
+
return amount * (1n << 192n) / denom;
|
|
1105
|
+
}
|
|
1106
|
+
const sp2Hi = sqrtPriceX96 * sqrtPriceX96 >> 64n;
|
|
1107
|
+
return amount * (1n << 128n) / sp2Hi;
|
|
1108
|
+
}
|
|
1109
|
+
/**
|
|
1110
|
+
* Check if an account is liquidatable with detailed margin breakdown.
|
|
1111
|
+
*
|
|
1112
|
+
* Sources gross collateral from `CollateralTracker.assetsOf` and per-position
|
|
1113
|
+
* required margin from `PanopticPool.getFullPositionsData.collateralRequirements[]`,
|
|
1114
|
+
* cross-converted to each token denomination at `atTick`. Loan tokenIds
|
|
1115
|
+
* (width=0 shorts) contribute correctly to required margin.
|
|
1116
|
+
*
|
|
1117
|
+
* @param params - The parameters
|
|
1118
|
+
* @returns Liquidation check result with detailed margin breakdown
|
|
1119
|
+
*
|
|
1120
|
+
* @example
|
|
1121
|
+
* ```typescript
|
|
1122
|
+
* const result = await isLiquidatable({
|
|
1123
|
+
* client,
|
|
1124
|
+
* poolAddress,
|
|
1125
|
+
* account,
|
|
1126
|
+
* tokenIds: [position1, position2],
|
|
1127
|
+
* })
|
|
1128
|
+
*
|
|
1129
|
+
* if (result.isLiquidatable) {
|
|
1130
|
+
* console.log('Account is liquidatable!')
|
|
1131
|
+
* }
|
|
1132
|
+
* ```
|
|
1133
|
+
*/
|
|
1134
|
+
async function isLiquidatable(params) {
|
|
1135
|
+
const { client, poolAddress, account, tokenIds, atTick, blockNumber } = params;
|
|
1136
|
+
const targetBlockNumber = blockNumber ?? params._meta?.blockNumber ?? await client.getBlockNumber();
|
|
1137
|
+
let collateralToken0;
|
|
1138
|
+
let collateralToken1;
|
|
1139
|
+
if (params.collateralAddresses) {
|
|
1140
|
+
collateralToken0 = params.collateralAddresses.collateralToken0;
|
|
1141
|
+
collateralToken1 = params.collateralAddresses.collateralToken1;
|
|
1142
|
+
} else {
|
|
1143
|
+
const addrs = await client.multicall({
|
|
1144
|
+
contracts: [{
|
|
1145
|
+
address: poolAddress,
|
|
1146
|
+
abi: panopticPoolV2Abi,
|
|
1147
|
+
functionName: "collateralToken0"
|
|
1148
|
+
}, {
|
|
1149
|
+
address: poolAddress,
|
|
1150
|
+
abi: panopticPoolV2Abi,
|
|
1151
|
+
functionName: "collateralToken1"
|
|
1152
|
+
}],
|
|
1153
|
+
blockNumber: targetBlockNumber,
|
|
1154
|
+
allowFailure: false
|
|
1155
|
+
});
|
|
1156
|
+
collateralToken0 = addrs[0];
|
|
1157
|
+
collateralToken1 = addrs[1];
|
|
1158
|
+
}
|
|
1159
|
+
const calls = [];
|
|
1160
|
+
const currentTickIndex = atTick === void 0 ? calls.length : null;
|
|
1161
|
+
if (currentTickIndex !== null) calls.push({
|
|
1162
|
+
target: poolAddress,
|
|
1163
|
+
callData: encodeFunctionData({
|
|
1164
|
+
abi: panopticPoolV2Abi,
|
|
1165
|
+
functionName: "getCurrentTick"
|
|
1166
|
+
})
|
|
1167
|
+
});
|
|
1168
|
+
const assets0Index = calls.length;
|
|
1169
|
+
calls.push({
|
|
1170
|
+
target: collateralToken0,
|
|
1171
|
+
callData: encodeFunctionData({
|
|
1172
|
+
abi: collateralTrackerV2Abi,
|
|
1173
|
+
functionName: "assetsOf",
|
|
1174
|
+
args: [account]
|
|
1175
|
+
})
|
|
1176
|
+
});
|
|
1177
|
+
const assets1Index = calls.length;
|
|
1178
|
+
calls.push({
|
|
1179
|
+
target: collateralToken1,
|
|
1180
|
+
callData: encodeFunctionData({
|
|
1181
|
+
abi: collateralTrackerV2Abi,
|
|
1182
|
+
functionName: "assetsOf",
|
|
1183
|
+
args: [account]
|
|
1184
|
+
})
|
|
1185
|
+
});
|
|
1186
|
+
const positionDataIndex = tokenIds.length > 0 ? calls.length : null;
|
|
1187
|
+
if (positionDataIndex !== null) calls.push({
|
|
1188
|
+
target: poolAddress,
|
|
1189
|
+
callData: encodeFunctionData({
|
|
1190
|
+
abi: panopticPoolV2Abi,
|
|
1191
|
+
functionName: "getFullPositionsData",
|
|
1192
|
+
args: [
|
|
1193
|
+
account,
|
|
1194
|
+
true,
|
|
1195
|
+
tokenIds
|
|
1196
|
+
]
|
|
1197
|
+
})
|
|
1198
|
+
});
|
|
1199
|
+
const { _meta, results } = await readBlockAndAggregate({
|
|
1200
|
+
client,
|
|
1201
|
+
calls,
|
|
1202
|
+
blockNumber: targetBlockNumber
|
|
1203
|
+
});
|
|
1204
|
+
let effectiveTick = atTick;
|
|
1205
|
+
if (effectiveTick === void 0) {
|
|
1206
|
+
if (currentTickIndex === null) throw new Error("Missing current tick Multicall3 result index");
|
|
1207
|
+
effectiveTick = BigInt(decodeFunctionResult({
|
|
1208
|
+
abi: panopticPoolV2Abi,
|
|
1209
|
+
functionName: "getCurrentTick",
|
|
1210
|
+
data: requireReturnData(results, currentTickIndex, "PanopticPool.getCurrentTick")
|
|
1211
|
+
}));
|
|
1212
|
+
}
|
|
1213
|
+
const assets0 = decodeFunctionResult({
|
|
1214
|
+
abi: collateralTrackerV2Abi,
|
|
1215
|
+
functionName: "assetsOf",
|
|
1216
|
+
data: requireReturnData(results, assets0Index, "CollateralTracker.assetsOf token0")
|
|
1217
|
+
});
|
|
1218
|
+
const assets1 = decodeFunctionResult({
|
|
1219
|
+
abi: collateralTrackerV2Abi,
|
|
1220
|
+
functionName: "assetsOf",
|
|
1221
|
+
data: requireReturnData(results, assets1Index, "CollateralTracker.assetsOf token1")
|
|
1222
|
+
});
|
|
1223
|
+
const positionDataResult = positionDataIndex === null ? null : decodeFunctionResult({
|
|
1224
|
+
abi: panopticPoolV2Abi,
|
|
1225
|
+
functionName: "getFullPositionsData",
|
|
1226
|
+
data: requireReturnData(results, positionDataIndex, "PanopticPool.getFullPositionsData")
|
|
1227
|
+
});
|
|
1228
|
+
let required0Native = 0n;
|
|
1229
|
+
let required1Native = 0n;
|
|
1230
|
+
if (positionDataResult) {
|
|
1231
|
+
const collateralRequirements = positionDataResult[3];
|
|
1232
|
+
for (const packed of collateralRequirements) {
|
|
1233
|
+
const decoded = decodeLeftRightUnsigned(packed);
|
|
1234
|
+
required0Native += decoded.right;
|
|
1235
|
+
required1Native += decoded.left;
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
const sqrtPriceX96 = tickToSqrtPriceX96(effectiveTick);
|
|
1239
|
+
const currentMargin0 = assets0 + convert1to0(assets1, sqrtPriceX96);
|
|
1240
|
+
const requiredMargin0 = required0Native + convert1to0(required1Native, sqrtPriceX96);
|
|
1241
|
+
const currentMargin1 = assets1 + convert0to1(assets0, sqrtPriceX96);
|
|
1242
|
+
const requiredMargin1 = required1Native + convert0to1(required0Native, sqrtPriceX96);
|
|
1243
|
+
const marginShortfall0 = requiredMargin0 - currentMargin0;
|
|
1244
|
+
const marginShortfall1 = requiredMargin1 - currentMargin1;
|
|
1245
|
+
const denominatedInToken = sqrtPriceX96 < FP96 ? 0n : 1n;
|
|
1246
|
+
const isLiquidatableResult = denominatedInToken === 0n ? marginShortfall0 > 0n : marginShortfall1 > 0n;
|
|
1247
|
+
return {
|
|
1248
|
+
isLiquidatable: isLiquidatableResult,
|
|
1249
|
+
marginShortfall0,
|
|
1250
|
+
marginShortfall1,
|
|
1251
|
+
currentMargin0,
|
|
1252
|
+
currentMargin1,
|
|
1253
|
+
requiredMargin0,
|
|
1254
|
+
requiredMargin1,
|
|
1255
|
+
denominatedInToken,
|
|
1256
|
+
atTick: effectiveTick,
|
|
1257
|
+
_meta
|
|
1258
|
+
};
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
//#endregion
|
|
1262
|
+
//#region src/panoptic/v2/reads/account.ts
|
|
1263
|
+
/**
|
|
1264
|
+
* Extract collateral tracker addresses from a Pool object.
|
|
1265
|
+
*
|
|
1266
|
+
* Convenience helper that avoids re-fetching immutable addresses
|
|
1267
|
+
* when you already have a Pool from a prior `getPool()` call.
|
|
1268
|
+
*
|
|
1269
|
+
* @param pool - Pool object from getPool()
|
|
1270
|
+
* @returns Collateral tracker addresses
|
|
1271
|
+
*/
|
|
1272
|
+
function getCollateralAddresses(pool) {
|
|
1273
|
+
return {
|
|
1274
|
+
collateralToken0: pool.collateralTracker0.address,
|
|
1275
|
+
collateralToken1: pool.collateralTracker1.address
|
|
1276
|
+
};
|
|
1277
|
+
}
|
|
1278
|
+
/**
|
|
1279
|
+
* Get collateral data for an account.
|
|
1280
|
+
*
|
|
1281
|
+
* ## Same-Block Guarantee
|
|
1282
|
+
* All dynamic data is fetched in ONE multicall at the target block.
|
|
1283
|
+
* Collateral tracker addresses are either provided or fetched separately (static prefetch).
|
|
1284
|
+
*
|
|
1285
|
+
* @param params - The parameters
|
|
1286
|
+
* @returns Account collateral data with block metadata
|
|
1287
|
+
*/
|
|
1288
|
+
async function getAccountCollateral(params) {
|
|
1289
|
+
const { client, poolAddress, account, blockNumber, collateralAddresses } = params;
|
|
1290
|
+
const targetBlockNumber = blockNumber ?? params._meta?.blockNumber ?? await client.getBlockNumber();
|
|
1291
|
+
let collateralToken0;
|
|
1292
|
+
let collateralToken1;
|
|
1293
|
+
if (collateralAddresses) {
|
|
1294
|
+
collateralToken0 = collateralAddresses.collateralToken0;
|
|
1295
|
+
collateralToken1 = collateralAddresses.collateralToken1;
|
|
1296
|
+
} else {
|
|
1297
|
+
const addressResults = await client.multicall({
|
|
1298
|
+
contracts: [{
|
|
1299
|
+
address: poolAddress,
|
|
1300
|
+
abi: panopticPoolV2Abi,
|
|
1301
|
+
functionName: "collateralToken0"
|
|
1302
|
+
}, {
|
|
1303
|
+
address: poolAddress,
|
|
1304
|
+
abi: panopticPoolV2Abi,
|
|
1305
|
+
functionName: "collateralToken1"
|
|
1306
|
+
}],
|
|
1307
|
+
allowFailure: false
|
|
1308
|
+
});
|
|
1309
|
+
collateralToken0 = addressResults[0];
|
|
1310
|
+
collateralToken1 = addressResults[1];
|
|
1311
|
+
}
|
|
1312
|
+
const [dynamicResults, _meta] = await Promise.all([client.multicall({
|
|
1313
|
+
contracts: [
|
|
1314
|
+
{
|
|
1315
|
+
address: collateralToken0,
|
|
1316
|
+
abi: collateralTrackerV2Abi,
|
|
1317
|
+
functionName: "balanceOf",
|
|
1318
|
+
args: [account]
|
|
1319
|
+
},
|
|
1320
|
+
{
|
|
1321
|
+
address: collateralToken0,
|
|
1322
|
+
abi: collateralTrackerV2Abi,
|
|
1323
|
+
functionName: "assetsOf",
|
|
1324
|
+
args: [account]
|
|
1325
|
+
},
|
|
1326
|
+
{
|
|
1327
|
+
address: collateralToken0,
|
|
1328
|
+
abi: collateralTrackerV2Abi,
|
|
1329
|
+
functionName: "maxWithdraw",
|
|
1330
|
+
args: [account]
|
|
1331
|
+
},
|
|
1332
|
+
{
|
|
1333
|
+
address: collateralToken1,
|
|
1334
|
+
abi: collateralTrackerV2Abi,
|
|
1335
|
+
functionName: "balanceOf",
|
|
1336
|
+
args: [account]
|
|
1337
|
+
},
|
|
1338
|
+
{
|
|
1339
|
+
address: collateralToken1,
|
|
1340
|
+
abi: collateralTrackerV2Abi,
|
|
1341
|
+
functionName: "assetsOf",
|
|
1342
|
+
args: [account]
|
|
1343
|
+
},
|
|
1344
|
+
{
|
|
1345
|
+
address: collateralToken1,
|
|
1346
|
+
abi: collateralTrackerV2Abi,
|
|
1347
|
+
functionName: "maxWithdraw",
|
|
1348
|
+
args: [account]
|
|
1349
|
+
},
|
|
1350
|
+
{
|
|
1351
|
+
address: poolAddress,
|
|
1352
|
+
abi: panopticPoolV2Abi,
|
|
1353
|
+
functionName: "numberOfLegs",
|
|
1354
|
+
args: [account]
|
|
1355
|
+
}
|
|
1356
|
+
],
|
|
1357
|
+
blockNumber: targetBlockNumber,
|
|
1358
|
+
allowFailure: false
|
|
1359
|
+
}), params._meta ?? getBlockMeta({
|
|
1360
|
+
client,
|
|
1361
|
+
blockNumber: targetBlockNumber
|
|
1362
|
+
})]);
|
|
1363
|
+
const [shares0, assets0, maxWithdraw0, shares1, assets1, maxWithdraw1, legCount] = dynamicResults;
|
|
1364
|
+
const locked0 = assets0 > maxWithdraw0 ? assets0 - maxWithdraw0 : 0n;
|
|
1365
|
+
const locked1 = assets1 > maxWithdraw1 ? assets1 - maxWithdraw1 : 0n;
|
|
1366
|
+
const token0 = {
|
|
1367
|
+
assets: assets0,
|
|
1368
|
+
shares: shares0,
|
|
1369
|
+
availableAssets: maxWithdraw0,
|
|
1370
|
+
lockedAssets: locked0
|
|
1371
|
+
};
|
|
1372
|
+
const token1 = {
|
|
1373
|
+
assets: assets1,
|
|
1374
|
+
shares: shares1,
|
|
1375
|
+
availableAssets: maxWithdraw1,
|
|
1376
|
+
lockedAssets: locked1
|
|
1377
|
+
};
|
|
1378
|
+
return {
|
|
1379
|
+
account,
|
|
1380
|
+
poolAddress,
|
|
1381
|
+
token0,
|
|
1382
|
+
token1,
|
|
1383
|
+
legCount,
|
|
1384
|
+
_meta
|
|
1385
|
+
};
|
|
1386
|
+
}
|
|
1387
|
+
async function getAccountSummaryCore(params) {
|
|
1388
|
+
const { client, poolAddress, account, chainId, tokenIds, blockNumber, poolMetadata } = params;
|
|
1389
|
+
const targetBlockNumber = blockNumber ?? params._meta?.blockNumber ?? await client.getBlockNumber();
|
|
1390
|
+
const sharedMeta = params._meta ?? await getBlockMeta({
|
|
1391
|
+
client,
|
|
1392
|
+
blockNumber: targetBlockNumber
|
|
1393
|
+
});
|
|
1394
|
+
const collateralAddresses = poolMetadata ? {
|
|
1395
|
+
collateralToken0: poolMetadata.collateralToken0Address,
|
|
1396
|
+
collateralToken1: poolMetadata.collateralToken1Address
|
|
1397
|
+
} : void 0;
|
|
1398
|
+
const [pool, collateral, { positions }] = await Promise.all([
|
|
1399
|
+
getPool({
|
|
1400
|
+
client,
|
|
1401
|
+
poolAddress,
|
|
1402
|
+
chainId,
|
|
1403
|
+
blockNumber: targetBlockNumber,
|
|
1404
|
+
poolMetadata,
|
|
1405
|
+
_meta: sharedMeta
|
|
1406
|
+
}),
|
|
1407
|
+
getAccountCollateral({
|
|
1408
|
+
client,
|
|
1409
|
+
poolAddress,
|
|
1410
|
+
account,
|
|
1411
|
+
blockNumber: targetBlockNumber,
|
|
1412
|
+
collateralAddresses,
|
|
1413
|
+
_meta: sharedMeta
|
|
1414
|
+
}),
|
|
1415
|
+
getPositions({
|
|
1416
|
+
client,
|
|
1417
|
+
poolAddress,
|
|
1418
|
+
owner: account,
|
|
1419
|
+
tokenIds,
|
|
1420
|
+
blockNumber: targetBlockNumber,
|
|
1421
|
+
_meta: sharedMeta
|
|
1422
|
+
})
|
|
1423
|
+
]);
|
|
1424
|
+
return {
|
|
1425
|
+
pool,
|
|
1426
|
+
collateral,
|
|
1427
|
+
positions,
|
|
1428
|
+
_meta: sharedMeta
|
|
1429
|
+
};
|
|
1430
|
+
}
|
|
1431
|
+
/**
|
|
1432
|
+
* Get base account summary data for UI dashboards.
|
|
1433
|
+
*
|
|
1434
|
+
* ## Same-Block Guarantee
|
|
1435
|
+
* Uses the same blockNumber for pool, collateral, and position reads.
|
|
1436
|
+
*
|
|
1437
|
+
* @param params - The parameters
|
|
1438
|
+
* @returns Base account summary with block metadata
|
|
1439
|
+
*/
|
|
1440
|
+
async function getAccountSummaryBasic(params) {
|
|
1441
|
+
const { account } = params;
|
|
1442
|
+
const { pool, collateral, positions, _meta } = await getAccountSummaryCore(params);
|
|
1443
|
+
return {
|
|
1444
|
+
account,
|
|
1445
|
+
pool,
|
|
1446
|
+
collateral,
|
|
1447
|
+
positions,
|
|
1448
|
+
healthStatus: pool.healthStatus,
|
|
1449
|
+
networkMismatch: false,
|
|
1450
|
+
_meta
|
|
1451
|
+
};
|
|
1452
|
+
}
|
|
1453
|
+
/**
|
|
1454
|
+
* Get risk-focused account summary including helper-dependent fields.
|
|
1455
|
+
*
|
|
1456
|
+
* ## Same-Block Guarantee
|
|
1457
|
+
* Uses one block target for all pool/collateral/position/risk reads.
|
|
1458
|
+
*
|
|
1459
|
+
* @param params - The parameters
|
|
1460
|
+
* @returns Risk-focused account summary with block metadata
|
|
1461
|
+
*/
|
|
1462
|
+
async function getAccountSummaryRisk(params) {
|
|
1463
|
+
const { client, poolAddress, account, tokenIds, queryAddress, atTick, includePendingPremium = true, blockNumber } = params;
|
|
1464
|
+
const targetBlockNumber = blockNumber ?? params._meta?.blockNumber ?? await client.getBlockNumber();
|
|
1465
|
+
const sharedMeta = params._meta ?? await getBlockMeta({
|
|
1466
|
+
client,
|
|
1467
|
+
blockNumber: targetBlockNumber
|
|
1468
|
+
});
|
|
1469
|
+
const [{ pool, collateral, positions }, nlv, liquidationCheck, liquidationPrices] = await Promise.all([
|
|
1470
|
+
getAccountSummaryCore({
|
|
1471
|
+
...params,
|
|
1472
|
+
blockNumber: targetBlockNumber,
|
|
1473
|
+
_meta: sharedMeta
|
|
1474
|
+
}),
|
|
1475
|
+
getNetLiquidationValue({
|
|
1476
|
+
client,
|
|
1477
|
+
poolAddress,
|
|
1478
|
+
account,
|
|
1479
|
+
tokenIds,
|
|
1480
|
+
atTick,
|
|
1481
|
+
includePendingPremium,
|
|
1482
|
+
queryAddress,
|
|
1483
|
+
blockNumber: targetBlockNumber,
|
|
1484
|
+
_meta: sharedMeta
|
|
1485
|
+
}),
|
|
1486
|
+
isLiquidatable({
|
|
1487
|
+
client,
|
|
1488
|
+
poolAddress,
|
|
1489
|
+
account,
|
|
1490
|
+
tokenIds,
|
|
1491
|
+
atTick,
|
|
1492
|
+
queryAddress,
|
|
1493
|
+
blockNumber: targetBlockNumber,
|
|
1494
|
+
_meta: sharedMeta
|
|
1495
|
+
}),
|
|
1496
|
+
getLiquidationPrices({
|
|
1497
|
+
client,
|
|
1498
|
+
poolAddress,
|
|
1499
|
+
account,
|
|
1500
|
+
tokenIds,
|
|
1501
|
+
queryAddress,
|
|
1502
|
+
blockNumber: targetBlockNumber,
|
|
1503
|
+
_meta: sharedMeta
|
|
1504
|
+
})
|
|
1505
|
+
]);
|
|
1506
|
+
const totalGreeks = {
|
|
1507
|
+
value: 0n,
|
|
1508
|
+
delta: 0n,
|
|
1509
|
+
gamma: 0n
|
|
1510
|
+
};
|
|
1511
|
+
const maintenanceMargin0 = liquidationCheck.requiredMargin0;
|
|
1512
|
+
const maintenanceMargin1 = liquidationCheck.requiredMargin1;
|
|
1513
|
+
const marginExcess0 = liquidationCheck.currentMargin0 - liquidationCheck.requiredMargin0;
|
|
1514
|
+
const marginExcess1 = liquidationCheck.currentMargin1 - liquidationCheck.requiredMargin1;
|
|
1515
|
+
return {
|
|
1516
|
+
account,
|
|
1517
|
+
pool,
|
|
1518
|
+
collateral,
|
|
1519
|
+
positions,
|
|
1520
|
+
totalGreeks,
|
|
1521
|
+
netLiquidationValue0: nlv.value0,
|
|
1522
|
+
netLiquidationValue1: nlv.value1,
|
|
1523
|
+
maintenanceMargin0,
|
|
1524
|
+
maintenanceMargin1,
|
|
1525
|
+
marginExcess0,
|
|
1526
|
+
marginExcess1,
|
|
1527
|
+
marginShortfall0: liquidationCheck.marginShortfall0,
|
|
1528
|
+
marginShortfall1: liquidationCheck.marginShortfall1,
|
|
1529
|
+
currentMargin0: liquidationCheck.currentMargin0,
|
|
1530
|
+
currentMargin1: liquidationCheck.currentMargin1,
|
|
1531
|
+
isLiquidatable: liquidationCheck.isLiquidatable,
|
|
1532
|
+
liquidationPrices,
|
|
1533
|
+
healthStatus: pool.healthStatus,
|
|
1534
|
+
networkMismatch: false,
|
|
1535
|
+
_meta: sharedMeta
|
|
1536
|
+
};
|
|
1537
|
+
}
|
|
1538
|
+
/**
|
|
1539
|
+
* Get net liquidation value for an account.
|
|
1540
|
+
*
|
|
1541
|
+
* ## Same-Block Guarantee
|
|
1542
|
+
* Tick and NLV are queried at the same target block.
|
|
1543
|
+
*
|
|
1544
|
+
* Requires PanopticQuery for accurate value and premium accounting.
|
|
1545
|
+
*
|
|
1546
|
+
* @param params - The parameters
|
|
1547
|
+
* @returns Net liquidation value with block metadata
|
|
1548
|
+
*/
|
|
1549
|
+
async function getNetLiquidationValue(params) {
|
|
1550
|
+
const { client, poolAddress, account, tokenIds, atTick, includePendingPremium = true, queryAddress, blockNumber } = params;
|
|
1551
|
+
const targetBlockNumber = blockNumber ?? params._meta?.blockNumber ?? await client.getBlockNumber();
|
|
1552
|
+
const [currentTickResult, _meta] = await Promise.all([atTick != null ? Promise.resolve(atTick) : client.readContract({
|
|
1553
|
+
address: poolAddress,
|
|
1554
|
+
abi: panopticPoolV2Abi,
|
|
1555
|
+
functionName: "getCurrentTick",
|
|
1556
|
+
blockNumber: targetBlockNumber
|
|
1557
|
+
}).then((r) => BigInt(r)), params._meta ?? getBlockMeta({
|
|
1558
|
+
client,
|
|
1559
|
+
blockNumber: targetBlockNumber
|
|
1560
|
+
})]);
|
|
1561
|
+
const effectiveTick = currentTickResult;
|
|
1562
|
+
const result = await client.readContract({
|
|
1563
|
+
address: queryAddress,
|
|
1564
|
+
abi: panopticQueryAbi,
|
|
1565
|
+
functionName: "getNetLiquidationValue",
|
|
1566
|
+
args: [
|
|
1567
|
+
poolAddress,
|
|
1568
|
+
account,
|
|
1569
|
+
includePendingPremium,
|
|
1570
|
+
tokenIds,
|
|
1571
|
+
Number(effectiveTick)
|
|
1572
|
+
],
|
|
1573
|
+
blockNumber: targetBlockNumber
|
|
1574
|
+
});
|
|
1575
|
+
const [value0, value1] = result;
|
|
1576
|
+
return {
|
|
1577
|
+
value0,
|
|
1578
|
+
value1,
|
|
1579
|
+
atTick: effectiveTick,
|
|
1580
|
+
includedPendingPremium: includePendingPremium,
|
|
1581
|
+
_meta
|
|
1582
|
+
};
|
|
1583
|
+
}
|
|
1584
|
+
/**
|
|
1585
|
+
* Get net liquidation values at multiple ticks in a single contract call.
|
|
1586
|
+
*
|
|
1587
|
+
* Uses the `int24[]` overload of `getNetLiquidationValue` on PanopticQuery.
|
|
1588
|
+
*
|
|
1589
|
+
* @param params - The parameters
|
|
1590
|
+
* @returns Net liquidation values with block metadata
|
|
1591
|
+
*/
|
|
1592
|
+
async function getNetLiquidationValues(params) {
|
|
1593
|
+
const { client, poolAddress, account, tokenIds, atTicks, includePendingPremium = true, queryAddress, blockNumber } = params;
|
|
1594
|
+
const targetBlockNumber = blockNumber ?? params._meta?.blockNumber ?? await client.getBlockNumber();
|
|
1595
|
+
const batchNlvAbi = [{
|
|
1596
|
+
type: "function",
|
|
1597
|
+
name: "getNetLiquidationValue",
|
|
1598
|
+
inputs: [
|
|
1599
|
+
{
|
|
1600
|
+
name: "pool",
|
|
1601
|
+
type: "address"
|
|
1602
|
+
},
|
|
1603
|
+
{
|
|
1604
|
+
name: "account",
|
|
1605
|
+
type: "address"
|
|
1606
|
+
},
|
|
1607
|
+
{
|
|
1608
|
+
name: "includePendingPremium",
|
|
1609
|
+
type: "bool"
|
|
1610
|
+
},
|
|
1611
|
+
{
|
|
1612
|
+
name: "positionIdList",
|
|
1613
|
+
type: "uint256[]"
|
|
1614
|
+
},
|
|
1615
|
+
{
|
|
1616
|
+
name: "atTicks",
|
|
1617
|
+
type: "int24[]"
|
|
1618
|
+
}
|
|
1619
|
+
],
|
|
1620
|
+
outputs: [{
|
|
1621
|
+
name: "value0",
|
|
1622
|
+
type: "int256[]"
|
|
1623
|
+
}, {
|
|
1624
|
+
name: "value1",
|
|
1625
|
+
type: "int256[]"
|
|
1626
|
+
}],
|
|
1627
|
+
stateMutability: "view"
|
|
1628
|
+
}];
|
|
1629
|
+
const [result, _meta] = await Promise.all([client.readContract({
|
|
1630
|
+
address: queryAddress,
|
|
1631
|
+
abi: batchNlvAbi,
|
|
1632
|
+
functionName: "getNetLiquidationValue",
|
|
1633
|
+
args: [
|
|
1634
|
+
poolAddress,
|
|
1635
|
+
account,
|
|
1636
|
+
includePendingPremium,
|
|
1637
|
+
tokenIds,
|
|
1638
|
+
atTicks.map((t) => Number(t))
|
|
1639
|
+
],
|
|
1640
|
+
blockNumber: targetBlockNumber
|
|
1641
|
+
}), params._meta ?? getBlockMeta({
|
|
1642
|
+
client,
|
|
1643
|
+
blockNumber: targetBlockNumber
|
|
1644
|
+
})]);
|
|
1645
|
+
const [values0, values1] = result;
|
|
1646
|
+
return {
|
|
1647
|
+
values0: [...values0],
|
|
1648
|
+
values1: [...values1],
|
|
1649
|
+
atTicks,
|
|
1650
|
+
_meta
|
|
1651
|
+
};
|
|
1652
|
+
}
|
|
1653
|
+
/**
|
|
1654
|
+
* Get liquidation prices for an account.
|
|
1655
|
+
*
|
|
1656
|
+
* ## Same-Block Guarantee
|
|
1657
|
+
* Liquidation price query is made at a single block.
|
|
1658
|
+
*
|
|
1659
|
+
* @param params - The parameters
|
|
1660
|
+
* @returns Liquidation prices with block metadata
|
|
1661
|
+
*/
|
|
1662
|
+
async function getLiquidationPrices(params) {
|
|
1663
|
+
const { client, poolAddress, account, tokenIds, queryAddress, blockNumber } = params;
|
|
1664
|
+
const targetBlockNumber = blockNumber ?? params._meta?.blockNumber ?? await client.getBlockNumber();
|
|
1665
|
+
const MIN_TICK = -887272n;
|
|
1666
|
+
const MAX_TICK = 887272n;
|
|
1667
|
+
const [result, _meta] = await Promise.all([client.readContract({
|
|
1668
|
+
address: queryAddress,
|
|
1669
|
+
abi: panopticQueryAbi,
|
|
1670
|
+
functionName: "getLiquidationPrices",
|
|
1671
|
+
args: [
|
|
1672
|
+
poolAddress,
|
|
1673
|
+
account,
|
|
1674
|
+
tokenIds
|
|
1675
|
+
],
|
|
1676
|
+
blockNumber: targetBlockNumber
|
|
1677
|
+
}), params._meta ?? getBlockMeta({
|
|
1678
|
+
client,
|
|
1679
|
+
blockNumber: targetBlockNumber
|
|
1680
|
+
})]);
|
|
1681
|
+
const liqPriceDown = BigInt(result[0]);
|
|
1682
|
+
const liqPriceUp = BigInt(result[1]);
|
|
1683
|
+
return {
|
|
1684
|
+
lowerTick: liqPriceDown === MIN_TICK ? null : liqPriceDown,
|
|
1685
|
+
upperTick: liqPriceUp === MAX_TICK ? null : liqPriceUp,
|
|
1686
|
+
isLiquidatable: liqPriceDown !== MIN_TICK || liqPriceUp !== MAX_TICK,
|
|
1687
|
+
_meta
|
|
1688
|
+
};
|
|
1689
|
+
}
|
|
1690
|
+
|
|
1691
|
+
//#endregion
|
|
1692
|
+
//#region src/panoptic/v2/reads/collateral.ts
|
|
1693
|
+
const SECONDS_PER_YEAR$2 = 31536000n;
|
|
1694
|
+
const erc20Abi$1 = [{
|
|
1695
|
+
type: "function",
|
|
1696
|
+
name: "symbol",
|
|
1697
|
+
inputs: [],
|
|
1698
|
+
outputs: [{ type: "string" }],
|
|
1699
|
+
stateMutability: "view"
|
|
1700
|
+
}, {
|
|
1701
|
+
type: "function",
|
|
1702
|
+
name: "decimals",
|
|
1703
|
+
inputs: [],
|
|
1704
|
+
outputs: [{ type: "uint8" }],
|
|
1705
|
+
stateMutability: "view"
|
|
1706
|
+
}];
|
|
1707
|
+
/**
|
|
1708
|
+
* Get collateral tracker data for a specific token.
|
|
1709
|
+
*
|
|
1710
|
+
* ## Same-Block Guarantee
|
|
1711
|
+
* All dynamic data is fetched in ONE multicall at the target block.
|
|
1712
|
+
* Static metadata (address, symbol, decimals) is either provided or fetched separately.
|
|
1713
|
+
*
|
|
1714
|
+
* @param params - The parameters
|
|
1715
|
+
* @returns Collateral tracker data with block metadata
|
|
1716
|
+
*/
|
|
1717
|
+
async function getCollateralData(params) {
|
|
1718
|
+
const { client, poolAddress, tokenIndex, blockNumber, trackerMetadata } = params;
|
|
1719
|
+
const targetBlockNumber = blockNumber ?? params._meta?.blockNumber ?? await client.getBlockNumber();
|
|
1720
|
+
if (trackerMetadata) {
|
|
1721
|
+
const [dynamicResults, _meta$1] = await Promise.all([client.multicall({
|
|
1722
|
+
contracts: [
|
|
1723
|
+
{
|
|
1724
|
+
address: trackerMetadata.address,
|
|
1725
|
+
abi: collateralTrackerV2Abi,
|
|
1726
|
+
functionName: "getPoolData"
|
|
1727
|
+
},
|
|
1728
|
+
{
|
|
1729
|
+
address: trackerMetadata.address,
|
|
1730
|
+
abi: collateralTrackerV2Abi,
|
|
1731
|
+
functionName: "totalSupply"
|
|
1732
|
+
},
|
|
1733
|
+
{
|
|
1734
|
+
address: trackerMetadata.address,
|
|
1735
|
+
abi: collateralTrackerV2Abi,
|
|
1736
|
+
functionName: "interestRate"
|
|
1737
|
+
}
|
|
1738
|
+
],
|
|
1739
|
+
blockNumber: targetBlockNumber,
|
|
1740
|
+
allowFailure: false
|
|
1741
|
+
}), params._meta ?? getBlockMeta({
|
|
1742
|
+
client,
|
|
1743
|
+
blockNumber: targetBlockNumber
|
|
1744
|
+
})]);
|
|
1745
|
+
const [poolData$1, totalShares$1, interestRate$1] = dynamicResults;
|
|
1746
|
+
const [depositedAssets$1, insideAMM$1, creditedShares$1, utilization$1] = poolData$1;
|
|
1747
|
+
const totalAssets$1 = depositedAssets$1 + insideAMM$1;
|
|
1748
|
+
const borrowRate$1 = BigInt(interestRate$1) * SECONDS_PER_YEAR$2;
|
|
1749
|
+
const supplyRate$1 = borrowRate$1 * utilization$1 / 10000n;
|
|
1750
|
+
return {
|
|
1751
|
+
address: trackerMetadata.address,
|
|
1752
|
+
token: trackerMetadata.assetAddress,
|
|
1753
|
+
symbol: trackerMetadata.symbol,
|
|
1754
|
+
decimals: trackerMetadata.decimals,
|
|
1755
|
+
totalAssets: totalAssets$1,
|
|
1756
|
+
insideAMM: insideAMM$1,
|
|
1757
|
+
creditedShares: creditedShares$1,
|
|
1758
|
+
totalShares: totalShares$1,
|
|
1759
|
+
utilization: utilization$1,
|
|
1760
|
+
borrowRate: borrowRate$1,
|
|
1761
|
+
supplyRate: supplyRate$1,
|
|
1762
|
+
_meta: _meta$1
|
|
1763
|
+
};
|
|
1764
|
+
}
|
|
1765
|
+
const collateralTrackerAddress = await client.readContract({
|
|
1766
|
+
address: poolAddress,
|
|
1767
|
+
abi: panopticPoolV2Abi,
|
|
1768
|
+
functionName: tokenIndex === 0 ? "collateralToken0" : "collateralToken1"
|
|
1769
|
+
});
|
|
1770
|
+
const [trackerData, _meta] = await Promise.all([client.multicall({
|
|
1771
|
+
contracts: [
|
|
1772
|
+
{
|
|
1773
|
+
address: collateralTrackerAddress,
|
|
1774
|
+
abi: collateralTrackerV2Abi,
|
|
1775
|
+
functionName: "asset"
|
|
1776
|
+
},
|
|
1777
|
+
{
|
|
1778
|
+
address: collateralTrackerAddress,
|
|
1779
|
+
abi: collateralTrackerV2Abi,
|
|
1780
|
+
functionName: "getPoolData"
|
|
1781
|
+
},
|
|
1782
|
+
{
|
|
1783
|
+
address: collateralTrackerAddress,
|
|
1784
|
+
abi: collateralTrackerV2Abi,
|
|
1785
|
+
functionName: "totalSupply"
|
|
1786
|
+
},
|
|
1787
|
+
{
|
|
1788
|
+
address: collateralTrackerAddress,
|
|
1789
|
+
abi: collateralTrackerV2Abi,
|
|
1790
|
+
functionName: "interestRate"
|
|
1791
|
+
}
|
|
1792
|
+
],
|
|
1793
|
+
blockNumber: targetBlockNumber,
|
|
1794
|
+
allowFailure: false
|
|
1795
|
+
}), params._meta ?? getBlockMeta({
|
|
1796
|
+
client,
|
|
1797
|
+
blockNumber: targetBlockNumber
|
|
1798
|
+
})]);
|
|
1799
|
+
const [assetAddress, poolData, totalShares, interestRate] = trackerData;
|
|
1800
|
+
const [symbol, decimals] = await client.multicall({
|
|
1801
|
+
contracts: [{
|
|
1802
|
+
address: assetAddress,
|
|
1803
|
+
abi: erc20Abi$1,
|
|
1804
|
+
functionName: "symbol"
|
|
1805
|
+
}, {
|
|
1806
|
+
address: assetAddress,
|
|
1807
|
+
abi: erc20Abi$1,
|
|
1808
|
+
functionName: "decimals"
|
|
1809
|
+
}],
|
|
1810
|
+
allowFailure: false
|
|
1811
|
+
});
|
|
1812
|
+
const [depositedAssets, insideAMM, creditedShares, utilization] = poolData;
|
|
1813
|
+
const totalAssets = depositedAssets + insideAMM;
|
|
1814
|
+
const borrowRate = BigInt(interestRate) * SECONDS_PER_YEAR$2;
|
|
1815
|
+
const supplyRate = borrowRate * utilization / 10000n;
|
|
1816
|
+
return {
|
|
1817
|
+
address: collateralTrackerAddress,
|
|
1818
|
+
token: assetAddress,
|
|
1819
|
+
symbol,
|
|
1820
|
+
decimals: BigInt(decimals),
|
|
1821
|
+
totalAssets,
|
|
1822
|
+
insideAMM,
|
|
1823
|
+
creditedShares,
|
|
1824
|
+
totalShares,
|
|
1825
|
+
utilization,
|
|
1826
|
+
borrowRate,
|
|
1827
|
+
supplyRate,
|
|
1828
|
+
_meta
|
|
1829
|
+
};
|
|
1830
|
+
}
|
|
1831
|
+
/**
|
|
1832
|
+
* Get current interest rates for both tokens.
|
|
1833
|
+
*
|
|
1834
|
+
* ## Same-Block Guarantee
|
|
1835
|
+
* All dynamic data is fetched in ONE multicall at the target block.
|
|
1836
|
+
* Collateral tracker addresses are either provided or fetched separately (static prefetch).
|
|
1837
|
+
*
|
|
1838
|
+
* @param params - The parameters
|
|
1839
|
+
* @returns Current rates with block metadata
|
|
1840
|
+
*/
|
|
1841
|
+
async function getCurrentRates(params) {
|
|
1842
|
+
const { client, poolAddress, blockNumber, collateralAddresses } = params;
|
|
1843
|
+
const targetBlockNumber = blockNumber ?? params._meta?.blockNumber ?? await client.getBlockNumber();
|
|
1844
|
+
let collateralToken0;
|
|
1845
|
+
let collateralToken1;
|
|
1846
|
+
if (collateralAddresses) {
|
|
1847
|
+
collateralToken0 = collateralAddresses.collateralToken0;
|
|
1848
|
+
collateralToken1 = collateralAddresses.collateralToken1;
|
|
1849
|
+
} else {
|
|
1850
|
+
const addressResults = await client.multicall({
|
|
1851
|
+
contracts: [{
|
|
1852
|
+
address: poolAddress,
|
|
1853
|
+
abi: panopticPoolV2Abi,
|
|
1854
|
+
functionName: "collateralToken0"
|
|
1855
|
+
}, {
|
|
1856
|
+
address: poolAddress,
|
|
1857
|
+
abi: panopticPoolV2Abi,
|
|
1858
|
+
functionName: "collateralToken1"
|
|
1859
|
+
}],
|
|
1860
|
+
allowFailure: false
|
|
1861
|
+
});
|
|
1862
|
+
collateralToken0 = addressResults[0];
|
|
1863
|
+
collateralToken1 = addressResults[1];
|
|
1864
|
+
}
|
|
1865
|
+
const [rateData, _meta] = await Promise.all([client.multicall({
|
|
1866
|
+
contracts: [
|
|
1867
|
+
{
|
|
1868
|
+
address: collateralToken0,
|
|
1869
|
+
abi: collateralTrackerV2Abi,
|
|
1870
|
+
functionName: "interestRate"
|
|
1871
|
+
},
|
|
1872
|
+
{
|
|
1873
|
+
address: collateralToken0,
|
|
1874
|
+
abi: collateralTrackerV2Abi,
|
|
1875
|
+
functionName: "getPoolData"
|
|
1876
|
+
},
|
|
1877
|
+
{
|
|
1878
|
+
address: collateralToken1,
|
|
1879
|
+
abi: collateralTrackerV2Abi,
|
|
1880
|
+
functionName: "interestRate"
|
|
1881
|
+
},
|
|
1882
|
+
{
|
|
1883
|
+
address: collateralToken1,
|
|
1884
|
+
abi: collateralTrackerV2Abi,
|
|
1885
|
+
functionName: "getPoolData"
|
|
1886
|
+
}
|
|
1887
|
+
],
|
|
1888
|
+
blockNumber: targetBlockNumber,
|
|
1889
|
+
allowFailure: false
|
|
1890
|
+
}), params._meta ?? getBlockMeta({
|
|
1891
|
+
client,
|
|
1892
|
+
blockNumber: targetBlockNumber
|
|
1893
|
+
})]);
|
|
1894
|
+
const [interestRate0, poolData0, interestRate1, poolData1] = rateData;
|
|
1895
|
+
const utilization0 = poolData0[3];
|
|
1896
|
+
const utilization1 = poolData1[3];
|
|
1897
|
+
const borrowRate0 = BigInt(interestRate0) * SECONDS_PER_YEAR$2;
|
|
1898
|
+
const borrowRate1 = BigInt(interestRate1) * SECONDS_PER_YEAR$2;
|
|
1899
|
+
const supplyRate0 = borrowRate0 * utilization0 / 10000n;
|
|
1900
|
+
const supplyRate1 = borrowRate1 * utilization1 / 10000n;
|
|
1901
|
+
return {
|
|
1902
|
+
borrowRate0,
|
|
1903
|
+
supplyRate0,
|
|
1904
|
+
borrowRate1,
|
|
1905
|
+
supplyRate1,
|
|
1906
|
+
_meta
|
|
1907
|
+
};
|
|
1908
|
+
}
|
|
1909
|
+
/**
|
|
1910
|
+
* Get per-user interest state (borrow index + net borrows) for both tokens.
|
|
1911
|
+
*
|
|
1912
|
+
* Calls `collateralTracker.interestState(user)` on both trackers in a single multicall.
|
|
1913
|
+
*
|
|
1914
|
+
* @param params - The parameters
|
|
1915
|
+
* @returns Interest state for both tokens with block metadata
|
|
1916
|
+
*/
|
|
1917
|
+
async function getInterestState(params) {
|
|
1918
|
+
const { client, poolAddress, account, blockNumber, collateralAddresses } = params;
|
|
1919
|
+
const targetBlockNumber = blockNumber ?? params._meta?.blockNumber ?? await client.getBlockNumber();
|
|
1920
|
+
let collateralToken0;
|
|
1921
|
+
let collateralToken1;
|
|
1922
|
+
if (collateralAddresses) {
|
|
1923
|
+
collateralToken0 = collateralAddresses.collateralToken0;
|
|
1924
|
+
collateralToken1 = collateralAddresses.collateralToken1;
|
|
1925
|
+
} else {
|
|
1926
|
+
const addressResults = await client.multicall({
|
|
1927
|
+
contracts: [{
|
|
1928
|
+
address: poolAddress,
|
|
1929
|
+
abi: panopticPoolV2Abi,
|
|
1930
|
+
functionName: "collateralToken0"
|
|
1931
|
+
}, {
|
|
1932
|
+
address: poolAddress,
|
|
1933
|
+
abi: panopticPoolV2Abi,
|
|
1934
|
+
functionName: "collateralToken1"
|
|
1935
|
+
}],
|
|
1936
|
+
allowFailure: false
|
|
1937
|
+
});
|
|
1938
|
+
collateralToken0 = addressResults[0];
|
|
1939
|
+
collateralToken1 = addressResults[1];
|
|
1940
|
+
}
|
|
1941
|
+
const [results, _meta] = await Promise.all([client.multicall({
|
|
1942
|
+
contracts: [{
|
|
1943
|
+
address: collateralToken0,
|
|
1944
|
+
abi: collateralTrackerV2Abi,
|
|
1945
|
+
functionName: "interestState",
|
|
1946
|
+
args: [account]
|
|
1947
|
+
}, {
|
|
1948
|
+
address: collateralToken1,
|
|
1949
|
+
abi: collateralTrackerV2Abi,
|
|
1950
|
+
functionName: "interestState",
|
|
1951
|
+
args: [account]
|
|
1952
|
+
}],
|
|
1953
|
+
blockNumber: targetBlockNumber,
|
|
1954
|
+
allowFailure: false
|
|
1955
|
+
}), params._meta ?? getBlockMeta({
|
|
1956
|
+
client,
|
|
1957
|
+
blockNumber: targetBlockNumber
|
|
1958
|
+
})]);
|
|
1959
|
+
const [state0, state1] = results;
|
|
1960
|
+
return {
|
|
1961
|
+
token0: {
|
|
1962
|
+
userBorrowIndex: state0[0],
|
|
1963
|
+
netBorrows: state0[1]
|
|
1964
|
+
},
|
|
1965
|
+
token1: {
|
|
1966
|
+
userBorrowIndex: state1[0],
|
|
1967
|
+
netBorrows: state1[1]
|
|
1968
|
+
},
|
|
1969
|
+
_meta
|
|
1970
|
+
};
|
|
1971
|
+
}
|
|
1972
|
+
|
|
1973
|
+
//#endregion
|
|
1974
|
+
//#region src/panoptic/v2/formatters/amount.ts
|
|
1975
|
+
/**
|
|
1976
|
+
* Format a raw token amount to a human-readable string.
|
|
1977
|
+
*
|
|
1978
|
+
* @param amount - The amount in smallest units (e.g., wei)
|
|
1979
|
+
* @param decimals - Token decimals (e.g., 18n for WETH, 6n for USDC)
|
|
1980
|
+
* @param precision - Number of decimal places to display
|
|
1981
|
+
* @returns Formatted string
|
|
1982
|
+
*
|
|
1983
|
+
* @example
|
|
1984
|
+
* ```typescript
|
|
1985
|
+
* formatTokenAmount(1500000000000000000n, 18n, 4n) // "1.5000"
|
|
1986
|
+
* formatTokenAmount(1500000000000000000n, 18n, 2n) // "1.50"
|
|
1987
|
+
* formatTokenAmount(1500000n, 6n, 2n) // "1.50" (USDC)
|
|
1988
|
+
* formatTokenAmount(-500000000000000000n, 18n, 4n) // "-0.5000"
|
|
1989
|
+
* ```
|
|
1990
|
+
*/
|
|
1991
|
+
function formatTokenAmount(amount, decimals, precision) {
|
|
1992
|
+
const isNegative = amount < 0n;
|
|
1993
|
+
const absAmount = isNegative ? -amount : amount;
|
|
1994
|
+
const divisor = 10n ** decimals;
|
|
1995
|
+
const integerPart = absAmount / divisor;
|
|
1996
|
+
const fractionalPart = absAmount % divisor;
|
|
1997
|
+
const fullFractionalStr = fractionalPart.toString().padStart(Number(decimals), "0");
|
|
1998
|
+
const truncatedFractionalStr = fullFractionalStr.slice(0, Number(precision));
|
|
1999
|
+
const paddedFractionalStr = truncatedFractionalStr.padEnd(Number(precision), "0");
|
|
2000
|
+
const sign = isNegative ? "-" : "";
|
|
2001
|
+
return precision > 0n ? `${sign}${integerPart}.${paddedFractionalStr}` : `${sign}${integerPart}`;
|
|
2002
|
+
}
|
|
2003
|
+
/**
|
|
2004
|
+
* Format a token amount with a sign prefix (+/-) for non-zero values.
|
|
2005
|
+
* Useful for displaying PnL, deltas, or changes.
|
|
2006
|
+
*
|
|
2007
|
+
* @param amount - The amount in smallest units
|
|
2008
|
+
* @param decimals - Token decimals
|
|
2009
|
+
* @param precision - Number of decimal places to display
|
|
2010
|
+
* @returns Formatted string with sign prefix
|
|
2011
|
+
*
|
|
2012
|
+
* @example
|
|
2013
|
+
* ```typescript
|
|
2014
|
+
* formatTokenAmountSigned(1500000000000000000n, 18n, 4n) // "+1.5000"
|
|
2015
|
+
* formatTokenAmountSigned(-500000000000000000n, 18n, 4n) // "-0.5000"
|
|
2016
|
+
* formatTokenAmountSigned(0n, 18n, 4n) // "0.0000"
|
|
2017
|
+
* ```
|
|
2018
|
+
*/
|
|
2019
|
+
function formatTokenAmountSigned(amount, decimals, precision) {
|
|
2020
|
+
const formatted = formatTokenAmount(amount, decimals, precision);
|
|
2021
|
+
if (amount > 0n) return `+${formatted}`;
|
|
2022
|
+
return formatted;
|
|
2023
|
+
}
|
|
2024
|
+
/**
|
|
2025
|
+
* Parse a human-readable token amount string to raw units.
|
|
2026
|
+
*
|
|
2027
|
+
* @param amount - Human-readable amount string (e.g., "1.5")
|
|
2028
|
+
* @param decimals - Token decimals
|
|
2029
|
+
* @returns Amount in smallest units
|
|
2030
|
+
*
|
|
2031
|
+
* @example
|
|
2032
|
+
* ```typescript
|
|
2033
|
+
* parseTokenAmount("1.5", 18n) // 1500000000000000000n
|
|
2034
|
+
* parseTokenAmount("1.5", 6n) // 1500000n (USDC)
|
|
2035
|
+
* parseTokenAmount("100", 18n) // 100000000000000000000n
|
|
2036
|
+
* parseTokenAmount("-0.5", 18n) // -500000000000000000n
|
|
2037
|
+
* ```
|
|
2038
|
+
*/
|
|
2039
|
+
function parseTokenAmount(amount, decimals) {
|
|
2040
|
+
const trimmed = amount.trim();
|
|
2041
|
+
const isNegative = trimmed.startsWith("-");
|
|
2042
|
+
const cleanAmount = isNegative ? trimmed.slice(1) : trimmed;
|
|
2043
|
+
const [integerStr, fractionalStr = ""] = cleanAmount.split(".");
|
|
2044
|
+
const paddedFractional = fractionalStr.padEnd(Number(decimals), "0").slice(0, Number(decimals));
|
|
2045
|
+
const integerPart = BigInt(integerStr || "0") * 10n ** decimals;
|
|
2046
|
+
const fractionalPart = BigInt(paddedFractional || "0");
|
|
2047
|
+
const result = integerPart + fractionalPart;
|
|
2048
|
+
return isNegative ? -result : result;
|
|
2049
|
+
}
|
|
2050
|
+
/**
|
|
2051
|
+
* Format a token delta amount with a sign prefix (+/-) for non-zero values.
|
|
2052
|
+
* Alias for formatTokenAmountSigned, useful for clarity at call sites.
|
|
2053
|
+
*
|
|
2054
|
+
* @param amount - The delta amount in smallest units
|
|
2055
|
+
* @param decimals - Token decimals
|
|
2056
|
+
* @param precision - Number of decimal places to display
|
|
2057
|
+
* @returns Formatted string with sign prefix
|
|
2058
|
+
*/
|
|
2059
|
+
function formatTokenDelta(amount, decimals, precision) {
|
|
2060
|
+
return formatTokenAmountSigned(amount, decimals, precision);
|
|
2061
|
+
}
|
|
2062
|
+
/**
|
|
2063
|
+
* Format token flow deltas and balances from simulation results.
|
|
2064
|
+
*
|
|
2065
|
+
* @param flow - Token flow data
|
|
2066
|
+
* @param decimals0 - Token0 decimals
|
|
2067
|
+
* @param decimals1 - Token1 decimals
|
|
2068
|
+
* @param precision0 - Precision for token0 formatting
|
|
2069
|
+
* @param precision1 - Precision for token1 formatting
|
|
2070
|
+
* @returns Formatted token flow strings
|
|
2071
|
+
*/
|
|
2072
|
+
function formatTokenFlow(flow, decimals0, decimals1, precision0, precision1) {
|
|
2073
|
+
return {
|
|
2074
|
+
delta0: formatTokenAmountSigned(flow.delta0, decimals0, precision0),
|
|
2075
|
+
delta1: formatTokenAmountSigned(flow.delta1, decimals1, precision1),
|
|
2076
|
+
balanceBefore0: formatTokenAmount(flow.balanceBefore0, decimals0, precision0),
|
|
2077
|
+
balanceBefore1: formatTokenAmount(flow.balanceBefore1, decimals1, precision1),
|
|
2078
|
+
balanceAfter0: formatTokenAmount(flow.balanceAfter0, decimals0, precision0),
|
|
2079
|
+
balanceAfter1: formatTokenAmount(flow.balanceAfter1, decimals1, precision1)
|
|
2080
|
+
};
|
|
2081
|
+
}
|
|
2082
|
+
|
|
2083
|
+
//#endregion
|
|
2084
|
+
//#region src/panoptic/v2/formatters/wad.ts
|
|
2085
|
+
/**
|
|
2086
|
+
* Format a WAD-scaled value (1e18 = 1.0).
|
|
2087
|
+
*
|
|
2088
|
+
* @param wad - WAD-scaled value
|
|
2089
|
+
* @param precision - Number of decimal places to display
|
|
2090
|
+
* @returns Formatted string
|
|
2091
|
+
*
|
|
2092
|
+
* @example
|
|
2093
|
+
* ```typescript
|
|
2094
|
+
* formatWad(1220000000000000000n, 2n) // "1.22"
|
|
2095
|
+
* formatWad(1220000000000000000n, 4n) // "1.2200"
|
|
2096
|
+
* formatWad(1000000000000000000n, 2n) // "1.00"
|
|
2097
|
+
* formatWad(500000000000000000n, 2n) // "0.50"
|
|
2098
|
+
* ```
|
|
2099
|
+
*/
|
|
2100
|
+
function formatWad(wad, precision) {
|
|
2101
|
+
return formatTokenAmount(wad, 18n, precision);
|
|
2102
|
+
}
|
|
2103
|
+
/**
|
|
2104
|
+
* Format a WAD-scaled value with sign prefix (+/-) for non-zero values.
|
|
2105
|
+
*
|
|
2106
|
+
* @param wad - WAD-scaled value
|
|
2107
|
+
* @param precision - Number of decimal places to display
|
|
2108
|
+
* @returns Formatted string with sign prefix
|
|
2109
|
+
*
|
|
2110
|
+
* @example
|
|
2111
|
+
* ```typescript
|
|
2112
|
+
* formatWadSigned(1220000000000000000n, 2n) // "+1.22"
|
|
2113
|
+
* formatWadSigned(-500000000000000000n, 2n) // "-0.50"
|
|
2114
|
+
* formatWadSigned(0n, 2n) // "0.00"
|
|
2115
|
+
* ```
|
|
2116
|
+
*/
|
|
2117
|
+
function formatWadSigned(wad, precision) {
|
|
2118
|
+
const formatted = formatWad(wad, precision);
|
|
2119
|
+
if (wad > 0n) return `+${formatted}`;
|
|
2120
|
+
return formatted;
|
|
2121
|
+
}
|
|
2122
|
+
/**
|
|
2123
|
+
* Format a WAD-scaled value as a percentage string.
|
|
2124
|
+
*
|
|
2125
|
+
* @param wad - WAD-scaled value
|
|
2126
|
+
* @param precision - Number of decimal places to display
|
|
2127
|
+
* @returns Formatted percentage string
|
|
2128
|
+
*
|
|
2129
|
+
* @example
|
|
2130
|
+
* ```typescript
|
|
2131
|
+
* formatWadPercent(50000000000000000n, 2n) // "5.00%"
|
|
2132
|
+
* formatWadPercent(1000000000000000000n, 1n) // "100.0%"
|
|
2133
|
+
* ```
|
|
2134
|
+
*/
|
|
2135
|
+
function formatWadPercent(wad, precision) {
|
|
2136
|
+
return `${formatTokenAmount(wad * 100n, 18n, precision)}%`;
|
|
2137
|
+
}
|
|
2138
|
+
/**
|
|
2139
|
+
* Format an annualized rate stored as a WAD-scaled value.
|
|
2140
|
+
* Alias for formatWadPercent.
|
|
2141
|
+
*
|
|
2142
|
+
* @param rateWad - Rate in WAD (1e18 = 1.0)
|
|
2143
|
+
* @param precision - Number of decimal places to display
|
|
2144
|
+
* @returns Formatted percentage string
|
|
2145
|
+
*/
|
|
2146
|
+
function formatRateWad(rateWad, precision) {
|
|
2147
|
+
return formatWadPercent(rateWad, precision);
|
|
2148
|
+
}
|
|
2149
|
+
/**
|
|
2150
|
+
* Parse a decimal string to a WAD-scaled value.
|
|
2151
|
+
*
|
|
2152
|
+
* @param value - Decimal string (e.g., "1.5")
|
|
2153
|
+
* @returns WAD-scaled bigint
|
|
2154
|
+
*
|
|
2155
|
+
* @example
|
|
2156
|
+
* ```typescript
|
|
2157
|
+
* parseWad("1.5") // 1500000000000000000n
|
|
2158
|
+
* parseWad("0.5") // 500000000000000000n
|
|
2159
|
+
* parseWad("100") // 100000000000000000000n
|
|
2160
|
+
* parseWad("-1.22") // -1220000000000000000n
|
|
2161
|
+
* ```
|
|
2162
|
+
*/
|
|
2163
|
+
function parseWad(value) {
|
|
2164
|
+
const trimmed = value.trim();
|
|
2165
|
+
const isNegative = trimmed.startsWith("-");
|
|
2166
|
+
const cleanValue = isNegative ? trimmed.slice(1) : trimmed;
|
|
2167
|
+
const [integerStr, fractionalStr = ""] = cleanValue.split(".");
|
|
2168
|
+
const paddedFractional = fractionalStr.padEnd(18, "0").slice(0, 18);
|
|
2169
|
+
const integerPart = BigInt(integerStr || "0") * 10n ** 18n;
|
|
2170
|
+
const fractionalPart = BigInt(paddedFractional || "0");
|
|
2171
|
+
const result = integerPart + fractionalPart;
|
|
2172
|
+
return isNegative ? -result : result;
|
|
2173
|
+
}
|
|
2174
|
+
|
|
2175
|
+
//#endregion
|
|
2176
|
+
//#region src/panoptic/v2/formatters/rates.ts
|
|
2177
|
+
const SECONDS_PER_DAY = 86400n;
|
|
2178
|
+
const DAYS_PER_YEAR = 365n;
|
|
2179
|
+
const SECONDS_PER_YEAR$1 = SECONDS_PER_DAY * DAYS_PER_YEAR;
|
|
2180
|
+
/**
|
|
2181
|
+
* Annualize a per-second WAD-scaled rate to annual WAD.
|
|
2182
|
+
*
|
|
2183
|
+
* @param ratePerSecondWad - Rate in WAD per second
|
|
2184
|
+
* @returns Annualized rate in WAD
|
|
2185
|
+
*/
|
|
2186
|
+
function annualizePerSecondRateWad(ratePerSecondWad) {
|
|
2187
|
+
return ratePerSecondWad * SECONDS_PER_YEAR$1;
|
|
2188
|
+
}
|
|
2189
|
+
/**
|
|
2190
|
+
* Format a per-second WAD rate as APY percentage text.
|
|
2191
|
+
* Uses linear annualization, then formats as WAD percent.
|
|
2192
|
+
*
|
|
2193
|
+
* @param ratePerSecondWad - Rate in WAD per second
|
|
2194
|
+
* @param precision - Decimal places
|
|
2195
|
+
* @returns Percentage string, e.g. "2.41%"
|
|
2196
|
+
*/
|
|
2197
|
+
function formatPerSecondRateWadAsApyPct(ratePerSecondWad, precision) {
|
|
2198
|
+
return formatWadPercent(annualizePerSecondRateWad(ratePerSecondWad), precision);
|
|
2199
|
+
}
|
|
2200
|
+
/**
|
|
2201
|
+
* Format a per-second WAD rate as APR percentage text.
|
|
2202
|
+
* For this rate model, APR presentation uses the same annualized output.
|
|
2203
|
+
*
|
|
2204
|
+
* @param ratePerSecondWad - Rate in WAD per second
|
|
2205
|
+
* @param precision - Decimal places
|
|
2206
|
+
* @returns Percentage string, e.g. "2.41%"
|
|
2207
|
+
*/
|
|
2208
|
+
function formatPerSecondRateWadAsAprPct(ratePerSecondWad, precision) {
|
|
2209
|
+
return formatWadPercent(annualizePerSecondRateWad(ratePerSecondWad), precision);
|
|
2210
|
+
}
|
|
2211
|
+
|
|
2212
|
+
//#endregion
|
|
2213
|
+
//#region src/panoptic/v2/reads/irm.ts
|
|
2214
|
+
const WAD = 10n ** 18n;
|
|
2215
|
+
const BPS_SCALE = 10000n;
|
|
2216
|
+
const SECONDS_PER_YEAR = 31536000n;
|
|
2217
|
+
const MARKET_EPOCH_SHIFT = 2n;
|
|
2218
|
+
const BORROW_INDEX_BITS = 80n;
|
|
2219
|
+
const MARKET_EPOCH_BITS = 32n;
|
|
2220
|
+
const RATE_AT_TARGET_BITS = 38n;
|
|
2221
|
+
const UNREALIZED_INTEREST_BITS = 106n;
|
|
2222
|
+
const BORROW_INDEX_SHIFT = 0n;
|
|
2223
|
+
const MARKET_EPOCH_FIELD_SHIFT = BORROW_INDEX_BITS;
|
|
2224
|
+
const RATE_AT_TARGET_FIELD_SHIFT = BORROW_INDEX_BITS + MARKET_EPOCH_BITS;
|
|
2225
|
+
const UNREALIZED_INTEREST_FIELD_SHIFT = RATE_AT_TARGET_FIELD_SHIFT + RATE_AT_TARGET_BITS;
|
|
2226
|
+
const MAX_IRM_CURVE_POINTS = 500;
|
|
2227
|
+
const clampUtilizationBps = (utilizationBps) => {
|
|
2228
|
+
if (utilizationBps < 0n) return 0n;
|
|
2229
|
+
if (utilizationBps > BPS_SCALE) return BPS_SCALE;
|
|
2230
|
+
return utilizationBps;
|
|
2231
|
+
};
|
|
2232
|
+
const getMaxValue = (bits) => (1n << bits) - 1n;
|
|
2233
|
+
const assertFitsBits = (value, bits, fieldName) => {
|
|
2234
|
+
if (value < 0n) throw new PanopticValidationError(`${fieldName} must be >= 0`);
|
|
2235
|
+
if (value > getMaxValue(bits)) throw new PanopticValidationError(`${fieldName} exceeds ${bits.toString()} bits`);
|
|
2236
|
+
};
|
|
2237
|
+
function packMarketState(inputs) {
|
|
2238
|
+
const { borrowIndex, lastInteractionTimestamp, rateAtTarget, unrealizedGlobalInterest } = inputs;
|
|
2239
|
+
const marketEpoch = lastInteractionTimestamp >> MARKET_EPOCH_SHIFT;
|
|
2240
|
+
assertFitsBits(borrowIndex, BORROW_INDEX_BITS, "borrowIndex");
|
|
2241
|
+
assertFitsBits(marketEpoch, MARKET_EPOCH_BITS, "marketEpoch");
|
|
2242
|
+
assertFitsBits(rateAtTarget, RATE_AT_TARGET_BITS, "rateAtTarget");
|
|
2243
|
+
assertFitsBits(unrealizedGlobalInterest, UNREALIZED_INTEREST_BITS, "unrealizedGlobalInterest");
|
|
2244
|
+
return (borrowIndex << BORROW_INDEX_SHIFT) + (marketEpoch << MARKET_EPOCH_FIELD_SHIFT) + (rateAtTarget << RATE_AT_TARGET_FIELD_SHIFT) + (unrealizedGlobalInterest << UNREALIZED_INTEREST_FIELD_SHIFT);
|
|
2245
|
+
}
|
|
2246
|
+
function utilizationPctToWad(utilizationPct) {
|
|
2247
|
+
if (!Number.isFinite(utilizationPct)) throw new PanopticValidationError("utilizationPct must be finite");
|
|
2248
|
+
if (utilizationPct < 0 || utilizationPct > 100) throw new PanopticValidationError("utilizationPct must be between 0 and 100");
|
|
2249
|
+
const scaledPct = Math.round(utilizationPct * 1e6);
|
|
2250
|
+
return BigInt(scaledPct) * WAD / 100000000n;
|
|
2251
|
+
}
|
|
2252
|
+
function utilizationBpsToWad(utilizationBps) {
|
|
2253
|
+
return clampUtilizationBps(utilizationBps) * WAD / BPS_SCALE;
|
|
2254
|
+
}
|
|
2255
|
+
function ratePerSecWadToAprPct(ratePerSecWad) {
|
|
2256
|
+
return Number(ratePerSecWad) * Number(SECONDS_PER_YEAR) * 100 / Number(WAD);
|
|
2257
|
+
}
|
|
2258
|
+
function deriveSupplyRatePerSecWad(borrowRatePerSecWad, utilizationWad) {
|
|
2259
|
+
return borrowRatePerSecWad * utilizationWad / WAD;
|
|
2260
|
+
}
|
|
2261
|
+
async function getIrmCurrent(params) {
|
|
2262
|
+
const { client, collateralTrackerAddress, blockNumber } = params;
|
|
2263
|
+
const [borrowIndex, lastInteractionTimestamp, rateAtTarget, unrealizedGlobalInterest, poolData, riskEngineAddress] = await client.multicall({
|
|
2264
|
+
contracts: [
|
|
2265
|
+
{
|
|
2266
|
+
address: collateralTrackerAddress,
|
|
2267
|
+
abi: collateralTrackerV2Abi,
|
|
2268
|
+
functionName: "borrowIndex"
|
|
2269
|
+
},
|
|
2270
|
+
{
|
|
2271
|
+
address: collateralTrackerAddress,
|
|
2272
|
+
abi: collateralTrackerV2Abi,
|
|
2273
|
+
functionName: "lastInteractionTimestamp"
|
|
2274
|
+
},
|
|
2275
|
+
{
|
|
2276
|
+
address: collateralTrackerAddress,
|
|
2277
|
+
abi: collateralTrackerV2Abi,
|
|
2278
|
+
functionName: "rateAtTarget"
|
|
2279
|
+
},
|
|
2280
|
+
{
|
|
2281
|
+
address: collateralTrackerAddress,
|
|
2282
|
+
abi: collateralTrackerV2Abi,
|
|
2283
|
+
functionName: "unrealizedGlobalInterest"
|
|
2284
|
+
},
|
|
2285
|
+
{
|
|
2286
|
+
address: collateralTrackerAddress,
|
|
2287
|
+
abi: collateralTrackerV2Abi,
|
|
2288
|
+
functionName: "getPoolData"
|
|
2289
|
+
},
|
|
2290
|
+
{
|
|
2291
|
+
address: collateralTrackerAddress,
|
|
2292
|
+
abi: collateralTrackerV2Abi,
|
|
2293
|
+
functionName: "riskEngine"
|
|
2294
|
+
}
|
|
2295
|
+
],
|
|
2296
|
+
blockNumber,
|
|
2297
|
+
allowFailure: false
|
|
2298
|
+
});
|
|
2299
|
+
const currentUtilizationBps = clampUtilizationBps(poolData[3]);
|
|
2300
|
+
const currentUtilizationWad = utilizationBpsToWad(currentUtilizationBps);
|
|
2301
|
+
const currentUtilizationPct = Number(currentUtilizationBps) / 100;
|
|
2302
|
+
const marketStatePacked = packMarketState({
|
|
2303
|
+
borrowIndex,
|
|
2304
|
+
lastInteractionTimestamp,
|
|
2305
|
+
rateAtTarget,
|
|
2306
|
+
unrealizedGlobalInterest
|
|
2307
|
+
});
|
|
2308
|
+
const borrowRatePerSecWad = await client.readContract({
|
|
2309
|
+
address: riskEngineAddress,
|
|
2310
|
+
abi: riskEngineAbi,
|
|
2311
|
+
functionName: "interestRate",
|
|
2312
|
+
args: [currentUtilizationWad, marketStatePacked],
|
|
2313
|
+
blockNumber
|
|
2314
|
+
});
|
|
2315
|
+
const supplyRatePerSecWad = deriveSupplyRatePerSecWad(borrowRatePerSecWad, currentUtilizationWad);
|
|
2316
|
+
return {
|
|
2317
|
+
collateralTrackerAddress,
|
|
2318
|
+
riskEngineAddress,
|
|
2319
|
+
currentUtilizationBps,
|
|
2320
|
+
currentUtilizationWad,
|
|
2321
|
+
currentUtilizationPct,
|
|
2322
|
+
borrowRatePerSecWad,
|
|
2323
|
+
supplyRatePerSecWad,
|
|
2324
|
+
borrowAprPct: ratePerSecWadToAprPct(borrowRatePerSecWad),
|
|
2325
|
+
supplyAprPct: ratePerSecWadToAprPct(supplyRatePerSecWad),
|
|
2326
|
+
marketStatePacked
|
|
2327
|
+
};
|
|
2328
|
+
}
|
|
2329
|
+
async function getIrmCurve(params) {
|
|
2330
|
+
const { client, collateralTrackerAddress, points = 201, blockNumber } = params;
|
|
2331
|
+
if (!Number.isInteger(points) || points < 2) throw new PanopticValidationError("points must be an integer >= 2");
|
|
2332
|
+
if (points > MAX_IRM_CURVE_POINTS) throw new PanopticValidationError(`points must be <= ${MAX_IRM_CURVE_POINTS}`);
|
|
2333
|
+
const current = await getIrmCurrent({
|
|
2334
|
+
client,
|
|
2335
|
+
collateralTrackerAddress,
|
|
2336
|
+
blockNumber
|
|
2337
|
+
});
|
|
2338
|
+
const denominator = BigInt(points - 1);
|
|
2339
|
+
const contracts = Array.from({ length: points }, (_, idx) => {
|
|
2340
|
+
const i = BigInt(idx);
|
|
2341
|
+
const utilizationWad = i * WAD / denominator;
|
|
2342
|
+
return {
|
|
2343
|
+
address: current.riskEngineAddress,
|
|
2344
|
+
abi: riskEngineAbi,
|
|
2345
|
+
functionName: "interestRate",
|
|
2346
|
+
args: [utilizationWad, current.marketStatePacked]
|
|
2347
|
+
};
|
|
2348
|
+
});
|
|
2349
|
+
const borrowRatesPerSecWad = await client.multicall({
|
|
2350
|
+
contracts,
|
|
2351
|
+
blockNumber,
|
|
2352
|
+
allowFailure: false
|
|
2353
|
+
});
|
|
2354
|
+
const curvePoints = borrowRatesPerSecWad.map((borrowRatePerSecWad, idx) => {
|
|
2355
|
+
const i = BigInt(idx);
|
|
2356
|
+
const utilizationWad = i * WAD / denominator;
|
|
2357
|
+
const supplyRatePerSecWad = deriveSupplyRatePerSecWad(borrowRatePerSecWad, utilizationWad);
|
|
2358
|
+
return {
|
|
2359
|
+
utilizationWad,
|
|
2360
|
+
utilizationPct: idx * 100 / (points - 1),
|
|
2361
|
+
borrowRatePerSecWad,
|
|
2362
|
+
supplyRatePerSecWad,
|
|
2363
|
+
borrowAprPct: ratePerSecWadToAprPct(borrowRatePerSecWad),
|
|
2364
|
+
supplyAprPct: ratePerSecWadToAprPct(supplyRatePerSecWad)
|
|
2365
|
+
};
|
|
2366
|
+
});
|
|
2367
|
+
return {
|
|
2368
|
+
current,
|
|
2369
|
+
points: curvePoints
|
|
2370
|
+
};
|
|
2371
|
+
}
|
|
2372
|
+
|
|
2373
|
+
//#endregion
|
|
2374
|
+
export { BORROW_INDEX_BITS, BPS_SCALE, MARKET_EPOCH_BITS, MARKET_EPOCH_SHIFT, Multicall3Abi, RATE_AT_TARGET_BITS, SECONDS_PER_YEAR, UNREALIZED_INTEREST_BITS, WAD, annualizePerSecondRateWad, deriveSupplyRatePerSecWad, formatPerSecondRateWadAsAprPct, formatPerSecondRateWadAsApyPct, formatRateWad, formatTokenAmount, formatTokenAmountSigned, formatTokenDelta, formatTokenFlow, formatWad, formatWadPercent, formatWadSigned, getAccountCollateral, getAccountSummaryBasic, getAccountSummaryRisk, getCollateralAddresses, getCollateralData, getCurrentRates, getInterestState, getIrmCurrent, getIrmCurve, getLiquidationPrices, getNetLiquidationValue, getNetLiquidationValues, isLiquidatable, packMarketState, panopticQueryAbi, parseTokenAmount, parseWad, ratePerSecWadToAprPct, readBlockAndAggregate, requireReturnData, utilizationBpsToWad, utilizationPctToWad };
|
|
2375
|
+
//# sourceMappingURL=irm-CBrX8bjH.js.map
|