@gearbox-protocol/sdk 3.0.0-vfourabi.1 → 3.0.0-vfourabi.3
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/.eslintignore +3 -0
- package/.github/workflows/lint_pr.yml +18 -0
- package/.github/workflows/pr.yml +39 -0
- package/.github/workflows/release.yml +47 -0
- package/.gitignore +19 -0
- package/.husky/commit-msg +1 -0
- package/.husky/pre-commit +1 -0
- package/.nvmrc +1 -0
- package/.releaserc.json +34 -0
- package/.vscode/extensions.json +7 -0
- package/.vscode/settings.json +16 -0
- package/.yarn/install-state.gz +0 -0
- package/.yarnrc.yml +1 -0
- package/ContributionAgreement +72 -0
- package/dist/cjs/abi/iZapper.cjs +85 -0
- package/dist/cjs/abi/iZapper.d.ts +123 -0
- package/dist/cjs/sdk/index.cjs +19830 -19764
- package/dist/cjs/sdk/index.d.ts +3746 -3061
- package/dist/esm/abi/iZapper.d.mts +123 -0
- package/dist/esm/abi/iZapper.mjs +83 -0
- package/dist/esm/sdk/index.d.mts +3746 -3061
- package/dist/esm/sdk/index.mjs +19807 -19765
- package/jest.config.js +7 -0
- package/package.json +32 -2
- package/scripts/example.ts +30 -0
- package/src/abi/compressors.ts +3962 -0
- package/src/abi/errors.ts +196 -0
- package/src/abi/iERC20.ts +122 -0
- package/src/abi/iPausable.ts +35 -0
- package/src/abi/iPriceFeedStore.ts +227 -0
- package/src/abi/iUpdatablePriceFeed.ts +16 -0
- package/src/abi/iVersion.ts +28 -0
- package/src/abi/iZapper.ts +84 -0
- package/src/abi/routerV300.ts +378 -0
- package/src/abi/v300.ts +4151 -0
- package/src/abi/v310.ts +5179 -0
- package/src/adapters/AbstractAdapter.ts +28 -0
- package/src/adapters/BalancerV2VaultAdapterContract.ts +19 -0
- package/src/adapters/BalancerV3RouterAdapterContract.ts +19 -0
- package/src/adapters/CamelotV3AdapterContract.ts +20 -0
- package/src/adapters/ConvexV1BaseRewardPoolAdapterContract.ts +20 -0
- package/src/adapters/ConvexV1BoosterAdapterContract.ts +20 -0
- package/src/adapters/Curve2AssetsAdapterContract.ts +20 -0
- package/src/adapters/Curve3AssetsAdapterContract.ts +20 -0
- package/src/adapters/Curve4AssetsAdapterContract.ts +20 -0
- package/src/adapters/CurveV1AdapterStETHContract.ts +20 -0
- package/src/adapters/CurveV1StableNGAdapterContract.ts +20 -0
- package/src/adapters/DaiUsdsAdapterContract.ts +21 -0
- package/src/adapters/ERC4626AdapterContract.ts +20 -0
- package/src/adapters/MellowERC4626VaultAdapterContract.ts +20 -0
- package/src/adapters/MellowVaultAdapterContract.ts +20 -0
- package/src/adapters/PendleRouterAdapterContract.ts +21 -0
- package/src/adapters/StakingRewardsAdapterContract.ts +21 -0
- package/src/adapters/UniswapV2AdapterContract.ts +20 -0
- package/src/adapters/UniswapV3AdapterContract.ts +170 -0
- package/src/adapters/VelodromeV2AdapterContract.ts +20 -0
- package/src/adapters/WstETHV1AdapterContract.ts +20 -0
- package/src/adapters/YearnV2AdapterContract.ts +20 -0
- package/src/adapters/abi/adapters.ts +4325 -0
- package/src/adapters/abi/iBalancerV3RouterAdapter.ts +126 -0
- package/src/adapters/abi/index.ts +2 -0
- package/src/adapters/index.ts +2 -0
- package/src/adapters/plugin.ts +90 -0
- package/src/adapters/types.ts +62 -0
- package/src/dev/AccountOpener.ts +611 -0
- package/src/dev/PriceFeedStore.ts +95 -0
- package/src/dev/SDKExample.ts +167 -0
- package/src/dev/abi.ts +14 -0
- package/src/dev/calcLiquidatableLTs.ts +77 -0
- package/src/dev/createAnvilClient.ts +155 -0
- package/src/dev/index.ts +7 -0
- package/src/dev/setLTZero.ts +127 -0
- package/src/dev/setLTs.ts +68 -0
- package/src/sdk/GearboxSDK.ts +488 -0
- package/src/sdk/abi/index.ts +1 -0
- package/src/sdk/abi/oracles.ts +4614 -0
- package/src/sdk/accounts/CreditAccountsService.ts +1123 -0
- package/src/sdk/accounts/index.ts +1 -0
- package/src/sdk/base/AddressLabeller.ts +35 -0
- package/src/sdk/base/BaseContract.ts +237 -0
- package/src/sdk/base/IAddressLabeller.ts +13 -0
- package/src/sdk/base/PlaceholderContract.ts +12 -0
- package/src/sdk/base/SDKConstruct.ts +35 -0
- package/src/sdk/base/TokensMeta.ts +45 -0
- package/src/sdk/base/index.ts +6 -0
- package/src/sdk/base/types.ts +102 -0
- package/src/sdk/bots/BotsService.ts +92 -0
- package/src/sdk/bots/index.ts +2 -0
- package/src/sdk/bots/utils.ts +19 -0
- package/src/sdk/chain/Provider.ts +99 -0
- package/src/sdk/chain/chains.ts +41 -0
- package/src/sdk/chain/detectChain.ts +21 -0
- package/src/sdk/chain/index.ts +3 -0
- package/src/sdk/constants/address-provider.ts +47 -0
- package/src/sdk/constants/addresses.ts +82 -0
- package/src/sdk/constants/bot-permissions.ts +36 -0
- package/src/sdk/constants/index.ts +6 -0
- package/src/sdk/constants/math.ts +23 -0
- package/src/sdk/constants/networks.ts +38 -0
- package/src/sdk/constants/periphery.ts +7 -0
- package/src/sdk/core/BotListV3Contract.ts +103 -0
- package/src/sdk/core/GearStakingV3Contract.ts +84 -0
- package/src/sdk/core/address-provider/AbstractAddressProviderContract.ts +101 -0
- package/src/sdk/core/address-provider/AddressProviderV3Contract.ts +105 -0
- package/src/sdk/core/address-provider/AddressProviderV3_1Contract.ts +92 -0
- package/src/sdk/core/address-provider/getAddressProvider.ts +45 -0
- package/src/sdk/core/address-provider/index.ts +4 -0
- package/src/sdk/core/address-provider/types.ts +17 -0
- package/src/sdk/core/index.ts +3 -0
- package/src/sdk/gauges/GaugeStakingService.ts +100 -0
- package/src/sdk/gauges/index.ts +2 -0
- package/src/sdk/gauges/utils.ts +25 -0
- package/src/sdk/index.ts +17 -0
- package/src/sdk/market/MarketConfiguratorContract.ts +78 -0
- package/src/sdk/market/MarketRegister.ts +330 -0
- package/src/sdk/market/MarketSuite.ts +83 -0
- package/src/sdk/market/adapters/PlaceholderAdapterContracts.ts +18 -0
- package/src/sdk/market/adapters/factory.ts +34 -0
- package/src/sdk/market/adapters/index.ts +3 -0
- package/src/sdk/market/adapters/types.ts +7 -0
- package/src/sdk/market/credit/CreditConfiguratorV300Contract.ts +164 -0
- package/src/sdk/market/credit/CreditConfiguratorV310Contract.ts +139 -0
- package/src/sdk/market/credit/CreditFacadeV300Contract.ts +206 -0
- package/src/sdk/market/credit/CreditFacadeV310Contract.ts +190 -0
- package/src/sdk/market/credit/CreditManagerV300Contract.ts +122 -0
- package/src/sdk/market/credit/CreditManagerV310Contract.ts +122 -0
- package/src/sdk/market/credit/CreditSuite.ts +65 -0
- package/src/sdk/market/credit/createCreditConfigurator.ts +18 -0
- package/src/sdk/market/credit/createCreditFacade.ts +18 -0
- package/src/sdk/market/credit/createCreditManager.ts +18 -0
- package/src/sdk/market/credit/index.ts +8 -0
- package/src/sdk/market/credit/types.ts +42 -0
- package/src/sdk/market/index.ts +7 -0
- package/src/sdk/market/oracle/PriceOracleBaseContract.ts +376 -0
- package/src/sdk/market/oracle/PriceOracleV300Contract.ts +71 -0
- package/src/sdk/market/oracle/PriceOracleV310Contract.ts +43 -0
- package/src/sdk/market/oracle/createPriceOracle.ts +22 -0
- package/src/sdk/market/oracle/index.ts +4 -0
- package/src/sdk/market/oracle/types.ts +48 -0
- package/src/sdk/market/pool/GaugeContract.ts +120 -0
- package/src/sdk/market/pool/LinearInterestRateModelContract.ts +75 -0
- package/src/sdk/market/pool/PoolQuotaKeeperV300Contract.ts +89 -0
- package/src/sdk/market/pool/PoolQuotaKeeperV310Contract.ts +89 -0
- package/src/sdk/market/pool/PoolSuite.ts +76 -0
- package/src/sdk/market/pool/PoolV300Contract.ts +144 -0
- package/src/sdk/market/pool/PoolV310Contract.ts +144 -0
- package/src/sdk/market/pool/TumblerContract.ts +73 -0
- package/src/sdk/market/pool/createInterestRateModel.ts +33 -0
- package/src/sdk/market/pool/createPool.ts +19 -0
- package/src/sdk/market/pool/createPoolQuotaKeeper.ts +20 -0
- package/src/sdk/market/pool/createRateKeeper.ts +25 -0
- package/src/sdk/market/pool/index.ts +6 -0
- package/src/sdk/market/pool/types.ts +28 -0
- package/src/sdk/market/pricefeeds/AbstractLPPriceFeed.ts +71 -0
- package/src/sdk/market/pricefeeds/AbstractPriceFeed.ts +137 -0
- package/src/sdk/market/pricefeeds/BalancerStablePriceFeed.ts +24 -0
- package/src/sdk/market/pricefeeds/BalancerWeightedPriceFeed.ts +70 -0
- package/src/sdk/market/pricefeeds/BoundedPriceFeed.ts +34 -0
- package/src/sdk/market/pricefeeds/ChainlinkPriceFeed.ts +16 -0
- package/src/sdk/market/pricefeeds/CompositePriceFeed.ts +25 -0
- package/src/sdk/market/pricefeeds/CurveCryptoPriceFeed.ts +24 -0
- package/src/sdk/market/pricefeeds/CurveStablePriceFeed.ts +24 -0
- package/src/sdk/market/pricefeeds/CurveUSDPriceFeed.ts +24 -0
- package/src/sdk/market/pricefeeds/Erc4626PriceFeed.ts +36 -0
- package/src/sdk/market/pricefeeds/MellowLRTPriceFeed.ts +26 -0
- package/src/sdk/market/pricefeeds/PendleTWAPPTPriceFeed.ts +44 -0
- package/src/sdk/market/pricefeeds/PriceFeedRef.ts +34 -0
- package/src/sdk/market/pricefeeds/PriceFeedsRegister.ts +293 -0
- package/src/sdk/market/pricefeeds/RedstonePriceFeed.ts +65 -0
- package/src/sdk/market/pricefeeds/RedstoneUpdater.ts +304 -0
- package/src/sdk/market/pricefeeds/WstETHPriceFeed.ts +24 -0
- package/src/sdk/market/pricefeeds/YearnPriceFeed.ts +24 -0
- package/src/sdk/market/pricefeeds/ZeroPriceFeed.ts +17 -0
- package/src/sdk/market/pricefeeds/index.ts +20 -0
- package/src/sdk/market/pricefeeds/types.ts +82 -0
- package/src/sdk/market/pricefeeds/utils.ts +24 -0
- package/src/sdk/plugins/index.ts +10 -0
- package/src/sdk/router/PathOptionFactory.ts +147 -0
- package/src/sdk/router/RouterV3Contract.ts +558 -0
- package/src/sdk/router/index.ts +2 -0
- package/src/sdk/router/types.ts +48 -0
- package/src/sdk/sdk-gov-legacy/contracts/adapters.ts +39 -0
- package/src/sdk/sdk-gov-legacy/contracts/contracts.ts +647 -0
- package/src/sdk/sdk-gov-legacy/contracts/index.ts +2 -0
- package/src/sdk/sdk-gov-legacy/core/constants.ts +11 -0
- package/src/sdk/sdk-gov-legacy/index.ts +4 -0
- package/src/sdk/sdk-gov-legacy/oracles/PriceFeedType.ts +24 -0
- package/src/sdk/sdk-gov-legacy/oracles/index.ts +1 -0
- package/src/sdk/sdk-gov-legacy/tokens/aave.ts +101 -0
- package/src/sdk/sdk-gov-legacy/tokens/aura.ts +284 -0
- package/src/sdk/sdk-gov-legacy/tokens/balancer.ts +421 -0
- package/src/sdk/sdk-gov-legacy/tokens/compound.ts +79 -0
- package/src/sdk/sdk-gov-legacy/tokens/convex.ts +561 -0
- package/src/sdk/sdk-gov-legacy/tokens/curveLP.ts +480 -0
- package/src/sdk/sdk-gov-legacy/tokens/decimals.ts +301 -0
- package/src/sdk/sdk-gov-legacy/tokens/erc4626.ts +75 -0
- package/src/sdk/sdk-gov-legacy/tokens/gear.ts +273 -0
- package/src/sdk/sdk-gov-legacy/tokens/index.ts +18 -0
- package/src/sdk/sdk-gov-legacy/tokens/normal.ts +613 -0
- package/src/sdk/sdk-gov-legacy/tokens/quoted.ts +10 -0
- package/src/sdk/sdk-gov-legacy/tokens/stakingRewards.ts +41 -0
- package/src/sdk/sdk-gov-legacy/tokens/token.ts +2354 -0
- package/src/sdk/sdk-gov-legacy/tokens/tokenData.ts +44 -0
- package/src/sdk/sdk-gov-legacy/tokens/tokenType.ts +33 -0
- package/src/sdk/sdk-gov-legacy/tokens/wrapped.ts +28 -0
- package/src/sdk/sdk-gov-legacy/tokens/yearn.ts +122 -0
- package/src/sdk/sdk-gov-legacy/tokens/zircuit.ts +44 -0
- package/src/sdk/sdk-legacy/apy/index.ts +149 -0
- package/src/sdk/sdk-legacy/core/assets.ts +200 -0
- package/src/sdk/sdk-legacy/core/creditAccount.spec.ts +1966 -0
- package/src/sdk/sdk-legacy/core/creditAccount.ts +816 -0
- package/src/sdk/sdk-legacy/core/creditManager.ts +316 -0
- package/src/sdk/sdk-legacy/core/creditSession.ts +352 -0
- package/src/sdk/sdk-legacy/core/endpoint.ts +131 -0
- package/src/sdk/sdk-legacy/core/eventOrTx.ts +101 -0
- package/src/sdk/sdk-legacy/core/pool.ts +439 -0
- package/src/sdk/sdk-legacy/core/strategy.ts +82 -0
- package/src/sdk/sdk-legacy/core/transactions.ts +865 -0
- package/src/sdk/sdk-legacy/gearboxRewards/api.ts +704 -0
- package/src/sdk/sdk-legacy/gearboxRewards/apy.ts +267 -0
- package/src/sdk/sdk-legacy/gearboxRewards/extraAPY.ts +165 -0
- package/src/sdk/sdk-legacy/gearboxRewards/index.ts +3 -0
- package/src/sdk/sdk-legacy/gearboxRewards/merklAPI.ts +151 -0
- package/src/sdk/sdk-legacy/index.ts +21 -0
- package/src/sdk/sdk-legacy/pathfinder/core.ts +18 -0
- package/src/sdk/sdk-legacy/pathfinder/index.ts +1 -0
- package/src/sdk/sdk-legacy/payload/creditAccount.ts +48 -0
- package/src/sdk/sdk-legacy/payload/creditManager.ts +133 -0
- package/src/sdk/sdk-legacy/payload/creditSession.ts +143 -0
- package/src/sdk/sdk-legacy/payload/graphPayload.ts +10 -0
- package/src/sdk/sdk-legacy/payload/pool.ts +198 -0
- package/src/sdk/sdk-legacy/payload/token.ts +13 -0
- package/src/sdk/sdk-legacy/tokens/tokenData.ts +57 -0
- package/src/sdk/sdk-legacy/types/IAirdropDistributor.ts +103 -0
- package/src/sdk/sdk-legacy/types/IBaseRewardPool.ts +249 -0
- package/src/sdk/sdk-legacy/types/IDataCompressorV3.ts +957 -0
- package/src/sdk/sdk-legacy/types/IDegenDistributor.ts +70 -0
- package/src/sdk/sdk-legacy/types/IERC20Permit.ts +35 -0
- package/src/sdk/sdk-legacy/types/IERC20ZapperDeposits.ts +99 -0
- package/src/sdk/sdk-legacy/types/IETHZapperDeposits.ts +27 -0
- package/src/sdk/sdk-legacy/types/IFarmingPool.ts +229 -0
- package/src/sdk/sdk-legacy/types/IInterestRateModel.ts +23 -0
- package/src/sdk/sdk-legacy/types/IMulticall3.ts +242 -0
- package/src/sdk/sdk-legacy/types/IOffchainOracle.ts +31 -0
- package/src/sdk/sdk-legacy/types/index.ts +11 -0
- package/src/sdk/sdk-legacy/utils/formatter.ts +46 -0
- package/src/sdk/sdk-legacy/utils/index.ts +3 -0
- package/src/sdk/sdk-legacy/utils/math.ts +6 -0
- package/src/sdk/sdk-legacy/utils/price.ts +27 -0
- package/src/sdk/types/index.ts +5 -0
- package/src/sdk/types/logger.ts +13 -0
- package/src/sdk/types/state-human.ts +224 -0
- package/src/sdk/types/state.ts +8 -0
- package/src/sdk/types/transactions.ts +22 -0
- package/src/sdk/types/tvl.ts +4 -0
- package/src/sdk/utils/AddressMap.ts +111 -0
- package/src/sdk/utils/bytes32ToString.ts +6 -0
- package/src/sdk/utils/childLogger.ts +8 -0
- package/src/sdk/utils/createRawTx.ts +86 -0
- package/src/sdk/utils/etherscan.ts +42 -0
- package/src/sdk/utils/filterDust.ts +20 -0
- package/src/sdk/utils/formatter.ts +124 -0
- package/src/sdk/utils/index.ts +10 -0
- package/src/sdk/utils/internal/Hooks.ts +51 -0
- package/src/sdk/utils/internal/index.ts +1 -0
- package/src/sdk/utils/json.ts +27 -0
- package/src/sdk/utils/mappers.ts +38 -0
- package/src/sdk/utils/retry.ts +24 -0
- package/src/sdk/utils/viem/detectNetwork.ts +27 -0
- package/src/sdk/utils/viem/index.ts +3 -0
- package/src/sdk/utils/viem/sendRawTx.ts +36 -0
- package/src/sdk/utils/viem/simulateMulticall.ts +262 -0
- package/tsconfig.build.json +4 -0
- package/tsconfig.json +16 -0
- package/tsup.config.ts +77 -0
|
@@ -0,0 +1,1123 @@
|
|
|
1
|
+
import type { Address, ContractFunctionArgs } from "viem";
|
|
2
|
+
import { encodeFunctionData } from "viem";
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
iCreditAccountCompressorAbi,
|
|
6
|
+
iPeripheryCompressorAbi,
|
|
7
|
+
iRewardsCompressorAbi,
|
|
8
|
+
} from "../../abi/compressors";
|
|
9
|
+
import { iCreditFacadeV300MulticallAbi } from "../../abi/v300";
|
|
10
|
+
import type { CreditAccountData } from "../base";
|
|
11
|
+
import { SDKConstruct } from "../base";
|
|
12
|
+
import {
|
|
13
|
+
ADDRESS_0X0,
|
|
14
|
+
AP_CREDIT_ACCOUNT_COMPRESSOR,
|
|
15
|
+
AP_PERIPHERY_COMPRESSOR,
|
|
16
|
+
AP_REWARDS_COMPRESSOR,
|
|
17
|
+
MAX_UINT256,
|
|
18
|
+
MIN_INT96,
|
|
19
|
+
} from "../constants";
|
|
20
|
+
import type { GearboxSDK } from "../GearboxSDK";
|
|
21
|
+
import type {
|
|
22
|
+
CreditSuite,
|
|
23
|
+
IPriceFeedContract,
|
|
24
|
+
IPriceOracleContract,
|
|
25
|
+
OnDemandPriceUpdate,
|
|
26
|
+
UpdatePriceFeedsResult,
|
|
27
|
+
} from "../market";
|
|
28
|
+
import { rawTxToMulticallPriceUpdate } from "../market";
|
|
29
|
+
import {
|
|
30
|
+
type Asset,
|
|
31
|
+
assetsMap,
|
|
32
|
+
type CreditAccountDataSlice,
|
|
33
|
+
type RouterCloseResult,
|
|
34
|
+
} from "../router";
|
|
35
|
+
import { iBaseRewardPoolAbi } from "../sdk-legacy";
|
|
36
|
+
import type { ILogger, MultiCall, RawTx } from "../types";
|
|
37
|
+
import { childLogger } from "../utils";
|
|
38
|
+
import { simulateMulticall } from "../utils/viem";
|
|
39
|
+
|
|
40
|
+
type CompressorAbi = typeof iCreditAccountCompressorAbi;
|
|
41
|
+
|
|
42
|
+
type GetCreditAccountsArgs = ContractFunctionArgs<
|
|
43
|
+
typeof iCreditAccountCompressorAbi,
|
|
44
|
+
"pure" | "view",
|
|
45
|
+
"getCreditAccounts"
|
|
46
|
+
>;
|
|
47
|
+
|
|
48
|
+
export interface CreditAccountServiceOptions {
|
|
49
|
+
batchSize?: number;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
interface ReadContractOptions {
|
|
53
|
+
blockNumber?: bigint;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface CreditAccountFilter {
|
|
57
|
+
creditManager?: Address;
|
|
58
|
+
owner?: Address;
|
|
59
|
+
includeZeroDebt?: boolean;
|
|
60
|
+
minHealthFactor?: number;
|
|
61
|
+
maxHealthFactor?: number;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface CloseCreditAccountResult extends CommonResult {
|
|
65
|
+
routerCloseResult: RouterCloseResult;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface CommonResult {
|
|
69
|
+
tx: RawTx;
|
|
70
|
+
calls: Array<MultiCall>;
|
|
71
|
+
creditFacade: CreditSuite["creditFacade"];
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
type CloseOptions = "close" | "zeroDebt";
|
|
75
|
+
|
|
76
|
+
interface CloseCreditAccountProps {
|
|
77
|
+
operation: CloseOptions;
|
|
78
|
+
creditAccount: CreditAccountDataSlice;
|
|
79
|
+
assetsToWithdraw: Array<Address>;
|
|
80
|
+
to: Address;
|
|
81
|
+
slippage?: bigint;
|
|
82
|
+
closePath?: RouterCloseResult;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
interface RepayCreditAccountProps extends RepayAndLiquidateCreditAccountProps {
|
|
86
|
+
operation: CloseOptions;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
interface RepayAndLiquidateCreditAccountProps {
|
|
90
|
+
collateralAssets: Array<Asset>;
|
|
91
|
+
assetsToWithdraw: Array<Address>;
|
|
92
|
+
creditAccount: CreditAccountDataSlice;
|
|
93
|
+
to: Address;
|
|
94
|
+
permits: Record<string, PermitResult>;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
interface PrepareUpdateQuotasProps {
|
|
98
|
+
minQuota: Array<Asset>;
|
|
99
|
+
averageQuota: Array<Asset>;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
interface UpdateQuotasProps extends PrepareUpdateQuotasProps {
|
|
103
|
+
creditAccount: CreditAccountDataSlice;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
interface AddCollateralProps extends PrepareUpdateQuotasProps {
|
|
107
|
+
asset: Asset;
|
|
108
|
+
ethAmount: bigint;
|
|
109
|
+
permit: PermitResult | undefined;
|
|
110
|
+
creditAccount: CreditAccountDataSlice;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
interface WithdrawCollateralProps extends PrepareUpdateQuotasProps {
|
|
114
|
+
assetsToWithdraw: Array<Asset>;
|
|
115
|
+
to: Address;
|
|
116
|
+
creditAccount: CreditAccountDataSlice;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
interface ExecuteSwapProps extends PrepareUpdateQuotasProps {
|
|
120
|
+
calls: Array<MultiCall>;
|
|
121
|
+
creditAccount: CreditAccountDataSlice;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface ClaimFarmRewardsProps extends PrepareUpdateQuotasProps {
|
|
125
|
+
tokensToDisable: Array<Asset>;
|
|
126
|
+
calls: Array<MultiCall>;
|
|
127
|
+
creditAccount: CreditAccountDataSlice;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export interface OpenCAProps extends PrepareUpdateQuotasProps {
|
|
131
|
+
ethAmount: bigint;
|
|
132
|
+
collateral: Array<Asset>;
|
|
133
|
+
debt: bigint;
|
|
134
|
+
withdrawDebt?: boolean;
|
|
135
|
+
permits: Record<string, PermitResult>;
|
|
136
|
+
calls: Array<MultiCall>;
|
|
137
|
+
|
|
138
|
+
creditManager: Address;
|
|
139
|
+
|
|
140
|
+
to: Address;
|
|
141
|
+
referralCode: bigint;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
interface ChangeDeptProps {
|
|
145
|
+
creditAccount: CreditAccountDataSlice;
|
|
146
|
+
amount: bigint;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export interface PermitResult {
|
|
150
|
+
r: Address;
|
|
151
|
+
s: Address;
|
|
152
|
+
v: number;
|
|
153
|
+
|
|
154
|
+
token: Address;
|
|
155
|
+
owner: Address;
|
|
156
|
+
spender: Address;
|
|
157
|
+
value: bigint;
|
|
158
|
+
|
|
159
|
+
deadline: bigint;
|
|
160
|
+
nonce: bigint;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
export interface Rewards {
|
|
164
|
+
adapter: Address;
|
|
165
|
+
stakedPhantomToken: Address;
|
|
166
|
+
calls: Array<MultiCall>;
|
|
167
|
+
|
|
168
|
+
rewards: Array<Asset>;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export class CreditAccountsService extends SDKConstruct {
|
|
172
|
+
#compressor: Address;
|
|
173
|
+
#batchSize?: number;
|
|
174
|
+
#logger?: ILogger;
|
|
175
|
+
|
|
176
|
+
constructor(sdk: GearboxSDK, options?: CreditAccountServiceOptions) {
|
|
177
|
+
super(sdk);
|
|
178
|
+
this.#compressor = sdk.addressProvider.getLatestVersion(
|
|
179
|
+
AP_CREDIT_ACCOUNT_COMPRESSOR,
|
|
180
|
+
);
|
|
181
|
+
this.#batchSize = options?.batchSize;
|
|
182
|
+
this.#logger = childLogger("CreditAccountsService", sdk.logger);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Returns single credit account data, or undefined if it's not found
|
|
187
|
+
* Performs all necessary price feed updates under the hood
|
|
188
|
+
* @param account
|
|
189
|
+
* @param options
|
|
190
|
+
* @returns
|
|
191
|
+
*/
|
|
192
|
+
public async getCreditAccountData(
|
|
193
|
+
account: Address,
|
|
194
|
+
options?: ReadContractOptions,
|
|
195
|
+
): Promise<CreditAccountData | undefined> {
|
|
196
|
+
const blockNumber = options?.blockNumber;
|
|
197
|
+
let raw: CreditAccountData;
|
|
198
|
+
try {
|
|
199
|
+
raw = await this.provider.publicClient.readContract({
|
|
200
|
+
abi: iCreditAccountCompressorAbi,
|
|
201
|
+
address: this.#compressor,
|
|
202
|
+
functionName: "getCreditAccountData",
|
|
203
|
+
args: [account],
|
|
204
|
+
blockNumber,
|
|
205
|
+
});
|
|
206
|
+
} catch (e) {
|
|
207
|
+
// TODO: reverts if account is not found, how to handle other revert reasons?
|
|
208
|
+
return undefined;
|
|
209
|
+
}
|
|
210
|
+
if (raw.success) {
|
|
211
|
+
return raw;
|
|
212
|
+
}
|
|
213
|
+
const { txs: priceUpdateTxs, timestamp: _ } =
|
|
214
|
+
await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(undefined, {
|
|
215
|
+
account,
|
|
216
|
+
});
|
|
217
|
+
const resp = await simulateMulticall(this.provider.publicClient, {
|
|
218
|
+
contracts: [
|
|
219
|
+
...priceUpdateTxs.map(rawTxToMulticallPriceUpdate),
|
|
220
|
+
{
|
|
221
|
+
abi: iCreditAccountCompressorAbi,
|
|
222
|
+
address: this.#compressor,
|
|
223
|
+
functionName: "getCreditAccountData",
|
|
224
|
+
args: [account],
|
|
225
|
+
},
|
|
226
|
+
],
|
|
227
|
+
allowFailure: false,
|
|
228
|
+
// gas: 550_000_000n,
|
|
229
|
+
batchSize: 0, // we cannot have price updates and compressor request in different batches
|
|
230
|
+
blockNumber,
|
|
231
|
+
});
|
|
232
|
+
const cad = resp.pop() as CreditAccountData;
|
|
233
|
+
return cad;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Methods to get all credit accounts with some optional filtering
|
|
238
|
+
* Performs all necessary price feed updates under the hood
|
|
239
|
+
*
|
|
240
|
+
* TODO: do we want to expose pagination?
|
|
241
|
+
* TODO: do we want to expose "reverting"?
|
|
242
|
+
* TODO: do we want to expose MarketFilter in any way? If so, we need to check that the MarketFilter is compatibled with attached markets?
|
|
243
|
+
* @param args
|
|
244
|
+
* @param options
|
|
245
|
+
* @returns returned credit accounts are sorted by health factor in ascending order
|
|
246
|
+
*/
|
|
247
|
+
public async getCreditAccounts(
|
|
248
|
+
args?: CreditAccountFilter,
|
|
249
|
+
options?: ReadContractOptions,
|
|
250
|
+
): Promise<Array<CreditAccountData>> {
|
|
251
|
+
const {
|
|
252
|
+
creditManager,
|
|
253
|
+
includeZeroDebt = false,
|
|
254
|
+
maxHealthFactor = 65_535, // TODO: this will change to bigint
|
|
255
|
+
minHealthFactor = 0,
|
|
256
|
+
owner = ADDRESS_0X0,
|
|
257
|
+
} = args ?? {};
|
|
258
|
+
// either credit manager or all attached markets
|
|
259
|
+
const arg0 = creditManager ?? {
|
|
260
|
+
configurators: this.marketConfigurators,
|
|
261
|
+
pools: [],
|
|
262
|
+
underlying: ADDRESS_0X0,
|
|
263
|
+
};
|
|
264
|
+
const caFilter = {
|
|
265
|
+
owner,
|
|
266
|
+
includeZeroDebt,
|
|
267
|
+
minHealthFactor,
|
|
268
|
+
maxHealthFactor,
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
const { txs: priceUpdateTxs, timestamp: _ } =
|
|
272
|
+
await this.sdk.priceFeeds.generatePriceFeedsUpdateTxs();
|
|
273
|
+
|
|
274
|
+
const allCAs: Array<CreditAccountData> = [];
|
|
275
|
+
// reverting filter is exclusive, we need both options to get all accounts
|
|
276
|
+
for (const reverting of [false, true]) {
|
|
277
|
+
let offset = 0n;
|
|
278
|
+
do {
|
|
279
|
+
const [accounts, newOffset] = await this.#getCreditAccounts(
|
|
280
|
+
this.#batchSize
|
|
281
|
+
? [
|
|
282
|
+
arg0,
|
|
283
|
+
{ ...caFilter, reverting },
|
|
284
|
+
offset,
|
|
285
|
+
BigInt(this.#batchSize), // limit
|
|
286
|
+
]
|
|
287
|
+
: [arg0, { ...caFilter, reverting }, offset],
|
|
288
|
+
priceUpdateTxs,
|
|
289
|
+
options,
|
|
290
|
+
);
|
|
291
|
+
allCAs.push(...accounts);
|
|
292
|
+
offset = newOffset;
|
|
293
|
+
} while (offset !== 0n);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// sort by health factor ascending
|
|
297
|
+
return allCAs.sort((a, b) => Number(a.healthFactor - b.healthFactor));
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
async getRewards(creditAccount: Address): Promise<Array<Rewards>> {
|
|
301
|
+
const rewards = await this.provider.publicClient.readContract({
|
|
302
|
+
abi: iRewardsCompressorAbi,
|
|
303
|
+
address: this.rewardCompressor,
|
|
304
|
+
functionName: "getRewards",
|
|
305
|
+
args: [creditAccount],
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
const r = rewards.reduce<Record<string, Rewards>>((acc, r) => {
|
|
309
|
+
const adapter = r.adapter.toLowerCase() as Address;
|
|
310
|
+
const stakedPhantomToken = r.stakedPhantomToken.toLowerCase() as Address;
|
|
311
|
+
const rewardToken = r.rewardToken.toLowerCase() as Address;
|
|
312
|
+
|
|
313
|
+
const key = [adapter, stakedPhantomToken].join("-");
|
|
314
|
+
|
|
315
|
+
if (!acc[key]) {
|
|
316
|
+
const callData = encodeFunctionData({
|
|
317
|
+
abi: iBaseRewardPoolAbi,
|
|
318
|
+
functionName: "getReward",
|
|
319
|
+
args: [],
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
acc[adapter] = {
|
|
323
|
+
adapter,
|
|
324
|
+
stakedPhantomToken,
|
|
325
|
+
calls: [
|
|
326
|
+
{
|
|
327
|
+
target: adapter,
|
|
328
|
+
callData,
|
|
329
|
+
},
|
|
330
|
+
],
|
|
331
|
+
rewards: [],
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
acc[adapter].rewards.push({
|
|
336
|
+
token: rewardToken,
|
|
337
|
+
balance: r.amount,
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
return acc;
|
|
341
|
+
}, {});
|
|
342
|
+
|
|
343
|
+
return Object.values(r);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
async getConnectedBots(
|
|
347
|
+
accountsToCheck: Array<{ creditAccount: Address; creditManager: Address }>,
|
|
348
|
+
) {
|
|
349
|
+
const resp = await this.provider.publicClient.multicall({
|
|
350
|
+
contracts: accountsToCheck.map(o => {
|
|
351
|
+
const pool = this.sdk.marketRegister.findByCreditManager(
|
|
352
|
+
o.creditManager,
|
|
353
|
+
);
|
|
354
|
+
|
|
355
|
+
return {
|
|
356
|
+
abi: iPeripheryCompressorAbi,
|
|
357
|
+
address: this.peripheryCompressor,
|
|
358
|
+
functionName: "getConnectedBots",
|
|
359
|
+
args: [pool.configurator.address, o.creditAccount],
|
|
360
|
+
} as const;
|
|
361
|
+
}),
|
|
362
|
+
allowFailure: true,
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
return resp;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Generates transaction to liquidate credit account
|
|
370
|
+
* @param account
|
|
371
|
+
* @param to Address to transfer underlying left after liquidation
|
|
372
|
+
* @param slippage
|
|
373
|
+
* @returns
|
|
374
|
+
*/
|
|
375
|
+
public async fullyLiquidate(
|
|
376
|
+
account: CreditAccountDataSlice,
|
|
377
|
+
to: Address,
|
|
378
|
+
slippage = 50n,
|
|
379
|
+
): Promise<CloseCreditAccountResult> {
|
|
380
|
+
const cm = this.sdk.marketRegister.findCreditManager(account.creditManager);
|
|
381
|
+
const routerCloseResult = await this.sdk.router.findBestClosePath({
|
|
382
|
+
creditAccount: account,
|
|
383
|
+
creditManager: cm.creditManager,
|
|
384
|
+
slippage,
|
|
385
|
+
});
|
|
386
|
+
const priceUpdates = await this.getPriceUpdatesForFacade(
|
|
387
|
+
account.creditManager,
|
|
388
|
+
account,
|
|
389
|
+
undefined,
|
|
390
|
+
);
|
|
391
|
+
const calls = [...priceUpdates, ...routerCloseResult.calls];
|
|
392
|
+
const tx = cm.creditFacade.liquidateCreditAccount(
|
|
393
|
+
account.creditAccount,
|
|
394
|
+
to,
|
|
395
|
+
calls,
|
|
396
|
+
);
|
|
397
|
+
return { tx, calls, routerCloseResult, creditFacade: cm.creditFacade };
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Closes credit account or sets debt to zero (but keep account)
|
|
402
|
+
* @param operation
|
|
403
|
+
* @param creditAccount
|
|
404
|
+
* @param assetsToWithdraw Tokens to withdraw from credit account
|
|
405
|
+
* @param to Address to withdraw underlying to
|
|
406
|
+
* @param slippage
|
|
407
|
+
* @param closePath
|
|
408
|
+
* @returns
|
|
409
|
+
*/
|
|
410
|
+
async closeCreditAccount({
|
|
411
|
+
operation,
|
|
412
|
+
assetsToWithdraw,
|
|
413
|
+
creditAccount: ca,
|
|
414
|
+
to,
|
|
415
|
+
slippage = 50n,
|
|
416
|
+
closePath,
|
|
417
|
+
}: CloseCreditAccountProps): Promise<CloseCreditAccountResult> {
|
|
418
|
+
const cm = this.sdk.marketRegister.findCreditManager(ca.creditManager);
|
|
419
|
+
|
|
420
|
+
const routerCloseResult =
|
|
421
|
+
closePath ||
|
|
422
|
+
(await this.sdk.router.findBestClosePath({
|
|
423
|
+
creditAccount: ca,
|
|
424
|
+
creditManager: cm.creditManager,
|
|
425
|
+
slippage,
|
|
426
|
+
}));
|
|
427
|
+
|
|
428
|
+
const calls: Array<MultiCall> = [
|
|
429
|
+
...routerCloseResult.calls,
|
|
430
|
+
...this.#prepareDisableQuotas(ca),
|
|
431
|
+
...this.#prepareDecreaseDebt(ca),
|
|
432
|
+
...this.#prepareDisableTokens(ca),
|
|
433
|
+
...assetsToWithdraw.map(t =>
|
|
434
|
+
this.#prepareWithdrawToken(ca.creditFacade, t, MAX_UINT256, to),
|
|
435
|
+
),
|
|
436
|
+
];
|
|
437
|
+
|
|
438
|
+
const tx =
|
|
439
|
+
operation === "close"
|
|
440
|
+
? cm.creditFacade.closeCreditAccount(ca.creditAccount, calls)
|
|
441
|
+
: cm.creditFacade.multicall(ca.creditAccount, calls);
|
|
442
|
+
return { tx, calls, routerCloseResult, creditFacade: cm.creditFacade };
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* Repays credit account or sets debt to zero (but keep account)
|
|
447
|
+
* @param operation
|
|
448
|
+
* @param creditAccount
|
|
449
|
+
* @param assetsToWithdraw Tokens to withdraw from credit account
|
|
450
|
+
* @param collateralAssets Tokens to pay for
|
|
451
|
+
* @param to Address to withdraw underlying to
|
|
452
|
+
* @param slippage
|
|
453
|
+
* @param permits
|
|
454
|
+
* @returns
|
|
455
|
+
*/
|
|
456
|
+
async repayCreditAccount({
|
|
457
|
+
operation,
|
|
458
|
+
collateralAssets,
|
|
459
|
+
assetsToWithdraw,
|
|
460
|
+
creditAccount: ca,
|
|
461
|
+
permits,
|
|
462
|
+
to,
|
|
463
|
+
}: RepayCreditAccountProps): Promise<CommonResult> {
|
|
464
|
+
const cm = this.sdk.marketRegister.findCreditManager(ca.creditManager);
|
|
465
|
+
const addCollateral = collateralAssets.filter(a => a.balance > 0);
|
|
466
|
+
|
|
467
|
+
const calls: Array<MultiCall> = [
|
|
468
|
+
...this.#prepareAddCollateral(ca.creditFacade, addCollateral, permits),
|
|
469
|
+
...this.#prepareDisableQuotas(ca),
|
|
470
|
+
...this.#prepareDecreaseDebt(ca),
|
|
471
|
+
...this.#prepareDisableTokens(ca),
|
|
472
|
+
// TODO: probably needs a better way to handle reward tokens
|
|
473
|
+
...assetsToWithdraw.map(t =>
|
|
474
|
+
this.#prepareWithdrawToken(ca.creditFacade, t, MAX_UINT256, to),
|
|
475
|
+
),
|
|
476
|
+
];
|
|
477
|
+
|
|
478
|
+
const tx =
|
|
479
|
+
operation === "close"
|
|
480
|
+
? cm.creditFacade.closeCreditAccount(ca.creditAccount, calls)
|
|
481
|
+
: cm.creditFacade.multicall(ca.creditAccount, calls);
|
|
482
|
+
return { tx, calls, creditFacade: cm.creditFacade };
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* Repays liquidatable credit account
|
|
487
|
+
* @param creditAccount
|
|
488
|
+
* @param assetsToWithdraw Tokens to withdraw from credit account
|
|
489
|
+
* @param collateralAssets Tokens to pay for
|
|
490
|
+
* @param to Address to withdraw underlying to
|
|
491
|
+
* @param slippage
|
|
492
|
+
* @returns
|
|
493
|
+
*/
|
|
494
|
+
async repayAndLiquidateCreditAccount({
|
|
495
|
+
collateralAssets,
|
|
496
|
+
assetsToWithdraw,
|
|
497
|
+
creditAccount: ca,
|
|
498
|
+
permits,
|
|
499
|
+
to,
|
|
500
|
+
}: RepayAndLiquidateCreditAccountProps): Promise<CommonResult> {
|
|
501
|
+
const cm = this.sdk.marketRegister.findCreditManager(ca.creditManager);
|
|
502
|
+
|
|
503
|
+
const priceUpdates = await this.getPriceUpdatesForFacade(
|
|
504
|
+
ca.creditManager,
|
|
505
|
+
ca,
|
|
506
|
+
undefined,
|
|
507
|
+
);
|
|
508
|
+
|
|
509
|
+
const addCollateral = collateralAssets.filter(a => a.balance > 0);
|
|
510
|
+
|
|
511
|
+
const calls: Array<MultiCall> = [
|
|
512
|
+
...priceUpdates,
|
|
513
|
+
...this.#prepareAddCollateral(ca.creditFacade, addCollateral, permits),
|
|
514
|
+
...assetsToWithdraw.map(t =>
|
|
515
|
+
this.#prepareWithdrawToken(ca.creditFacade, t, MAX_UINT256, to),
|
|
516
|
+
),
|
|
517
|
+
];
|
|
518
|
+
|
|
519
|
+
const tx = cm.creditFacade.liquidateCreditAccount(
|
|
520
|
+
ca.creditAccount,
|
|
521
|
+
to,
|
|
522
|
+
calls,
|
|
523
|
+
);
|
|
524
|
+
return { tx, calls, creditFacade: cm.creditFacade };
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
public async updateQuotas(props: UpdateQuotasProps): Promise<CommonResult> {
|
|
528
|
+
const { creditAccount } = props;
|
|
529
|
+
const cm = this.sdk.marketRegister.findCreditManager(
|
|
530
|
+
creditAccount.creditManager,
|
|
531
|
+
);
|
|
532
|
+
const priceUpdates = await this.getPriceUpdatesForFacade(
|
|
533
|
+
creditAccount.creditManager,
|
|
534
|
+
creditAccount,
|
|
535
|
+
undefined,
|
|
536
|
+
);
|
|
537
|
+
|
|
538
|
+
const calls: Array<MultiCall> = [
|
|
539
|
+
...priceUpdates,
|
|
540
|
+
...this.#prepareUpdateQuotas(props.creditAccount.creditFacade, props),
|
|
541
|
+
];
|
|
542
|
+
|
|
543
|
+
const tx = cm.creditFacade.multicall(creditAccount.creditAccount, [
|
|
544
|
+
...priceUpdates,
|
|
545
|
+
...this.#prepareUpdateQuotas(props.creditAccount.creditFacade, props),
|
|
546
|
+
]);
|
|
547
|
+
|
|
548
|
+
return { tx, calls, creditFacade: cm.creditFacade };
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
public async addCollateral(props: AddCollateralProps): Promise<CommonResult> {
|
|
552
|
+
const { creditAccount, asset, permit, ethAmount } = props;
|
|
553
|
+
const cm = this.sdk.marketRegister.findCreditManager(
|
|
554
|
+
creditAccount.creditManager,
|
|
555
|
+
);
|
|
556
|
+
|
|
557
|
+
const priceUpdatesCalls = await this.getPriceUpdatesForFacade(
|
|
558
|
+
creditAccount.creditManager,
|
|
559
|
+
creditAccount,
|
|
560
|
+
props.averageQuota,
|
|
561
|
+
);
|
|
562
|
+
|
|
563
|
+
const calls: Array<MultiCall> = [
|
|
564
|
+
...priceUpdatesCalls,
|
|
565
|
+
...this.#prepareAddCollateral(
|
|
566
|
+
creditAccount.creditFacade,
|
|
567
|
+
[asset],
|
|
568
|
+
permit ? { [asset.token]: permit } : {},
|
|
569
|
+
),
|
|
570
|
+
...this.#prepareUpdateQuotas(creditAccount.creditFacade, props),
|
|
571
|
+
];
|
|
572
|
+
|
|
573
|
+
const tx = cm.creditFacade.multicall(creditAccount.creditAccount, calls);
|
|
574
|
+
tx.value = ethAmount.toString(10);
|
|
575
|
+
|
|
576
|
+
return { tx, calls, creditFacade: cm.creditFacade };
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
public async changeDebt({
|
|
580
|
+
creditAccount,
|
|
581
|
+
amount,
|
|
582
|
+
}: ChangeDeptProps): Promise<CommonResult> {
|
|
583
|
+
if (amount === 0n) {
|
|
584
|
+
throw new Error("debt increase or decrease must be non-zero");
|
|
585
|
+
}
|
|
586
|
+
const isDecrease = amount < 0n;
|
|
587
|
+
const change = isDecrease ? -amount : amount;
|
|
588
|
+
|
|
589
|
+
const cm = this.sdk.marketRegister.findCreditManager(
|
|
590
|
+
creditAccount.creditManager,
|
|
591
|
+
);
|
|
592
|
+
|
|
593
|
+
const priceUpdatesCalls = await this.getPriceUpdatesForFacade(
|
|
594
|
+
creditAccount.creditManager,
|
|
595
|
+
creditAccount,
|
|
596
|
+
undefined,
|
|
597
|
+
);
|
|
598
|
+
|
|
599
|
+
const underlyingEnabled = (creditAccount.enabledTokensMask & 1n) === 1n;
|
|
600
|
+
const shouldEnable = !isDecrease && !underlyingEnabled;
|
|
601
|
+
|
|
602
|
+
const calls: Array<MultiCall> = [
|
|
603
|
+
...priceUpdatesCalls,
|
|
604
|
+
...(shouldEnable
|
|
605
|
+
? this.#prepareEnableTokens(creditAccount.creditFacade, [
|
|
606
|
+
creditAccount.underlying,
|
|
607
|
+
])
|
|
608
|
+
: []),
|
|
609
|
+
this.#prepareChangeDebt(creditAccount.creditFacade, change, isDecrease),
|
|
610
|
+
];
|
|
611
|
+
|
|
612
|
+
const tx = cm.creditFacade.multicall(creditAccount.creditAccount, calls);
|
|
613
|
+
|
|
614
|
+
return { tx, calls, creditFacade: cm.creditFacade };
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
public async withdrawCollateral(
|
|
618
|
+
props: WithdrawCollateralProps,
|
|
619
|
+
): Promise<CommonResult> {
|
|
620
|
+
const { creditAccount, assetsToWithdraw, to } = props;
|
|
621
|
+
|
|
622
|
+
const cm = this.sdk.marketRegister.findCreditManager(
|
|
623
|
+
creditAccount.creditManager,
|
|
624
|
+
);
|
|
625
|
+
|
|
626
|
+
const priceUpdatesCalls = await this.getPriceUpdatesForFacade(
|
|
627
|
+
creditAccount.creditManager,
|
|
628
|
+
creditAccount,
|
|
629
|
+
undefined,
|
|
630
|
+
);
|
|
631
|
+
|
|
632
|
+
const calls: Array<MultiCall> = [
|
|
633
|
+
...priceUpdatesCalls,
|
|
634
|
+
...assetsToWithdraw.map(a =>
|
|
635
|
+
this.#prepareWithdrawToken(
|
|
636
|
+
creditAccount.creditFacade,
|
|
637
|
+
a.token,
|
|
638
|
+
a.balance,
|
|
639
|
+
to,
|
|
640
|
+
),
|
|
641
|
+
),
|
|
642
|
+
...this.#prepareUpdateQuotas(creditAccount.creditFacade, props),
|
|
643
|
+
];
|
|
644
|
+
|
|
645
|
+
const tx = cm.creditFacade.multicall(creditAccount.creditAccount, calls);
|
|
646
|
+
|
|
647
|
+
return { tx, calls, creditFacade: cm.creditFacade };
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
public async executeSwap(props: ExecuteSwapProps): Promise<CommonResult> {
|
|
651
|
+
const { creditAccount, calls: swapCalls } = props;
|
|
652
|
+
if (swapCalls.length === 0) throw new Error("No path to execute");
|
|
653
|
+
|
|
654
|
+
const cm = this.sdk.marketRegister.findCreditManager(
|
|
655
|
+
creditAccount.creditManager,
|
|
656
|
+
);
|
|
657
|
+
|
|
658
|
+
const priceUpdatesCalls = await this.getPriceUpdatesForFacade(
|
|
659
|
+
creditAccount.creditManager,
|
|
660
|
+
creditAccount,
|
|
661
|
+
props.averageQuota,
|
|
662
|
+
);
|
|
663
|
+
|
|
664
|
+
const calls: Array<MultiCall> = [
|
|
665
|
+
...priceUpdatesCalls,
|
|
666
|
+
...swapCalls,
|
|
667
|
+
...this.#prepareUpdateQuotas(creditAccount.creditFacade, props),
|
|
668
|
+
];
|
|
669
|
+
|
|
670
|
+
const tx = cm.creditFacade.multicall(creditAccount.creditAccount, calls);
|
|
671
|
+
|
|
672
|
+
return { tx, calls, creditFacade: cm.creditFacade };
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
public async claimFarmRewards(
|
|
676
|
+
props: ClaimFarmRewardsProps,
|
|
677
|
+
): Promise<CommonResult> {
|
|
678
|
+
const { tokensToDisable, calls: claimCalls, creditAccount: ca } = props;
|
|
679
|
+
if (claimCalls.length === 0) throw new Error("No path to execute");
|
|
680
|
+
|
|
681
|
+
const cm = this.sdk.marketRegister.findCreditManager(ca.creditManager);
|
|
682
|
+
|
|
683
|
+
const priceUpdatesCalls = await this.getPriceUpdatesForFacade(
|
|
684
|
+
ca.creditManager,
|
|
685
|
+
ca,
|
|
686
|
+
props.averageQuota,
|
|
687
|
+
);
|
|
688
|
+
|
|
689
|
+
// TODO: probably needs a better way to handle reward tokens
|
|
690
|
+
const calls = [
|
|
691
|
+
...priceUpdatesCalls,
|
|
692
|
+
...claimCalls,
|
|
693
|
+
...tokensToDisable.map(a =>
|
|
694
|
+
this.#prepareDisableToken(ca.creditFacade, a.token),
|
|
695
|
+
),
|
|
696
|
+
...this.#prepareUpdateQuotas(ca.creditFacade, props),
|
|
697
|
+
];
|
|
698
|
+
|
|
699
|
+
const tx = cm.creditFacade.multicall(ca.creditAccount, calls);
|
|
700
|
+
|
|
701
|
+
return { tx, calls, creditFacade: cm.creditFacade };
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
public async openCA(props: OpenCAProps): Promise<CommonResult> {
|
|
705
|
+
const {
|
|
706
|
+
ethAmount,
|
|
707
|
+
creditManager,
|
|
708
|
+
collateral,
|
|
709
|
+
permits,
|
|
710
|
+
debt,
|
|
711
|
+
withdrawDebt,
|
|
712
|
+
referralCode,
|
|
713
|
+
to,
|
|
714
|
+
calls: openPathCalls,
|
|
715
|
+
} = props;
|
|
716
|
+
|
|
717
|
+
const cmSuite = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
718
|
+
const cm = cmSuite.creditManager;
|
|
719
|
+
|
|
720
|
+
const priceUpdatesCalls = await this.getPriceUpdatesForFacade(
|
|
721
|
+
cm.address,
|
|
722
|
+
undefined,
|
|
723
|
+
props.averageQuota,
|
|
724
|
+
);
|
|
725
|
+
|
|
726
|
+
const calls = [
|
|
727
|
+
...priceUpdatesCalls,
|
|
728
|
+
this.#prepareIncreaseDebt(cm.creditFacade, debt),
|
|
729
|
+
...this.#prepareAddCollateral(cm.creditFacade, collateral, permits),
|
|
730
|
+
...this.#prepareUpdateQuotas(cm.creditFacade, props),
|
|
731
|
+
...openPathCalls,
|
|
732
|
+
...(withdrawDebt
|
|
733
|
+
? [this.#prepareWithdrawToken(cm.creditFacade, cm.underlying, debt, to)]
|
|
734
|
+
: []),
|
|
735
|
+
];
|
|
736
|
+
|
|
737
|
+
const tx = cmSuite.creditFacade.openCreditAccount(to, calls, referralCode);
|
|
738
|
+
tx.value = ethAmount.toString(10);
|
|
739
|
+
|
|
740
|
+
return { calls, tx, creditFacade: cmSuite.creditFacade };
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
/**
|
|
744
|
+
* Internal wrapper for CreditAccountCompressor.getCreditAccounts + price updates wrapped into multicall
|
|
745
|
+
* @param args
|
|
746
|
+
* @param priceUpdateTxs
|
|
747
|
+
* @param options
|
|
748
|
+
* @returns
|
|
749
|
+
*/
|
|
750
|
+
async #getCreditAccounts(
|
|
751
|
+
args: GetCreditAccountsArgs,
|
|
752
|
+
priceUpdateTxs?: Array<RawTx>,
|
|
753
|
+
options?: ReadContractOptions,
|
|
754
|
+
): Promise<[accounts: Array<CreditAccountData>, newOffset: bigint]> {
|
|
755
|
+
const blockNumber = options?.blockNumber;
|
|
756
|
+
if (priceUpdateTxs?.length) {
|
|
757
|
+
const resp = await simulateMulticall(this.provider.publicClient, {
|
|
758
|
+
contracts: [
|
|
759
|
+
...priceUpdateTxs.map(rawTxToMulticallPriceUpdate),
|
|
760
|
+
{
|
|
761
|
+
abi: iCreditAccountCompressorAbi,
|
|
762
|
+
address: this.#compressor,
|
|
763
|
+
functionName: "getCreditAccounts",
|
|
764
|
+
args,
|
|
765
|
+
},
|
|
766
|
+
],
|
|
767
|
+
allowFailure: false,
|
|
768
|
+
// gas: 550_000_000n,
|
|
769
|
+
batchSize: 0, // we cannot have price updates and compressor request in different batches
|
|
770
|
+
blockNumber,
|
|
771
|
+
});
|
|
772
|
+
const getCreditAccountsResp = resp.pop() as any as [
|
|
773
|
+
Array<CreditAccountData>,
|
|
774
|
+
bigint,
|
|
775
|
+
];
|
|
776
|
+
return getCreditAccountsResp;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
return this.provider.publicClient.readContract<
|
|
780
|
+
CompressorAbi,
|
|
781
|
+
"getCreditAccounts",
|
|
782
|
+
GetCreditAccountsArgs
|
|
783
|
+
>({
|
|
784
|
+
abi: iCreditAccountCompressorAbi,
|
|
785
|
+
address: this.#compressor,
|
|
786
|
+
functionName: "getCreditAccounts",
|
|
787
|
+
args,
|
|
788
|
+
blockNumber,
|
|
789
|
+
});
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
/**
|
|
793
|
+
* Returns raw txs that are needed to update all price feeds so that all credit accounts (possibly from different markets) compute
|
|
794
|
+
* @param accounts
|
|
795
|
+
* @returns
|
|
796
|
+
*/
|
|
797
|
+
public async getUpdateForAccounts(
|
|
798
|
+
accounts: Array<CreditAccountDataSlice>,
|
|
799
|
+
): Promise<UpdatePriceFeedsResult> {
|
|
800
|
+
// for each market, using pool address as key, gather tokens to update and find PriceFeedFactories
|
|
801
|
+
const tokensByPool = new Map<Address, Set<Address>>();
|
|
802
|
+
const oracleByPool = new Map<Address, IPriceOracleContract>();
|
|
803
|
+
|
|
804
|
+
for (const acc of accounts) {
|
|
805
|
+
const market = this.sdk.marketRegister.findByCreditManager(
|
|
806
|
+
acc.creditManager,
|
|
807
|
+
);
|
|
808
|
+
const pool = market.pool.pool.address;
|
|
809
|
+
oracleByPool.set(pool, market.priceOracle);
|
|
810
|
+
|
|
811
|
+
for (const t of acc.tokens) {
|
|
812
|
+
if (t.balance > 10n) {
|
|
813
|
+
const tokens = tokensByPool.get(pool) ?? new Set<Address>();
|
|
814
|
+
tokens.add(t.token);
|
|
815
|
+
tokensByPool.set(pool, tokens);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
// priceFeeds can contain PriceFeeds from different markets
|
|
820
|
+
const priceFeeds: Array<IPriceFeedContract> = [];
|
|
821
|
+
for (const [pool, oracle] of oracleByPool.entries()) {
|
|
822
|
+
const tokens = Array.from(tokensByPool.get(pool) ?? []);
|
|
823
|
+
priceFeeds.push(...oracle.priceFeedsForTokens(tokens));
|
|
824
|
+
}
|
|
825
|
+
return this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(priceFeeds);
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
public async getUpdateForAccount(
|
|
829
|
+
creditManager: Address,
|
|
830
|
+
creditAccount: CreditAccountDataSlice | undefined,
|
|
831
|
+
desiredQuotas: Array<Asset> | undefined,
|
|
832
|
+
): Promise<UpdatePriceFeedsResult> {
|
|
833
|
+
// for each market, using pool address as key, gather tokens to update and find PriceFeedFactories
|
|
834
|
+
const tokensByPool = new Map<Address, Set<Address>>();
|
|
835
|
+
const oracleByPool = new Map<Address, IPriceOracleContract>();
|
|
836
|
+
const quotaRecord = desiredQuotas
|
|
837
|
+
? assetsMap(desiredQuotas)
|
|
838
|
+
: desiredQuotas;
|
|
839
|
+
const caBalancesRecord = creditAccount
|
|
840
|
+
? assetsMap(creditAccount.tokens)
|
|
841
|
+
: creditAccount;
|
|
842
|
+
|
|
843
|
+
const market = this.sdk.marketRegister.findByCreditManager(creditManager);
|
|
844
|
+
const cm =
|
|
845
|
+
this.sdk.marketRegister.findCreditManager(creditManager).creditManager;
|
|
846
|
+
const pool = market.pool.pool.address;
|
|
847
|
+
|
|
848
|
+
oracleByPool.set(pool, market.priceOracle);
|
|
849
|
+
|
|
850
|
+
const insertToken = (p: Address, t: Address) => {
|
|
851
|
+
const tokens = tokensByPool.get(p) ?? new Set<Address>();
|
|
852
|
+
tokens.add(t);
|
|
853
|
+
tokensByPool.set(pool, tokens);
|
|
854
|
+
};
|
|
855
|
+
|
|
856
|
+
for (const t of cm.collateralTokens) {
|
|
857
|
+
if (creditAccount && caBalancesRecord && quotaRecord) {
|
|
858
|
+
const balanceAsset = caBalancesRecord.get(t);
|
|
859
|
+
const balance = balanceAsset?.balance || 0n;
|
|
860
|
+
const mask = balanceAsset?.mask || 0n;
|
|
861
|
+
const isEnabled = (mask & creditAccount.enabledTokensMask) !== 0n;
|
|
862
|
+
|
|
863
|
+
const quotaAsset = quotaRecord.get(t);
|
|
864
|
+
const quotaBalance = quotaAsset?.balance || 0n;
|
|
865
|
+
|
|
866
|
+
if ((balance > 10n && isEnabled) || quotaBalance > 0)
|
|
867
|
+
insertToken(pool, t);
|
|
868
|
+
} else if (creditAccount && caBalancesRecord) {
|
|
869
|
+
const balanceAsset = caBalancesRecord.get(t);
|
|
870
|
+
const balance = balanceAsset?.balance || 0n;
|
|
871
|
+
const mask = balanceAsset?.mask || 0n;
|
|
872
|
+
const isEnabled = (mask & creditAccount.enabledTokensMask) !== 0n;
|
|
873
|
+
|
|
874
|
+
if (balance > 10n && isEnabled) insertToken(pool, t);
|
|
875
|
+
} else if (quotaRecord) {
|
|
876
|
+
const quotaAsset = quotaRecord.get(t);
|
|
877
|
+
const quotaBalance = quotaAsset?.balance || 0n;
|
|
878
|
+
|
|
879
|
+
if (quotaBalance > 0) insertToken(pool, t);
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
// priceFeeds can contain PriceFeeds from different markets
|
|
884
|
+
const priceFeeds: Array<IPriceFeedContract> = [];
|
|
885
|
+
for (const [pool, oracle] of oracleByPool.entries()) {
|
|
886
|
+
const tokens = Array.from(tokensByPool.get(pool) ?? []);
|
|
887
|
+
priceFeeds.push(...oracle.priceFeedsForTokens(tokens));
|
|
888
|
+
}
|
|
889
|
+
this.#logger?.debug(
|
|
890
|
+
{ account: creditAccount?.creditAccount, manager: cm.name },
|
|
891
|
+
`generating price feed updates for ${priceFeeds.length} price feeds`,
|
|
892
|
+
);
|
|
893
|
+
return this.sdk.priceFeeds.generatePriceFeedsUpdateTxs(
|
|
894
|
+
priceFeeds,
|
|
895
|
+
creditAccount ? { account: creditAccount.creditAccount } : undefined,
|
|
896
|
+
);
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
/**
|
|
900
|
+
* Returns account price updates in a non-encoded format
|
|
901
|
+
* @param acc
|
|
902
|
+
* @returns
|
|
903
|
+
*/
|
|
904
|
+
public async getOnDemandPriceUpdates(
|
|
905
|
+
creditManager: Address,
|
|
906
|
+
creditAccount: CreditAccountDataSlice | undefined,
|
|
907
|
+
desiredQuotas: Array<Asset> | undefined,
|
|
908
|
+
): Promise<Array<OnDemandPriceUpdate>> {
|
|
909
|
+
const market = this.sdk.marketRegister.findByCreditManager(creditManager);
|
|
910
|
+
const cm = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
911
|
+
const update = await this.getUpdateForAccount(
|
|
912
|
+
creditManager,
|
|
913
|
+
creditAccount,
|
|
914
|
+
desiredQuotas,
|
|
915
|
+
);
|
|
916
|
+
this.#logger?.debug(
|
|
917
|
+
{ account: creditAccount?.creditAccount, manager: cm.name },
|
|
918
|
+
`getting on demand price updates from ${update.txs.length} txs`,
|
|
919
|
+
);
|
|
920
|
+
return market.priceOracle.onDemandPriceUpdates(update);
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
/**
|
|
924
|
+
* Returns price updates in format that is accepted by various credit facade methods (multicall, close/liquidate, etc...)
|
|
925
|
+
* @param acc
|
|
926
|
+
* @returns
|
|
927
|
+
*/
|
|
928
|
+
public async getPriceUpdatesForFacade(
|
|
929
|
+
creditManager: Address,
|
|
930
|
+
creditAccount: CreditAccountDataSlice | undefined,
|
|
931
|
+
desiredQuotas: Array<Asset> | undefined,
|
|
932
|
+
): Promise<Array<MultiCall>> {
|
|
933
|
+
const cm = this.sdk.marketRegister.findCreditManager(creditManager);
|
|
934
|
+
const updates = await this.getOnDemandPriceUpdates(
|
|
935
|
+
creditManager,
|
|
936
|
+
creditAccount,
|
|
937
|
+
desiredQuotas,
|
|
938
|
+
);
|
|
939
|
+
return cm.creditFacade.encodeOnDemandPriceUpdates(updates);
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
#prepareDisableQuotas(ca: CreditAccountDataSlice): Array<MultiCall> {
|
|
943
|
+
const calls: Array<MultiCall> = [];
|
|
944
|
+
for (const { token, quota } of ca.tokens) {
|
|
945
|
+
if (quota > 0n) {
|
|
946
|
+
calls.push({
|
|
947
|
+
target: ca.creditFacade,
|
|
948
|
+
callData: encodeFunctionData({
|
|
949
|
+
abi: iCreditFacadeV300MulticallAbi,
|
|
950
|
+
functionName: "updateQuota",
|
|
951
|
+
args: [token, MIN_INT96, 0n],
|
|
952
|
+
}),
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
return calls;
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
#prepareUpdateQuotas(
|
|
960
|
+
creditFacade: Address,
|
|
961
|
+
{ averageQuota, minQuota }: PrepareUpdateQuotasProps,
|
|
962
|
+
): Array<MultiCall> {
|
|
963
|
+
const minRecord = assetsMap(minQuota);
|
|
964
|
+
|
|
965
|
+
const calls: Array<MultiCall> = averageQuota.map(q => {
|
|
966
|
+
const minAsset = minRecord.get(q.token);
|
|
967
|
+
const min = minAsset && minAsset?.balance > 0 ? minAsset.balance : 0n;
|
|
968
|
+
|
|
969
|
+
return {
|
|
970
|
+
target: creditFacade,
|
|
971
|
+
callData: encodeFunctionData({
|
|
972
|
+
abi: iCreditFacadeV300MulticallAbi,
|
|
973
|
+
functionName: "updateQuota",
|
|
974
|
+
args: [q.token, q.balance, min],
|
|
975
|
+
}),
|
|
976
|
+
};
|
|
977
|
+
});
|
|
978
|
+
|
|
979
|
+
return calls;
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
#prepareDecreaseDebt(ca: CreditAccountDataSlice): Array<MultiCall> {
|
|
983
|
+
if (ca.debt > 0n) {
|
|
984
|
+
return [
|
|
985
|
+
{
|
|
986
|
+
target: ca.creditFacade,
|
|
987
|
+
callData: encodeFunctionData({
|
|
988
|
+
abi: iCreditFacadeV300MulticallAbi,
|
|
989
|
+
functionName: "decreaseDebt",
|
|
990
|
+
args: [MAX_UINT256],
|
|
991
|
+
}),
|
|
992
|
+
},
|
|
993
|
+
];
|
|
994
|
+
}
|
|
995
|
+
return [];
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
#prepareDisableTokens(ca: CreditAccountDataSlice): Array<MultiCall> {
|
|
999
|
+
const calls: Array<MultiCall> = [];
|
|
1000
|
+
for (const t of ca.tokens) {
|
|
1001
|
+
if (
|
|
1002
|
+
t.token !== ca.underlying &&
|
|
1003
|
+
(t.mask & ca.enabledTokensMask) !== 0n &&
|
|
1004
|
+
t.quota === 0n
|
|
1005
|
+
) {
|
|
1006
|
+
calls.push(this.#prepareDisableToken(ca.creditFacade, t.token));
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
return calls;
|
|
1010
|
+
}
|
|
1011
|
+
#prepareDisableToken(creditFacade: Address, token: Address): MultiCall {
|
|
1012
|
+
return {
|
|
1013
|
+
target: creditFacade,
|
|
1014
|
+
callData: encodeFunctionData({
|
|
1015
|
+
abi: iCreditFacadeV300MulticallAbi,
|
|
1016
|
+
functionName: "disableToken",
|
|
1017
|
+
args: [token],
|
|
1018
|
+
}),
|
|
1019
|
+
};
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
#prepareEnableTokens(
|
|
1023
|
+
creditFacade: Address,
|
|
1024
|
+
tokens: Array<Address>,
|
|
1025
|
+
): Array<MultiCall> {
|
|
1026
|
+
return tokens.map(t => ({
|
|
1027
|
+
target: creditFacade,
|
|
1028
|
+
callData: encodeFunctionData({
|
|
1029
|
+
abi: iCreditFacadeV300MulticallAbi,
|
|
1030
|
+
functionName: "enableToken",
|
|
1031
|
+
args: [t],
|
|
1032
|
+
}),
|
|
1033
|
+
}));
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
#prepareWithdrawToken(
|
|
1037
|
+
creditFacade: Address,
|
|
1038
|
+
token: Address,
|
|
1039
|
+
amount: bigint,
|
|
1040
|
+
to: Address,
|
|
1041
|
+
): MultiCall {
|
|
1042
|
+
return {
|
|
1043
|
+
target: creditFacade,
|
|
1044
|
+
callData: encodeFunctionData({
|
|
1045
|
+
abi: iCreditFacadeV300MulticallAbi,
|
|
1046
|
+
functionName: "withdrawCollateral",
|
|
1047
|
+
args: [token, amount, to],
|
|
1048
|
+
}),
|
|
1049
|
+
};
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
#prepareIncreaseDebt(creditFacade: Address, debt: bigint): MultiCall {
|
|
1053
|
+
return {
|
|
1054
|
+
target: creditFacade,
|
|
1055
|
+
callData: encodeFunctionData({
|
|
1056
|
+
abi: iCreditFacadeV300MulticallAbi,
|
|
1057
|
+
functionName: "increaseDebt",
|
|
1058
|
+
args: [debt],
|
|
1059
|
+
}),
|
|
1060
|
+
};
|
|
1061
|
+
}
|
|
1062
|
+
#prepareChangeDebt(
|
|
1063
|
+
creditFacade: Address,
|
|
1064
|
+
change: bigint,
|
|
1065
|
+
isDecrease: boolean,
|
|
1066
|
+
): MultiCall {
|
|
1067
|
+
return {
|
|
1068
|
+
target: creditFacade,
|
|
1069
|
+
callData: encodeFunctionData({
|
|
1070
|
+
abi: iCreditFacadeV300MulticallAbi,
|
|
1071
|
+
functionName: isDecrease ? "decreaseDebt" : "increaseDebt",
|
|
1072
|
+
args: [change],
|
|
1073
|
+
}),
|
|
1074
|
+
};
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
#prepareAddCollateral(
|
|
1078
|
+
creditFacade: Address,
|
|
1079
|
+
assets: Array<Asset>,
|
|
1080
|
+
permits: Record<string, PermitResult>,
|
|
1081
|
+
): Array<MultiCall> {
|
|
1082
|
+
const calls = assets.map(({ token, balance }) => {
|
|
1083
|
+
const p = permits[token];
|
|
1084
|
+
|
|
1085
|
+
if (p) {
|
|
1086
|
+
return {
|
|
1087
|
+
target: creditFacade,
|
|
1088
|
+
callData: encodeFunctionData({
|
|
1089
|
+
abi: iCreditFacadeV300MulticallAbi,
|
|
1090
|
+
functionName: "addCollateralWithPermit",
|
|
1091
|
+
args: [token, balance, p.deadline, p.v, p.r, p.s],
|
|
1092
|
+
}),
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
return {
|
|
1097
|
+
target: creditFacade,
|
|
1098
|
+
callData: encodeFunctionData({
|
|
1099
|
+
abi: iCreditFacadeV300MulticallAbi,
|
|
1100
|
+
functionName: "addCollateral",
|
|
1101
|
+
args: [token, balance],
|
|
1102
|
+
}),
|
|
1103
|
+
};
|
|
1104
|
+
});
|
|
1105
|
+
|
|
1106
|
+
return calls;
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
/**
|
|
1110
|
+
* Returns addresses of market configurators
|
|
1111
|
+
*/
|
|
1112
|
+
private get marketConfigurators(): Array<Address> {
|
|
1113
|
+
return this.sdk.marketRegister.marketConfigurators.map(mc => mc.address);
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
private get rewardCompressor(): Address {
|
|
1117
|
+
return this.sdk.addressProvider.getLatestVersion(AP_REWARDS_COMPRESSOR);
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
private get peripheryCompressor(): Address {
|
|
1121
|
+
return this.sdk.addressProvider.getLatestVersion(AP_PERIPHERY_COMPRESSOR);
|
|
1122
|
+
}
|
|
1123
|
+
}
|