@gearbox-protocol/sdk 3.0.0-vfour.90 → 3.0.0-vfour.92
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/sdk/index.cjs +988 -891
- package/dist/cjs/sdk/index.d.ts +43 -26
- package/dist/esm/sdk/index.d.mts +43 -26
- package/dist/esm/sdk/index.mjs +987 -892
- package/package.json +1 -1
package/dist/cjs/sdk/index.cjs
CHANGED
|
@@ -22320,986 +22320,1081 @@ var MarketRegister = class extends SDKConstruct {
|
|
|
22320
22320
|
return this.#curators;
|
|
22321
22321
|
}
|
|
22322
22322
|
};
|
|
22323
|
-
|
|
22324
|
-
//
|
|
22325
|
-
|
|
22326
|
-
|
|
22327
|
-
|
|
22328
|
-
|
|
22329
|
-
|
|
22330
|
-
|
|
22323
|
+
var PathOptionFactory = class _PathOptionFactory {
|
|
22324
|
+
// TODO: get rid of token data from SDK
|
|
22325
|
+
static generatePathOptions(balances, network, loopsInTx) {
|
|
22326
|
+
const curvePools = _PathOptionFactory.getCurvePools(balances);
|
|
22327
|
+
const balancerPools = _PathOptionFactory.getBalancerPools(balances);
|
|
22328
|
+
const curveInitPO = curvePools.map((symbol) => {
|
|
22329
|
+
return {
|
|
22330
|
+
target: sdkGov.tokenDataByNetwork[network][symbol],
|
|
22331
|
+
option: 0,
|
|
22332
|
+
totalOptions: sdkGov.contractParams[sdkGov.curveTokens[symbol].pool].tokens.length
|
|
22333
|
+
};
|
|
22334
|
+
});
|
|
22335
|
+
const balancerInitPO = balancerPools.map((symbol) => {
|
|
22336
|
+
return {
|
|
22337
|
+
target: sdkGov.tokenDataByNetwork[network][symbol],
|
|
22338
|
+
option: 0,
|
|
22339
|
+
totalOptions: sdkGov.balancerLpTokens[symbol].underlying.length
|
|
22340
|
+
};
|
|
22341
|
+
});
|
|
22342
|
+
const initPO = [...curveInitPO, ...balancerInitPO];
|
|
22343
|
+
const totalLoops = initPO.reduce(
|
|
22344
|
+
(acc, item) => acc * item.totalOptions,
|
|
22345
|
+
1
|
|
22331
22346
|
);
|
|
22332
|
-
|
|
22333
|
-
|
|
22334
|
-
|
|
22335
|
-
|
|
22336
|
-
|
|
22337
|
-
|
|
22338
|
-
|
|
22339
|
-
|
|
22340
|
-
|
|
22341
|
-
const blockNumber = options?.blockNumber;
|
|
22342
|
-
let raw;
|
|
22343
|
-
try {
|
|
22344
|
-
raw = await this.provider.publicClient.readContract({
|
|
22345
|
-
abi: iCreditAccountCompressorAbi,
|
|
22346
|
-
address: this.#compressor,
|
|
22347
|
-
functionName: "getCreditAccountData",
|
|
22348
|
-
args: [account],
|
|
22349
|
-
blockNumber
|
|
22350
|
-
});
|
|
22351
|
-
} catch (e) {
|
|
22352
|
-
return void 0;
|
|
22353
|
-
}
|
|
22354
|
-
if (raw.success) {
|
|
22355
|
-
return raw;
|
|
22347
|
+
const result = [];
|
|
22348
|
+
let currentPo = [...initPO];
|
|
22349
|
+
for (let i = 0; i < totalLoops; i++) {
|
|
22350
|
+
if (i % loopsInTx === 0) {
|
|
22351
|
+
result.push(currentPo);
|
|
22352
|
+
}
|
|
22353
|
+
if (i < totalLoops - 1) {
|
|
22354
|
+
currentPo = _PathOptionFactory.next(currentPo);
|
|
22355
|
+
}
|
|
22356
22356
|
}
|
|
22357
|
-
|
|
22358
|
-
const resp = await simulateMulticall(this.provider.publicClient, {
|
|
22359
|
-
contracts: [
|
|
22360
|
-
...priceUpdateTxs.map(rawTxToMulticallPriceUpdate),
|
|
22361
|
-
{
|
|
22362
|
-
abi: iCreditAccountCompressorAbi,
|
|
22363
|
-
address: this.#compressor,
|
|
22364
|
-
functionName: "getCreditAccountData",
|
|
22365
|
-
args: [account]
|
|
22366
|
-
}
|
|
22367
|
-
],
|
|
22368
|
-
allowFailure: false,
|
|
22369
|
-
gas: 550000000n,
|
|
22370
|
-
batchSize: 0,
|
|
22371
|
-
// we cannot have price updates and compressor request in different batches
|
|
22372
|
-
blockNumber
|
|
22373
|
-
});
|
|
22374
|
-
const cad = resp.pop();
|
|
22375
|
-
return cad;
|
|
22357
|
+
return result;
|
|
22376
22358
|
}
|
|
22377
|
-
|
|
22378
|
-
|
|
22379
|
-
|
|
22380
|
-
|
|
22381
|
-
|
|
22382
|
-
|
|
22383
|
-
|
|
22384
|
-
|
|
22385
|
-
|
|
22386
|
-
|
|
22387
|
-
|
|
22388
|
-
|
|
22389
|
-
|
|
22390
|
-
|
|
22391
|
-
|
|
22392
|
-
|
|
22393
|
-
|
|
22394
|
-
|
|
22395
|
-
|
|
22396
|
-
|
|
22397
|
-
const
|
|
22398
|
-
|
|
22399
|
-
|
|
22400
|
-
underlying
|
|
22401
|
-
|
|
22402
|
-
const
|
|
22403
|
-
|
|
22404
|
-
|
|
22405
|
-
|
|
22406
|
-
|
|
22407
|
-
|
|
22408
|
-
|
|
22409
|
-
|
|
22410
|
-
|
|
22411
|
-
|
|
22412
|
-
|
|
22413
|
-
const [accounts, newOffset] = await this.#getCreditAccounts(
|
|
22414
|
-
[arg0, { ...caFilter, reverting }, offset],
|
|
22415
|
-
priceUpdateTxs,
|
|
22416
|
-
options
|
|
22417
|
-
);
|
|
22418
|
-
allCAs.push(...accounts);
|
|
22419
|
-
offset = newOffset;
|
|
22420
|
-
} while (offset !== 0n);
|
|
22359
|
+
static getCurvePools(balances) {
|
|
22360
|
+
const nonZeroBalances = balances.filter((b) => b.balance > 1n);
|
|
22361
|
+
const curvePools = nonZeroBalances.map((b) => sdkGov.getTokenSymbol(b.token)).filter((symbol) => sdkGov.isCurveLPToken(symbol));
|
|
22362
|
+
const yearnCurveTokens = Object.entries(sdkGov.yearnTokens).filter(([, data]) => sdkGov.isCurveLPToken(data.underlying)).map(([token]) => token);
|
|
22363
|
+
const curvePoolsFromYearn = nonZeroBalances.map((b) => sdkGov.getTokenSymbol(b.token)).filter((symbol) => yearnCurveTokens.includes(symbol)).map(
|
|
22364
|
+
(symbol) => sdkGov.yearnTokens[symbol].underlying
|
|
22365
|
+
);
|
|
22366
|
+
const convexCurveTokens = Object.entries(sdkGov.convexTokens).filter(([, data]) => sdkGov.isCurveLPToken(data.underlying)).map(([token]) => token);
|
|
22367
|
+
const curvePoolsFromConvex = nonZeroBalances.map((b) => sdkGov.getTokenSymbol(b.token)).filter((symbol) => convexCurveTokens.includes(symbol)).map((symbol) => sdkGov.convexTokens[symbol].underlying);
|
|
22368
|
+
const curveSet = /* @__PURE__ */ new Set([
|
|
22369
|
+
...curvePools,
|
|
22370
|
+
...curvePoolsFromYearn,
|
|
22371
|
+
...curvePoolsFromConvex
|
|
22372
|
+
]);
|
|
22373
|
+
return Array.from(curveSet.values());
|
|
22374
|
+
}
|
|
22375
|
+
static getBalancerPools(balances) {
|
|
22376
|
+
const nonZeroBalances = Object.entries(balances).filter(
|
|
22377
|
+
([, balance]) => balance.balance > 1
|
|
22378
|
+
);
|
|
22379
|
+
const balancerPools = nonZeroBalances.map(([token]) => sdkGov.getTokenSymbol(token)).filter((symbol) => sdkGov.isBalancerLPToken(symbol));
|
|
22380
|
+
const balancerAuraTokens = Object.entries(sdkGov.auraTokens).filter(([, data]) => sdkGov.isBalancerLPToken(data.underlying)).map(([token]) => token);
|
|
22381
|
+
const balancerTokensFromAura = nonZeroBalances.map(([token]) => sdkGov.getTokenSymbol(token)).filter((symbol) => balancerAuraTokens.includes(symbol)).map(
|
|
22382
|
+
(symbol) => sdkGov.auraTokens[symbol].underlying
|
|
22383
|
+
);
|
|
22384
|
+
const balancerSet = /* @__PURE__ */ new Set([...balancerPools, ...balancerTokensFromAura]);
|
|
22385
|
+
return Array.from(balancerSet.values());
|
|
22386
|
+
}
|
|
22387
|
+
static next(path) {
|
|
22388
|
+
let newPath = [...path];
|
|
22389
|
+
for (let i = path.length - 1; i >= 0; i--) {
|
|
22390
|
+
const po = { ...newPath[i] };
|
|
22391
|
+
po.option++;
|
|
22392
|
+
newPath[i] = po;
|
|
22393
|
+
if (po.option < po.totalOptions) return newPath;
|
|
22394
|
+
po.option = 0;
|
|
22421
22395
|
}
|
|
22422
|
-
|
|
22396
|
+
throw new Error("Path options overflow");
|
|
22423
22397
|
}
|
|
22424
|
-
|
|
22425
|
-
|
|
22426
|
-
|
|
22427
|
-
|
|
22428
|
-
|
|
22429
|
-
|
|
22430
|
-
|
|
22431
|
-
|
|
22432
|
-
|
|
22433
|
-
|
|
22434
|
-
|
|
22435
|
-
|
|
22436
|
-
|
|
22398
|
+
};
|
|
22399
|
+
|
|
22400
|
+
// src/sdk/router/RouterV3Contract.ts
|
|
22401
|
+
var MAX_GAS_PER_ROUTE = 200000000n;
|
|
22402
|
+
var GAS_PER_BLOCK = 400000000n;
|
|
22403
|
+
var LOOPS_PER_TX = Number(GAS_PER_BLOCK / MAX_GAS_PER_ROUTE);
|
|
22404
|
+
var SWAP_OPERATIONS = {
|
|
22405
|
+
EXACT_INPUT: 0,
|
|
22406
|
+
EXACT_INPUT_ALL: 1,
|
|
22407
|
+
EXACT_OUTPUT: 2
|
|
22408
|
+
};
|
|
22409
|
+
var RouterV3Contract = class extends BaseContract {
|
|
22410
|
+
#connectors;
|
|
22411
|
+
#hooks = new Hooks();
|
|
22412
|
+
constructor(sdk, address) {
|
|
22413
|
+
super(sdk, {
|
|
22414
|
+
addr: address,
|
|
22415
|
+
name: "RouterV3",
|
|
22416
|
+
abi: routerV3Abi
|
|
22437
22417
|
});
|
|
22438
|
-
|
|
22439
|
-
const tx = cm.creditFacade.liquidateCreditAccount(
|
|
22440
|
-
account.creditAccount,
|
|
22441
|
-
to,
|
|
22442
|
-
[...priceUpdates, ...routerCloseResult.calls]
|
|
22443
|
-
);
|
|
22444
|
-
return { tx, routerCloseResult };
|
|
22418
|
+
this.#connectors = sdkGov.getConnectors(sdk.provider.networkType);
|
|
22445
22419
|
}
|
|
22420
|
+
addHook = this.#hooks.addHook.bind(this.#hooks);
|
|
22421
|
+
removeHook = this.#hooks.removeHook.bind(this.#hooks);
|
|
22446
22422
|
/**
|
|
22447
|
-
*
|
|
22448
|
-
* @param
|
|
22449
|
-
* @param
|
|
22450
|
-
* @param
|
|
22451
|
-
* @param
|
|
22423
|
+
* Finds all available swaps for NORMAL tokens
|
|
22424
|
+
* @param ca
|
|
22425
|
+
* @param cm
|
|
22426
|
+
* @param swapOperation
|
|
22427
|
+
* @param tokenIn
|
|
22428
|
+
* @param tokenOut
|
|
22429
|
+
* @param amount
|
|
22430
|
+
* @param leftoverAmount
|
|
22452
22431
|
* @param slippage
|
|
22453
|
-
* @param closePath
|
|
22454
22432
|
* @returns
|
|
22455
22433
|
*/
|
|
22456
|
-
async
|
|
22457
|
-
operation,
|
|
22458
|
-
assetsToWithdraw,
|
|
22434
|
+
async findAllSwaps({
|
|
22459
22435
|
creditAccount: ca,
|
|
22460
|
-
|
|
22461
|
-
|
|
22462
|
-
|
|
22436
|
+
creditManager: cm,
|
|
22437
|
+
swapOperation,
|
|
22438
|
+
tokenIn,
|
|
22439
|
+
tokenOut,
|
|
22440
|
+
amount,
|
|
22441
|
+
leftoverAmount,
|
|
22442
|
+
slippage
|
|
22463
22443
|
}) {
|
|
22464
|
-
const
|
|
22465
|
-
const
|
|
22466
|
-
|
|
22467
|
-
|
|
22468
|
-
|
|
22469
|
-
|
|
22470
|
-
|
|
22471
|
-
|
|
22472
|
-
|
|
22473
|
-
|
|
22474
|
-
|
|
22475
|
-
|
|
22476
|
-
|
|
22477
|
-
|
|
22478
|
-
|
|
22479
|
-
|
|
22480
|
-
|
|
22481
|
-
|
|
22482
|
-
|
|
22483
|
-
|
|
22484
|
-
|
|
22485
|
-
|
|
22486
|
-
|
|
22487
|
-
|
|
22488
|
-
|
|
22489
|
-
|
|
22490
|
-
* @param permits
|
|
22491
|
-
* @returns
|
|
22492
|
-
*/
|
|
22493
|
-
async repayCreditAccount({
|
|
22494
|
-
operation,
|
|
22495
|
-
collateralAssets,
|
|
22496
|
-
assetsToWithdraw,
|
|
22497
|
-
creditAccount: ca,
|
|
22498
|
-
permits,
|
|
22499
|
-
to
|
|
22500
|
-
}) {
|
|
22501
|
-
const cm = this.sdk.marketRegister.findCreditManager(ca.creditManager);
|
|
22502
|
-
const addCollateral = collateralAssets.filter((a) => a.balance > 0);
|
|
22503
|
-
const calls = [
|
|
22504
|
-
...this.#prepareAddCollateralCalls(addCollateral, ca, permits),
|
|
22505
|
-
...this.#prepareDisableQuotas(ca),
|
|
22506
|
-
...this.#prepareDecreaseDebt(ca),
|
|
22507
|
-
...this.#prepareDisableTokens(ca),
|
|
22508
|
-
// TODO: probably needs a way to handle reward tokens
|
|
22509
|
-
...assetsToWithdraw.map(
|
|
22510
|
-
(t) => this.#prepareWithdrawToken(ca, t, MAX_UINT256, to)
|
|
22511
|
-
)
|
|
22512
|
-
];
|
|
22513
|
-
const tx = operation === "close" ? cm.creditFacade.closeCreditAccount(ca.creditAccount, calls) : cm.creditFacade.multicall(ca.creditAccount, calls);
|
|
22514
|
-
return { tx, calls };
|
|
22444
|
+
const connectors = this.getAvailableConnectors(cm.collateralTokens);
|
|
22445
|
+
const swapTask = {
|
|
22446
|
+
swapOperation: SWAP_OPERATIONS[swapOperation],
|
|
22447
|
+
creditAccount: ca.creditAccount,
|
|
22448
|
+
tokenIn,
|
|
22449
|
+
tokenOut,
|
|
22450
|
+
connectors,
|
|
22451
|
+
amount,
|
|
22452
|
+
leftoverAmount
|
|
22453
|
+
};
|
|
22454
|
+
const { result } = await this.contract.simulate.findAllSwaps(
|
|
22455
|
+
[swapTask, BigInt(slippage)],
|
|
22456
|
+
{
|
|
22457
|
+
gas: GAS_PER_BLOCK
|
|
22458
|
+
}
|
|
22459
|
+
);
|
|
22460
|
+
const unique = {};
|
|
22461
|
+
result.forEach((r) => {
|
|
22462
|
+
const key = `${r.minAmount.toString()}${r.calls.map((c) => `${c.target.toLowerCase()}${c.callData}`).join("-")}`;
|
|
22463
|
+
unique[key] = {
|
|
22464
|
+
amount: r.amount,
|
|
22465
|
+
minAmount: r.minAmount,
|
|
22466
|
+
calls: [...r.calls]
|
|
22467
|
+
};
|
|
22468
|
+
});
|
|
22469
|
+
return Object.values(unique);
|
|
22515
22470
|
}
|
|
22516
22471
|
/**
|
|
22517
|
-
*
|
|
22472
|
+
* Finds best path to swap all Normal tokens and tokens "on the way" to target one and vice versa
|
|
22518
22473
|
* @param creditAccount
|
|
22519
|
-
* @param
|
|
22520
|
-
* @param
|
|
22521
|
-
* @param
|
|
22474
|
+
* @param creditManager
|
|
22475
|
+
* @param tokenIn
|
|
22476
|
+
* @param tokenOut
|
|
22477
|
+
* @param amount
|
|
22522
22478
|
* @param slippage
|
|
22523
22479
|
* @returns
|
|
22524
22480
|
*/
|
|
22525
|
-
async
|
|
22526
|
-
collateralAssets,
|
|
22527
|
-
assetsToWithdraw,
|
|
22481
|
+
async findOneTokenPath({
|
|
22528
22482
|
creditAccount: ca,
|
|
22529
|
-
|
|
22530
|
-
|
|
22483
|
+
creditManager: cm,
|
|
22484
|
+
tokenIn,
|
|
22485
|
+
tokenOut,
|
|
22486
|
+
amount,
|
|
22487
|
+
slippage
|
|
22531
22488
|
}) {
|
|
22532
|
-
const
|
|
22533
|
-
const
|
|
22534
|
-
|
|
22535
|
-
|
|
22536
|
-
|
|
22537
|
-
|
|
22538
|
-
|
|
22539
|
-
|
|
22540
|
-
|
|
22541
|
-
|
|
22542
|
-
|
|
22543
|
-
|
|
22544
|
-
|
|
22545
|
-
calls
|
|
22489
|
+
const connectors = this.getAvailableConnectors(cm.collateralTokens);
|
|
22490
|
+
const { result } = await this.contract.simulate.findOneTokenPath(
|
|
22491
|
+
[
|
|
22492
|
+
tokenIn,
|
|
22493
|
+
amount,
|
|
22494
|
+
tokenOut,
|
|
22495
|
+
ca.creditAccount,
|
|
22496
|
+
connectors,
|
|
22497
|
+
BigInt(slippage)
|
|
22498
|
+
],
|
|
22499
|
+
{
|
|
22500
|
+
gas: GAS_PER_BLOCK
|
|
22501
|
+
}
|
|
22546
22502
|
);
|
|
22547
|
-
return {
|
|
22548
|
-
|
|
22549
|
-
|
|
22550
|
-
|
|
22551
|
-
|
|
22552
|
-
* @param priceUpdateTxs
|
|
22553
|
-
* @param options
|
|
22554
|
-
* @returns
|
|
22555
|
-
*/
|
|
22556
|
-
async #getCreditAccounts(args, priceUpdateTxs, options) {
|
|
22557
|
-
const blockNumber = options?.blockNumber;
|
|
22558
|
-
if (priceUpdateTxs?.length) {
|
|
22559
|
-
const resp = await simulateMulticall(this.provider.publicClient, {
|
|
22560
|
-
contracts: [
|
|
22561
|
-
...priceUpdateTxs.map(rawTxToMulticallPriceUpdate),
|
|
22562
|
-
{
|
|
22563
|
-
abi: iCreditAccountCompressorAbi,
|
|
22564
|
-
address: this.#compressor,
|
|
22565
|
-
functionName: "getCreditAccounts",
|
|
22566
|
-
args
|
|
22567
|
-
}
|
|
22568
|
-
],
|
|
22569
|
-
allowFailure: false,
|
|
22570
|
-
gas: 550000000n,
|
|
22571
|
-
batchSize: 0,
|
|
22572
|
-
// we cannot have price updates and compressor request in different batches
|
|
22573
|
-
blockNumber
|
|
22574
|
-
});
|
|
22575
|
-
const getCreditAccountsResp = resp.pop();
|
|
22576
|
-
return getCreditAccountsResp;
|
|
22577
|
-
}
|
|
22578
|
-
return this.provider.publicClient.readContract({
|
|
22579
|
-
abi: iCreditAccountCompressorAbi,
|
|
22580
|
-
address: this.#compressor,
|
|
22581
|
-
functionName: "getCreditAccounts",
|
|
22582
|
-
args,
|
|
22583
|
-
blockNumber
|
|
22584
|
-
});
|
|
22503
|
+
return {
|
|
22504
|
+
amount: result.amount,
|
|
22505
|
+
minAmount: result.minAmount,
|
|
22506
|
+
calls: [...result.calls]
|
|
22507
|
+
};
|
|
22585
22508
|
}
|
|
22586
22509
|
/**
|
|
22587
|
-
*
|
|
22588
|
-
* @param
|
|
22589
|
-
* @
|
|
22510
|
+
* @dev Finds the best path for opening Credit Account and converting all NORMAL tokens and LP token in the way to TARGET
|
|
22511
|
+
* @param creditManager CreditManagerData which represents credit manager you want to use to open Credit Account
|
|
22512
|
+
* @param expectedBalances Expected balances which would be on account accounting also debt. For example,
|
|
22513
|
+
* if you open an USDC Credit Account, borrow 50_000 USDC and provide 10 WETH and 10_USDC as collateral
|
|
22514
|
+
* from your own funds, expectedBalances should be: { "USDC": 60_000 * (10**6), "<address of WETH>": WAD.mul(10) }
|
|
22515
|
+
* @param leftoverBalances Balances to keep on account after opening
|
|
22516
|
+
* @param target Address of symbol of desired token
|
|
22517
|
+
* @param slippage Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
|
|
22518
|
+
* @returns PathFinderOpenStrategyResult which
|
|
22590
22519
|
*/
|
|
22591
|
-
async
|
|
22592
|
-
|
|
22593
|
-
|
|
22594
|
-
|
|
22595
|
-
|
|
22596
|
-
|
|
22597
|
-
|
|
22598
|
-
|
|
22599
|
-
|
|
22600
|
-
|
|
22601
|
-
|
|
22602
|
-
|
|
22603
|
-
|
|
22604
|
-
|
|
22605
|
-
|
|
22520
|
+
async findOpenStrategyPath({
|
|
22521
|
+
creditManager: cm,
|
|
22522
|
+
expectedBalances,
|
|
22523
|
+
leftoverBalances,
|
|
22524
|
+
target,
|
|
22525
|
+
slippage
|
|
22526
|
+
}) {
|
|
22527
|
+
const [expectedMap, leftoverMap] = [
|
|
22528
|
+
balancesMap(expectedBalances),
|
|
22529
|
+
balancesMap(leftoverBalances)
|
|
22530
|
+
];
|
|
22531
|
+
const input = cm.collateralTokens.map((token) => ({
|
|
22532
|
+
token,
|
|
22533
|
+
balance: expectedMap.get(token) ?? 0n
|
|
22534
|
+
}));
|
|
22535
|
+
const leftover = cm.collateralTokens.map((token) => ({
|
|
22536
|
+
token,
|
|
22537
|
+
balance: leftoverMap.get(token) ?? 0n
|
|
22538
|
+
}));
|
|
22539
|
+
const connectors = this.getAvailableConnectors(cm.collateralTokens);
|
|
22540
|
+
const {
|
|
22541
|
+
result: [outBalances, result]
|
|
22542
|
+
} = await this.contract.simulate.findOpenStrategyPath(
|
|
22543
|
+
[cm.address, input, leftover, target, connectors, BigInt(slippage)],
|
|
22544
|
+
{
|
|
22545
|
+
gas: GAS_PER_BLOCK
|
|
22606
22546
|
}
|
|
22607
|
-
}
|
|
22608
|
-
const priceFeeds = [];
|
|
22609
|
-
for (const [pool, priceFeedFactory] of oracleByPool.entries()) {
|
|
22610
|
-
const tokens = Array.from(tokensByPool.get(pool) ?? []);
|
|
22611
|
-
priceFeeds.push(...priceFeedFactory.priceFeedsForTokens(tokens));
|
|
22612
|
-
}
|
|
22613
|
-
return this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(priceFeeds);
|
|
22614
|
-
}
|
|
22615
|
-
/**
|
|
22616
|
-
* Returns account price updates in a non-encoded format
|
|
22617
|
-
* @param acc
|
|
22618
|
-
* @returns
|
|
22619
|
-
*/
|
|
22620
|
-
async getOnDemandPriceUpdates(acc) {
|
|
22621
|
-
const market = this.sdk.marketRegister.findByCreditManager(
|
|
22622
|
-
acc.creditManager
|
|
22623
22547
|
);
|
|
22624
|
-
const
|
|
22625
|
-
|
|
22548
|
+
const balancesAfter = Object.fromEntries(
|
|
22549
|
+
outBalances.map((b) => [b.token.toLowerCase(), b.balance])
|
|
22550
|
+
);
|
|
22551
|
+
return {
|
|
22552
|
+
balances: {
|
|
22553
|
+
...balancesAfter,
|
|
22554
|
+
[target]: (expectedMap.get(target) ?? 0n) + result.amount
|
|
22555
|
+
},
|
|
22556
|
+
minBalances: {
|
|
22557
|
+
...balancesAfter,
|
|
22558
|
+
[target]: (expectedMap.get(target) ?? 0n) + result.minAmount
|
|
22559
|
+
},
|
|
22560
|
+
amount: result.amount,
|
|
22561
|
+
minAmount: result.minAmount,
|
|
22562
|
+
calls: [...result.calls]
|
|
22563
|
+
};
|
|
22626
22564
|
}
|
|
22627
22565
|
/**
|
|
22628
|
-
*
|
|
22629
|
-
*
|
|
22630
|
-
* @
|
|
22566
|
+
* @dev Finds the path to swap / withdraw all assets from CreditAccount into underlying asset
|
|
22567
|
+
* Can bu used for closing Credit Account and for liquidations as well.
|
|
22568
|
+
* @param creditAccount CreditAccountStruct object used for close path computation
|
|
22569
|
+
* @param creditManager CreditManagerSlice for corresponding credit manager
|
|
22570
|
+
* @param slippage Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
|
|
22571
|
+
* @return The best option in PathFinderCloseResult format, which
|
|
22572
|
+
* - underlyingBalance - total balance of underlying token
|
|
22573
|
+
* - calls - list of calls which should be done to swap & unwrap everything to underlying token
|
|
22631
22574
|
*/
|
|
22632
|
-
async
|
|
22633
|
-
|
|
22634
|
-
|
|
22635
|
-
|
|
22636
|
-
|
|
22637
|
-
|
|
22638
|
-
const
|
|
22639
|
-
|
|
22640
|
-
|
|
22641
|
-
|
|
22642
|
-
|
|
22643
|
-
|
|
22644
|
-
|
|
22645
|
-
functionName: "updateQuota",
|
|
22646
|
-
args: [token, MIN_INT96, 0n]
|
|
22647
|
-
})
|
|
22648
|
-
});
|
|
22649
|
-
}
|
|
22650
|
-
}
|
|
22651
|
-
return calls;
|
|
22652
|
-
}
|
|
22653
|
-
#prepareDecreaseDebt(ca) {
|
|
22654
|
-
if (ca.debt > 0n) {
|
|
22655
|
-
return [
|
|
22656
|
-
{
|
|
22657
|
-
target: ca.creditFacade,
|
|
22658
|
-
callData: viem.encodeFunctionData({
|
|
22659
|
-
abi: iCreditFacadeV3MulticallAbi,
|
|
22660
|
-
functionName: "decreaseDebt",
|
|
22661
|
-
args: [MAX_UINT256]
|
|
22662
|
-
})
|
|
22663
|
-
}
|
|
22664
|
-
];
|
|
22665
|
-
}
|
|
22666
|
-
return [];
|
|
22667
|
-
}
|
|
22668
|
-
#prepareDisableTokens(ca) {
|
|
22669
|
-
const calls = [];
|
|
22670
|
-
for (const t of ca.tokens) {
|
|
22671
|
-
if (t.token !== ca.underlying && (t.mask & ca.enabledTokensMask) !== 0n && t.quota === 0n) {
|
|
22672
|
-
calls.push({
|
|
22673
|
-
target: ca.creditFacade,
|
|
22674
|
-
callData: viem.encodeFunctionData({
|
|
22675
|
-
abi: iCreditFacadeV3MulticallAbi,
|
|
22676
|
-
functionName: "disableToken",
|
|
22677
|
-
args: [t.token]
|
|
22678
|
-
})
|
|
22679
|
-
});
|
|
22680
|
-
}
|
|
22681
|
-
}
|
|
22682
|
-
return calls;
|
|
22683
|
-
}
|
|
22684
|
-
#prepareWithdrawToken(ca, token, amount, to) {
|
|
22685
|
-
return {
|
|
22686
|
-
target: ca.creditFacade,
|
|
22687
|
-
callData: viem.encodeFunctionData({
|
|
22688
|
-
abi: iCreditFacadeV3MulticallAbi,
|
|
22689
|
-
functionName: "withdrawCollateral",
|
|
22690
|
-
args: [token, amount, to]
|
|
22691
|
-
})
|
|
22692
|
-
};
|
|
22693
|
-
}
|
|
22694
|
-
#prepareAddCollateralCalls(assets, ca, permits) {
|
|
22695
|
-
const calls = assets.map(({ token, balance }) => {
|
|
22696
|
-
const p = permits[token];
|
|
22697
|
-
if (p) {
|
|
22698
|
-
return {
|
|
22699
|
-
target: ca.creditFacade,
|
|
22700
|
-
callData: viem.encodeFunctionData({
|
|
22701
|
-
abi: iCreditFacadeV3MulticallAbi,
|
|
22702
|
-
functionName: "addCollateralWithPermit",
|
|
22703
|
-
args: [token, balance, p.deadline, p.v, p.r, p.s]
|
|
22704
|
-
})
|
|
22705
|
-
};
|
|
22706
|
-
}
|
|
22707
|
-
return {
|
|
22708
|
-
target: ca.creditFacade,
|
|
22709
|
-
callData: viem.encodeFunctionData({
|
|
22710
|
-
abi: iCreditFacadeV3MulticallAbi,
|
|
22711
|
-
functionName: "addCollateral",
|
|
22712
|
-
args: [token, balance]
|
|
22713
|
-
})
|
|
22714
|
-
};
|
|
22715
|
-
});
|
|
22716
|
-
return calls;
|
|
22717
|
-
}
|
|
22718
|
-
/**
|
|
22719
|
-
* Returns addresses of pools of attached markets
|
|
22720
|
-
*/
|
|
22721
|
-
get pools() {
|
|
22722
|
-
return this.sdk.marketRegister.pools.map((p) => p.pool.address);
|
|
22723
|
-
}
|
|
22724
|
-
};
|
|
22725
|
-
var AddressProviderContractV3_1 = class extends BaseContract {
|
|
22726
|
-
#addresses = {};
|
|
22727
|
-
versions = {};
|
|
22728
|
-
latest = {};
|
|
22729
|
-
constructor(sdk, address) {
|
|
22730
|
-
super(sdk, {
|
|
22731
|
-
addr: address,
|
|
22732
|
-
name: "AddressProviderV3",
|
|
22733
|
-
abi: iAddressProviderV3_1Abi
|
|
22734
|
-
});
|
|
22735
|
-
}
|
|
22736
|
-
parseFunctionParams(params) {
|
|
22737
|
-
switch (params.functionName) {
|
|
22738
|
-
case "setAddress": {
|
|
22739
|
-
if (params.args.length !== 3) {
|
|
22740
|
-
const [key2, saveVersion2] = params.args;
|
|
22741
|
-
return [key2, `${saveVersion2}`];
|
|
22742
|
-
}
|
|
22743
|
-
const [key, value, saveVersion] = params.args;
|
|
22744
|
-
return [viem.bytesToString(viem.toBytes(key)), value, `${saveVersion}`];
|
|
22745
|
-
}
|
|
22746
|
-
default:
|
|
22747
|
-
return void 0;
|
|
22748
|
-
}
|
|
22749
|
-
}
|
|
22750
|
-
setInternalAddress(key, address, version) {
|
|
22751
|
-
if (!this.#addresses[key]) {
|
|
22752
|
-
this.#addresses[key] = {};
|
|
22753
|
-
}
|
|
22754
|
-
this.#addresses[key][version] = address;
|
|
22755
|
-
if (!this.latest[key] || version > this.latest[key]) {
|
|
22756
|
-
this.latest[key] = version;
|
|
22757
|
-
}
|
|
22758
|
-
if (!this.versions[key]) {
|
|
22759
|
-
this.versions[key] = /* @__PURE__ */ new Set();
|
|
22760
|
-
}
|
|
22761
|
-
this.versions[key].add(version);
|
|
22762
|
-
}
|
|
22763
|
-
getAddress(contract, version = NO_VERSION) {
|
|
22764
|
-
if (!this.#addresses[contract]) {
|
|
22765
|
-
throw new Error(`Address ${contract}, version: ${version} not found`);
|
|
22766
|
-
}
|
|
22767
|
-
const result = this.#addresses[contract][version];
|
|
22768
|
-
if (!result) {
|
|
22769
|
-
throw new Error(`Address ${contract}, version: ${version} not found`);
|
|
22770
|
-
}
|
|
22771
|
-
return result;
|
|
22772
|
-
}
|
|
22773
|
-
getLatestVersion(contract) {
|
|
22774
|
-
if (!this.latest[contract]) {
|
|
22775
|
-
throw new Error(`Latest version for ${contract} not found`);
|
|
22776
|
-
}
|
|
22777
|
-
this.logger?.debug(
|
|
22778
|
-
`Latest version found for ${contract} : ${this.latest[contract]}`
|
|
22575
|
+
async findBestClosePath({
|
|
22576
|
+
creditAccount: ca,
|
|
22577
|
+
creditManager: cm,
|
|
22578
|
+
slippage,
|
|
22579
|
+
balances
|
|
22580
|
+
}) {
|
|
22581
|
+
const { pathOptions, expected, leftover, connectors } = this.getFindClosePathInput(
|
|
22582
|
+
ca,
|
|
22583
|
+
cm,
|
|
22584
|
+
balances ? {
|
|
22585
|
+
expectedBalances: assetsMap(balances.expectedBalances),
|
|
22586
|
+
leftoverBalances: assetsMap(balances.leftoverBalances)
|
|
22587
|
+
} : void 0
|
|
22779
22588
|
);
|
|
22780
|
-
|
|
22781
|
-
|
|
22782
|
-
|
|
22783
|
-
|
|
22784
|
-
|
|
22785
|
-
|
|
22786
|
-
for (const log of entries) {
|
|
22787
|
-
this.setInternalAddress(log.key, log.value, Number(log.version));
|
|
22788
|
-
}
|
|
22789
|
-
}
|
|
22790
|
-
stateHuman(raw = true) {
|
|
22791
|
-
return {
|
|
22792
|
-
...super.stateHuman(raw),
|
|
22793
|
-
addresses: Object.entries(this.#addresses).map(([key, value]) => {
|
|
22794
|
-
return Object.entries(value).map(([version, address]) => {
|
|
22795
|
-
return {
|
|
22796
|
-
key,
|
|
22797
|
-
version,
|
|
22798
|
-
address: this.sdk.provider.addressLabels.get(address)
|
|
22799
|
-
};
|
|
22800
|
-
});
|
|
22801
|
-
}).reduce(
|
|
22802
|
-
(acc, vals) => {
|
|
22803
|
-
for (const val of vals) {
|
|
22804
|
-
if (!acc[val.key]) {
|
|
22805
|
-
acc[val.key] = {};
|
|
22806
|
-
}
|
|
22807
|
-
acc[val.key][val.version] = val.address;
|
|
22808
|
-
}
|
|
22809
|
-
return acc;
|
|
22810
|
-
},
|
|
22811
|
-
{}
|
|
22812
|
-
)
|
|
22813
|
-
};
|
|
22814
|
-
}
|
|
22815
|
-
processLog(log) {
|
|
22816
|
-
switch (log.eventName) {
|
|
22817
|
-
case "SetAddress": {
|
|
22818
|
-
const parsedLog2 = viem.parseEventLogs({
|
|
22819
|
-
abi: this.abi,
|
|
22820
|
-
eventName: "SetAddress",
|
|
22821
|
-
logs: [log]
|
|
22822
|
-
})[0];
|
|
22823
|
-
const key = parsedLog2.args.key;
|
|
22824
|
-
this.setInternalAddress(
|
|
22825
|
-
key,
|
|
22826
|
-
log.args.value,
|
|
22827
|
-
Number(parsedLog2.args.version)
|
|
22828
|
-
);
|
|
22829
|
-
break;
|
|
22830
|
-
}
|
|
22831
|
-
default:
|
|
22832
|
-
this.logger?.warn(`Unknown event: ${log.eventName}`);
|
|
22833
|
-
break;
|
|
22834
|
-
}
|
|
22835
|
-
}
|
|
22836
|
-
};
|
|
22837
|
-
|
|
22838
|
-
// src/sdk/core/BotListV3Contract.ts
|
|
22839
|
-
var BotListContract = class extends BaseContract {
|
|
22840
|
-
#approvedCreditManagers;
|
|
22841
|
-
#currentBlock;
|
|
22842
|
-
constructor(sdk, address) {
|
|
22843
|
-
super(sdk, { addr: address, name: "BotListV3", abi: botListV3Abi });
|
|
22844
|
-
this.#currentBlock = ADDRESS_PROVIDER_BLOCK[sdk.provider.networkType];
|
|
22845
|
-
}
|
|
22846
|
-
parseFunctionParams(params) {
|
|
22847
|
-
switch (params.functionName) {
|
|
22848
|
-
case "setCreditManagerApprovedStatus": {
|
|
22849
|
-
const [creditManager, status] = params.args;
|
|
22850
|
-
return [this.addressLabels.get(creditManager), `${status}`];
|
|
22851
|
-
}
|
|
22852
|
-
case "setBotSpecialPermissions": {
|
|
22853
|
-
const [bot, creditManager, permissions] = params.args;
|
|
22854
|
-
return [
|
|
22855
|
-
this.addressLabels.get(bot),
|
|
22856
|
-
this.addressLabels.get(creditManager),
|
|
22857
|
-
botPermissionsToString(permissions)
|
|
22858
|
-
];
|
|
22859
|
-
}
|
|
22860
|
-
default:
|
|
22861
|
-
return void 0;
|
|
22862
|
-
}
|
|
22863
|
-
}
|
|
22864
|
-
async syncState(toBlock) {
|
|
22865
|
-
const logs = await this.provider.publicClient.getContractEvents({
|
|
22866
|
-
address: this.address,
|
|
22867
|
-
abi: this.abi,
|
|
22868
|
-
fromBlock: this.#currentBlock,
|
|
22869
|
-
toBlock
|
|
22589
|
+
await this.#hooks.triggerHooks("foundPathOptions", {
|
|
22590
|
+
creditAccount: ca.creditAccount,
|
|
22591
|
+
pathOptions,
|
|
22592
|
+
expected,
|
|
22593
|
+
leftover,
|
|
22594
|
+
connectors
|
|
22870
22595
|
});
|
|
22871
|
-
|
|
22872
|
-
|
|
22873
|
-
|
|
22874
|
-
|
|
22875
|
-
|
|
22876
|
-
|
|
22877
|
-
|
|
22878
|
-
|
|
22879
|
-
|
|
22880
|
-
|
|
22881
|
-
|
|
22882
|
-
|
|
22883
|
-
|
|
22884
|
-
|
|
22885
|
-
|
|
22886
|
-
|
|
22887
|
-
|
|
22888
|
-
|
|
22889
|
-
|
|
22890
|
-
|
|
22891
|
-
|
|
22892
|
-
break;
|
|
22596
|
+
let results = [];
|
|
22597
|
+
for (const po of pathOptions) {
|
|
22598
|
+
const { result: result2 } = await this.contract.simulate.findBestClosePath(
|
|
22599
|
+
[
|
|
22600
|
+
ca.creditAccount,
|
|
22601
|
+
expected,
|
|
22602
|
+
leftover,
|
|
22603
|
+
connectors,
|
|
22604
|
+
BigInt(slippage),
|
|
22605
|
+
po,
|
|
22606
|
+
BigInt(LOOPS_PER_TX),
|
|
22607
|
+
false
|
|
22608
|
+
],
|
|
22609
|
+
{
|
|
22610
|
+
gas: GAS_PER_BLOCK
|
|
22611
|
+
}
|
|
22612
|
+
);
|
|
22613
|
+
results.push({
|
|
22614
|
+
...result2,
|
|
22615
|
+
calls: [...result2.calls]
|
|
22616
|
+
});
|
|
22893
22617
|
}
|
|
22618
|
+
const bestResult = results.reduce(compareRouterResults, {
|
|
22619
|
+
amount: 0n,
|
|
22620
|
+
minAmount: 0n,
|
|
22621
|
+
calls: []
|
|
22622
|
+
});
|
|
22623
|
+
const underlyingBalance = ca.tokens.find((t) => t.token === ca.underlying)?.balance ?? 0n;
|
|
22624
|
+
const result = {
|
|
22625
|
+
amount: bestResult.amount,
|
|
22626
|
+
minAmount: bestResult.minAmount,
|
|
22627
|
+
calls: bestResult.calls.map((c) => ({
|
|
22628
|
+
callData: c.callData,
|
|
22629
|
+
target: c.target
|
|
22630
|
+
})),
|
|
22631
|
+
underlyingBalance: underlyingBalance + bestResult.minAmount
|
|
22632
|
+
};
|
|
22633
|
+
return result;
|
|
22894
22634
|
}
|
|
22895
|
-
|
|
22896
|
-
|
|
22897
|
-
|
|
22898
|
-
|
|
22899
|
-
|
|
22635
|
+
/**
|
|
22636
|
+
* Finds input to be used with findBestClosePath
|
|
22637
|
+
* @param ca
|
|
22638
|
+
* @param cm
|
|
22639
|
+
* @returns
|
|
22640
|
+
*/
|
|
22641
|
+
getFindClosePathInput(ca, cm, balances) {
|
|
22642
|
+
const b = balances || this.getDefaultExpectedAndLeftover(ca);
|
|
22643
|
+
const { leftoverBalances, expectedBalances } = b;
|
|
22644
|
+
const pathOptions = PathOptionFactory.generatePathOptions(
|
|
22645
|
+
ca.tokens,
|
|
22646
|
+
this.provider.networkType,
|
|
22647
|
+
LOOPS_PER_TX
|
|
22648
|
+
);
|
|
22649
|
+
const expected = cm.collateralTokens.map((token) => {
|
|
22650
|
+
const actual = expectedBalances.get(token)?.balance || 0n;
|
|
22651
|
+
return {
|
|
22652
|
+
token,
|
|
22653
|
+
balance: actual > 10n ? actual : 0n
|
|
22654
|
+
};
|
|
22655
|
+
});
|
|
22656
|
+
const leftover = cm.collateralTokens.map((token) => ({
|
|
22657
|
+
token,
|
|
22658
|
+
balance: leftoverBalances.get(token)?.balance || 1n
|
|
22659
|
+
}));
|
|
22660
|
+
const connectors = this.getAvailableConnectors(cm.collateralTokens);
|
|
22661
|
+
return { expected, leftover, connectors, pathOptions };
|
|
22662
|
+
}
|
|
22663
|
+
getDefaultExpectedAndLeftover(ca) {
|
|
22664
|
+
const expectedBalances = new AddressMap();
|
|
22665
|
+
const leftoverBalances = new AddressMap();
|
|
22666
|
+
for (const { token: t, balance, mask } of ca.tokens) {
|
|
22667
|
+
const token = t;
|
|
22668
|
+
const isEnabled = (mask & ca.enabledTokensMask) !== 0n;
|
|
22669
|
+
expectedBalances.upsert(token, { token, balance });
|
|
22670
|
+
const decimals = this.sdk.tokensMeta.decimals(token);
|
|
22671
|
+
const minBalance = 10n ** BigInt(Math.max(8, decimals) - 8);
|
|
22672
|
+
if (balance < minBalance || !isEnabled) {
|
|
22673
|
+
leftoverBalances.upsert(token, { token, balance });
|
|
22674
|
+
}
|
|
22900
22675
|
}
|
|
22901
|
-
return
|
|
22676
|
+
return { expectedBalances, leftoverBalances };
|
|
22902
22677
|
}
|
|
22903
|
-
|
|
22904
|
-
return
|
|
22678
|
+
getAvailableConnectors(collateralTokens) {
|
|
22679
|
+
return collateralTokens.filter(
|
|
22680
|
+
(t) => this.#connectors.includes(t.toLowerCase())
|
|
22681
|
+
);
|
|
22905
22682
|
}
|
|
22906
22683
|
};
|
|
22684
|
+
function compareRouterResults(a, b) {
|
|
22685
|
+
return a.amount > b.amount ? a : b;
|
|
22686
|
+
}
|
|
22687
|
+
function balancesMap(assets) {
|
|
22688
|
+
return new AddressMap(assets.map(({ token, balance }) => [token, balance]));
|
|
22689
|
+
}
|
|
22690
|
+
function assetsMap(assets) {
|
|
22691
|
+
return new AddressMap(assets.map((a) => [a.token, a]));
|
|
22692
|
+
}
|
|
22907
22693
|
|
|
22908
|
-
// src/sdk/
|
|
22909
|
-
var
|
|
22910
|
-
|
|
22911
|
-
|
|
22694
|
+
// src/sdk/accounts/CreditAccountsService.ts
|
|
22695
|
+
var CreditAccountsService = class extends SDKConstruct {
|
|
22696
|
+
#compressor;
|
|
22697
|
+
constructor(sdk) {
|
|
22698
|
+
super(sdk);
|
|
22699
|
+
this.#compressor = sdk.addressProvider.getLatestVersion(
|
|
22700
|
+
AP_CREDIT_ACCOUNT_COMPRESSOR
|
|
22701
|
+
);
|
|
22912
22702
|
}
|
|
22913
|
-
|
|
22914
|
-
|
|
22915
|
-
|
|
22916
|
-
|
|
22917
|
-
|
|
22918
|
-
|
|
22919
|
-
|
|
22920
|
-
|
|
22703
|
+
/**
|
|
22704
|
+
* Returns single credit account data, or undefined if it's not found
|
|
22705
|
+
* Performs all necessary price feed updates under the hood
|
|
22706
|
+
* @param account
|
|
22707
|
+
* @param options
|
|
22708
|
+
* @returns
|
|
22709
|
+
*/
|
|
22710
|
+
async getCreditAccountData(account, options) {
|
|
22711
|
+
const blockNumber = options?.blockNumber;
|
|
22712
|
+
let raw;
|
|
22713
|
+
try {
|
|
22714
|
+
raw = await this.provider.publicClient.readContract({
|
|
22715
|
+
abi: iCreditAccountCompressorAbi,
|
|
22716
|
+
address: this.#compressor,
|
|
22717
|
+
functionName: "getCreditAccountData",
|
|
22718
|
+
args: [account],
|
|
22719
|
+
blockNumber
|
|
22720
|
+
});
|
|
22721
|
+
} catch (e) {
|
|
22722
|
+
return void 0;
|
|
22921
22723
|
}
|
|
22724
|
+
if (raw.success) {
|
|
22725
|
+
return raw;
|
|
22726
|
+
}
|
|
22727
|
+
const { txs: priceUpdateTxs, timestamp: _ } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs();
|
|
22728
|
+
const resp = await simulateMulticall(this.provider.publicClient, {
|
|
22729
|
+
contracts: [
|
|
22730
|
+
...priceUpdateTxs.map(rawTxToMulticallPriceUpdate),
|
|
22731
|
+
{
|
|
22732
|
+
abi: iCreditAccountCompressorAbi,
|
|
22733
|
+
address: this.#compressor,
|
|
22734
|
+
functionName: "getCreditAccountData",
|
|
22735
|
+
args: [account]
|
|
22736
|
+
}
|
|
22737
|
+
],
|
|
22738
|
+
allowFailure: false,
|
|
22739
|
+
gas: 550000000n,
|
|
22740
|
+
batchSize: 0,
|
|
22741
|
+
// we cannot have price updates and compressor request in different batches
|
|
22742
|
+
blockNumber
|
|
22743
|
+
});
|
|
22744
|
+
const cad = resp.pop();
|
|
22745
|
+
return cad;
|
|
22922
22746
|
}
|
|
22923
|
-
|
|
22924
|
-
|
|
22925
|
-
|
|
22926
|
-
|
|
22927
|
-
|
|
22747
|
+
/**
|
|
22748
|
+
* Methods to get all credit accounts with some optional filtering
|
|
22749
|
+
* Performs all necessary price feed updates under the hood
|
|
22750
|
+
*
|
|
22751
|
+
* TODO: do we want to expose pagination?
|
|
22752
|
+
* TODO: do we want to expose "reverting"?
|
|
22753
|
+
* TODO: do we want to expose MarketFilter in any way? If so, we need to check that the MarketFilter is compatibled with attached markets?
|
|
22754
|
+
* @param args
|
|
22755
|
+
* @param options
|
|
22756
|
+
* @returns returned credit accounts are sorted by health factor in ascending order
|
|
22757
|
+
*/
|
|
22758
|
+
async getCreditAccounts(args, options) {
|
|
22759
|
+
const {
|
|
22760
|
+
creditManager,
|
|
22761
|
+
includeZeroDebt = false,
|
|
22762
|
+
maxHealthFactor = 65535,
|
|
22763
|
+
// TODO: this will change to bigint
|
|
22764
|
+
minHealthFactor = 0,
|
|
22765
|
+
owner = ADDRESS_0X0
|
|
22766
|
+
} = args ?? {};
|
|
22767
|
+
const arg0 = creditManager ?? {
|
|
22768
|
+
curators: [],
|
|
22769
|
+
pools: this.pools,
|
|
22770
|
+
underlying: ADDRESS_0X0
|
|
22771
|
+
};
|
|
22772
|
+
const caFilter = {
|
|
22773
|
+
owner,
|
|
22774
|
+
includeZeroDebt,
|
|
22775
|
+
minHealthFactor,
|
|
22776
|
+
maxHealthFactor
|
|
22928
22777
|
};
|
|
22778
|
+
const { txs: priceUpdateTxs, timestamp: _ } = await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs();
|
|
22779
|
+
const allCAs = [];
|
|
22780
|
+
for (const reverting of [false, true]) {
|
|
22781
|
+
let offset = 0n;
|
|
22782
|
+
do {
|
|
22783
|
+
const [accounts, newOffset] = await this.#getCreditAccounts(
|
|
22784
|
+
[arg0, { ...caFilter, reverting }, offset],
|
|
22785
|
+
priceUpdateTxs,
|
|
22786
|
+
options
|
|
22787
|
+
);
|
|
22788
|
+
allCAs.push(...accounts);
|
|
22789
|
+
offset = newOffset;
|
|
22790
|
+
} while (offset !== 0n);
|
|
22791
|
+
}
|
|
22792
|
+
return allCAs.sort((a, b) => Number(a.healthFactor - b.healthFactor));
|
|
22929
22793
|
}
|
|
22930
|
-
|
|
22931
|
-
|
|
22932
|
-
|
|
22933
|
-
|
|
22934
|
-
|
|
22935
|
-
|
|
22936
|
-
|
|
22937
|
-
|
|
22938
|
-
|
|
22939
|
-
|
|
22940
|
-
|
|
22941
|
-
|
|
22794
|
+
/**
|
|
22795
|
+
* Generates transaction to liquidate credit account
|
|
22796
|
+
* @param account
|
|
22797
|
+
* @param to Address to transfer underlying left after liquidation
|
|
22798
|
+
* @param slippage
|
|
22799
|
+
* @returns
|
|
22800
|
+
*/
|
|
22801
|
+
async fullyLiquidate(account, to, slippage = 50n) {
|
|
22802
|
+
const cm = this.sdk.marketRegister.findCreditManager(account.creditManager);
|
|
22803
|
+
const routerCloseResult = await this.sdk.router.findBestClosePath({
|
|
22804
|
+
creditAccount: account,
|
|
22805
|
+
creditManager: cm.creditManager,
|
|
22806
|
+
slippage
|
|
22942
22807
|
});
|
|
22943
|
-
const
|
|
22944
|
-
|
|
22945
|
-
|
|
22946
|
-
|
|
22947
|
-
|
|
22948
|
-
|
|
22808
|
+
const priceUpdates = await this.getPriceUpdatesForFacade(account);
|
|
22809
|
+
const tx = cm.creditFacade.liquidateCreditAccount(
|
|
22810
|
+
account.creditAccount,
|
|
22811
|
+
to,
|
|
22812
|
+
[...priceUpdates, ...routerCloseResult.calls]
|
|
22813
|
+
);
|
|
22814
|
+
return { tx, routerCloseResult };
|
|
22815
|
+
}
|
|
22816
|
+
/**
|
|
22817
|
+
* Closes credit account or sets debt to zero (but keep account)
|
|
22818
|
+
* @param operation
|
|
22819
|
+
* @param creditAccount
|
|
22820
|
+
* @param assetsToWithdraw Tokens to withdraw from credit account
|
|
22821
|
+
* @param to Address to withdraw underlying to
|
|
22822
|
+
* @param slippage
|
|
22823
|
+
* @param closePath
|
|
22824
|
+
* @returns
|
|
22825
|
+
*/
|
|
22826
|
+
async closeCreditAccount({
|
|
22827
|
+
operation,
|
|
22828
|
+
assetsToWithdraw,
|
|
22829
|
+
creditAccount: ca,
|
|
22830
|
+
to,
|
|
22831
|
+
slippage = 50n,
|
|
22832
|
+
closePath
|
|
22833
|
+
}) {
|
|
22834
|
+
const cm = this.sdk.marketRegister.findCreditManager(ca.creditManager);
|
|
22835
|
+
const routerCloseResult = closePath || await this.sdk.router.findBestClosePath({
|
|
22836
|
+
creditAccount: ca,
|
|
22837
|
+
creditManager: cm.creditManager,
|
|
22838
|
+
slippage
|
|
22949
22839
|
});
|
|
22950
|
-
const
|
|
22951
|
-
|
|
22952
|
-
(
|
|
22953
|
-
|
|
22840
|
+
const calls = [
|
|
22841
|
+
...routerCloseResult.calls,
|
|
22842
|
+
...this.#prepareDisableQuotas(ca),
|
|
22843
|
+
...this.#prepareDecreaseDebt(ca),
|
|
22844
|
+
...this.#prepareDisableTokens(ca),
|
|
22845
|
+
...assetsToWithdraw.map(
|
|
22846
|
+
(t) => this.#prepareWithdrawToken(ca, t, MAX_UINT256, to)
|
|
22847
|
+
)
|
|
22848
|
+
];
|
|
22849
|
+
const tx = operation === "close" ? cm.creditFacade.closeCreditAccount(ca.creditAccount, calls) : cm.creditFacade.multicall(ca.creditAccount, calls);
|
|
22850
|
+
return { tx, calls, routerCloseResult };
|
|
22851
|
+
}
|
|
22852
|
+
/**
|
|
22853
|
+
* Repays credit account or sets debt to zero (but keep account)
|
|
22854
|
+
* @param operation
|
|
22855
|
+
* @param creditAccount
|
|
22856
|
+
* @param assetsToWithdraw Tokens to withdraw from credit account
|
|
22857
|
+
* @param collateralAssets Tokens to pay for
|
|
22858
|
+
* @param to Address to withdraw underlying to
|
|
22859
|
+
* @param slippage
|
|
22860
|
+
* @param permits
|
|
22861
|
+
* @returns
|
|
22862
|
+
*/
|
|
22863
|
+
async repayCreditAccount({
|
|
22864
|
+
operation,
|
|
22865
|
+
collateralAssets,
|
|
22866
|
+
assetsToWithdraw,
|
|
22867
|
+
creditAccount: ca,
|
|
22868
|
+
permits,
|
|
22869
|
+
to
|
|
22870
|
+
}) {
|
|
22871
|
+
const cm = this.sdk.marketRegister.findCreditManager(ca.creditManager);
|
|
22872
|
+
const addCollateral = collateralAssets.filter((a) => a.balance > 0);
|
|
22873
|
+
const calls = [
|
|
22874
|
+
...this.#prepareAddCollateral(addCollateral, ca, permits),
|
|
22875
|
+
...this.#prepareDisableQuotas(ca),
|
|
22876
|
+
...this.#prepareDecreaseDebt(ca),
|
|
22877
|
+
...this.#prepareDisableTokens(ca),
|
|
22878
|
+
// TODO: probably needs a way to handle reward tokens
|
|
22879
|
+
...assetsToWithdraw.map(
|
|
22880
|
+
(t) => this.#prepareWithdrawToken(ca, t, MAX_UINT256, to)
|
|
22881
|
+
)
|
|
22882
|
+
];
|
|
22883
|
+
const tx = operation === "close" ? cm.creditFacade.closeCreditAccount(ca.creditAccount, calls) : cm.creditFacade.multicall(ca.creditAccount, calls);
|
|
22884
|
+
return { tx, calls };
|
|
22885
|
+
}
|
|
22886
|
+
/**
|
|
22887
|
+
* Repays liquidatable credit account
|
|
22888
|
+
* @param creditAccount
|
|
22889
|
+
* @param assetsToWithdraw Tokens to withdraw from credit account
|
|
22890
|
+
* @param collateralAssets Tokens to pay for
|
|
22891
|
+
* @param to Address to withdraw underlying to
|
|
22892
|
+
* @param slippage
|
|
22893
|
+
* @returns
|
|
22894
|
+
*/
|
|
22895
|
+
async repayAndLiquidateCreditAccount({
|
|
22896
|
+
collateralAssets,
|
|
22897
|
+
assetsToWithdraw,
|
|
22898
|
+
creditAccount: ca,
|
|
22899
|
+
permits,
|
|
22900
|
+
to
|
|
22901
|
+
}) {
|
|
22902
|
+
const cm = this.sdk.marketRegister.findCreditManager(ca.creditManager);
|
|
22903
|
+
const priceUpdates = await this.getPriceUpdatesForFacade(ca);
|
|
22904
|
+
const addCollateral = collateralAssets.filter((a) => a.balance > 0);
|
|
22905
|
+
const calls = [
|
|
22906
|
+
...priceUpdates,
|
|
22907
|
+
...this.#prepareAddCollateral(addCollateral, ca, permits),
|
|
22908
|
+
...assetsToWithdraw.map(
|
|
22909
|
+
(t) => this.#prepareWithdrawToken(ca, t, MAX_UINT256, to)
|
|
22910
|
+
)
|
|
22911
|
+
];
|
|
22912
|
+
const tx = cm.creditFacade.liquidateCreditAccount(
|
|
22913
|
+
ca.creditAccount,
|
|
22914
|
+
to,
|
|
22915
|
+
calls
|
|
22954
22916
|
);
|
|
22955
|
-
|
|
22956
|
-
let currentPo = [...initPO];
|
|
22957
|
-
for (let i = 0; i < totalLoops; i++) {
|
|
22958
|
-
if (i % loopsInTx === 0) {
|
|
22959
|
-
result.push(currentPo);
|
|
22960
|
-
}
|
|
22961
|
-
if (i < totalLoops - 1) {
|
|
22962
|
-
currentPo = _PathOptionFactory.next(currentPo);
|
|
22963
|
-
}
|
|
22964
|
-
}
|
|
22965
|
-
return result;
|
|
22917
|
+
return { tx, calls };
|
|
22966
22918
|
}
|
|
22967
|
-
|
|
22968
|
-
const
|
|
22969
|
-
const
|
|
22970
|
-
|
|
22971
|
-
const curvePoolsFromYearn = nonZeroBalances.map((b) => sdkGov.getTokenSymbol(b.token)).filter((symbol) => yearnCurveTokens.includes(symbol)).map(
|
|
22972
|
-
(symbol) => sdkGov.yearnTokens[symbol].underlying
|
|
22919
|
+
async updateQuotas(props) {
|
|
22920
|
+
const { creditAccount } = props;
|
|
22921
|
+
const cm = this.sdk.marketRegister.findCreditManager(
|
|
22922
|
+
creditAccount.creditManager
|
|
22973
22923
|
);
|
|
22974
|
-
const
|
|
22975
|
-
const
|
|
22976
|
-
|
|
22977
|
-
...
|
|
22978
|
-
|
|
22979
|
-
|
|
22924
|
+
const priceUpdates = await this.getPriceUpdatesForFacade(creditAccount);
|
|
22925
|
+
const calls = [
|
|
22926
|
+
...priceUpdates,
|
|
22927
|
+
...this.#prepareUpdateQuotas(props)
|
|
22928
|
+
];
|
|
22929
|
+
const tx = cm.creditFacade.multicall(creditAccount.creditAccount, [
|
|
22930
|
+
...priceUpdates,
|
|
22931
|
+
...this.#prepareUpdateQuotas(props)
|
|
22980
22932
|
]);
|
|
22981
|
-
return
|
|
22933
|
+
return {
|
|
22934
|
+
tx,
|
|
22935
|
+
calls
|
|
22936
|
+
};
|
|
22982
22937
|
}
|
|
22983
|
-
|
|
22984
|
-
const
|
|
22985
|
-
|
|
22938
|
+
async addCollateral(props) {
|
|
22939
|
+
const { creditAccount, asset, permit, ethAmount } = props;
|
|
22940
|
+
const cm = this.sdk.marketRegister.findCreditManager(
|
|
22941
|
+
creditAccount.creditManager
|
|
22986
22942
|
);
|
|
22987
|
-
const
|
|
22988
|
-
const
|
|
22989
|
-
|
|
22990
|
-
|
|
22943
|
+
const priceUpdatesCalls = await this.getPriceUpdatesForFacade(creditAccount);
|
|
22944
|
+
const addCollateralCalls = this.#prepareAddCollateral(
|
|
22945
|
+
[asset],
|
|
22946
|
+
creditAccount,
|
|
22947
|
+
permit ? { [asset.token]: permit } : {}
|
|
22991
22948
|
);
|
|
22992
|
-
const
|
|
22993
|
-
|
|
22949
|
+
const updateQuotaCalls = this.#prepareUpdateQuotas(props);
|
|
22950
|
+
const calls = [
|
|
22951
|
+
...priceUpdatesCalls,
|
|
22952
|
+
...addCollateralCalls,
|
|
22953
|
+
...updateQuotaCalls
|
|
22954
|
+
];
|
|
22955
|
+
const tx = cm.creditFacade.multicall(creditAccount.creditAccount, calls);
|
|
22956
|
+
tx.value = ethAmount.toString(10);
|
|
22957
|
+
return { tx, calls };
|
|
22994
22958
|
}
|
|
22995
|
-
|
|
22996
|
-
|
|
22997
|
-
|
|
22998
|
-
|
|
22999
|
-
|
|
23000
|
-
|
|
23001
|
-
if (po.option < po.totalOptions) return newPath;
|
|
23002
|
-
po.option = 0;
|
|
22959
|
+
async changeDebt({
|
|
22960
|
+
creditAccount,
|
|
22961
|
+
amount
|
|
22962
|
+
}) {
|
|
22963
|
+
if (amount === 0n) {
|
|
22964
|
+
throw new Error("debt increase or decrease must be non-zero");
|
|
23003
22965
|
}
|
|
23004
|
-
|
|
22966
|
+
const isDecrease = amount < 0n;
|
|
22967
|
+
const change = isDecrease ? -amount : amount;
|
|
22968
|
+
const cm = this.sdk.marketRegister.findCreditManager(
|
|
22969
|
+
creditAccount.creditManager
|
|
22970
|
+
);
|
|
22971
|
+
const priceUpdatesCalls = await this.getPriceUpdatesForFacade(creditAccount);
|
|
22972
|
+
const underlyingEnabled = (creditAccount.enabledTokensMask & 1n) === 1n;
|
|
22973
|
+
const shouldEnable = !isDecrease && !underlyingEnabled;
|
|
22974
|
+
const calls = [
|
|
22975
|
+
...priceUpdatesCalls,
|
|
22976
|
+
...shouldEnable ? this.#prepareEnableTokens(creditAccount, [creditAccount.underlying]) : [],
|
|
22977
|
+
{
|
|
22978
|
+
target: creditAccount.creditFacade,
|
|
22979
|
+
callData: viem.encodeFunctionData({
|
|
22980
|
+
abi: iCreditFacadeV3MulticallAbi,
|
|
22981
|
+
functionName: isDecrease ? "increaseDebt" : "decreaseDebt",
|
|
22982
|
+
args: [change]
|
|
22983
|
+
})
|
|
22984
|
+
}
|
|
22985
|
+
];
|
|
22986
|
+
const tx = cm.creditFacade.multicall(creditAccount.creditAccount, calls);
|
|
22987
|
+
return { tx, calls };
|
|
23005
22988
|
}
|
|
23006
|
-
|
|
23007
|
-
|
|
23008
|
-
|
|
23009
|
-
|
|
23010
|
-
|
|
23011
|
-
|
|
23012
|
-
|
|
23013
|
-
|
|
23014
|
-
|
|
23015
|
-
|
|
23016
|
-
|
|
23017
|
-
|
|
23018
|
-
|
|
23019
|
-
|
|
23020
|
-
|
|
23021
|
-
|
|
23022
|
-
|
|
23023
|
-
|
|
23024
|
-
|
|
22989
|
+
/**
|
|
22990
|
+
* Internal wrapper for CreditAccountCompressor.getCreditAccounts + price updates wrapped into multicall
|
|
22991
|
+
* @param args
|
|
22992
|
+
* @param priceUpdateTxs
|
|
22993
|
+
* @param options
|
|
22994
|
+
* @returns
|
|
22995
|
+
*/
|
|
22996
|
+
async #getCreditAccounts(args, priceUpdateTxs, options) {
|
|
22997
|
+
const blockNumber = options?.blockNumber;
|
|
22998
|
+
if (priceUpdateTxs?.length) {
|
|
22999
|
+
const resp = await simulateMulticall(this.provider.publicClient, {
|
|
23000
|
+
contracts: [
|
|
23001
|
+
...priceUpdateTxs.map(rawTxToMulticallPriceUpdate),
|
|
23002
|
+
{
|
|
23003
|
+
abi: iCreditAccountCompressorAbi,
|
|
23004
|
+
address: this.#compressor,
|
|
23005
|
+
functionName: "getCreditAccounts",
|
|
23006
|
+
args
|
|
23007
|
+
}
|
|
23008
|
+
],
|
|
23009
|
+
allowFailure: false,
|
|
23010
|
+
gas: 550000000n,
|
|
23011
|
+
batchSize: 0,
|
|
23012
|
+
// we cannot have price updates and compressor request in different batches
|
|
23013
|
+
blockNumber
|
|
23014
|
+
});
|
|
23015
|
+
const getCreditAccountsResp = resp.pop();
|
|
23016
|
+
return getCreditAccountsResp;
|
|
23017
|
+
}
|
|
23018
|
+
return this.provider.publicClient.readContract({
|
|
23019
|
+
abi: iCreditAccountCompressorAbi,
|
|
23020
|
+
address: this.#compressor,
|
|
23021
|
+
functionName: "getCreditAccounts",
|
|
23022
|
+
args,
|
|
23023
|
+
blockNumber
|
|
23025
23024
|
});
|
|
23026
|
-
this.#connectors = sdkGov.getConnectors(sdk.provider.networkType);
|
|
23027
23025
|
}
|
|
23028
|
-
addHook = this.#hooks.addHook.bind(this.#hooks);
|
|
23029
|
-
removeHook = this.#hooks.removeHook.bind(this.#hooks);
|
|
23030
23026
|
/**
|
|
23031
|
-
*
|
|
23032
|
-
* @param
|
|
23033
|
-
* @param cm
|
|
23034
|
-
* @param swapOperation
|
|
23035
|
-
* @param tokenIn
|
|
23036
|
-
* @param tokenOut
|
|
23037
|
-
* @param amount
|
|
23038
|
-
* @param leftoverAmount
|
|
23039
|
-
* @param slippage
|
|
23027
|
+
* Returns raw txs that are needed to update all price feeds so that all credit accounts (possibly from different markets) compute
|
|
23028
|
+
* @param accounts
|
|
23040
23029
|
* @returns
|
|
23041
23030
|
*/
|
|
23042
|
-
async
|
|
23043
|
-
|
|
23044
|
-
|
|
23045
|
-
|
|
23046
|
-
|
|
23047
|
-
|
|
23048
|
-
|
|
23049
|
-
|
|
23050
|
-
|
|
23051
|
-
|
|
23052
|
-
|
|
23053
|
-
|
|
23054
|
-
|
|
23055
|
-
|
|
23056
|
-
|
|
23057
|
-
tokenOut,
|
|
23058
|
-
connectors,
|
|
23059
|
-
amount,
|
|
23060
|
-
leftoverAmount
|
|
23061
|
-
};
|
|
23062
|
-
const { result } = await this.contract.simulate.findAllSwaps(
|
|
23063
|
-
[swapTask, BigInt(slippage)],
|
|
23064
|
-
{
|
|
23065
|
-
gas: GAS_PER_BLOCK
|
|
23031
|
+
async getUpdateForAccounts(accounts) {
|
|
23032
|
+
const tokensByPool = /* @__PURE__ */ new Map();
|
|
23033
|
+
const oracleByPool = /* @__PURE__ */ new Map();
|
|
23034
|
+
for (const acc of accounts) {
|
|
23035
|
+
const market = this.sdk.marketRegister.findByCreditManager(
|
|
23036
|
+
acc.creditManager
|
|
23037
|
+
);
|
|
23038
|
+
const pool = market.poolFactory.pool.address;
|
|
23039
|
+
oracleByPool.set(pool, market.priceOracle);
|
|
23040
|
+
for (const t of acc.tokens) {
|
|
23041
|
+
if (t.balance > 10n) {
|
|
23042
|
+
const tokens = tokensByPool.get(pool) ?? /* @__PURE__ */ new Set();
|
|
23043
|
+
tokens.add(t.token);
|
|
23044
|
+
tokensByPool.set(pool, tokens);
|
|
23045
|
+
}
|
|
23066
23046
|
}
|
|
23047
|
+
}
|
|
23048
|
+
const priceFeeds = [];
|
|
23049
|
+
for (const [pool, priceFeedFactory] of oracleByPool.entries()) {
|
|
23050
|
+
const tokens = Array.from(tokensByPool.get(pool) ?? []);
|
|
23051
|
+
priceFeeds.push(...priceFeedFactory.priceFeedsForTokens(tokens));
|
|
23052
|
+
}
|
|
23053
|
+
return this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(priceFeeds);
|
|
23054
|
+
}
|
|
23055
|
+
/**
|
|
23056
|
+
* Returns account price updates in a non-encoded format
|
|
23057
|
+
* @param acc
|
|
23058
|
+
* @returns
|
|
23059
|
+
*/
|
|
23060
|
+
async getOnDemandPriceUpdates(acc) {
|
|
23061
|
+
const market = this.sdk.marketRegister.findByCreditManager(
|
|
23062
|
+
acc.creditManager
|
|
23067
23063
|
);
|
|
23068
|
-
const
|
|
23069
|
-
|
|
23070
|
-
const key = `${r.minAmount.toString()}${r.calls.map((c) => `${c.target.toLowerCase()}${c.callData}`).join("-")}`;
|
|
23071
|
-
unique[key] = {
|
|
23072
|
-
amount: r.amount,
|
|
23073
|
-
minAmount: r.minAmount,
|
|
23074
|
-
calls: [...r.calls]
|
|
23075
|
-
};
|
|
23076
|
-
});
|
|
23077
|
-
return Object.values(unique);
|
|
23064
|
+
const update = await this.getUpdateForAccounts([acc]);
|
|
23065
|
+
return market.priceOracle.onDemandPriceUpdates(update);
|
|
23078
23066
|
}
|
|
23079
23067
|
/**
|
|
23080
|
-
*
|
|
23081
|
-
* @param
|
|
23082
|
-
* @param creditManager
|
|
23083
|
-
* @param tokenIn
|
|
23084
|
-
* @param tokenOut
|
|
23085
|
-
* @param amount
|
|
23086
|
-
* @param slippage
|
|
23068
|
+
* Returns price updates in format that is accepted by various credit facade methods (multicall, close/liquidate, etc...)
|
|
23069
|
+
* @param acc
|
|
23087
23070
|
* @returns
|
|
23088
23071
|
*/
|
|
23089
|
-
async
|
|
23090
|
-
|
|
23091
|
-
|
|
23092
|
-
|
|
23093
|
-
|
|
23094
|
-
|
|
23095
|
-
|
|
23096
|
-
|
|
23097
|
-
|
|
23098
|
-
|
|
23099
|
-
|
|
23100
|
-
|
|
23101
|
-
|
|
23102
|
-
|
|
23103
|
-
|
|
23104
|
-
|
|
23105
|
-
|
|
23106
|
-
],
|
|
23107
|
-
{
|
|
23108
|
-
gas: GAS_PER_BLOCK
|
|
23072
|
+
async getPriceUpdatesForFacade(acc) {
|
|
23073
|
+
const cm = this.sdk.marketRegister.findCreditManager(acc.creditManager);
|
|
23074
|
+
const updates = await this.getOnDemandPriceUpdates(acc);
|
|
23075
|
+
return cm.creditFacade.encodeOnDemandPriceUpdates(updates);
|
|
23076
|
+
}
|
|
23077
|
+
#prepareDisableQuotas(ca) {
|
|
23078
|
+
const calls = [];
|
|
23079
|
+
for (const { token, quota } of ca.tokens) {
|
|
23080
|
+
if (quota > 0n) {
|
|
23081
|
+
calls.push({
|
|
23082
|
+
target: ca.creditFacade,
|
|
23083
|
+
callData: viem.encodeFunctionData({
|
|
23084
|
+
abi: iCreditFacadeV3MulticallAbi,
|
|
23085
|
+
functionName: "updateQuota",
|
|
23086
|
+
args: [token, MIN_INT96, 0n]
|
|
23087
|
+
})
|
|
23088
|
+
});
|
|
23109
23089
|
}
|
|
23110
|
-
|
|
23090
|
+
}
|
|
23091
|
+
return calls;
|
|
23092
|
+
}
|
|
23093
|
+
#prepareUpdateQuotas(props) {
|
|
23094
|
+
const { creditAccount, averageQuota, minQuota } = props;
|
|
23095
|
+
const minRecord = assetsMap(minQuota);
|
|
23096
|
+
const calls = averageQuota.map((q) => {
|
|
23097
|
+
const minAsset = minRecord.get(q.token);
|
|
23098
|
+
const min = minAsset && minAsset?.balance > 0 ? minAsset.balance : 0n;
|
|
23099
|
+
return {
|
|
23100
|
+
target: creditAccount.creditFacade,
|
|
23101
|
+
callData: viem.encodeFunctionData({
|
|
23102
|
+
abi: iCreditFacadeV3MulticallAbi,
|
|
23103
|
+
functionName: "updateQuota",
|
|
23104
|
+
args: [q.token, q.balance, min]
|
|
23105
|
+
})
|
|
23106
|
+
};
|
|
23107
|
+
});
|
|
23108
|
+
return calls;
|
|
23109
|
+
}
|
|
23110
|
+
#prepareDecreaseDebt(ca) {
|
|
23111
|
+
if (ca.debt > 0n) {
|
|
23112
|
+
return [
|
|
23113
|
+
{
|
|
23114
|
+
target: ca.creditFacade,
|
|
23115
|
+
callData: viem.encodeFunctionData({
|
|
23116
|
+
abi: iCreditFacadeV3MulticallAbi,
|
|
23117
|
+
functionName: "decreaseDebt",
|
|
23118
|
+
args: [MAX_UINT256]
|
|
23119
|
+
})
|
|
23120
|
+
}
|
|
23121
|
+
];
|
|
23122
|
+
}
|
|
23123
|
+
return [];
|
|
23124
|
+
}
|
|
23125
|
+
#prepareDisableTokens(ca) {
|
|
23126
|
+
const calls = [];
|
|
23127
|
+
for (const t of ca.tokens) {
|
|
23128
|
+
if (t.token !== ca.underlying && (t.mask & ca.enabledTokensMask) !== 0n && t.quota === 0n) {
|
|
23129
|
+
calls.push({
|
|
23130
|
+
target: ca.creditFacade,
|
|
23131
|
+
callData: viem.encodeFunctionData({
|
|
23132
|
+
abi: iCreditFacadeV3MulticallAbi,
|
|
23133
|
+
functionName: "disableToken",
|
|
23134
|
+
args: [t.token]
|
|
23135
|
+
})
|
|
23136
|
+
});
|
|
23137
|
+
}
|
|
23138
|
+
}
|
|
23139
|
+
return calls;
|
|
23140
|
+
}
|
|
23141
|
+
#prepareEnableTokens(ca, tokens) {
|
|
23142
|
+
return tokens.map((t) => ({
|
|
23143
|
+
target: ca.creditFacade,
|
|
23144
|
+
callData: viem.encodeFunctionData({
|
|
23145
|
+
abi: iCreditFacadeV3MulticallAbi,
|
|
23146
|
+
functionName: "enableToken",
|
|
23147
|
+
args: [t]
|
|
23148
|
+
})
|
|
23149
|
+
}));
|
|
23150
|
+
}
|
|
23151
|
+
#prepareWithdrawToken(ca, token, amount, to) {
|
|
23111
23152
|
return {
|
|
23112
|
-
|
|
23113
|
-
|
|
23114
|
-
|
|
23153
|
+
target: ca.creditFacade,
|
|
23154
|
+
callData: viem.encodeFunctionData({
|
|
23155
|
+
abi: iCreditFacadeV3MulticallAbi,
|
|
23156
|
+
functionName: "withdrawCollateral",
|
|
23157
|
+
args: [token, amount, to]
|
|
23158
|
+
})
|
|
23115
23159
|
};
|
|
23116
23160
|
}
|
|
23161
|
+
#prepareAddCollateral(assets, ca, permits) {
|
|
23162
|
+
const calls = assets.map(({ token, balance }) => {
|
|
23163
|
+
const p = permits[token];
|
|
23164
|
+
if (p) {
|
|
23165
|
+
return {
|
|
23166
|
+
target: ca.creditFacade,
|
|
23167
|
+
callData: viem.encodeFunctionData({
|
|
23168
|
+
abi: iCreditFacadeV3MulticallAbi,
|
|
23169
|
+
functionName: "addCollateralWithPermit",
|
|
23170
|
+
args: [token, balance, p.deadline, p.v, p.r, p.s]
|
|
23171
|
+
})
|
|
23172
|
+
};
|
|
23173
|
+
}
|
|
23174
|
+
return {
|
|
23175
|
+
target: ca.creditFacade,
|
|
23176
|
+
callData: viem.encodeFunctionData({
|
|
23177
|
+
abi: iCreditFacadeV3MulticallAbi,
|
|
23178
|
+
functionName: "addCollateral",
|
|
23179
|
+
args: [token, balance]
|
|
23180
|
+
})
|
|
23181
|
+
};
|
|
23182
|
+
});
|
|
23183
|
+
return calls;
|
|
23184
|
+
}
|
|
23117
23185
|
/**
|
|
23118
|
-
*
|
|
23119
|
-
* @param creditManager CreditManagerData which represents credit manager you want to use to open Credit Account
|
|
23120
|
-
* @param expectedBalances Expected balances which would be on account accounting also debt. For example,
|
|
23121
|
-
* if you open an USDC Credit Account, borrow 50_000 USDC and provide 10 WETH and 10_USDC as collateral
|
|
23122
|
-
* from your own funds, expectedBalances should be: { "USDC": 60_000 * (10**6), "<address of WETH>": WAD.mul(10) }
|
|
23123
|
-
* @param leftoverBalances Balances to keep on account after opening
|
|
23124
|
-
* @param target Address of symbol of desired token
|
|
23125
|
-
* @param slippage Slippage in PERCENTAGE_FORMAT (100% = 10_000) per operation
|
|
23126
|
-
* @returns PathFinderOpenStrategyResult which
|
|
23186
|
+
* Returns addresses of pools of attached markets
|
|
23127
23187
|
*/
|
|
23128
|
-
|
|
23129
|
-
|
|
23130
|
-
|
|
23131
|
-
|
|
23132
|
-
|
|
23133
|
-
|
|
23134
|
-
|
|
23135
|
-
|
|
23136
|
-
|
|
23137
|
-
|
|
23138
|
-
|
|
23139
|
-
|
|
23140
|
-
|
|
23141
|
-
|
|
23142
|
-
|
|
23143
|
-
|
|
23144
|
-
|
|
23145
|
-
|
|
23146
|
-
|
|
23147
|
-
|
|
23148
|
-
|
|
23149
|
-
|
|
23150
|
-
|
|
23151
|
-
|
|
23152
|
-
{
|
|
23153
|
-
gas: GAS_PER_BLOCK
|
|
23188
|
+
get pools() {
|
|
23189
|
+
return this.sdk.marketRegister.pools.map((p) => p.pool.address);
|
|
23190
|
+
}
|
|
23191
|
+
};
|
|
23192
|
+
var AddressProviderContractV3_1 = class extends BaseContract {
|
|
23193
|
+
#addresses = {};
|
|
23194
|
+
versions = {};
|
|
23195
|
+
latest = {};
|
|
23196
|
+
constructor(sdk, address) {
|
|
23197
|
+
super(sdk, {
|
|
23198
|
+
addr: address,
|
|
23199
|
+
name: "AddressProviderV3",
|
|
23200
|
+
abi: iAddressProviderV3_1Abi
|
|
23201
|
+
});
|
|
23202
|
+
}
|
|
23203
|
+
parseFunctionParams(params) {
|
|
23204
|
+
switch (params.functionName) {
|
|
23205
|
+
case "setAddress": {
|
|
23206
|
+
if (params.args.length !== 3) {
|
|
23207
|
+
const [key2, saveVersion2] = params.args;
|
|
23208
|
+
return [key2, `${saveVersion2}`];
|
|
23209
|
+
}
|
|
23210
|
+
const [key, value, saveVersion] = params.args;
|
|
23211
|
+
return [viem.bytesToString(viem.toBytes(key)), value, `${saveVersion}`];
|
|
23154
23212
|
}
|
|
23213
|
+
default:
|
|
23214
|
+
return void 0;
|
|
23215
|
+
}
|
|
23216
|
+
}
|
|
23217
|
+
setInternalAddress(key, address, version) {
|
|
23218
|
+
if (!this.#addresses[key]) {
|
|
23219
|
+
this.#addresses[key] = {};
|
|
23220
|
+
}
|
|
23221
|
+
this.#addresses[key][version] = address;
|
|
23222
|
+
if (!this.latest[key] || version > this.latest[key]) {
|
|
23223
|
+
this.latest[key] = version;
|
|
23224
|
+
}
|
|
23225
|
+
if (!this.versions[key]) {
|
|
23226
|
+
this.versions[key] = /* @__PURE__ */ new Set();
|
|
23227
|
+
}
|
|
23228
|
+
this.versions[key].add(version);
|
|
23229
|
+
}
|
|
23230
|
+
getAddress(contract, version = NO_VERSION) {
|
|
23231
|
+
if (!this.#addresses[contract]) {
|
|
23232
|
+
throw new Error(`Address ${contract}, version: ${version} not found`);
|
|
23233
|
+
}
|
|
23234
|
+
const result = this.#addresses[contract][version];
|
|
23235
|
+
if (!result) {
|
|
23236
|
+
throw new Error(`Address ${contract}, version: ${version} not found`);
|
|
23237
|
+
}
|
|
23238
|
+
return result;
|
|
23239
|
+
}
|
|
23240
|
+
getLatestVersion(contract) {
|
|
23241
|
+
if (!this.latest[contract]) {
|
|
23242
|
+
throw new Error(`Latest version for ${contract} not found`);
|
|
23243
|
+
}
|
|
23244
|
+
this.logger?.debug(
|
|
23245
|
+
`Latest version found for ${contract} : ${this.latest[contract]}`
|
|
23155
23246
|
);
|
|
23156
|
-
|
|
23157
|
-
|
|
23158
|
-
|
|
23247
|
+
return this.getAddress(contract, this.latest[contract]);
|
|
23248
|
+
}
|
|
23249
|
+
async syncState(blockNumber) {
|
|
23250
|
+
const entries = await this.contract.read.getAllSavedContracts({
|
|
23251
|
+
blockNumber
|
|
23252
|
+
});
|
|
23253
|
+
for (const log of entries) {
|
|
23254
|
+
this.setInternalAddress(log.key, log.value, Number(log.version));
|
|
23255
|
+
}
|
|
23256
|
+
}
|
|
23257
|
+
stateHuman(raw = true) {
|
|
23159
23258
|
return {
|
|
23160
|
-
|
|
23161
|
-
|
|
23162
|
-
|
|
23163
|
-
|
|
23164
|
-
|
|
23165
|
-
|
|
23166
|
-
|
|
23167
|
-
|
|
23168
|
-
|
|
23169
|
-
|
|
23170
|
-
|
|
23259
|
+
...super.stateHuman(raw),
|
|
23260
|
+
addresses: Object.entries(this.#addresses).map(([key, value]) => {
|
|
23261
|
+
return Object.entries(value).map(([version, address]) => {
|
|
23262
|
+
return {
|
|
23263
|
+
key,
|
|
23264
|
+
version,
|
|
23265
|
+
address: this.sdk.provider.addressLabels.get(address)
|
|
23266
|
+
};
|
|
23267
|
+
});
|
|
23268
|
+
}).reduce(
|
|
23269
|
+
(acc, vals) => {
|
|
23270
|
+
for (const val of vals) {
|
|
23271
|
+
if (!acc[val.key]) {
|
|
23272
|
+
acc[val.key] = {};
|
|
23273
|
+
}
|
|
23274
|
+
acc[val.key][val.version] = val.address;
|
|
23275
|
+
}
|
|
23276
|
+
return acc;
|
|
23277
|
+
},
|
|
23278
|
+
{}
|
|
23279
|
+
)
|
|
23171
23280
|
};
|
|
23172
23281
|
}
|
|
23173
|
-
|
|
23174
|
-
|
|
23175
|
-
|
|
23176
|
-
|
|
23177
|
-
|
|
23178
|
-
|
|
23179
|
-
|
|
23180
|
-
|
|
23181
|
-
|
|
23182
|
-
|
|
23183
|
-
|
|
23184
|
-
|
|
23185
|
-
|
|
23186
|
-
|
|
23187
|
-
|
|
23188
|
-
|
|
23189
|
-
|
|
23190
|
-
|
|
23191
|
-
|
|
23192
|
-
|
|
23193
|
-
|
|
23194
|
-
|
|
23195
|
-
|
|
23196
|
-
|
|
23197
|
-
|
|
23198
|
-
|
|
23199
|
-
|
|
23200
|
-
|
|
23201
|
-
|
|
23202
|
-
|
|
23282
|
+
processLog(log) {
|
|
23283
|
+
switch (log.eventName) {
|
|
23284
|
+
case "SetAddress": {
|
|
23285
|
+
const parsedLog2 = viem.parseEventLogs({
|
|
23286
|
+
abi: this.abi,
|
|
23287
|
+
eventName: "SetAddress",
|
|
23288
|
+
logs: [log]
|
|
23289
|
+
})[0];
|
|
23290
|
+
const key = parsedLog2.args.key;
|
|
23291
|
+
this.setInternalAddress(
|
|
23292
|
+
key,
|
|
23293
|
+
log.args.value,
|
|
23294
|
+
Number(parsedLog2.args.version)
|
|
23295
|
+
);
|
|
23296
|
+
break;
|
|
23297
|
+
}
|
|
23298
|
+
default:
|
|
23299
|
+
this.logger?.warn(`Unknown event: ${log.eventName}`);
|
|
23300
|
+
break;
|
|
23301
|
+
}
|
|
23302
|
+
}
|
|
23303
|
+
};
|
|
23304
|
+
|
|
23305
|
+
// src/sdk/core/BotListV3Contract.ts
|
|
23306
|
+
var BotListContract = class extends BaseContract {
|
|
23307
|
+
#approvedCreditManagers;
|
|
23308
|
+
#currentBlock;
|
|
23309
|
+
constructor(sdk, address) {
|
|
23310
|
+
super(sdk, { addr: address, name: "BotListV3", abi: botListV3Abi });
|
|
23311
|
+
this.#currentBlock = ADDRESS_PROVIDER_BLOCK[sdk.provider.networkType];
|
|
23312
|
+
}
|
|
23313
|
+
parseFunctionParams(params) {
|
|
23314
|
+
switch (params.functionName) {
|
|
23315
|
+
case "setCreditManagerApprovedStatus": {
|
|
23316
|
+
const [creditManager, status] = params.args;
|
|
23317
|
+
return [this.addressLabels.get(creditManager), `${status}`];
|
|
23318
|
+
}
|
|
23319
|
+
case "setBotSpecialPermissions": {
|
|
23320
|
+
const [bot, creditManager, permissions] = params.args;
|
|
23321
|
+
return [
|
|
23322
|
+
this.addressLabels.get(bot),
|
|
23323
|
+
this.addressLabels.get(creditManager),
|
|
23324
|
+
botPermissionsToString(permissions)
|
|
23325
|
+
];
|
|
23326
|
+
}
|
|
23327
|
+
default:
|
|
23328
|
+
return void 0;
|
|
23329
|
+
}
|
|
23330
|
+
}
|
|
23331
|
+
async syncState(toBlock) {
|
|
23332
|
+
const logs = await this.provider.publicClient.getContractEvents({
|
|
23333
|
+
address: this.address,
|
|
23334
|
+
abi: this.abi,
|
|
23335
|
+
fromBlock: this.#currentBlock,
|
|
23336
|
+
toBlock
|
|
23203
23337
|
});
|
|
23204
|
-
|
|
23205
|
-
|
|
23206
|
-
|
|
23207
|
-
|
|
23208
|
-
|
|
23209
|
-
|
|
23210
|
-
|
|
23211
|
-
|
|
23212
|
-
|
|
23213
|
-
|
|
23214
|
-
BigInt(LOOPS_PER_TX),
|
|
23215
|
-
false
|
|
23216
|
-
],
|
|
23217
|
-
{
|
|
23218
|
-
gas: GAS_PER_BLOCK
|
|
23338
|
+
logs.forEach((e) => this.processLog(e));
|
|
23339
|
+
this.#currentBlock = toBlock;
|
|
23340
|
+
}
|
|
23341
|
+
processLog(log) {
|
|
23342
|
+
switch (log.eventName) {
|
|
23343
|
+
case "SetCreditManagerApprovedStatus":
|
|
23344
|
+
if (log.args.approved) {
|
|
23345
|
+
this.approvedCreditManagers.add(log.args.creditManager);
|
|
23346
|
+
} else {
|
|
23347
|
+
this.approvedCreditManagers.delete(log.args.creditManager);
|
|
23219
23348
|
}
|
|
23349
|
+
break;
|
|
23350
|
+
case "SetBotSpecialPermissions":
|
|
23351
|
+
this.logger?.debug(
|
|
23352
|
+
`Bot ${log.args.bot} has been given permissions ${botPermissionsToString(
|
|
23353
|
+
log.args.permissions
|
|
23354
|
+
)} for credit manager ${log.args.creditManager}`
|
|
23355
|
+
);
|
|
23356
|
+
break;
|
|
23357
|
+
default:
|
|
23358
|
+
this.logger?.warn(`Unknown event: ${log.eventName}`);
|
|
23359
|
+
break;
|
|
23360
|
+
}
|
|
23361
|
+
}
|
|
23362
|
+
get approvedCreditManagers() {
|
|
23363
|
+
if (!this.#approvedCreditManagers) {
|
|
23364
|
+
throw new Error(
|
|
23365
|
+
"BotListContract state needs to be synced to load approvedCreditManagers"
|
|
23220
23366
|
);
|
|
23221
|
-
results.push({
|
|
23222
|
-
...result2,
|
|
23223
|
-
calls: [...result2.calls]
|
|
23224
|
-
});
|
|
23225
23367
|
}
|
|
23226
|
-
|
|
23227
|
-
amount: 0n,
|
|
23228
|
-
minAmount: 0n,
|
|
23229
|
-
calls: []
|
|
23230
|
-
});
|
|
23231
|
-
const underlyingBalance = ca.tokens.find((t) => t.token === ca.underlying)?.balance ?? 0n;
|
|
23232
|
-
const result = {
|
|
23233
|
-
amount: bestResult.amount,
|
|
23234
|
-
minAmount: bestResult.minAmount,
|
|
23235
|
-
calls: bestResult.calls.map((c) => ({
|
|
23236
|
-
callData: c.callData,
|
|
23237
|
-
target: c.target
|
|
23238
|
-
})),
|
|
23239
|
-
underlyingBalance: underlyingBalance + bestResult.minAmount
|
|
23240
|
-
};
|
|
23241
|
-
return result;
|
|
23368
|
+
return this.#approvedCreditManagers;
|
|
23242
23369
|
}
|
|
23243
|
-
|
|
23244
|
-
|
|
23245
|
-
* @param ca
|
|
23246
|
-
* @param cm
|
|
23247
|
-
* @returns
|
|
23248
|
-
*/
|
|
23249
|
-
getFindClosePathInput(ca, cm, balances) {
|
|
23250
|
-
const b = balances || this.getDefaultExpectedAndLeftover(ca);
|
|
23251
|
-
const { leftoverBalances, expectedBalances } = b;
|
|
23252
|
-
const pathOptions = PathOptionFactory.generatePathOptions(
|
|
23253
|
-
ca.tokens,
|
|
23254
|
-
this.provider.networkType,
|
|
23255
|
-
LOOPS_PER_TX
|
|
23256
|
-
);
|
|
23257
|
-
const expected = cm.collateralTokens.map((token) => {
|
|
23258
|
-
const actual = expectedBalances.get(token)?.balance || 0n;
|
|
23259
|
-
return {
|
|
23260
|
-
token,
|
|
23261
|
-
balance: actual > 10n ? actual : 0n
|
|
23262
|
-
};
|
|
23263
|
-
});
|
|
23264
|
-
const leftover = cm.collateralTokens.map((token) => ({
|
|
23265
|
-
token,
|
|
23266
|
-
balance: leftoverBalances.get(token)?.balance || 1n
|
|
23267
|
-
}));
|
|
23268
|
-
const connectors = this.getAvailableConnectors(cm.collateralTokens);
|
|
23269
|
-
return { expected, leftover, connectors, pathOptions };
|
|
23370
|
+
stateHuman(raw = true) {
|
|
23371
|
+
return super.stateHuman(raw);
|
|
23270
23372
|
}
|
|
23271
|
-
|
|
23272
|
-
|
|
23273
|
-
|
|
23274
|
-
|
|
23275
|
-
|
|
23276
|
-
|
|
23277
|
-
|
|
23278
|
-
|
|
23279
|
-
|
|
23280
|
-
|
|
23281
|
-
|
|
23373
|
+
};
|
|
23374
|
+
|
|
23375
|
+
// src/sdk/core/GearStakingV3Contract.ts
|
|
23376
|
+
var GearStakingContract = class extends BaseContract {
|
|
23377
|
+
constructor(sdk, address) {
|
|
23378
|
+
super(sdk, { addr: address, name: "GearStakingV3", abi: gearStakingV3Abi });
|
|
23379
|
+
}
|
|
23380
|
+
parseFunctionParams(params) {
|
|
23381
|
+
switch (params.functionName) {
|
|
23382
|
+
case "setVotingContractStatus": {
|
|
23383
|
+
const [address, status] = params.args;
|
|
23384
|
+
return [this.addressLabels.get(address), VotingContractStatus[status]];
|
|
23282
23385
|
}
|
|
23386
|
+
default:
|
|
23387
|
+
return void 0;
|
|
23283
23388
|
}
|
|
23284
|
-
return { expectedBalances, leftoverBalances };
|
|
23285
23389
|
}
|
|
23286
|
-
|
|
23287
|
-
return
|
|
23288
|
-
|
|
23289
|
-
|
|
23390
|
+
stateHuman(raw = true) {
|
|
23391
|
+
return {
|
|
23392
|
+
...super.stateHuman(raw),
|
|
23393
|
+
successor: this.labelAddress(ADDRESS_0X0),
|
|
23394
|
+
migrator: this.labelAddress(ADDRESS_0X0)
|
|
23395
|
+
};
|
|
23290
23396
|
}
|
|
23291
23397
|
};
|
|
23292
|
-
function compareRouterResults(a, b) {
|
|
23293
|
-
return a.amount > b.amount ? a : b;
|
|
23294
|
-
}
|
|
23295
|
-
function balancesMap(assets) {
|
|
23296
|
-
return new AddressMap(assets.map(({ token, balance }) => [token, balance]));
|
|
23297
|
-
}
|
|
23298
|
-
function assetsMap(assets) {
|
|
23299
|
-
return new AddressMap(assets.map((a) => [a.token, a]));
|
|
23300
|
-
}
|
|
23301
|
-
|
|
23302
|
-
// src/sdk/GearboxSDK.ts
|
|
23303
23398
|
var GearboxSDK = class _GearboxSDK {
|
|
23304
23399
|
#hooks = new Hooks();
|
|
23305
23400
|
// Represents chain object
|
|
@@ -23698,6 +23793,8 @@ exports.WstETHV1AdapterContract = WstETHV1AdapterContract;
|
|
|
23698
23793
|
exports.YearnPriceFeedContract = YearnPriceFeedContract;
|
|
23699
23794
|
exports.YearnV2RouterAdapterContract = YearnV2RouterAdapterContract;
|
|
23700
23795
|
exports.ZeroPriceFeedContract = ZeroPriceFeedContract;
|
|
23796
|
+
exports.assetsMap = assetsMap;
|
|
23797
|
+
exports.balancesMap = balancesMap;
|
|
23701
23798
|
exports.botPermissionsToString = botPermissionsToString;
|
|
23702
23799
|
exports.bytes32ToString = bytes32ToString;
|
|
23703
23800
|
exports.chains = chains;
|