@gearbox-protocol/sdk 13.3.3 → 13.4.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/sdk/accounts/AbstractCreditAccountsService.js +152 -175
- package/dist/cjs/sdk/accounts/CreditAccountsServiceV310.js +25 -30
- package/dist/cjs/sdk/accounts/multicall-utils.js +91 -0
- package/dist/cjs/sdk/market/credit/CreditFacadeV310Contract.js +6 -0
- package/dist/esm/sdk/accounts/AbstractCreditAccountsService.js +157 -176
- package/dist/esm/sdk/accounts/CreditAccountsServiceV310.js +25 -30
- package/dist/esm/sdk/accounts/multicall-utils.js +69 -0
- package/dist/esm/sdk/market/credit/CreditFacadeV310Contract.js +6 -0
- package/dist/types/sdk/accounts/AbstractCreditAccountsService.d.ts +40 -18
- package/dist/types/sdk/accounts/multicall-utils.d.ts +39 -0
- package/dist/types/sdk/accounts/types.d.ts +24 -14
- package/dist/types/sdk/market/credit/CreditFacadeV310Contract.d.ts +1 -0
- package/package.json +2 -1
|
@@ -22,8 +22,13 @@ import {
|
|
|
22
22
|
VERSION_RANGE_310
|
|
23
23
|
} from "../constants/index.js";
|
|
24
24
|
import { assetsMap } from "../router/index.js";
|
|
25
|
-
import { AddressMap } from "../utils/index.js";
|
|
25
|
+
import { AddressMap, AddressSet } from "../utils/index.js";
|
|
26
26
|
import { simulateWithPriceUpdates } from "../utils/viem/index.js";
|
|
27
|
+
import {
|
|
28
|
+
extractPriceUpdates,
|
|
29
|
+
extractQuotaTokens,
|
|
30
|
+
mergePriceUpdates
|
|
31
|
+
} from "./multicall-utils.js";
|
|
27
32
|
const COMPRESSORS = {
|
|
28
33
|
[chains.Mainnet.id]: "0x36F3d0Bb73CBC2E94fE24dF0f26a689409cF9023",
|
|
29
34
|
[chains.Monad.id]: "0x36F3d0Bb73CBC2E94fE24dF0f26a689409cF9023"
|
|
@@ -323,12 +328,12 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
323
328
|
keepAssets,
|
|
324
329
|
debtOnly
|
|
325
330
|
});
|
|
326
|
-
const
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
331
|
+
const calls = await this.prependPriceUpdates(
|
|
332
|
+
account.creditManager,
|
|
333
|
+
routerCloseResult.calls,
|
|
334
|
+
account,
|
|
335
|
+
{ ignoreReservePrices }
|
|
336
|
+
);
|
|
332
337
|
let lossPolicyData;
|
|
333
338
|
if (applyLossPolicy) {
|
|
334
339
|
const market = this.sdk.marketRegister.findByCreditManager(
|
|
@@ -383,12 +388,7 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
383
388
|
creditManager: cm.creditManager,
|
|
384
389
|
slippage
|
|
385
390
|
});
|
|
386
|
-
const
|
|
387
|
-
creditManager: ca.creditManager,
|
|
388
|
-
creditAccount: ca
|
|
389
|
-
});
|
|
390
|
-
const calls = [
|
|
391
|
-
...operation === "close" ? [] : priceUpdates,
|
|
391
|
+
const operationCalls = [
|
|
392
392
|
...routerCloseResult.calls,
|
|
393
393
|
...this.prepareDisableQuotas(ca),
|
|
394
394
|
...this.prepareDecreaseDebt(ca),
|
|
@@ -396,6 +396,7 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
396
396
|
(t) => this.prepareWithdrawToken(ca.creditFacade, t, MAX_UINT256, to)
|
|
397
397
|
)
|
|
398
398
|
];
|
|
399
|
+
const calls = operation === "close" ? operationCalls : await this.prependPriceUpdates(ca.creditManager, operationCalls, ca);
|
|
399
400
|
const tx = operation === "close" ? cm.creditFacade.closeCreditAccount(ca.creditAccount, calls) : cm.creditFacade.multicall(ca.creditAccount, calls);
|
|
400
401
|
return { tx, calls, routerCloseResult, creditFacade: cm.creditFacade };
|
|
401
402
|
}
|
|
@@ -415,17 +416,15 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
415
416
|
const cm = this.sdk.marketRegister.findCreditManager(
|
|
416
417
|
creditAccount.creditManager
|
|
417
418
|
);
|
|
418
|
-
const
|
|
419
|
-
|
|
419
|
+
const operationCalls = this.prepareUpdateQuotas(
|
|
420
|
+
creditAccount.creditFacade,
|
|
421
|
+
{ minQuota, averageQuota }
|
|
422
|
+
);
|
|
423
|
+
const calls = await this.prependPriceUpdates(
|
|
424
|
+
creditAccount.creditManager,
|
|
425
|
+
operationCalls,
|
|
420
426
|
creditAccount
|
|
421
|
-
|
|
422
|
-
const calls = [
|
|
423
|
-
...priceUpdates,
|
|
424
|
-
...this.prepareUpdateQuotas(creditAccount.creditFacade, {
|
|
425
|
-
minQuota,
|
|
426
|
-
averageQuota
|
|
427
|
-
})
|
|
428
|
-
];
|
|
427
|
+
);
|
|
429
428
|
const tx = cm.creditFacade.multicall(creditAccount.creditAccount, calls);
|
|
430
429
|
return { tx, calls, creditFacade: cm.creditFacade };
|
|
431
430
|
}
|
|
@@ -451,13 +450,7 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
451
450
|
const cm = this.sdk.marketRegister.findCreditManager(
|
|
452
451
|
creditAccount.creditManager
|
|
453
452
|
);
|
|
454
|
-
const
|
|
455
|
-
creditManager: creditAccount.creditManager,
|
|
456
|
-
creditAccount,
|
|
457
|
-
desiredQuotas: averageQuota
|
|
458
|
-
});
|
|
459
|
-
const calls = [
|
|
460
|
-
...priceUpdatesCalls,
|
|
453
|
+
const operationCalls = [
|
|
461
454
|
...this.prepareAddCollateral(
|
|
462
455
|
creditAccount.creditFacade,
|
|
463
456
|
[asset],
|
|
@@ -468,6 +461,11 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
468
461
|
averageQuota
|
|
469
462
|
})
|
|
470
463
|
];
|
|
464
|
+
const calls = await this.prependPriceUpdates(
|
|
465
|
+
creditAccount.creditManager,
|
|
466
|
+
operationCalls,
|
|
467
|
+
creditAccount
|
|
468
|
+
);
|
|
471
469
|
const tx = cm.creditFacade.multicall(creditAccount.creditAccount, calls);
|
|
472
470
|
tx.value = ethAmount.toString(10);
|
|
473
471
|
return { tx, calls, creditFacade: cm.creditFacade };
|
|
@@ -495,10 +493,6 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
495
493
|
const cm = this.sdk.marketRegister.findCreditManager(
|
|
496
494
|
creditAccount.creditManager
|
|
497
495
|
);
|
|
498
|
-
const priceUpdatesCalls = await this.getPriceUpdatesForFacade({
|
|
499
|
-
creditManager: creditAccount.creditManager,
|
|
500
|
-
creditAccount
|
|
501
|
-
});
|
|
502
496
|
const addCollateralCalls = addCollateral && isDecrease ? this.prepareAddCollateral(
|
|
503
497
|
creditAccount.creditFacade,
|
|
504
498
|
[
|
|
@@ -509,11 +503,15 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
509
503
|
],
|
|
510
504
|
{}
|
|
511
505
|
) : [];
|
|
512
|
-
const
|
|
513
|
-
...priceUpdatesCalls,
|
|
506
|
+
const operationCalls = [
|
|
514
507
|
...addCollateralCalls,
|
|
515
508
|
this.#prepareChangeDebt(creditAccount.creditFacade, change, isDecrease)
|
|
516
509
|
];
|
|
510
|
+
const calls = await this.prependPriceUpdates(
|
|
511
|
+
creditAccount.creditManager,
|
|
512
|
+
operationCalls,
|
|
513
|
+
creditAccount
|
|
514
|
+
);
|
|
517
515
|
const tx = cm.creditFacade.multicall(creditAccount.creditAccount, calls);
|
|
518
516
|
return { tx, calls, creditFacade: cm.creditFacade };
|
|
519
517
|
}
|
|
@@ -536,19 +534,18 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
536
534
|
const cm = this.sdk.marketRegister.findCreditManager(
|
|
537
535
|
creditAccount.creditManager
|
|
538
536
|
);
|
|
539
|
-
const
|
|
540
|
-
creditManager: creditAccount.creditManager,
|
|
541
|
-
creditAccount,
|
|
542
|
-
desiredQuotas: averageQuota
|
|
543
|
-
});
|
|
544
|
-
const calls = [
|
|
545
|
-
...priceUpdatesCalls,
|
|
537
|
+
const operationCalls = [
|
|
546
538
|
...swapCalls,
|
|
547
539
|
...this.prepareUpdateQuotas(creditAccount.creditFacade, {
|
|
548
540
|
minQuota,
|
|
549
541
|
averageQuota
|
|
550
542
|
})
|
|
551
543
|
];
|
|
544
|
+
const calls = await this.prependPriceUpdates(
|
|
545
|
+
creditAccount.creditManager,
|
|
546
|
+
operationCalls,
|
|
547
|
+
creditAccount
|
|
548
|
+
);
|
|
552
549
|
const tx = cm.creditFacade.multicall(creditAccount.creditAccount, calls);
|
|
553
550
|
return { tx, calls, creditFacade: cm.creditFacade };
|
|
554
551
|
}
|
|
@@ -650,13 +647,7 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
650
647
|
args: []
|
|
651
648
|
})
|
|
652
649
|
};
|
|
653
|
-
const
|
|
654
|
-
creditManager: creditAccount.creditManager,
|
|
655
|
-
creditAccount,
|
|
656
|
-
desiredQuotas: averageQuota
|
|
657
|
-
});
|
|
658
|
-
const calls = [
|
|
659
|
-
...priceUpdatesCalls,
|
|
650
|
+
const operationCalls = [
|
|
660
651
|
storeExpectedBalances,
|
|
661
652
|
...preview.requestCalls,
|
|
662
653
|
compareBalances,
|
|
@@ -665,6 +656,11 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
665
656
|
averageQuota
|
|
666
657
|
})
|
|
667
658
|
];
|
|
659
|
+
const calls = await this.prependPriceUpdates(
|
|
660
|
+
creditAccount.creditManager,
|
|
661
|
+
operationCalls,
|
|
662
|
+
creditAccount
|
|
663
|
+
);
|
|
668
664
|
const tx = cm.creditFacade.multicall(creditAccount.creditAccount, calls);
|
|
669
665
|
return { tx, calls, creditFacade: cm.creditFacade };
|
|
670
666
|
}
|
|
@@ -714,22 +710,21 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
714
710
|
args: []
|
|
715
711
|
})
|
|
716
712
|
};
|
|
717
|
-
const priceUpdatesCalls = zeroDebt ? [] : await this.getPriceUpdatesForFacade({
|
|
718
|
-
creditManager: creditAccount.creditManager,
|
|
719
|
-
creditAccount,
|
|
720
|
-
desiredQuotas: averageQuota
|
|
721
|
-
});
|
|
722
713
|
const quotaCalls = zeroDebt ? [] : this.prepareUpdateQuotas(creditAccount.creditFacade, {
|
|
723
714
|
minQuota,
|
|
724
715
|
averageQuota
|
|
725
716
|
});
|
|
726
|
-
const
|
|
727
|
-
...priceUpdatesCalls,
|
|
717
|
+
const operationCalls = [
|
|
728
718
|
storeExpectedBalances,
|
|
729
719
|
...claimableNow.claimCalls,
|
|
730
720
|
compareBalances,
|
|
731
721
|
...quotaCalls
|
|
732
722
|
];
|
|
723
|
+
const calls = zeroDebt ? operationCalls : await this.prependPriceUpdates(
|
|
724
|
+
creditAccount.creditManager,
|
|
725
|
+
operationCalls,
|
|
726
|
+
creditAccount
|
|
727
|
+
);
|
|
733
728
|
const tx = cm.creditFacade.multicall(creditAccount.creditAccount, calls);
|
|
734
729
|
return { tx, calls, creditFacade: cm.creditFacade };
|
|
735
730
|
}
|
|
@@ -772,12 +767,7 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
772
767
|
}) {
|
|
773
768
|
const cmSuite = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
774
769
|
const cm = cmSuite.creditManager;
|
|
775
|
-
const
|
|
776
|
-
creditManager: cm.address,
|
|
777
|
-
desiredQuotas: averageQuota
|
|
778
|
-
});
|
|
779
|
-
const calls = [
|
|
780
|
-
...priceUpdatesCalls,
|
|
770
|
+
const operationCalls = [
|
|
781
771
|
this.#prepareIncreaseDebt(cm.creditFacade, debt),
|
|
782
772
|
...this.prepareAddCollateral(cm.creditFacade, collateral, permits),
|
|
783
773
|
...openPathCalls,
|
|
@@ -787,6 +777,7 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
787
777
|
averageQuota
|
|
788
778
|
})
|
|
789
779
|
];
|
|
780
|
+
const calls = await this.prependPriceUpdates(cm.address, operationCalls);
|
|
790
781
|
const tx = cmSuite.creditFacade.openCreditAccount(to, calls, referralCode);
|
|
791
782
|
tx.value = ethAmount.toString(10);
|
|
792
783
|
return { calls, tx, creditFacade: cmSuite.creditFacade };
|
|
@@ -871,37 +862,6 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
871
862
|
);
|
|
872
863
|
return resp;
|
|
873
864
|
}
|
|
874
|
-
/**
|
|
875
|
-
* Returns raw txs that are needed to update all price feeds so that all credit accounts (possibly from different markets) compute
|
|
876
|
-
*
|
|
877
|
-
* This can be used by batch liquidator
|
|
878
|
-
* @param accounts
|
|
879
|
-
* @returns
|
|
880
|
-
*/
|
|
881
|
-
async getUpdateForAccounts(accounts) {
|
|
882
|
-
const tokensByPool = /* @__PURE__ */ new Map();
|
|
883
|
-
const oracleByPool = /* @__PURE__ */ new Map();
|
|
884
|
-
for (const acc of accounts) {
|
|
885
|
-
const market = this.sdk.marketRegister.findByCreditManager(
|
|
886
|
-
acc.creditManager
|
|
887
|
-
);
|
|
888
|
-
const pool = market.pool.pool.address;
|
|
889
|
-
oracleByPool.set(pool, market.priceOracle);
|
|
890
|
-
for (const t of acc.tokens) {
|
|
891
|
-
if (t.balance > 10n) {
|
|
892
|
-
const tokens = tokensByPool.get(pool) ?? /* @__PURE__ */ new Set();
|
|
893
|
-
tokens.add(t.token);
|
|
894
|
-
tokensByPool.set(pool, tokens);
|
|
895
|
-
}
|
|
896
|
-
}
|
|
897
|
-
}
|
|
898
|
-
const priceFeeds = [];
|
|
899
|
-
for (const [pool, oracle] of oracleByPool.entries()) {
|
|
900
|
-
const tokens = Array.from(tokensByPool.get(pool) ?? []);
|
|
901
|
-
priceFeeds.push(...oracle.priceFeedsForTokens(tokens));
|
|
902
|
-
}
|
|
903
|
-
return this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(priceFeeds);
|
|
904
|
-
}
|
|
905
865
|
async getUpdateForAccount(options) {
|
|
906
866
|
const { creditManager, creditAccount, desiredQuotas, ignoreReservePrices } = options;
|
|
907
867
|
const quotaRecord = desiredQuotas ? assetsMap(desiredQuotas) : desiredQuotas;
|
|
@@ -965,19 +925,113 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
965
925
|
return market.priceOracle.onDemandPriceUpdates(
|
|
966
926
|
cm.creditFacade.address,
|
|
967
927
|
update
|
|
928
|
+
).raw;
|
|
929
|
+
}
|
|
930
|
+
/**
|
|
931
|
+
* Analyzes a multicall array and prepends necessary on-demand price feed updates.
|
|
932
|
+
*
|
|
933
|
+
* Deduplicates existing `onDemandPriceUpdates` calls
|
|
934
|
+
*
|
|
935
|
+
* @param creditManager - Address of the credit manager
|
|
936
|
+
* @param calls - The multicall array to prepend price updates to
|
|
937
|
+
* @param ca - Credit account slice, undefined when opening a new account
|
|
938
|
+
* @param options - Optional settings for price update generation
|
|
939
|
+
* @returns A new array with a single consolidated price update call prepended,
|
|
940
|
+
* followed by the non-price-update calls in their original order
|
|
941
|
+
*/
|
|
942
|
+
async prependPriceUpdates(creditManager, calls, ca, options) {
|
|
943
|
+
const market = this.sdk.marketRegister.findByCreditManager(creditManager);
|
|
944
|
+
const cm = this.sdk.marketRegister.findCreditManager(creditManager).creditManager;
|
|
945
|
+
const { priceUpdates: existingUpdates, remainingCalls } = extractPriceUpdates(calls);
|
|
946
|
+
const tokens = new AddressSet([
|
|
947
|
+
cm.underlying,
|
|
948
|
+
// underlying - always included
|
|
949
|
+
...extractQuotaTokens(calls)
|
|
950
|
+
// tokens from `updateQuota` calls
|
|
951
|
+
]);
|
|
952
|
+
if (ca) {
|
|
953
|
+
for (const t of ca.tokens) {
|
|
954
|
+
const isEnabled = (t.mask & ca.enabledTokensMask) !== 0n;
|
|
955
|
+
if (t.balance > 10n && isEnabled) {
|
|
956
|
+
tokens.add(t.token);
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
const ignoreReservePrices = options?.ignoreReservePrices;
|
|
961
|
+
const priceFeeds = market.priceOracle.priceFeedsForTokens(Array.from(tokens), {
|
|
962
|
+
main: true,
|
|
963
|
+
reserve: !ignoreReservePrices
|
|
964
|
+
});
|
|
965
|
+
const tStr = tokens.map((t) => this.labelAddress(t)).join(", ");
|
|
966
|
+
const remark = ignoreReservePrices ? " main" : "";
|
|
967
|
+
this.logger?.debug(
|
|
968
|
+
{ account: ca?.creditAccount, manager: cm.name },
|
|
969
|
+
`prependPriceUpdates for ${tStr} from ${priceFeeds.length}${remark} price feeds`
|
|
968
970
|
);
|
|
971
|
+
const generatedUpdates = await this.sdk.priceFeeds.generatePriceFeedsUpdates(priceFeeds);
|
|
972
|
+
const merged = mergePriceUpdates(existingUpdates, generatedUpdates);
|
|
973
|
+
if (merged.length === 0) {
|
|
974
|
+
return remainingCalls;
|
|
975
|
+
}
|
|
976
|
+
return [
|
|
977
|
+
{
|
|
978
|
+
target: cm.creditFacade,
|
|
979
|
+
callData: encodeFunctionData({
|
|
980
|
+
abi: iCreditFacadeMulticallV310Abi,
|
|
981
|
+
functionName: "onDemandPriceUpdates",
|
|
982
|
+
args: [merged]
|
|
983
|
+
})
|
|
984
|
+
},
|
|
985
|
+
...remainingCalls
|
|
986
|
+
];
|
|
969
987
|
}
|
|
970
988
|
/**
|
|
971
|
-
*
|
|
972
|
-
* -
|
|
973
|
-
*
|
|
974
|
-
*
|
|
975
|
-
* @param
|
|
976
|
-
* @
|
|
989
|
+
* Executes a multicall on a credit account, automatically prepending
|
|
990
|
+
* necessary on-demand price feed updates.
|
|
991
|
+
*
|
|
992
|
+
* @param creditAccount - Credit account to execute multicall on
|
|
993
|
+
* @param calls - Array of multicall operations (price updates will be inferred)
|
|
994
|
+
* @param options - Optional settings for price update generation
|
|
995
|
+
* @returns Raw transaction ready to be signed and sent
|
|
977
996
|
*/
|
|
978
|
-
async
|
|
979
|
-
const
|
|
980
|
-
|
|
997
|
+
async multicall(creditAccount, calls, options) {
|
|
998
|
+
const cm = this.sdk.marketRegister.findCreditManager(
|
|
999
|
+
creditAccount.creditManager
|
|
1000
|
+
);
|
|
1001
|
+
const callsWithPrices = await this.prependPriceUpdates(
|
|
1002
|
+
creditAccount.creditManager,
|
|
1003
|
+
calls,
|
|
1004
|
+
creditAccount,
|
|
1005
|
+
options
|
|
1006
|
+
);
|
|
1007
|
+
return cm.creditFacade.multicall(
|
|
1008
|
+
creditAccount.creditAccount,
|
|
1009
|
+
callsWithPrices
|
|
1010
|
+
);
|
|
1011
|
+
}
|
|
1012
|
+
/**
|
|
1013
|
+
* Executes a bot multicall on a credit account, automatically prepending
|
|
1014
|
+
* necessary on-demand price feed updates.
|
|
1015
|
+
*
|
|
1016
|
+
* @param creditAccount - Credit account to execute bot multicall on
|
|
1017
|
+
* @param calls - Array of multicall operations (price updates will be inferred)
|
|
1018
|
+
* @param options - Optional settings for price update generation
|
|
1019
|
+
* @returns Raw transaction ready to be signed and sent
|
|
1020
|
+
*/
|
|
1021
|
+
async botMulticall(creditAccount, calls, options) {
|
|
1022
|
+
const cm = this.sdk.marketRegister.findCreditManager(
|
|
1023
|
+
creditAccount.creditManager
|
|
1024
|
+
);
|
|
1025
|
+
const callsWithPrices = await this.prependPriceUpdates(
|
|
1026
|
+
creditAccount.creditManager,
|
|
1027
|
+
calls,
|
|
1028
|
+
creditAccount,
|
|
1029
|
+
options
|
|
1030
|
+
);
|
|
1031
|
+
return cm.creditFacade.botMulticall(
|
|
1032
|
+
creditAccount.creditAccount,
|
|
1033
|
+
callsWithPrices
|
|
1034
|
+
);
|
|
981
1035
|
}
|
|
982
1036
|
prepareDisableQuotas(ca) {
|
|
983
1037
|
const calls = [];
|
|
@@ -1099,79 +1153,6 @@ class AbstractCreditAccountService extends SDKConstruct {
|
|
|
1099
1153
|
)[0];
|
|
1100
1154
|
}
|
|
1101
1155
|
}
|
|
1102
|
-
const iMellowClaimerAdapterAbi = [
|
|
1103
|
-
{
|
|
1104
|
-
type: "function",
|
|
1105
|
-
name: "getMultiVaultSubvaultIndices",
|
|
1106
|
-
inputs: [{ name: "multiVault", type: "address", internalType: "address" }],
|
|
1107
|
-
outputs: [
|
|
1108
|
-
{
|
|
1109
|
-
name: "subvaultIndices",
|
|
1110
|
-
type: "uint256[]",
|
|
1111
|
-
internalType: "uint256[]"
|
|
1112
|
-
},
|
|
1113
|
-
{
|
|
1114
|
-
name: "withdrawalIndices",
|
|
1115
|
-
type: "uint256[][]",
|
|
1116
|
-
internalType: "uint256[][]"
|
|
1117
|
-
}
|
|
1118
|
-
],
|
|
1119
|
-
stateMutability: "view"
|
|
1120
|
-
},
|
|
1121
|
-
{
|
|
1122
|
-
type: "function",
|
|
1123
|
-
name: "getUserSubvaultIndices",
|
|
1124
|
-
inputs: [
|
|
1125
|
-
{ name: "multiVault", type: "address", internalType: "address" },
|
|
1126
|
-
{ name: "user", type: "address", internalType: "address" }
|
|
1127
|
-
],
|
|
1128
|
-
outputs: [
|
|
1129
|
-
{
|
|
1130
|
-
name: "subvaultIndices",
|
|
1131
|
-
type: "uint256[]",
|
|
1132
|
-
internalType: "uint256[]"
|
|
1133
|
-
},
|
|
1134
|
-
{
|
|
1135
|
-
name: "withdrawalIndices",
|
|
1136
|
-
type: "uint256[][]",
|
|
1137
|
-
internalType: "uint256[][]"
|
|
1138
|
-
}
|
|
1139
|
-
],
|
|
1140
|
-
stateMutability: "view"
|
|
1141
|
-
},
|
|
1142
|
-
{
|
|
1143
|
-
type: "function",
|
|
1144
|
-
name: "multiAccept",
|
|
1145
|
-
inputs: [
|
|
1146
|
-
{ name: "multiVault", type: "address", internalType: "address" },
|
|
1147
|
-
{
|
|
1148
|
-
name: "subvaultIndices",
|
|
1149
|
-
type: "uint256[]",
|
|
1150
|
-
internalType: "uint256[]"
|
|
1151
|
-
},
|
|
1152
|
-
{ name: "indices", type: "uint256[][]", internalType: "uint256[][]" }
|
|
1153
|
-
],
|
|
1154
|
-
outputs: [{ name: "", type: "bool", internalType: "bool" }],
|
|
1155
|
-
stateMutability: "nonpayable"
|
|
1156
|
-
},
|
|
1157
|
-
{
|
|
1158
|
-
type: "function",
|
|
1159
|
-
name: "multiAcceptAndClaim",
|
|
1160
|
-
inputs: [
|
|
1161
|
-
{ name: "multiVault", type: "address", internalType: "address" },
|
|
1162
|
-
{
|
|
1163
|
-
name: "subvaultIndices",
|
|
1164
|
-
type: "uint256[]",
|
|
1165
|
-
internalType: "uint256[]"
|
|
1166
|
-
},
|
|
1167
|
-
{ name: "indices", type: "uint256[][]", internalType: "uint256[][]" },
|
|
1168
|
-
{ name: "", type: "address", internalType: "address" },
|
|
1169
|
-
{ name: "maxAssets", type: "uint256", internalType: "uint256" }
|
|
1170
|
-
],
|
|
1171
|
-
outputs: [{ name: "", type: "bool", internalType: "bool" }],
|
|
1172
|
-
stateMutability: "nonpayable"
|
|
1173
|
-
}
|
|
1174
|
-
];
|
|
1175
1156
|
export {
|
|
1176
1157
|
AbstractCreditAccountService,
|
|
1177
1158
|
getWithdrawalCompressorAddress
|
|
@@ -14,10 +14,6 @@ class CreditAccountServiceV310 extends AbstractCreditAccountService {
|
|
|
14
14
|
const cm = this.sdk.marketRegister.findCreditManager(
|
|
15
15
|
targetContract.creditManager
|
|
16
16
|
);
|
|
17
|
-
const priceUpdatesCalls = targetContract.type === "creditAccount" ? await this.getPriceUpdatesForFacade({
|
|
18
|
-
creditManager: targetContract.creditManager,
|
|
19
|
-
creditAccount: targetContract
|
|
20
|
-
}) : [];
|
|
21
17
|
const permissions = defaultPermissions !== null ? defaultPermissions : await getContract({
|
|
22
18
|
address: botAddress,
|
|
23
19
|
client: this.sdk.client,
|
|
@@ -41,7 +37,11 @@ class CreditAccountServiceV310 extends AbstractCreditAccountService {
|
|
|
41
37
|
args: [botAddress, permissions]
|
|
42
38
|
})
|
|
43
39
|
};
|
|
44
|
-
const calls =
|
|
40
|
+
const calls = targetContract.type === "creditAccount" ? await this.prependPriceUpdates(
|
|
41
|
+
targetContract.creditManager,
|
|
42
|
+
[addBotCall],
|
|
43
|
+
targetContract
|
|
44
|
+
) : [addBotCall];
|
|
45
45
|
const tx = targetContract.type === "creditAccount" ? cm.creditFacade.multicall(targetContract.creditAccount, calls) : void 0;
|
|
46
46
|
return { tx, calls, creditFacade: cm.creditFacade };
|
|
47
47
|
}
|
|
@@ -58,12 +58,7 @@ class CreditAccountServiceV310 extends AbstractCreditAccountService {
|
|
|
58
58
|
const cm = this.sdk.marketRegister.findCreditManager(
|
|
59
59
|
creditAccount.creditManager
|
|
60
60
|
);
|
|
61
|
-
const
|
|
62
|
-
creditManager: creditAccount.creditManager,
|
|
63
|
-
creditAccount
|
|
64
|
-
});
|
|
65
|
-
const calls = [
|
|
66
|
-
...priceUpdatesCalls,
|
|
61
|
+
const operationCalls = [
|
|
67
62
|
...assetsToWithdraw.map(
|
|
68
63
|
(a) => this.prepareWithdrawToken(
|
|
69
64
|
creditAccount.creditFacade,
|
|
@@ -77,6 +72,11 @@ class CreditAccountServiceV310 extends AbstractCreditAccountService {
|
|
|
77
72
|
averageQuota
|
|
78
73
|
})
|
|
79
74
|
];
|
|
75
|
+
const calls = await this.prependPriceUpdates(
|
|
76
|
+
creditAccount.creditManager,
|
|
77
|
+
operationCalls,
|
|
78
|
+
creditAccount
|
|
79
|
+
);
|
|
80
80
|
const tx = cm.creditFacade.multicall(creditAccount.creditAccount, calls);
|
|
81
81
|
return { tx, calls, creditFacade: cm.creditFacade };
|
|
82
82
|
}
|
|
@@ -99,12 +99,7 @@ class CreditAccountServiceV310 extends AbstractCreditAccountService {
|
|
|
99
99
|
tokensToClaim,
|
|
100
100
|
creditAccount: ca
|
|
101
101
|
});
|
|
102
|
-
const
|
|
103
|
-
creditManager: ca.creditManager,
|
|
104
|
-
creditAccount: ca
|
|
105
|
-
});
|
|
106
|
-
const calls = [
|
|
107
|
-
...operation === "close" ? [] : priceUpdates,
|
|
102
|
+
const operationCalls = [
|
|
108
103
|
...this.prepareAddCollateral(ca.creditFacade, addCollateral, permits),
|
|
109
104
|
...this.prepareDisableQuotas(ca),
|
|
110
105
|
...this.prepareDecreaseDebt(ca),
|
|
@@ -113,6 +108,7 @@ class CreditAccountServiceV310 extends AbstractCreditAccountService {
|
|
|
113
108
|
(t) => this.prepareWithdrawToken(ca.creditFacade, t.token, MAX_UINT256, to)
|
|
114
109
|
)
|
|
115
110
|
];
|
|
111
|
+
const calls = operation === "close" ? operationCalls : await this.prependPriceUpdates(ca.creditManager, operationCalls, ca);
|
|
116
112
|
const tx = operation === "close" ? cm.creditFacade.closeCreditAccount(ca.creditAccount, calls) : cm.creditFacade.multicall(ca.creditAccount, calls);
|
|
117
113
|
return { tx, calls, creditFacade: cm.creditFacade };
|
|
118
114
|
}
|
|
@@ -133,19 +129,19 @@ class CreditAccountServiceV310 extends AbstractCreditAccountService {
|
|
|
133
129
|
tokensToClaim,
|
|
134
130
|
creditAccount: ca
|
|
135
131
|
});
|
|
136
|
-
const priceUpdates = await this.getPriceUpdatesForFacade({
|
|
137
|
-
creditManager: ca.creditManager,
|
|
138
|
-
creditAccount: ca
|
|
139
|
-
});
|
|
140
132
|
const addCollateral = collateralAssets.filter((a) => a.balance > 0);
|
|
141
|
-
const
|
|
142
|
-
...priceUpdates,
|
|
133
|
+
const operationCalls = [
|
|
143
134
|
...this.prepareAddCollateral(ca.creditFacade, addCollateral, permits),
|
|
144
135
|
...claimPath.calls,
|
|
145
136
|
...assetsToWithdraw.map(
|
|
146
137
|
(t) => this.prepareWithdrawToken(ca.creditFacade, t.token, MAX_UINT256, to)
|
|
147
138
|
)
|
|
148
139
|
];
|
|
140
|
+
const calls = await this.prependPriceUpdates(
|
|
141
|
+
ca.creditManager,
|
|
142
|
+
operationCalls,
|
|
143
|
+
ca
|
|
144
|
+
);
|
|
149
145
|
const tx = cm.creditFacade.liquidateCreditAccount(
|
|
150
146
|
ca.creditAccount,
|
|
151
147
|
to,
|
|
@@ -175,16 +171,15 @@ class CreditAccountServiceV310 extends AbstractCreditAccountService {
|
|
|
175
171
|
});
|
|
176
172
|
}
|
|
177
173
|
if (claimPath.calls.length === 0) throw new Error("No path to execute");
|
|
178
|
-
const
|
|
179
|
-
creditManager: ca.creditManager,
|
|
180
|
-
creditAccount: ca,
|
|
181
|
-
desiredQuotas: averageQuota
|
|
182
|
-
});
|
|
183
|
-
const calls = [
|
|
184
|
-
...priceUpdatesCalls,
|
|
174
|
+
const operationCalls = [
|
|
185
175
|
...claimPath.calls,
|
|
186
176
|
...this.prepareUpdateQuotas(ca.creditFacade, { minQuota, averageQuota })
|
|
187
177
|
];
|
|
178
|
+
const calls = await this.prependPriceUpdates(
|
|
179
|
+
ca.creditManager,
|
|
180
|
+
operationCalls,
|
|
181
|
+
ca
|
|
182
|
+
);
|
|
188
183
|
const tx = cm.creditFacade.multicall(ca.creditAccount, calls);
|
|
189
184
|
return { tx, calls, creditFacade: cm.creditFacade };
|
|
190
185
|
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import {
|
|
2
|
+
decodeFunctionData,
|
|
3
|
+
getAbiItem,
|
|
4
|
+
toFunctionSelector
|
|
5
|
+
} from "viem";
|
|
6
|
+
import { iCreditFacadeMulticallV310Abi } from "../../abi/310/generated.js";
|
|
7
|
+
import { AddressMap } from "../utils/AddressMap.js";
|
|
8
|
+
import { AddressSet } from "../utils/AddressSet.js";
|
|
9
|
+
const ON_DEMAND_SELECTOR = toFunctionSelector(
|
|
10
|
+
getAbiItem({
|
|
11
|
+
abi: iCreditFacadeMulticallV310Abi,
|
|
12
|
+
name: "onDemandPriceUpdates"
|
|
13
|
+
})
|
|
14
|
+
);
|
|
15
|
+
const UPDATE_QUOTA_SELECTOR = toFunctionSelector(
|
|
16
|
+
getAbiItem({
|
|
17
|
+
abi: iCreditFacadeMulticallV310Abi,
|
|
18
|
+
name: "updateQuota"
|
|
19
|
+
})
|
|
20
|
+
);
|
|
21
|
+
function extractPriceUpdates(calls) {
|
|
22
|
+
const priceUpdates = [];
|
|
23
|
+
const remainingCalls = [];
|
|
24
|
+
for (const call of calls) {
|
|
25
|
+
if (isOnDemandPriceUpdateCall(call)) {
|
|
26
|
+
const decoded = decodeFunctionData({
|
|
27
|
+
abi: iCreditFacadeMulticallV310Abi,
|
|
28
|
+
data: call.callData
|
|
29
|
+
});
|
|
30
|
+
const updates = decoded.args[0];
|
|
31
|
+
priceUpdates.push(...updates);
|
|
32
|
+
} else {
|
|
33
|
+
remainingCalls.push(call);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return { priceUpdates, remainingCalls };
|
|
37
|
+
}
|
|
38
|
+
function extractQuotaTokens(calls) {
|
|
39
|
+
const tokens = new AddressSet();
|
|
40
|
+
for (const { callData } of calls) {
|
|
41
|
+
if (callData.slice(0, 10) !== UPDATE_QUOTA_SELECTOR) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const decoded = decodeFunctionData({
|
|
45
|
+
abi: iCreditFacadeMulticallV310Abi,
|
|
46
|
+
data: callData
|
|
47
|
+
});
|
|
48
|
+
const [token, quotaChange] = decoded.args;
|
|
49
|
+
if (quotaChange > 0n) {
|
|
50
|
+
tokens.add(token);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return tokens;
|
|
54
|
+
}
|
|
55
|
+
function mergePriceUpdates(existing, generated) {
|
|
56
|
+
const seen = new AddressMap();
|
|
57
|
+
for (const u of [...generated, ...existing]) {
|
|
58
|
+
seen.upsert(u.priceFeed, u);
|
|
59
|
+
}
|
|
60
|
+
return seen.values();
|
|
61
|
+
}
|
|
62
|
+
function isOnDemandPriceUpdateCall(call) {
|
|
63
|
+
return call.callData.slice(0, 10) === ON_DEMAND_SELECTOR;
|
|
64
|
+
}
|
|
65
|
+
export {
|
|
66
|
+
extractPriceUpdates,
|
|
67
|
+
extractQuotaTokens,
|
|
68
|
+
mergePriceUpdates
|
|
69
|
+
};
|
|
@@ -72,6 +72,12 @@ class CreditFacadeV310Contract extends CreditFacadeV310BaseContract {
|
|
|
72
72
|
args: [ca, calls]
|
|
73
73
|
});
|
|
74
74
|
}
|
|
75
|
+
botMulticall(ca, calls) {
|
|
76
|
+
return this.createRawTx({
|
|
77
|
+
functionName: "botMulticall",
|
|
78
|
+
args: [ca, calls]
|
|
79
|
+
});
|
|
80
|
+
}
|
|
75
81
|
openCreditAccount(to, calls, referralCode) {
|
|
76
82
|
return this.createRawTx({
|
|
77
83
|
functionName: "openCreditAccount",
|