@gearbox-protocol/sdk 13.4.0 → 13.5.0-next.1
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/dist/cjs/abi/310/iSecuritizeDegenNFT.js +263 -0
- package/dist/cjs/abi/310/iSecuritizeKYCFactory.js +278 -0
- package/dist/cjs/{sdk/pools/PoolServiceV310.js → abi/iStateSerializer.js} +14 -8
- package/dist/cjs/dev/AccountOpener.js +45 -5
- package/dist/cjs/sdk/accounts/AbstractCreditAccountsService.js +375 -13
- package/dist/cjs/sdk/accounts/CreditAccountsServiceV310.js +16 -5
- package/dist/cjs/sdk/base/ChainContractsRegister.js +1 -1
- package/dist/cjs/sdk/base/TokensMeta.js +255 -32
- package/dist/cjs/sdk/base/index.js +2 -0
- package/dist/cjs/sdk/{constants/phantom-tokens.js → base/token-types.js} +9 -3
- package/dist/cjs/sdk/chain/chains.js +2 -1
- package/dist/cjs/sdk/constants/index.js +0 -2
- package/dist/cjs/sdk/market/MarketRegister.js +5 -2
- package/dist/cjs/sdk/market/MarketSuite.js +6 -0
- package/dist/cjs/{plugins/zappers/extraZappers.js → sdk/market/ZapperRegister.js} +110 -6
- package/dist/cjs/sdk/market/index.js +3 -1
- package/dist/cjs/sdk/market/pool/PoolSuite.js +3 -0
- package/dist/cjs/sdk/market/pool/PoolV310Contract.js +17 -2
- package/dist/cjs/sdk/market/pool/SecuritizeKYCFactory.js +97 -0
- package/dist/cjs/sdk/market/pool/index.js +4 -0
- package/dist/cjs/sdk/pools/PoolService.js +391 -0
- package/dist/cjs/sdk/pools/index.js +2 -4
- package/dist/esm/abi/310/iSecuritizeDegenNFT.js +239 -0
- package/dist/esm/abi/310/iSecuritizeKYCFactory.js +254 -0
- package/dist/esm/abi/iStateSerializer.js +12 -0
- package/dist/esm/dev/AccountOpener.js +47 -6
- package/dist/esm/sdk/accounts/AbstractCreditAccountsService.js +375 -13
- package/dist/esm/sdk/accounts/CreditAccountsServiceV310.js +16 -5
- package/dist/esm/sdk/base/ChainContractsRegister.js +1 -1
- package/dist/esm/sdk/base/TokensMeta.js +261 -32
- package/dist/esm/sdk/base/index.js +1 -0
- package/dist/esm/sdk/{constants/phantom-tokens.js → base/token-types.js} +4 -0
- package/dist/esm/sdk/chain/chains.js +2 -1
- package/dist/esm/sdk/constants/index.js +0 -1
- package/dist/esm/sdk/market/MarketRegister.js +5 -2
- package/dist/esm/sdk/market/MarketSuite.js +6 -0
- package/dist/esm/{plugins/zappers/extraZappers.js → sdk/market/ZapperRegister.js} +109 -2
- package/dist/esm/sdk/market/index.js +1 -0
- package/dist/esm/sdk/market/pool/PoolSuite.js +3 -0
- package/dist/esm/sdk/market/pool/PoolV310Contract.js +17 -2
- package/dist/esm/sdk/market/pool/SecuritizeKYCFactory.js +73 -0
- package/dist/esm/sdk/market/pool/index.js +2 -0
- package/dist/esm/sdk/pools/PoolService.js +371 -0
- package/dist/esm/sdk/pools/index.js +1 -2
- package/dist/types/abi/310/iSecuritizeDegenNFT.d.ts +324 -0
- package/dist/types/abi/310/iSecuritizeKYCFactory.d.ts +322 -0
- package/dist/types/abi/iStateSerializer.d.ts +11 -0
- package/dist/types/sdk/accounts/AbstractCreditAccountsService.d.ts +114 -3
- package/dist/types/sdk/accounts/CreditAccountsServiceV310.d.ts +1 -1
- package/dist/types/sdk/accounts/types.d.ts +96 -6
- package/dist/types/sdk/base/TokensMeta.d.ts +34 -21
- package/dist/types/sdk/base/index.d.ts +1 -0
- package/dist/types/sdk/base/token-types.d.ts +33 -0
- package/dist/types/sdk/base/types.d.ts +0 -7
- package/dist/types/sdk/chain/chains.d.ts +1 -1
- package/dist/types/sdk/constants/index.d.ts +0 -1
- package/dist/types/sdk/market/MarketRegister.d.ts +2 -2
- package/dist/types/sdk/market/MarketSuite.d.ts +3 -0
- package/dist/types/sdk/market/ZapperRegister.d.ts +17 -0
- package/dist/types/sdk/market/index.d.ts +1 -0
- package/dist/types/sdk/market/pool/PoolSuite.d.ts +2 -0
- package/dist/types/sdk/market/pool/PoolV310Contract.d.ts +6 -2
- package/dist/types/sdk/market/pool/SecuritizeKYCFactory.d.ts +345 -0
- package/dist/types/sdk/market/pool/index.d.ts +2 -0
- package/dist/types/sdk/market/types.d.ts +10 -0
- package/dist/types/sdk/pools/PoolService.d.ts +14 -0
- package/dist/types/sdk/pools/index.d.ts +1 -2
- package/dist/types/sdk/pools/types.d.ts +85 -111
- package/package.json +1 -1
- package/dist/cjs/plugins/zappers/ZappersPlugin.js +0 -144
- package/dist/cjs/plugins/zappers/index.js +0 -26
- package/dist/cjs/plugins/zappers/package.json +0 -1
- package/dist/cjs/sdk/pools/AbstractPoolService.js +0 -143
- package/dist/cjs/sdk/pools/createPoolService.js +0 -35
- package/dist/esm/plugins/zappers/ZappersPlugin.js +0 -126
- package/dist/esm/plugins/zappers/index.js +0 -3
- package/dist/esm/plugins/zappers/package.json +0 -1
- package/dist/esm/sdk/pools/AbstractPoolService.js +0 -119
- package/dist/esm/sdk/pools/PoolServiceV310.js +0 -6
- package/dist/esm/sdk/pools/createPoolService.js +0 -11
- package/dist/types/plugins/zappers/ZappersPlugin.d.ts +0 -18
- package/dist/types/plugins/zappers/extraZappers.d.ts +0 -6
- package/dist/types/plugins/zappers/index.d.ts +0 -3
- package/dist/types/plugins/zappers/types.d.ts +0 -12
- package/dist/types/sdk/constants/phantom-tokens.d.ts +0 -2
- package/dist/types/sdk/pools/AbstractPoolService.d.ts +0 -21
- package/dist/types/sdk/pools/PoolServiceV310.d.ts +0 -4
- package/dist/types/sdk/pools/createPoolService.d.ts +0 -3
- /package/dist/cjs/{plugins/zappers → sdk/market}/types.js +0 -0
- /package/dist/esm/{plugins/zappers → sdk/market}/types.js +0 -0
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
decodeAbiParameters,
|
|
3
|
+
erc20Abi
|
|
4
|
+
} from "viem";
|
|
5
|
+
import { iSecuritizeDegenNFTAbi } from "../../abi/310/iSecuritizeDegenNFT.js";
|
|
6
|
+
import { iSecuritizeKYCFactoryAbi } from "../../abi/310/iSecuritizeKYCFactory.js";
|
|
7
|
+
import { iStateSerializerAbi } from "../../abi/iStateSerializer.js";
|
|
1
8
|
import { iVersionAbi } from "../../abi/iVersion.js";
|
|
2
9
|
import {
|
|
3
10
|
AddressMap,
|
|
@@ -5,19 +12,36 @@ import {
|
|
|
5
12
|
bytes32ToString,
|
|
6
13
|
formatBN
|
|
7
14
|
} from "../utils/index.js";
|
|
15
|
+
import {
|
|
16
|
+
KYC_UNDERLYING_DEFAULT,
|
|
17
|
+
KYC_UNDERLYING_ON_DEMAND
|
|
18
|
+
} from "./token-types.js";
|
|
8
19
|
class TokensMeta extends AddressMap {
|
|
9
20
|
#client;
|
|
10
|
-
#
|
|
11
|
-
|
|
21
|
+
#tokenDataLoaded = new AddressSet();
|
|
22
|
+
#logger;
|
|
23
|
+
constructor(client, logger) {
|
|
12
24
|
super(void 0, "tokensMeta");
|
|
13
25
|
this.#client = client;
|
|
26
|
+
this.#logger = logger?.child?.({ name: "TokensMeta" }) ?? logger;
|
|
14
27
|
}
|
|
15
28
|
/**
|
|
16
29
|
* Clears all token metadata
|
|
17
30
|
**/
|
|
18
31
|
reset() {
|
|
19
32
|
this.clear();
|
|
20
|
-
this.#
|
|
33
|
+
this.#tokenDataLoaded.clear();
|
|
34
|
+
}
|
|
35
|
+
upsert(address, value) {
|
|
36
|
+
let v = value;
|
|
37
|
+
const existing = this.get(address);
|
|
38
|
+
if (existing && v) {
|
|
39
|
+
v = {
|
|
40
|
+
...existing,
|
|
41
|
+
...v
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
super.upsert(address, v);
|
|
21
45
|
}
|
|
22
46
|
/**
|
|
23
47
|
* Returns the symbol string for a token.
|
|
@@ -36,27 +60,78 @@ class TokensMeta extends AddressMap {
|
|
|
36
60
|
return this.mustGet(token).decimals;
|
|
37
61
|
}
|
|
38
62
|
/**
|
|
39
|
-
* Returns the
|
|
40
|
-
*
|
|
63
|
+
* Returns true if the token is a phantom token, throws if the token data is not loaded
|
|
64
|
+
* @param t
|
|
65
|
+
* @returns
|
|
66
|
+
*/
|
|
67
|
+
isPhantomToken(t) {
|
|
68
|
+
if (!this.#tokenDataLoaded.has(t.addr)) {
|
|
69
|
+
throw new Error(
|
|
70
|
+
`extended token data not loaded for ${t.symbol} (${t.addr})`
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
return !!t.contractType?.startsWith("PHANTOM_TOKEN::");
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Returns true if the token is a KYC underlying token, throws if the token data is not loaded
|
|
77
|
+
* @param t
|
|
78
|
+
* @returns
|
|
79
|
+
*/
|
|
80
|
+
isKYCUnderlying(t) {
|
|
81
|
+
if (!this.#tokenDataLoaded.has(t.addr)) {
|
|
82
|
+
throw new Error(
|
|
83
|
+
`extended token data not loaded for ${t.symbol} (${t.addr})`
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
return !!t.contractType?.startsWith("KYC_UNDERLYING::");
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Returns true if the token is a DSToken, throws if the token data is not loaded
|
|
90
|
+
* @param t
|
|
91
|
+
* @returns
|
|
41
92
|
*/
|
|
42
|
-
|
|
43
|
-
if (!this.#
|
|
44
|
-
throw new Error(
|
|
93
|
+
isDSToken(t) {
|
|
94
|
+
if (!this.#tokenDataLoaded.has(t.addr)) {
|
|
95
|
+
throw new Error(
|
|
96
|
+
`extended token data not loaded for ${t.symbol} (${t.addr})`
|
|
97
|
+
);
|
|
45
98
|
}
|
|
46
|
-
return
|
|
99
|
+
return !!t.isDSToken;
|
|
47
100
|
}
|
|
48
101
|
/**
|
|
49
102
|
* Returns a map of all phantom tokens
|
|
50
|
-
* Throws if
|
|
103
|
+
* Throws if token data is not loaded
|
|
51
104
|
*/
|
|
52
105
|
get phantomTokens() {
|
|
53
|
-
|
|
54
|
-
|
|
106
|
+
const result = new AddressMap();
|
|
107
|
+
for (const [token, meta] of this.entries()) {
|
|
108
|
+
if (this.isPhantomToken(meta)) {
|
|
109
|
+
result.upsert(token, meta);
|
|
110
|
+
}
|
|
55
111
|
}
|
|
56
|
-
return
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Returns a map of all KYC underlying tokens
|
|
116
|
+
* Throws if token data is not loaded
|
|
117
|
+
*/
|
|
118
|
+
get kycUnderlyings() {
|
|
119
|
+
const result = new AddressMap();
|
|
120
|
+
for (const [token, meta] of this.entries()) {
|
|
121
|
+
if (this.isKYCUnderlying(meta)) {
|
|
122
|
+
result.upsert(token, meta);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return result;
|
|
126
|
+
}
|
|
127
|
+
get dsTokens() {
|
|
128
|
+
const result = new AddressMap();
|
|
129
|
+
for (const [token, meta] of this.entries()) {
|
|
130
|
+
if (this.isDSToken(meta)) {
|
|
131
|
+
result.upsert(token, meta);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return result;
|
|
60
135
|
}
|
|
61
136
|
formatBN(arg0, arg1, arg2) {
|
|
62
137
|
const token = typeof arg0 === "object" ? arg0.token : arg0;
|
|
@@ -87,30 +162,184 @@ class TokensMeta extends AddressMap {
|
|
|
87
162
|
return meta;
|
|
88
163
|
}
|
|
89
164
|
/**
|
|
90
|
-
* Loads
|
|
165
|
+
* Loads token information about phantom tokens, KYC underlying tokens and DSTokens
|
|
166
|
+
*
|
|
167
|
+
* @param tokens - tokens to load data for, defaults to all tokens
|
|
91
168
|
*/
|
|
92
|
-
async
|
|
93
|
-
|
|
94
|
-
const
|
|
169
|
+
async loadTokenData(...tokens) {
|
|
170
|
+
const tokenz = new AddressSet(tokens.length > 0 ? tokens : this.keys());
|
|
171
|
+
const tokensToLoad = Array.from(tokenz.difference(this.#tokenDataLoaded));
|
|
172
|
+
if (tokensToLoad.length === 0) {
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
95
175
|
const resp = await this.#client.multicall({
|
|
96
|
-
contracts:
|
|
97
|
-
(t) =>
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
176
|
+
contracts: tokensToLoad.flatMap(
|
|
177
|
+
(t) => [
|
|
178
|
+
{
|
|
179
|
+
address: t,
|
|
180
|
+
abi: iVersionAbi,
|
|
181
|
+
functionName: "contractType"
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
address: t,
|
|
185
|
+
abi: iStateSerializerAbi,
|
|
186
|
+
functionName: "serialize"
|
|
187
|
+
}
|
|
188
|
+
]
|
|
102
189
|
),
|
|
103
190
|
allowFailure: true,
|
|
104
191
|
batchSize: 0
|
|
105
192
|
});
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
193
|
+
this.#logger?.debug(`loaded ${resp.length} contract types`);
|
|
194
|
+
const kycFactories = new AddressSet();
|
|
195
|
+
for (let i = 0; i < tokensToLoad.length; i++) {
|
|
196
|
+
const meta = this.#overrideTokenMeta(
|
|
197
|
+
tokensToLoad[i],
|
|
198
|
+
resp[2 * i],
|
|
199
|
+
resp[2 * i + 1]
|
|
200
|
+
);
|
|
201
|
+
this.#tokenDataLoaded.add(tokensToLoad[i]);
|
|
202
|
+
if (this.isKYCUnderlying(meta)) {
|
|
203
|
+
kycFactories.add(meta.kycFactory);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
this.#logger?.debug(`found ${kycFactories.size} KYC factories`);
|
|
207
|
+
await this.#loadDSTokens(kycFactories);
|
|
208
|
+
}
|
|
209
|
+
#overrideTokenMeta(token, contractTypeResp, serializeResp) {
|
|
210
|
+
const meta = this.mustGet(token);
|
|
211
|
+
if (contractTypeResp.status === "success") {
|
|
212
|
+
const contractType = bytes32ToString(contractTypeResp.result);
|
|
213
|
+
if (contractType.startsWith("KYC_UNDERLYING::")) {
|
|
214
|
+
if (serializeResp.status === "success") {
|
|
215
|
+
this.#overrideKYCUnderlying(meta, contractType, serializeResp.result);
|
|
216
|
+
} else {
|
|
217
|
+
throw new Error(
|
|
218
|
+
`token ${meta.symbol} (${token}) is ${contractType} but serialize failed: ${serializeResp.error}`
|
|
219
|
+
);
|
|
111
220
|
}
|
|
221
|
+
} else {
|
|
222
|
+
this.upsert(token, {
|
|
223
|
+
...meta,
|
|
224
|
+
contractType
|
|
225
|
+
});
|
|
112
226
|
}
|
|
113
|
-
this.#
|
|
227
|
+
this.#logger?.debug(`token ${meta.symbol} is ${contractType}`);
|
|
228
|
+
}
|
|
229
|
+
return this.mustGet(token);
|
|
230
|
+
}
|
|
231
|
+
#overrideKYCUnderlying(meta, contractType, serialized) {
|
|
232
|
+
if (contractType === KYC_UNDERLYING_DEFAULT) {
|
|
233
|
+
const decoded = decodeAbiParameters(
|
|
234
|
+
[
|
|
235
|
+
{ type: "address", name: "kycFactory" },
|
|
236
|
+
{ type: "address", name: "asset" }
|
|
237
|
+
],
|
|
238
|
+
serialized
|
|
239
|
+
);
|
|
240
|
+
this.upsert(meta.addr, {
|
|
241
|
+
...meta,
|
|
242
|
+
contractType,
|
|
243
|
+
kycFactory: decoded[0],
|
|
244
|
+
asset: decoded[1]
|
|
245
|
+
});
|
|
246
|
+
} else if (contractType === KYC_UNDERLYING_ON_DEMAND) {
|
|
247
|
+
const decoded = decodeAbiParameters(
|
|
248
|
+
[
|
|
249
|
+
{ type: "address", name: "kycFactory" },
|
|
250
|
+
{ type: "address", name: "asset" },
|
|
251
|
+
{ type: "address", name: "pool" },
|
|
252
|
+
{ type: "address", name: "liquidityProvider" }
|
|
253
|
+
],
|
|
254
|
+
serialized
|
|
255
|
+
);
|
|
256
|
+
this.upsert(meta.addr, {
|
|
257
|
+
...meta,
|
|
258
|
+
contractType,
|
|
259
|
+
kycFactory: decoded[0],
|
|
260
|
+
asset: decoded[1],
|
|
261
|
+
pool: decoded[2],
|
|
262
|
+
liquidityProvider: decoded[3]
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
async #loadDSTokens(kycFactories) {
|
|
267
|
+
const degenNFTs = await this.#client.multicall({
|
|
268
|
+
contracts: kycFactories.map((address) => {
|
|
269
|
+
return {
|
|
270
|
+
address,
|
|
271
|
+
abi: iSecuritizeKYCFactoryAbi,
|
|
272
|
+
functionName: "getDegenNFT"
|
|
273
|
+
};
|
|
274
|
+
}),
|
|
275
|
+
allowFailure: false,
|
|
276
|
+
batchSize: 0
|
|
277
|
+
});
|
|
278
|
+
const resp = await this.#client.multicall({
|
|
279
|
+
contracts: degenNFTs.map((address) => {
|
|
280
|
+
return {
|
|
281
|
+
address,
|
|
282
|
+
abi: iSecuritizeDegenNFTAbi,
|
|
283
|
+
functionName: "getDSTokens"
|
|
284
|
+
};
|
|
285
|
+
}),
|
|
286
|
+
allowFailure: false,
|
|
287
|
+
batchSize: 0
|
|
288
|
+
});
|
|
289
|
+
const dsToken = new AddressSet(resp.flat());
|
|
290
|
+
const tokensToLoad = dsToken.difference(new Set(this.keys()));
|
|
291
|
+
this.#logger?.debug(
|
|
292
|
+
`found ${dsToken.size} DSTokens in KYC factories, need to load ${tokensToLoad.size} basic metadata`
|
|
293
|
+
);
|
|
294
|
+
await this.#loadWithoutCompressor(tokensToLoad);
|
|
295
|
+
for (const token of dsToken) {
|
|
296
|
+
const meta = this.mustGet(token);
|
|
297
|
+
this.upsert(token, {
|
|
298
|
+
...meta,
|
|
299
|
+
isDSToken: true
|
|
300
|
+
});
|
|
301
|
+
this.#tokenDataLoaded.add(token);
|
|
302
|
+
this.#logger?.debug(`token ${meta.symbol} (${token}) is a DSToken`);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
async #loadWithoutCompressor(tokens_) {
|
|
306
|
+
if (tokens_.size === 0) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
const tokens = Array.from(tokens_);
|
|
310
|
+
const resp = await this.#client.multicall({
|
|
311
|
+
contracts: tokens.flatMap(
|
|
312
|
+
(t) => [
|
|
313
|
+
{
|
|
314
|
+
address: t,
|
|
315
|
+
abi: erc20Abi,
|
|
316
|
+
functionName: "symbol"
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
address: t,
|
|
320
|
+
abi: erc20Abi,
|
|
321
|
+
functionName: "name"
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
address: t,
|
|
325
|
+
abi: erc20Abi,
|
|
326
|
+
functionName: "decimals"
|
|
327
|
+
}
|
|
328
|
+
]
|
|
329
|
+
),
|
|
330
|
+
allowFailure: false,
|
|
331
|
+
batchSize: 0
|
|
332
|
+
});
|
|
333
|
+
this.#logger?.debug(
|
|
334
|
+
`loaded ${resp.length} basic metadata without compressor`
|
|
335
|
+
);
|
|
336
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
337
|
+
this.upsert(tokens[i], {
|
|
338
|
+
addr: tokens[i],
|
|
339
|
+
symbol: resp[3 * i],
|
|
340
|
+
name: resp[3 * i + 1],
|
|
341
|
+
decimals: resp[3 * i + 2]
|
|
342
|
+
});
|
|
114
343
|
}
|
|
115
344
|
}
|
|
116
345
|
}
|
|
@@ -7,6 +7,10 @@ const PHANTOM_TOKEN_CONTRACT_TYPES = [
|
|
|
7
7
|
"PHANTOM_TOKEN::STAKING_REWARDS",
|
|
8
8
|
"PHANTOM_TOKEN::UPSHIFT_WITHDRAW"
|
|
9
9
|
];
|
|
10
|
+
const KYC_UNDERLYING_DEFAULT = "KYC_UNDERLYING::DEFAULT";
|
|
11
|
+
const KYC_UNDERLYING_ON_DEMAND = "KYC_UNDERLYING::ON_DEMAND";
|
|
10
12
|
export {
|
|
13
|
+
KYC_UNDERLYING_DEFAULT,
|
|
14
|
+
KYC_UNDERLYING_ON_DEMAND,
|
|
11
15
|
PHANTOM_TOKEN_CONTRACT_TYPES
|
|
12
16
|
};
|
|
@@ -65,7 +65,8 @@ const chains = {
|
|
|
65
65
|
"0x601067eba24bb5b558a184fc082525637e96a42d": "Gami Labs"
|
|
66
66
|
},
|
|
67
67
|
testMarketConfigurators: {
|
|
68
|
-
"0x99df7330bf42d596af2e9d9836d4fc2077c574aa": "M11 Credit"
|
|
68
|
+
"0x99df7330bf42d596af2e9d9836d4fc2077c574aa": "M11 Credit",
|
|
69
|
+
"0xE0527dE5908B3fc2e054B7eEE0DeF6c9965AbF24": "Securitize"
|
|
69
70
|
},
|
|
70
71
|
isPublic: true,
|
|
71
72
|
wellKnownToken: {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { marketCompressorAbi } from "../../abi/compressors/marketCompressor.js";
|
|
2
|
-
import { SDKConstruct } from "../base/index.js";
|
|
3
2
|
import {
|
|
4
3
|
ADDRESS_0X0,
|
|
5
4
|
AP_MARKET_COMPRESSOR,
|
|
@@ -9,7 +8,11 @@ import { AddressMap } from "../utils/index.js";
|
|
|
9
8
|
import { simulateWithPriceUpdates } from "../utils/viem/index.js";
|
|
10
9
|
import { MarketConfiguratorContract } from "./MarketConfiguratorContract.js";
|
|
11
10
|
import { MarketSuite } from "./MarketSuite.js";
|
|
12
|
-
|
|
11
|
+
import { ZapperRegister } from "./ZapperRegister.js";
|
|
12
|
+
class MarketRegister extends ZapperRegister {
|
|
13
|
+
/**
|
|
14
|
+
* Mapping pool.address -> MarketSuite
|
|
15
|
+
*/
|
|
13
16
|
#markets = new AddressMap(void 0, "markets");
|
|
14
17
|
#marketFilter;
|
|
15
18
|
#marketConfigurators = new AddressMap(
|
|
@@ -41,6 +41,12 @@ class MarketSuite extends SDKConstruct {
|
|
|
41
41
|
this.priceOracle = createPriceOracle(sdk, marketData.priceOracle);
|
|
42
42
|
this.lossPolicy = createLossPolicy(sdk, marketData.lossPolicy);
|
|
43
43
|
}
|
|
44
|
+
get underlying() {
|
|
45
|
+
return this.pool.underlying;
|
|
46
|
+
}
|
|
47
|
+
async getKYCFactory() {
|
|
48
|
+
return this.pool.getKYCFactory();
|
|
49
|
+
}
|
|
44
50
|
get dirty() {
|
|
45
51
|
return this.configurator.dirty || this.pool.dirty || this.priceOracle.dirty || this.creditManagers.some((cm) => cm.dirty);
|
|
46
52
|
}
|
|
@@ -1,4 +1,110 @@
|
|
|
1
|
-
|
|
1
|
+
import { peripheryCompressorAbi } from "../../abi/compressors/peripheryCompressor.js";
|
|
2
|
+
import { SDKConstruct } from "../base/index.js";
|
|
3
|
+
import {
|
|
4
|
+
AP_PERIPHERY_COMPRESSOR,
|
|
5
|
+
VERSION_RANGE_310
|
|
6
|
+
} from "../constants/index.js";
|
|
7
|
+
import { AddressMap, hexEq } from "../utils/index.js";
|
|
8
|
+
class ZapperRegister extends SDKConstruct {
|
|
9
|
+
/**
|
|
10
|
+
* Mapping pool.address -> ZapperData[]
|
|
11
|
+
* Needs to be loaded explicitly using loadZappers method
|
|
12
|
+
*/
|
|
13
|
+
#zappers;
|
|
14
|
+
/**
|
|
15
|
+
* Load zappers for all pools using periphery compressor, adds hardcoded zappers
|
|
16
|
+
*/
|
|
17
|
+
async loadZappers(force) {
|
|
18
|
+
if (!force && this.#zappers) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const [pcAddr] = this.sdk.addressProvider.mustGetLatest(
|
|
22
|
+
AP_PERIPHERY_COMPRESSOR,
|
|
23
|
+
VERSION_RANGE_310
|
|
24
|
+
);
|
|
25
|
+
this.logger?.debug(`loading zappers with periphery compressor ${pcAddr}`);
|
|
26
|
+
const markets = this.sdk.marketRegister.markets;
|
|
27
|
+
const resp = await this.client.multicall({
|
|
28
|
+
contracts: markets.map(
|
|
29
|
+
(m) => ({
|
|
30
|
+
abi: peripheryCompressorAbi,
|
|
31
|
+
address: pcAddr,
|
|
32
|
+
functionName: "getZappers",
|
|
33
|
+
args: [m.configurator.address, m.pool.pool.address]
|
|
34
|
+
})
|
|
35
|
+
),
|
|
36
|
+
allowFailure: true,
|
|
37
|
+
batchSize: 0
|
|
38
|
+
});
|
|
39
|
+
this.#zappers = new AddressMap(void 0, "zappers");
|
|
40
|
+
for (let i = 0; i < resp.length; i++) {
|
|
41
|
+
const { status, result, error } = resp[i];
|
|
42
|
+
const marketConfigurator = markets[i].configurator.address;
|
|
43
|
+
const pool = markets[i].pool.pool.address;
|
|
44
|
+
if (status === "success") {
|
|
45
|
+
for (const z of result) {
|
|
46
|
+
this.#addZapper({ ...z, pool, type: "base" });
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
this.logger?.error(
|
|
50
|
+
`failed to load zapper for market configurator ${this.labelAddress(
|
|
51
|
+
marketConfigurator
|
|
52
|
+
)} and pool ${this.labelAddress(pool)}: ${error}`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
for (const z of KYC_ZAPPERS[this.networkType] ?? []) {
|
|
57
|
+
this.#addZapper({ ...z, type: "kyc" });
|
|
58
|
+
}
|
|
59
|
+
for (const z of MIGRATION_ZAPPERS[this.networkType] ?? []) {
|
|
60
|
+
this.#addZapper({ ...z, type: "migration" });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
#addZapper(z) {
|
|
64
|
+
if (BROKEN_ZAPPERS.has(z.baseParams.addr)) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const existing = this.zappers.get(z.pool);
|
|
68
|
+
if (existing) {
|
|
69
|
+
const hasZapper = existing.some(
|
|
70
|
+
(zz) => hexEq(zz.baseParams.addr, z.baseParams.addr)
|
|
71
|
+
);
|
|
72
|
+
if (!hasZapper) {
|
|
73
|
+
existing.push(z);
|
|
74
|
+
}
|
|
75
|
+
} else {
|
|
76
|
+
this.zappers.upsert(z.pool, [z]);
|
|
77
|
+
}
|
|
78
|
+
const zappersTokens = [z.tokenIn, z.tokenOut];
|
|
79
|
+
for (const t of zappersTokens) {
|
|
80
|
+
this.sdk.tokensMeta.upsert(t.addr, t);
|
|
81
|
+
this.sdk.setAddressLabel(t.addr, t.symbol);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
get zappers() {
|
|
85
|
+
if (!this.#zappers) {
|
|
86
|
+
throw new Error("zappers not loaded, call loadZappers first");
|
|
87
|
+
}
|
|
88
|
+
return this.#zappers;
|
|
89
|
+
}
|
|
90
|
+
poolZappers(pool) {
|
|
91
|
+
return this.zappers.get(pool) ?? [];
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Can return multiple zappers if there are multiple zappers for the same tokenIn and tokenOut
|
|
95
|
+
*/
|
|
96
|
+
getZapper(pool, tokenIn, tokenOut) {
|
|
97
|
+
const zappers = this.zappers.get(pool)?.filter(
|
|
98
|
+
(z) => hexEq(z.tokenIn.addr, tokenIn) && hexEq(z.tokenOut.addr, tokenOut)
|
|
99
|
+
);
|
|
100
|
+
return zappers;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const BROKEN_ZAPPERS = new AddressMap(
|
|
104
|
+
[["0x90D66b03EC4D462e42e3c7741049FB46a4a03B69", true]],
|
|
105
|
+
"brokenZappers"
|
|
106
|
+
);
|
|
107
|
+
const MIGRATION_ZAPPERS = {
|
|
2
108
|
Mainnet: [
|
|
3
109
|
{
|
|
4
110
|
baseParams: {
|
|
@@ -107,6 +213,7 @@ const extraZappers = {
|
|
|
107
213
|
}
|
|
108
214
|
]
|
|
109
215
|
};
|
|
216
|
+
const KYC_ZAPPERS = {};
|
|
110
217
|
export {
|
|
111
|
-
|
|
218
|
+
ZapperRegister
|
|
112
219
|
};
|
|
@@ -55,6 +55,9 @@ class PoolSuite extends SDKConstruct {
|
|
|
55
55
|
get underlying() {
|
|
56
56
|
return this.pool.underlying;
|
|
57
57
|
}
|
|
58
|
+
async getKYCFactory() {
|
|
59
|
+
return this.pool.getKYCFactory();
|
|
60
|
+
}
|
|
58
61
|
get dirty() {
|
|
59
62
|
return this.pool.dirty || this.rateKeeper.dirty || this.pqk.dirty || this.interestRateModel.dirty;
|
|
60
63
|
}
|
|
@@ -7,16 +7,20 @@ import {
|
|
|
7
7
|
formatBNvalue,
|
|
8
8
|
percentFmt
|
|
9
9
|
} from "../../utils/index.js";
|
|
10
|
+
import { SecuritizeKYCFactory } from "./SecuritizeKYCFactory.js";
|
|
10
11
|
const abi = [...iPoolV310Abi, ...iPausableAbi];
|
|
11
12
|
class PoolV310Contract extends BaseContract {
|
|
12
13
|
creditManagerDebtParams;
|
|
13
|
-
|
|
14
|
+
#sdk;
|
|
15
|
+
#kycFactory;
|
|
16
|
+
constructor(sdk, data) {
|
|
14
17
|
const { baseParams, creditManagerDebtParams, ...rest } = data;
|
|
15
|
-
super(
|
|
18
|
+
super(sdk, {
|
|
16
19
|
...data.baseParams,
|
|
17
20
|
name: `PoolV3(${data.name})`,
|
|
18
21
|
abi
|
|
19
22
|
});
|
|
23
|
+
this.#sdk = sdk;
|
|
20
24
|
Object.assign(this, rest);
|
|
21
25
|
this.creditManagerDebtParams = new AddressMap(
|
|
22
26
|
creditManagerDebtParams.map((p) => [p.creditManager, p])
|
|
@@ -28,6 +32,17 @@ class PoolV310Contract extends BaseContract {
|
|
|
28
32
|
symbol: data.symbol
|
|
29
33
|
});
|
|
30
34
|
}
|
|
35
|
+
async getKYCFactory() {
|
|
36
|
+
if (this.#kycFactory) {
|
|
37
|
+
return this.#kycFactory;
|
|
38
|
+
}
|
|
39
|
+
await this.#sdk.tokensMeta.loadTokenData(this.underlying);
|
|
40
|
+
const u = this.#sdk.tokensMeta.mustGet(this.underlying);
|
|
41
|
+
if (this.#sdk.tokensMeta.isKYCUnderlying(u)) {
|
|
42
|
+
this.#kycFactory = new SecuritizeKYCFactory(this.#sdk, u.kycFactory);
|
|
43
|
+
}
|
|
44
|
+
return this.#kycFactory;
|
|
45
|
+
}
|
|
31
46
|
stateHuman(raw = true) {
|
|
32
47
|
return {
|
|
33
48
|
...super.stateHuman(raw),
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { iSecuritizeDegenNFTAbi } from "../../../abi/310/iSecuritizeDegenNFT.js";
|
|
2
|
+
import { iSecuritizeKYCFactoryAbi } from "../../../abi/310/iSecuritizeKYCFactory.js";
|
|
3
|
+
import { BaseContract } from "../../base/index.js";
|
|
4
|
+
import { AddressMap } from "../../index.js";
|
|
5
|
+
const abi = iSecuritizeKYCFactoryAbi;
|
|
6
|
+
class SecuritizeKYCFactory extends BaseContract {
|
|
7
|
+
investorCache;
|
|
8
|
+
#degenNFT;
|
|
9
|
+
constructor(options, address) {
|
|
10
|
+
super(options, {
|
|
11
|
+
addr: address,
|
|
12
|
+
name: "SecuritizeKYCFactory",
|
|
13
|
+
abi
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
async precomputeWalletAddress(creditManager, investor) {
|
|
17
|
+
return this.contract.read.precomputeWalletAddress([
|
|
18
|
+
creditManager,
|
|
19
|
+
investor
|
|
20
|
+
]);
|
|
21
|
+
}
|
|
22
|
+
async getWallet(creditAccount) {
|
|
23
|
+
return this.contract.read.getWallet([creditAccount]);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Returns the investor address for a credit account.
|
|
27
|
+
* @param creditAccount - Credit account address
|
|
28
|
+
* @param fromCache - If true, use and update an in-memory cache (creditAccount -> investor). On cache miss, loads from contract and stores the result for future calls.
|
|
29
|
+
*/
|
|
30
|
+
async getInvestor(creditAccount, fromCache) {
|
|
31
|
+
if (fromCache && this.investorCache?.has(creditAccount)) {
|
|
32
|
+
return this.investorCache.get(creditAccount);
|
|
33
|
+
}
|
|
34
|
+
const investor = await this.contract.read.getInvestor([creditAccount]);
|
|
35
|
+
if (fromCache) {
|
|
36
|
+
if (!this.investorCache) {
|
|
37
|
+
this.investorCache = new AddressMap();
|
|
38
|
+
}
|
|
39
|
+
this.investorCache.upsert(creditAccount, investor);
|
|
40
|
+
}
|
|
41
|
+
return investor;
|
|
42
|
+
}
|
|
43
|
+
async getDSTokens() {
|
|
44
|
+
const degenNFT = await this.getDegenNFT();
|
|
45
|
+
const tokens = await this.client.readContract({
|
|
46
|
+
address: degenNFT,
|
|
47
|
+
abi: iSecuritizeDegenNFTAbi,
|
|
48
|
+
functionName: "getDSTokens"
|
|
49
|
+
});
|
|
50
|
+
return [...tokens];
|
|
51
|
+
}
|
|
52
|
+
multicall(creditAccount, calls, tokensToRegister) {
|
|
53
|
+
return this.createRawTx({
|
|
54
|
+
functionName: "multicall",
|
|
55
|
+
args: [creditAccount, calls, tokensToRegister]
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
openCreditAccount(creditManager, calls, tokensToRegister) {
|
|
59
|
+
return this.createRawTx({
|
|
60
|
+
functionName: "openCreditAccount",
|
|
61
|
+
args: [creditManager, calls, tokensToRegister]
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
async getDegenNFT() {
|
|
65
|
+
if (!this.#degenNFT) {
|
|
66
|
+
this.#degenNFT = await this.contract.read.getDegenNFT();
|
|
67
|
+
}
|
|
68
|
+
return this.#degenNFT;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export {
|
|
72
|
+
SecuritizeKYCFactory
|
|
73
|
+
};
|