@gearbox-protocol/sdk 3.0.0-vfour.17 → 3.0.0-vfour.170
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/README.md +0 -1
- package/dist/cjs/dev/index.cjs +577 -27
- package/dist/cjs/dev/index.d.ts +115 -4
- package/dist/cjs/sdk/index.cjs +69876 -12075
- package/dist/cjs/sdk/index.d.ts +90790 -10249
- package/dist/esm/dev/index.d.mts +115 -4
- package/dist/esm/dev/index.mjs +572 -29
- package/dist/esm/sdk/index.d.mts +90790 -10249
- package/dist/esm/sdk/index.mjs +69654 -12220
- package/package.json +29 -16
package/README.md
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
Gearbox core types SDK
|
|
4
4
|
Contains core datastructures which are used across multiple gearbox services
|
|
5
5
|
|
|
6
|
-
|
|
7
6
|
### Important information for contributors
|
|
8
7
|
|
|
9
8
|
As a contributor to the Gearbox Protocol GitHub repository, your pull requests indicate acceptance of our Gearbox Contribution Agreement. This agreement outlines that you assign the Intellectual Property Rights of your contributions to the Gearbox Foundation. This helps safeguard the Gearbox protocol and ensure the accumulation of its intellectual property. Contributions become part of the repository and may be used for various purposes, including commercial. As recognition for your expertise and work, you receive the opportunity to participate in the protocol's development and the potential to see your work integrated within it. The full Gearbox Contribution Agreement is accessible within the [repository](/ContributionAgreement) for comprehensive understanding. [Let's innovate together!]
|
package/dist/cjs/dev/index.cjs
CHANGED
|
@@ -1,9 +1,362 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var sdk = require('../sdk');
|
|
4
3
|
var viem = require('viem');
|
|
4
|
+
var accounts = require('viem/accounts');
|
|
5
|
+
var sdk = require('../sdk');
|
|
6
|
+
var promises = require('fs/promises');
|
|
5
7
|
|
|
6
|
-
// src/dev/
|
|
8
|
+
// src/dev/AccountOpener.ts
|
|
9
|
+
function createAnvilClient({
|
|
10
|
+
chain,
|
|
11
|
+
transport
|
|
12
|
+
}) {
|
|
13
|
+
return viem.createTestClient(
|
|
14
|
+
{
|
|
15
|
+
chain,
|
|
16
|
+
mode: "anvil",
|
|
17
|
+
transport,
|
|
18
|
+
cacheTime: 0
|
|
19
|
+
}
|
|
20
|
+
).extend(viem.publicActions).extend(viem.walletActions).extend((client) => ({
|
|
21
|
+
anvilNodeInfo: () => anvilNodeInfo(client),
|
|
22
|
+
isAnvil: () => isAnvil(client),
|
|
23
|
+
evmMineDetailed: (timestamp) => evmMineDetailed(client, timestamp)
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
async function isAnvil(client) {
|
|
27
|
+
try {
|
|
28
|
+
const resp = await client.request({
|
|
29
|
+
method: "anvil_nodeInfo",
|
|
30
|
+
params: []
|
|
31
|
+
});
|
|
32
|
+
return !!resp.currentBlockNumber;
|
|
33
|
+
} catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async function anvilNodeInfo(client) {
|
|
38
|
+
return client.request({
|
|
39
|
+
method: "anvil_nodeInfo",
|
|
40
|
+
params: []
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
async function evmMineDetailed(client, timestamp) {
|
|
44
|
+
try {
|
|
45
|
+
const [block] = await client.request({
|
|
46
|
+
method: "evm_mine_detailed",
|
|
47
|
+
params: [viem.toHex(timestamp)]
|
|
48
|
+
});
|
|
49
|
+
return block;
|
|
50
|
+
} catch {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// src/dev/AccountOpener.ts
|
|
56
|
+
var AccountOpener = class {
|
|
57
|
+
#service;
|
|
58
|
+
#anvil;
|
|
59
|
+
#logger;
|
|
60
|
+
#borrower;
|
|
61
|
+
#faucet;
|
|
62
|
+
constructor(service, options = {}) {
|
|
63
|
+
this.#service = service;
|
|
64
|
+
this.#logger = sdk.childLogger("AccountOpener", service.sdk.logger);
|
|
65
|
+
this.#anvil = createAnvilClient({
|
|
66
|
+
chain: service.sdk.provider.chain,
|
|
67
|
+
transport: service.sdk.provider.transport
|
|
68
|
+
});
|
|
69
|
+
this.#faucet = options.faucet ?? service.sdk.addressProvider.getAddress("FAUCET");
|
|
70
|
+
}
|
|
71
|
+
get borrower() {
|
|
72
|
+
if (!this.#borrower) {
|
|
73
|
+
throw new Error("borrower can be used only after openCreditAccounts");
|
|
74
|
+
}
|
|
75
|
+
return this.#borrower.address;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Tries to open account with underlying only in each CM
|
|
79
|
+
*/
|
|
80
|
+
async openCreditAccounts(targets) {
|
|
81
|
+
await this.#prepareBorrower(targets);
|
|
82
|
+
const toApprove = new sdk.AddressMap();
|
|
83
|
+
for (const c of targets) {
|
|
84
|
+
const cm = this.sdk.marketRegister.findCreditManager(c.creditManager);
|
|
85
|
+
const toApproveOnCM = toApprove.get(c.creditManager) ?? /* @__PURE__ */ new Set();
|
|
86
|
+
toApproveOnCM.add(cm.underlying);
|
|
87
|
+
toApprove.upsert(c.creditManager, toApproveOnCM);
|
|
88
|
+
}
|
|
89
|
+
for (const [cmAddr, tokens] of toApprove.entries()) {
|
|
90
|
+
const cm = this.sdk.marketRegister.findCreditManager(cmAddr);
|
|
91
|
+
for (const token of tokens) {
|
|
92
|
+
await this.#approve(token, cm);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
for (let i = 0; i < targets.length; i++) {
|
|
96
|
+
const target = targets[i];
|
|
97
|
+
try {
|
|
98
|
+
await this.#openAccount(target, i + 1, targets.length);
|
|
99
|
+
} catch (e) {
|
|
100
|
+
this.#logger?.error(e);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const accounts = await this.getOpenedAccounts();
|
|
104
|
+
this.#logger?.info(`opened ${accounts.length} accounts`);
|
|
105
|
+
return accounts;
|
|
106
|
+
}
|
|
107
|
+
async #openAccount({ creditManager, collateral, leverage = 4, slippage = 50 }, index, total) {
|
|
108
|
+
const borrower = await this.#getBorrower();
|
|
109
|
+
const cm = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
110
|
+
const symbol = this.sdk.tokensMeta.symbol(collateral);
|
|
111
|
+
const logger = this.#logger?.child?.({
|
|
112
|
+
creditManager: cm.name,
|
|
113
|
+
collateral: symbol
|
|
114
|
+
});
|
|
115
|
+
logger?.debug(`opening account #${index}/${total}`);
|
|
116
|
+
const { minDebt, underlying } = cm.creditFacade;
|
|
117
|
+
const expectedBalances = [];
|
|
118
|
+
const leftoverBalances = [];
|
|
119
|
+
for (const t of Object.keys(cm.collateralTokens)) {
|
|
120
|
+
const token = t;
|
|
121
|
+
expectedBalances.push({
|
|
122
|
+
token,
|
|
123
|
+
balance: token === underlying ? BigInt(leverage) * minDebt : 1n
|
|
124
|
+
});
|
|
125
|
+
leftoverBalances.push({
|
|
126
|
+
token,
|
|
127
|
+
balance: 1n
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
logger?.debug("looking for open strategy");
|
|
131
|
+
const strategy = await this.sdk.router.findOpenStrategyPath({
|
|
132
|
+
creditManager: cm.creditManager,
|
|
133
|
+
expectedBalances,
|
|
134
|
+
leftoverBalances,
|
|
135
|
+
slippage,
|
|
136
|
+
target: collateral
|
|
137
|
+
});
|
|
138
|
+
logger?.debug(strategy, "found open strategy");
|
|
139
|
+
const debt = minDebt * BigInt(leverage - 1);
|
|
140
|
+
const collateralLT = BigInt(cm.collateralTokens[collateral]);
|
|
141
|
+
const inUnderlying = collateral.toLowerCase() === underlying.toLowerCase();
|
|
142
|
+
const { tx, calls } = await this.#service.openCA({
|
|
143
|
+
creditManager: cm.creditManager.address,
|
|
144
|
+
averageQuota: inUnderlying ? [] : [
|
|
145
|
+
{
|
|
146
|
+
token: collateral,
|
|
147
|
+
balance: this.#calcQuota(strategy.amount, debt, collateralLT)
|
|
148
|
+
}
|
|
149
|
+
],
|
|
150
|
+
minQuota: inUnderlying ? [] : [
|
|
151
|
+
{
|
|
152
|
+
token: collateral,
|
|
153
|
+
balance: this.#calcQuota(strategy.minAmount, debt, collateralLT)
|
|
154
|
+
}
|
|
155
|
+
],
|
|
156
|
+
collateral: [{ token: underlying, balance: minDebt }],
|
|
157
|
+
debt,
|
|
158
|
+
calls: strategy.calls,
|
|
159
|
+
ethAmount: 0n,
|
|
160
|
+
permits: {},
|
|
161
|
+
to: borrower.address,
|
|
162
|
+
referralCode: 0n
|
|
163
|
+
});
|
|
164
|
+
for (let i = 0; i < calls.length; i++) {
|
|
165
|
+
const call = calls[i];
|
|
166
|
+
logger?.debug(
|
|
167
|
+
`call #${i + 1}: ${this.sdk.parseFunctionData(call.target, call.callData)}`
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
logger?.debug("prepared open account transaction");
|
|
171
|
+
const hash = await sdk.sendRawTx(this.#anvil, {
|
|
172
|
+
tx,
|
|
173
|
+
account: borrower
|
|
174
|
+
});
|
|
175
|
+
logger?.debug(`send transaction ${hash}`);
|
|
176
|
+
const receipt = await this.#anvil.waitForTransactionReceipt({ hash });
|
|
177
|
+
if (receipt.status === "reverted") {
|
|
178
|
+
throw new Error(`open credit account tx ${hash} reverted`);
|
|
179
|
+
}
|
|
180
|
+
logger?.debug(`opened credit account ${index}/${total}`);
|
|
181
|
+
}
|
|
182
|
+
async getOpenedAccounts() {
|
|
183
|
+
return await this.#service.getCreditAccounts({
|
|
184
|
+
owner: this.borrower
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Creates borrower wallet,
|
|
189
|
+
* Sets ETH balance,
|
|
190
|
+
* Gets tokens from faucet,
|
|
191
|
+
* Approves collateral tokens to credit manager,
|
|
192
|
+
* Gets DEGEN_NFT,
|
|
193
|
+
*/
|
|
194
|
+
async #prepareBorrower(targets) {
|
|
195
|
+
const borrower = await this.#getBorrower();
|
|
196
|
+
let claimUSD = 0n;
|
|
197
|
+
let degenNFTS = {};
|
|
198
|
+
for (const target of targets) {
|
|
199
|
+
const cm = this.sdk.marketRegister.findCreditManager(
|
|
200
|
+
target.creditManager
|
|
201
|
+
);
|
|
202
|
+
const market = this.sdk.marketRegister.findByCreditManager(
|
|
203
|
+
target.creditManager
|
|
204
|
+
);
|
|
205
|
+
const { minDebt, degenNFT } = cm.creditFacade;
|
|
206
|
+
claimUSD += market.priceOracle.convertToUSD(cm.underlying, minDebt);
|
|
207
|
+
if (viem.isAddress(degenNFT) && degenNFT !== sdk.ADDRESS_0X0) {
|
|
208
|
+
degenNFTS[degenNFT] = (degenNFTS[degenNFT] ?? 0) + 1;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
claimUSD = claimUSD * 11n / 10n;
|
|
212
|
+
this.#logger?.debug(`claiming ${sdk.formatBN(claimUSD, 8)} USD from faucet`);
|
|
213
|
+
let hash = await this.#anvil.writeContract({
|
|
214
|
+
account: borrower,
|
|
215
|
+
address: this.#faucet,
|
|
216
|
+
abi: [
|
|
217
|
+
{
|
|
218
|
+
type: "function",
|
|
219
|
+
inputs: [
|
|
220
|
+
{ name: "amountUSD", internalType: "uint256", type: "uint256" }
|
|
221
|
+
],
|
|
222
|
+
name: "claim",
|
|
223
|
+
outputs: [],
|
|
224
|
+
stateMutability: "nonpayable"
|
|
225
|
+
}
|
|
226
|
+
],
|
|
227
|
+
functionName: "claim",
|
|
228
|
+
args: [claimUSD],
|
|
229
|
+
chain: this.#anvil.chain
|
|
230
|
+
});
|
|
231
|
+
let receipt = await this.#anvil.waitForTransactionReceipt({
|
|
232
|
+
hash
|
|
233
|
+
});
|
|
234
|
+
if (receipt.status === "reverted") {
|
|
235
|
+
throw new Error(
|
|
236
|
+
`borrower ${borrower.address} failed to claimed equivalent of ${sdk.formatBN(claimUSD, 8)} USD from faucet, tx: ${hash}`
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
this.#logger?.debug(
|
|
240
|
+
`borrower ${borrower.address} claimed equivalent of ${sdk.formatBN(claimUSD, 8)} USD from faucet, tx: ${hash}`
|
|
241
|
+
);
|
|
242
|
+
for (const [degenNFT, amount] of Object.entries(degenNFTS)) {
|
|
243
|
+
await this.#mintDegenNft(degenNFT, borrower.address, amount);
|
|
244
|
+
}
|
|
245
|
+
this.#logger?.debug("prepared borrower");
|
|
246
|
+
return borrower;
|
|
247
|
+
}
|
|
248
|
+
async #approve(token, cm) {
|
|
249
|
+
const borrower = await this.#getBorrower();
|
|
250
|
+
const symbol = this.#service.sdk.tokensMeta.symbol(token);
|
|
251
|
+
try {
|
|
252
|
+
if (symbol === "USDT") {
|
|
253
|
+
const hash2 = await this.#anvil.writeContract({
|
|
254
|
+
account: borrower,
|
|
255
|
+
address: token,
|
|
256
|
+
abi: sdk.ierc20Abi,
|
|
257
|
+
functionName: "approve",
|
|
258
|
+
args: [cm.creditManager.address, 0n],
|
|
259
|
+
chain: this.#anvil.chain
|
|
260
|
+
});
|
|
261
|
+
await this.#anvil.waitForTransactionReceipt({
|
|
262
|
+
hash: hash2
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
const hash = await this.#anvil.writeContract({
|
|
266
|
+
account: borrower,
|
|
267
|
+
address: token,
|
|
268
|
+
abi: sdk.ierc20Abi,
|
|
269
|
+
functionName: "approve",
|
|
270
|
+
args: [cm.creditManager.address, sdk.MAX_UINT256],
|
|
271
|
+
chain: this.#anvil.chain
|
|
272
|
+
});
|
|
273
|
+
const receipt = await this.#anvil.waitForTransactionReceipt({
|
|
274
|
+
hash
|
|
275
|
+
});
|
|
276
|
+
if (receipt.status === "reverted") {
|
|
277
|
+
this.#logger?.error(
|
|
278
|
+
`failed to allowed credit manager ${cm.creditManager.name} to spend ${symbol} (${token}), tx reverted: ${hash}`
|
|
279
|
+
);
|
|
280
|
+
} else {
|
|
281
|
+
this.#logger?.debug(
|
|
282
|
+
`allowed credit manager ${cm.creditManager.name} to spend ${symbol} (${token}), tx: ${hash}`
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
} catch (e) {
|
|
286
|
+
this.#logger?.error(
|
|
287
|
+
`failed to allowed credit manager ${cm.creditManager.name} to spend ${symbol} (${token}): ${e}`
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
async #mintDegenNft(degenNFT, to, amount) {
|
|
292
|
+
if (amount <= 0) {
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
let minter;
|
|
296
|
+
try {
|
|
297
|
+
minter = await this.#anvil.readContract({
|
|
298
|
+
address: degenNFT,
|
|
299
|
+
abi: sdk.iDegenNftv2Abi,
|
|
300
|
+
functionName: "minter"
|
|
301
|
+
});
|
|
302
|
+
} catch (e) {
|
|
303
|
+
this.#logger?.error(`failed to get minter of degenNFT ${degenNFT}: ${e}`);
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
try {
|
|
307
|
+
await this.#anvil.impersonateAccount({ address: minter });
|
|
308
|
+
await this.#anvil.setBalance({
|
|
309
|
+
address: minter,
|
|
310
|
+
value: viem.parseEther("100")
|
|
311
|
+
});
|
|
312
|
+
const hash = await this.#anvil.writeContract({
|
|
313
|
+
account: minter,
|
|
314
|
+
address: degenNFT,
|
|
315
|
+
abi: sdk.iDegenNftv2Abi,
|
|
316
|
+
functionName: "mint",
|
|
317
|
+
args: [to, BigInt(amount)],
|
|
318
|
+
chain: this.#anvil.chain
|
|
319
|
+
});
|
|
320
|
+
const receipt = await this.#anvil.waitForTransactionReceipt({
|
|
321
|
+
hash
|
|
322
|
+
});
|
|
323
|
+
if (receipt.status === "reverted") {
|
|
324
|
+
this.#logger?.error(
|
|
325
|
+
`failed to mint ${amount} degenNFT ${degenNFT} to borrower ${to}, tx reverted: ${hash}`
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
this.#logger?.debug(
|
|
329
|
+
`minted ${amount} degenNFT ${degenNFT} to borrower ${to}, tx: ${hash}`
|
|
330
|
+
);
|
|
331
|
+
} catch (e) {
|
|
332
|
+
this.#logger?.error(
|
|
333
|
+
`failed to mint ${amount} degenNFT ${degenNFT} to borrower ${to}: ${e}`
|
|
334
|
+
);
|
|
335
|
+
} finally {
|
|
336
|
+
await this.#anvil.stopImpersonatingAccount({ address: minter });
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
async #getBorrower() {
|
|
340
|
+
if (!this.#borrower) {
|
|
341
|
+
this.#borrower = accounts.privateKeyToAccount(accounts.generatePrivateKey());
|
|
342
|
+
await this.#anvil.setBalance({
|
|
343
|
+
address: this.#borrower.address,
|
|
344
|
+
value: viem.parseEther("100")
|
|
345
|
+
});
|
|
346
|
+
this.#logger?.info(`created borrower ${this.#borrower.address}`);
|
|
347
|
+
}
|
|
348
|
+
return this.#borrower;
|
|
349
|
+
}
|
|
350
|
+
#calcQuota(amount, debt, lt) {
|
|
351
|
+
let quota = amount * lt / sdk.PERCENTAGE_FACTOR;
|
|
352
|
+
quota = debt < quota ? debt : quota;
|
|
353
|
+
quota = quota * (sdk.PERCENTAGE_FACTOR + 500n) / sdk.PERCENTAGE_FACTOR;
|
|
354
|
+
return quota / sdk.PERCENTAGE_FACTOR * sdk.PERCENTAGE_FACTOR;
|
|
355
|
+
}
|
|
356
|
+
get sdk() {
|
|
357
|
+
return this.#service.sdk;
|
|
358
|
+
}
|
|
359
|
+
};
|
|
7
360
|
async function calcLiquidatableLTs(sdk$1, ca, factor = 9990n, logger) {
|
|
8
361
|
const cm = sdk$1.marketRegister.findCreditManager(ca.creditManager);
|
|
9
362
|
const market = sdk$1.marketRegister.findByCreditManager(ca.creditManager);
|
|
@@ -42,13 +395,101 @@ async function calcLiquidatableLTs(sdk$1, ca, factor = 9990n, logger) {
|
|
|
42
395
|
if (token !== ca.underlying) {
|
|
43
396
|
const newLT = oldLT * k / sdk.WAD;
|
|
44
397
|
logger?.debug(
|
|
45
|
-
`proposed ${sdk$1.
|
|
398
|
+
`proposed ${sdk$1.tokensMeta.symbol(token)} LT change: ${oldLT} => ${newLT} `
|
|
46
399
|
);
|
|
47
400
|
result[token] = Number(newLT);
|
|
48
401
|
}
|
|
49
402
|
}
|
|
50
403
|
return result;
|
|
51
404
|
}
|
|
405
|
+
var SDKExample = class {
|
|
406
|
+
#sdk;
|
|
407
|
+
#logger;
|
|
408
|
+
constructor(logger) {
|
|
409
|
+
this.#logger = logger;
|
|
410
|
+
}
|
|
411
|
+
async run(opts) {
|
|
412
|
+
const {
|
|
413
|
+
addressProvider: ap,
|
|
414
|
+
addressProviderJson,
|
|
415
|
+
marketConfigurator: mc,
|
|
416
|
+
marketConfiguratorJson,
|
|
417
|
+
anvilUrl = "http://127.0.0.1:8545",
|
|
418
|
+
outFile
|
|
419
|
+
} = opts;
|
|
420
|
+
const addressProvider = await this.#readConfigAddress(
|
|
421
|
+
"addressProvider",
|
|
422
|
+
ap,
|
|
423
|
+
addressProviderJson
|
|
424
|
+
);
|
|
425
|
+
const marketConfigurator = await this.#readConfigAddress(
|
|
426
|
+
"marketConfigurator",
|
|
427
|
+
mc,
|
|
428
|
+
marketConfiguratorJson
|
|
429
|
+
);
|
|
430
|
+
this.#sdk = await sdk.GearboxSDK.attach({
|
|
431
|
+
rpcURLs: [anvilUrl],
|
|
432
|
+
timeout: 48e4,
|
|
433
|
+
addressProvider,
|
|
434
|
+
logger: this.#logger,
|
|
435
|
+
ignoreUpdateablePrices: true,
|
|
436
|
+
marketConfigurators: [marketConfigurator]
|
|
437
|
+
});
|
|
438
|
+
const puTx = await this.#sdk.priceFeeds.getUpdatePriceFeedsTx([
|
|
439
|
+
marketConfigurator
|
|
440
|
+
]);
|
|
441
|
+
const updater = viem.createWalletClient({
|
|
442
|
+
account: accounts.privateKeyToAccount(
|
|
443
|
+
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
|
|
444
|
+
// well-known anvil private key
|
|
445
|
+
),
|
|
446
|
+
transport: viem.http(anvilUrl)
|
|
447
|
+
});
|
|
448
|
+
const publicClient = viem.createPublicClient({
|
|
449
|
+
transport: viem.http(anvilUrl)
|
|
450
|
+
});
|
|
451
|
+
const hash = await sdk.sendRawTx(updater, { tx: puTx });
|
|
452
|
+
await publicClient.waitForTransactionReceipt({ hash });
|
|
453
|
+
await this.#sdk.marketRegister.loadMarkets([marketConfigurator], true);
|
|
454
|
+
this.#logger?.info("attached sdk");
|
|
455
|
+
if (outFile) {
|
|
456
|
+
try {
|
|
457
|
+
await promises.writeFile(
|
|
458
|
+
outFile,
|
|
459
|
+
sdk.json_stringify(this.#sdk.stateHuman()),
|
|
460
|
+
"utf-8"
|
|
461
|
+
);
|
|
462
|
+
} catch (e) {
|
|
463
|
+
this.#logger?.error(`failed to write to ${outFile}: ${e}`);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
async #readConfigAddress(name, value, file) {
|
|
468
|
+
let result = value;
|
|
469
|
+
if (!result) {
|
|
470
|
+
if (!file) {
|
|
471
|
+
throw new Error(`${name} is not specified`);
|
|
472
|
+
}
|
|
473
|
+
this.#logger?.debug(`reading ${name} json ${file}`);
|
|
474
|
+
const apFile = await promises.readFile(file, "utf-8").then(JSON.parse);
|
|
475
|
+
result = apFile[name];
|
|
476
|
+
}
|
|
477
|
+
if (!result) {
|
|
478
|
+
throw new Error(`${name} is not specified`);
|
|
479
|
+
}
|
|
480
|
+
if (!viem.isAddress(result)) {
|
|
481
|
+
throw new Error(`${name} is not a valid address: ${result}`);
|
|
482
|
+
}
|
|
483
|
+
this.#logger?.info(`using ${name} ${result}`);
|
|
484
|
+
return result;
|
|
485
|
+
}
|
|
486
|
+
get sdk() {
|
|
487
|
+
if (!this.#sdk) {
|
|
488
|
+
throw new Error("sdk is not attached");
|
|
489
|
+
}
|
|
490
|
+
return this.#sdk;
|
|
491
|
+
}
|
|
492
|
+
};
|
|
52
493
|
|
|
53
494
|
// src/dev/abi/v3.ts
|
|
54
495
|
var iaclAbi = [
|
|
@@ -150,6 +591,21 @@ var iaclAbi = [
|
|
|
150
591
|
name: "AddressNotUnpausableAdminException"
|
|
151
592
|
}
|
|
152
593
|
];
|
|
594
|
+
var iaclTraitAbi = [
|
|
595
|
+
{
|
|
596
|
+
type: "function",
|
|
597
|
+
name: "acl",
|
|
598
|
+
inputs: [],
|
|
599
|
+
outputs: [
|
|
600
|
+
{
|
|
601
|
+
name: "",
|
|
602
|
+
type: "address",
|
|
603
|
+
internalType: "address"
|
|
604
|
+
}
|
|
605
|
+
],
|
|
606
|
+
stateMutability: "view"
|
|
607
|
+
}
|
|
608
|
+
];
|
|
153
609
|
var iCreditConfiguratorV3Abi = [
|
|
154
610
|
{
|
|
155
611
|
type: "function",
|
|
@@ -1413,17 +1869,17 @@ var iCreditManagerV3Abi = [
|
|
|
1413
1869
|
];
|
|
1414
1870
|
|
|
1415
1871
|
// src/dev/setLTs.ts
|
|
1416
|
-
async function setLTs(
|
|
1417
|
-
const aclAddr =
|
|
1418
|
-
|
|
1872
|
+
async function setLTs(anvil, cm, newLTs, logger) {
|
|
1873
|
+
const aclAddr = await anvil.readContract({
|
|
1874
|
+
address: cm.creditConfigurator,
|
|
1875
|
+
abi: iaclTraitAbi,
|
|
1876
|
+
functionName: "acl"
|
|
1877
|
+
});
|
|
1878
|
+
const configuratorAddr = await anvil.readContract({
|
|
1419
1879
|
address: aclAddr,
|
|
1420
1880
|
abi: iaclAbi,
|
|
1421
1881
|
functionName: "owner"
|
|
1422
1882
|
});
|
|
1423
|
-
const anvil = sdk.createAnvilClient({
|
|
1424
|
-
transport: sdk$1.provider.transport,
|
|
1425
|
-
chain: sdk$1.provider.chain
|
|
1426
|
-
});
|
|
1427
1883
|
await anvil.impersonateAccount({
|
|
1428
1884
|
address: configuratorAddr
|
|
1429
1885
|
});
|
|
@@ -1432,28 +1888,122 @@ async function setLTs(sdk$1, cm, newLTs, logger) {
|
|
|
1432
1888
|
value: viem.parseEther("100")
|
|
1433
1889
|
});
|
|
1434
1890
|
for (const [t, lt] of Object.entries(newLTs)) {
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
`set ${
|
|
1451
|
-
|
|
1891
|
+
try {
|
|
1892
|
+
await anvil.writeContract({
|
|
1893
|
+
chain: anvil.chain,
|
|
1894
|
+
address: cm.creditConfigurator,
|
|
1895
|
+
account: configuratorAddr,
|
|
1896
|
+
abi: iCreditConfiguratorV3Abi,
|
|
1897
|
+
functionName: "setLiquidationThreshold",
|
|
1898
|
+
args: [t, lt]
|
|
1899
|
+
});
|
|
1900
|
+
const newLT = await anvil.readContract({
|
|
1901
|
+
address: cm.address,
|
|
1902
|
+
abi: iCreditManagerV3Abi,
|
|
1903
|
+
functionName: "liquidationThresholds",
|
|
1904
|
+
args: [t]
|
|
1905
|
+
});
|
|
1906
|
+
logger?.debug(`set ${t} LT to ${newLT}`);
|
|
1907
|
+
} catch {
|
|
1908
|
+
}
|
|
1452
1909
|
}
|
|
1453
1910
|
await anvil.stopImpersonatingAccount({
|
|
1454
1911
|
address: configuratorAddr
|
|
1455
1912
|
});
|
|
1456
1913
|
}
|
|
1914
|
+
async function setLTZero(anvil, cm, logger) {
|
|
1915
|
+
const aclAddr = await anvil.readContract({
|
|
1916
|
+
address: cm.creditConfigurator,
|
|
1917
|
+
abi: iaclTraitAbi,
|
|
1918
|
+
functionName: "acl"
|
|
1919
|
+
});
|
|
1920
|
+
const configuratorAddr = await anvil.readContract({
|
|
1921
|
+
address: aclAddr,
|
|
1922
|
+
abi: iaclAbi,
|
|
1923
|
+
functionName: "owner"
|
|
1924
|
+
});
|
|
1925
|
+
await anvil.impersonateAccount({
|
|
1926
|
+
address: configuratorAddr
|
|
1927
|
+
});
|
|
1928
|
+
await anvil.setBalance({
|
|
1929
|
+
address: configuratorAddr,
|
|
1930
|
+
value: viem.parseEther("100")
|
|
1931
|
+
});
|
|
1932
|
+
let hash = await anvil.writeContract({
|
|
1933
|
+
chain: anvil.chain,
|
|
1934
|
+
address: cm.creditConfigurator,
|
|
1935
|
+
account: configuratorAddr,
|
|
1936
|
+
abi: iCreditConfiguratorV3Abi,
|
|
1937
|
+
functionName: "setFees",
|
|
1938
|
+
args: [
|
|
1939
|
+
cm.feeInterest,
|
|
1940
|
+
cm.liquidationDiscount - 1,
|
|
1941
|
+
Number(sdk.PERCENTAGE_FACTOR) - cm.liquidationDiscount,
|
|
1942
|
+
cm.feeLiquidationExpired,
|
|
1943
|
+
cm.liquidationDiscountExpired
|
|
1944
|
+
]
|
|
1945
|
+
});
|
|
1946
|
+
await anvil.waitForTransactionReceipt({ hash });
|
|
1947
|
+
logger?.debug(`[${cm.name}] setFees part 2`);
|
|
1948
|
+
hash = await anvil.writeContract({
|
|
1949
|
+
chain: anvil.chain,
|
|
1950
|
+
address: cm.creditConfigurator,
|
|
1951
|
+
account: configuratorAddr,
|
|
1952
|
+
abi: iCreditConfiguratorV3Abi,
|
|
1953
|
+
functionName: "setFees",
|
|
1954
|
+
args: [
|
|
1955
|
+
cm.feeInterest,
|
|
1956
|
+
cm.feeLiquidation,
|
|
1957
|
+
Number(sdk.PERCENTAGE_FACTOR) - cm.liquidationDiscount,
|
|
1958
|
+
cm.feeLiquidationExpired,
|
|
1959
|
+
cm.liquidationDiscountExpired
|
|
1960
|
+
]
|
|
1961
|
+
});
|
|
1962
|
+
await anvil.waitForTransactionReceipt({ hash });
|
|
1963
|
+
logger?.debug(`[${cm.name}] setFees done`);
|
|
1964
|
+
await anvil.impersonateAccount({
|
|
1965
|
+
address: cm.creditConfigurator
|
|
1966
|
+
});
|
|
1967
|
+
await anvil.setBalance({
|
|
1968
|
+
address: cm.creditConfigurator,
|
|
1969
|
+
value: viem.parseEther("100")
|
|
1970
|
+
});
|
|
1971
|
+
logger?.debug(
|
|
1972
|
+
`[${cm.name}] impresonating creditConfigurator ${cm.creditConfigurator}`
|
|
1973
|
+
);
|
|
1974
|
+
logger?.debug(`[${cm.name}] setting liquidation threshold`);
|
|
1975
|
+
hash = await anvil.writeContract({
|
|
1976
|
+
chain: anvil.chain,
|
|
1977
|
+
address: cm.baseParams.addr,
|
|
1978
|
+
account: cm.creditConfigurator,
|
|
1979
|
+
abi: iCreditManagerV3Abi,
|
|
1980
|
+
functionName: "setCollateralTokenData",
|
|
1981
|
+
args: [cm.underlying, 1, 1, Number(2n ** 40n - 1n), 0]
|
|
1982
|
+
});
|
|
1983
|
+
await anvil.waitForTransactionReceipt({ hash });
|
|
1984
|
+
logger?.debug(`[${cm.name}] setting configurator ${cm.creditConfigurator}`);
|
|
1985
|
+
hash = await anvil.writeContract({
|
|
1986
|
+
chain: anvil.chain,
|
|
1987
|
+
address: cm.baseParams.addr,
|
|
1988
|
+
account: cm.creditConfigurator,
|
|
1989
|
+
abi: iCreditManagerV3Abi,
|
|
1990
|
+
functionName: "setCreditConfigurator",
|
|
1991
|
+
args: [cm.creditConfigurator]
|
|
1992
|
+
});
|
|
1993
|
+
await anvil.waitForTransactionReceipt({ hash });
|
|
1994
|
+
logger?.debug(`[${cm.name}] done`);
|
|
1995
|
+
await anvil.stopImpersonatingAccount({
|
|
1996
|
+
address: cm.creditConfigurator
|
|
1997
|
+
});
|
|
1998
|
+
await anvil.stopImpersonatingAccount({ address: configuratorAddr });
|
|
1999
|
+
}
|
|
1457
2000
|
|
|
2001
|
+
exports.AccountOpener = AccountOpener;
|
|
2002
|
+
exports.SDKExample = SDKExample;
|
|
2003
|
+
exports.anvilNodeInfo = anvilNodeInfo;
|
|
1458
2004
|
exports.calcLiquidatableLTs = calcLiquidatableLTs;
|
|
2005
|
+
exports.createAnvilClient = createAnvilClient;
|
|
2006
|
+
exports.evmMineDetailed = evmMineDetailed;
|
|
2007
|
+
exports.isAnvil = isAnvil;
|
|
2008
|
+
exports.setLTZero = setLTZero;
|
|
1459
2009
|
exports.setLTs = setLTs;
|