@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.
Files changed (275) hide show
  1. package/.eslintignore +3 -0
  2. package/.github/workflows/lint_pr.yml +18 -0
  3. package/.github/workflows/pr.yml +39 -0
  4. package/.github/workflows/release.yml +47 -0
  5. package/.gitignore +19 -0
  6. package/.husky/commit-msg +1 -0
  7. package/.husky/pre-commit +1 -0
  8. package/.nvmrc +1 -0
  9. package/.releaserc.json +34 -0
  10. package/.vscode/extensions.json +7 -0
  11. package/.vscode/settings.json +16 -0
  12. package/.yarn/install-state.gz +0 -0
  13. package/.yarnrc.yml +1 -0
  14. package/ContributionAgreement +72 -0
  15. package/dist/cjs/abi/iZapper.cjs +85 -0
  16. package/dist/cjs/abi/iZapper.d.ts +123 -0
  17. package/dist/cjs/sdk/index.cjs +19830 -19764
  18. package/dist/cjs/sdk/index.d.ts +3746 -3061
  19. package/dist/esm/abi/iZapper.d.mts +123 -0
  20. package/dist/esm/abi/iZapper.mjs +83 -0
  21. package/dist/esm/sdk/index.d.mts +3746 -3061
  22. package/dist/esm/sdk/index.mjs +19807 -19765
  23. package/jest.config.js +7 -0
  24. package/package.json +32 -2
  25. package/scripts/example.ts +30 -0
  26. package/src/abi/compressors.ts +3962 -0
  27. package/src/abi/errors.ts +196 -0
  28. package/src/abi/iERC20.ts +122 -0
  29. package/src/abi/iPausable.ts +35 -0
  30. package/src/abi/iPriceFeedStore.ts +227 -0
  31. package/src/abi/iUpdatablePriceFeed.ts +16 -0
  32. package/src/abi/iVersion.ts +28 -0
  33. package/src/abi/iZapper.ts +84 -0
  34. package/src/abi/routerV300.ts +378 -0
  35. package/src/abi/v300.ts +4151 -0
  36. package/src/abi/v310.ts +5179 -0
  37. package/src/adapters/AbstractAdapter.ts +28 -0
  38. package/src/adapters/BalancerV2VaultAdapterContract.ts +19 -0
  39. package/src/adapters/BalancerV3RouterAdapterContract.ts +19 -0
  40. package/src/adapters/CamelotV3AdapterContract.ts +20 -0
  41. package/src/adapters/ConvexV1BaseRewardPoolAdapterContract.ts +20 -0
  42. package/src/adapters/ConvexV1BoosterAdapterContract.ts +20 -0
  43. package/src/adapters/Curve2AssetsAdapterContract.ts +20 -0
  44. package/src/adapters/Curve3AssetsAdapterContract.ts +20 -0
  45. package/src/adapters/Curve4AssetsAdapterContract.ts +20 -0
  46. package/src/adapters/CurveV1AdapterStETHContract.ts +20 -0
  47. package/src/adapters/CurveV1StableNGAdapterContract.ts +20 -0
  48. package/src/adapters/DaiUsdsAdapterContract.ts +21 -0
  49. package/src/adapters/ERC4626AdapterContract.ts +20 -0
  50. package/src/adapters/MellowERC4626VaultAdapterContract.ts +20 -0
  51. package/src/adapters/MellowVaultAdapterContract.ts +20 -0
  52. package/src/adapters/PendleRouterAdapterContract.ts +21 -0
  53. package/src/adapters/StakingRewardsAdapterContract.ts +21 -0
  54. package/src/adapters/UniswapV2AdapterContract.ts +20 -0
  55. package/src/adapters/UniswapV3AdapterContract.ts +170 -0
  56. package/src/adapters/VelodromeV2AdapterContract.ts +20 -0
  57. package/src/adapters/WstETHV1AdapterContract.ts +20 -0
  58. package/src/adapters/YearnV2AdapterContract.ts +20 -0
  59. package/src/adapters/abi/adapters.ts +4325 -0
  60. package/src/adapters/abi/iBalancerV3RouterAdapter.ts +126 -0
  61. package/src/adapters/abi/index.ts +2 -0
  62. package/src/adapters/index.ts +2 -0
  63. package/src/adapters/plugin.ts +90 -0
  64. package/src/adapters/types.ts +62 -0
  65. package/src/dev/AccountOpener.ts +611 -0
  66. package/src/dev/PriceFeedStore.ts +95 -0
  67. package/src/dev/SDKExample.ts +167 -0
  68. package/src/dev/abi.ts +14 -0
  69. package/src/dev/calcLiquidatableLTs.ts +77 -0
  70. package/src/dev/createAnvilClient.ts +155 -0
  71. package/src/dev/index.ts +7 -0
  72. package/src/dev/setLTZero.ts +127 -0
  73. package/src/dev/setLTs.ts +68 -0
  74. package/src/sdk/GearboxSDK.ts +488 -0
  75. package/src/sdk/abi/index.ts +1 -0
  76. package/src/sdk/abi/oracles.ts +4614 -0
  77. package/src/sdk/accounts/CreditAccountsService.ts +1123 -0
  78. package/src/sdk/accounts/index.ts +1 -0
  79. package/src/sdk/base/AddressLabeller.ts +35 -0
  80. package/src/sdk/base/BaseContract.ts +237 -0
  81. package/src/sdk/base/IAddressLabeller.ts +13 -0
  82. package/src/sdk/base/PlaceholderContract.ts +12 -0
  83. package/src/sdk/base/SDKConstruct.ts +35 -0
  84. package/src/sdk/base/TokensMeta.ts +45 -0
  85. package/src/sdk/base/index.ts +6 -0
  86. package/src/sdk/base/types.ts +102 -0
  87. package/src/sdk/bots/BotsService.ts +92 -0
  88. package/src/sdk/bots/index.ts +2 -0
  89. package/src/sdk/bots/utils.ts +19 -0
  90. package/src/sdk/chain/Provider.ts +99 -0
  91. package/src/sdk/chain/chains.ts +41 -0
  92. package/src/sdk/chain/detectChain.ts +21 -0
  93. package/src/sdk/chain/index.ts +3 -0
  94. package/src/sdk/constants/address-provider.ts +47 -0
  95. package/src/sdk/constants/addresses.ts +82 -0
  96. package/src/sdk/constants/bot-permissions.ts +36 -0
  97. package/src/sdk/constants/index.ts +6 -0
  98. package/src/sdk/constants/math.ts +23 -0
  99. package/src/sdk/constants/networks.ts +38 -0
  100. package/src/sdk/constants/periphery.ts +7 -0
  101. package/src/sdk/core/BotListV3Contract.ts +103 -0
  102. package/src/sdk/core/GearStakingV3Contract.ts +84 -0
  103. package/src/sdk/core/address-provider/AbstractAddressProviderContract.ts +101 -0
  104. package/src/sdk/core/address-provider/AddressProviderV3Contract.ts +105 -0
  105. package/src/sdk/core/address-provider/AddressProviderV3_1Contract.ts +92 -0
  106. package/src/sdk/core/address-provider/getAddressProvider.ts +45 -0
  107. package/src/sdk/core/address-provider/index.ts +4 -0
  108. package/src/sdk/core/address-provider/types.ts +17 -0
  109. package/src/sdk/core/index.ts +3 -0
  110. package/src/sdk/gauges/GaugeStakingService.ts +100 -0
  111. package/src/sdk/gauges/index.ts +2 -0
  112. package/src/sdk/gauges/utils.ts +25 -0
  113. package/src/sdk/index.ts +17 -0
  114. package/src/sdk/market/MarketConfiguratorContract.ts +78 -0
  115. package/src/sdk/market/MarketRegister.ts +330 -0
  116. package/src/sdk/market/MarketSuite.ts +83 -0
  117. package/src/sdk/market/adapters/PlaceholderAdapterContracts.ts +18 -0
  118. package/src/sdk/market/adapters/factory.ts +34 -0
  119. package/src/sdk/market/adapters/index.ts +3 -0
  120. package/src/sdk/market/adapters/types.ts +7 -0
  121. package/src/sdk/market/credit/CreditConfiguratorV300Contract.ts +164 -0
  122. package/src/sdk/market/credit/CreditConfiguratorV310Contract.ts +139 -0
  123. package/src/sdk/market/credit/CreditFacadeV300Contract.ts +206 -0
  124. package/src/sdk/market/credit/CreditFacadeV310Contract.ts +190 -0
  125. package/src/sdk/market/credit/CreditManagerV300Contract.ts +122 -0
  126. package/src/sdk/market/credit/CreditManagerV310Contract.ts +122 -0
  127. package/src/sdk/market/credit/CreditSuite.ts +65 -0
  128. package/src/sdk/market/credit/createCreditConfigurator.ts +18 -0
  129. package/src/sdk/market/credit/createCreditFacade.ts +18 -0
  130. package/src/sdk/market/credit/createCreditManager.ts +18 -0
  131. package/src/sdk/market/credit/index.ts +8 -0
  132. package/src/sdk/market/credit/types.ts +42 -0
  133. package/src/sdk/market/index.ts +7 -0
  134. package/src/sdk/market/oracle/PriceOracleBaseContract.ts +376 -0
  135. package/src/sdk/market/oracle/PriceOracleV300Contract.ts +71 -0
  136. package/src/sdk/market/oracle/PriceOracleV310Contract.ts +43 -0
  137. package/src/sdk/market/oracle/createPriceOracle.ts +22 -0
  138. package/src/sdk/market/oracle/index.ts +4 -0
  139. package/src/sdk/market/oracle/types.ts +48 -0
  140. package/src/sdk/market/pool/GaugeContract.ts +120 -0
  141. package/src/sdk/market/pool/LinearInterestRateModelContract.ts +75 -0
  142. package/src/sdk/market/pool/PoolQuotaKeeperV300Contract.ts +89 -0
  143. package/src/sdk/market/pool/PoolQuotaKeeperV310Contract.ts +89 -0
  144. package/src/sdk/market/pool/PoolSuite.ts +76 -0
  145. package/src/sdk/market/pool/PoolV300Contract.ts +144 -0
  146. package/src/sdk/market/pool/PoolV310Contract.ts +144 -0
  147. package/src/sdk/market/pool/TumblerContract.ts +73 -0
  148. package/src/sdk/market/pool/createInterestRateModel.ts +33 -0
  149. package/src/sdk/market/pool/createPool.ts +19 -0
  150. package/src/sdk/market/pool/createPoolQuotaKeeper.ts +20 -0
  151. package/src/sdk/market/pool/createRateKeeper.ts +25 -0
  152. package/src/sdk/market/pool/index.ts +6 -0
  153. package/src/sdk/market/pool/types.ts +28 -0
  154. package/src/sdk/market/pricefeeds/AbstractLPPriceFeed.ts +71 -0
  155. package/src/sdk/market/pricefeeds/AbstractPriceFeed.ts +137 -0
  156. package/src/sdk/market/pricefeeds/BalancerStablePriceFeed.ts +24 -0
  157. package/src/sdk/market/pricefeeds/BalancerWeightedPriceFeed.ts +70 -0
  158. package/src/sdk/market/pricefeeds/BoundedPriceFeed.ts +34 -0
  159. package/src/sdk/market/pricefeeds/ChainlinkPriceFeed.ts +16 -0
  160. package/src/sdk/market/pricefeeds/CompositePriceFeed.ts +25 -0
  161. package/src/sdk/market/pricefeeds/CurveCryptoPriceFeed.ts +24 -0
  162. package/src/sdk/market/pricefeeds/CurveStablePriceFeed.ts +24 -0
  163. package/src/sdk/market/pricefeeds/CurveUSDPriceFeed.ts +24 -0
  164. package/src/sdk/market/pricefeeds/Erc4626PriceFeed.ts +36 -0
  165. package/src/sdk/market/pricefeeds/MellowLRTPriceFeed.ts +26 -0
  166. package/src/sdk/market/pricefeeds/PendleTWAPPTPriceFeed.ts +44 -0
  167. package/src/sdk/market/pricefeeds/PriceFeedRef.ts +34 -0
  168. package/src/sdk/market/pricefeeds/PriceFeedsRegister.ts +293 -0
  169. package/src/sdk/market/pricefeeds/RedstonePriceFeed.ts +65 -0
  170. package/src/sdk/market/pricefeeds/RedstoneUpdater.ts +304 -0
  171. package/src/sdk/market/pricefeeds/WstETHPriceFeed.ts +24 -0
  172. package/src/sdk/market/pricefeeds/YearnPriceFeed.ts +24 -0
  173. package/src/sdk/market/pricefeeds/ZeroPriceFeed.ts +17 -0
  174. package/src/sdk/market/pricefeeds/index.ts +20 -0
  175. package/src/sdk/market/pricefeeds/types.ts +82 -0
  176. package/src/sdk/market/pricefeeds/utils.ts +24 -0
  177. package/src/sdk/plugins/index.ts +10 -0
  178. package/src/sdk/router/PathOptionFactory.ts +147 -0
  179. package/src/sdk/router/RouterV3Contract.ts +558 -0
  180. package/src/sdk/router/index.ts +2 -0
  181. package/src/sdk/router/types.ts +48 -0
  182. package/src/sdk/sdk-gov-legacy/contracts/adapters.ts +39 -0
  183. package/src/sdk/sdk-gov-legacy/contracts/contracts.ts +647 -0
  184. package/src/sdk/sdk-gov-legacy/contracts/index.ts +2 -0
  185. package/src/sdk/sdk-gov-legacy/core/constants.ts +11 -0
  186. package/src/sdk/sdk-gov-legacy/index.ts +4 -0
  187. package/src/sdk/sdk-gov-legacy/oracles/PriceFeedType.ts +24 -0
  188. package/src/sdk/sdk-gov-legacy/oracles/index.ts +1 -0
  189. package/src/sdk/sdk-gov-legacy/tokens/aave.ts +101 -0
  190. package/src/sdk/sdk-gov-legacy/tokens/aura.ts +284 -0
  191. package/src/sdk/sdk-gov-legacy/tokens/balancer.ts +421 -0
  192. package/src/sdk/sdk-gov-legacy/tokens/compound.ts +79 -0
  193. package/src/sdk/sdk-gov-legacy/tokens/convex.ts +561 -0
  194. package/src/sdk/sdk-gov-legacy/tokens/curveLP.ts +480 -0
  195. package/src/sdk/sdk-gov-legacy/tokens/decimals.ts +301 -0
  196. package/src/sdk/sdk-gov-legacy/tokens/erc4626.ts +75 -0
  197. package/src/sdk/sdk-gov-legacy/tokens/gear.ts +273 -0
  198. package/src/sdk/sdk-gov-legacy/tokens/index.ts +18 -0
  199. package/src/sdk/sdk-gov-legacy/tokens/normal.ts +613 -0
  200. package/src/sdk/sdk-gov-legacy/tokens/quoted.ts +10 -0
  201. package/src/sdk/sdk-gov-legacy/tokens/stakingRewards.ts +41 -0
  202. package/src/sdk/sdk-gov-legacy/tokens/token.ts +2354 -0
  203. package/src/sdk/sdk-gov-legacy/tokens/tokenData.ts +44 -0
  204. package/src/sdk/sdk-gov-legacy/tokens/tokenType.ts +33 -0
  205. package/src/sdk/sdk-gov-legacy/tokens/wrapped.ts +28 -0
  206. package/src/sdk/sdk-gov-legacy/tokens/yearn.ts +122 -0
  207. package/src/sdk/sdk-gov-legacy/tokens/zircuit.ts +44 -0
  208. package/src/sdk/sdk-legacy/apy/index.ts +149 -0
  209. package/src/sdk/sdk-legacy/core/assets.ts +200 -0
  210. package/src/sdk/sdk-legacy/core/creditAccount.spec.ts +1966 -0
  211. package/src/sdk/sdk-legacy/core/creditAccount.ts +816 -0
  212. package/src/sdk/sdk-legacy/core/creditManager.ts +316 -0
  213. package/src/sdk/sdk-legacy/core/creditSession.ts +352 -0
  214. package/src/sdk/sdk-legacy/core/endpoint.ts +131 -0
  215. package/src/sdk/sdk-legacy/core/eventOrTx.ts +101 -0
  216. package/src/sdk/sdk-legacy/core/pool.ts +439 -0
  217. package/src/sdk/sdk-legacy/core/strategy.ts +82 -0
  218. package/src/sdk/sdk-legacy/core/transactions.ts +865 -0
  219. package/src/sdk/sdk-legacy/gearboxRewards/api.ts +704 -0
  220. package/src/sdk/sdk-legacy/gearboxRewards/apy.ts +267 -0
  221. package/src/sdk/sdk-legacy/gearboxRewards/extraAPY.ts +165 -0
  222. package/src/sdk/sdk-legacy/gearboxRewards/index.ts +3 -0
  223. package/src/sdk/sdk-legacy/gearboxRewards/merklAPI.ts +151 -0
  224. package/src/sdk/sdk-legacy/index.ts +21 -0
  225. package/src/sdk/sdk-legacy/pathfinder/core.ts +18 -0
  226. package/src/sdk/sdk-legacy/pathfinder/index.ts +1 -0
  227. package/src/sdk/sdk-legacy/payload/creditAccount.ts +48 -0
  228. package/src/sdk/sdk-legacy/payload/creditManager.ts +133 -0
  229. package/src/sdk/sdk-legacy/payload/creditSession.ts +143 -0
  230. package/src/sdk/sdk-legacy/payload/graphPayload.ts +10 -0
  231. package/src/sdk/sdk-legacy/payload/pool.ts +198 -0
  232. package/src/sdk/sdk-legacy/payload/token.ts +13 -0
  233. package/src/sdk/sdk-legacy/tokens/tokenData.ts +57 -0
  234. package/src/sdk/sdk-legacy/types/IAirdropDistributor.ts +103 -0
  235. package/src/sdk/sdk-legacy/types/IBaseRewardPool.ts +249 -0
  236. package/src/sdk/sdk-legacy/types/IDataCompressorV3.ts +957 -0
  237. package/src/sdk/sdk-legacy/types/IDegenDistributor.ts +70 -0
  238. package/src/sdk/sdk-legacy/types/IERC20Permit.ts +35 -0
  239. package/src/sdk/sdk-legacy/types/IERC20ZapperDeposits.ts +99 -0
  240. package/src/sdk/sdk-legacy/types/IETHZapperDeposits.ts +27 -0
  241. package/src/sdk/sdk-legacy/types/IFarmingPool.ts +229 -0
  242. package/src/sdk/sdk-legacy/types/IInterestRateModel.ts +23 -0
  243. package/src/sdk/sdk-legacy/types/IMulticall3.ts +242 -0
  244. package/src/sdk/sdk-legacy/types/IOffchainOracle.ts +31 -0
  245. package/src/sdk/sdk-legacy/types/index.ts +11 -0
  246. package/src/sdk/sdk-legacy/utils/formatter.ts +46 -0
  247. package/src/sdk/sdk-legacy/utils/index.ts +3 -0
  248. package/src/sdk/sdk-legacy/utils/math.ts +6 -0
  249. package/src/sdk/sdk-legacy/utils/price.ts +27 -0
  250. package/src/sdk/types/index.ts +5 -0
  251. package/src/sdk/types/logger.ts +13 -0
  252. package/src/sdk/types/state-human.ts +224 -0
  253. package/src/sdk/types/state.ts +8 -0
  254. package/src/sdk/types/transactions.ts +22 -0
  255. package/src/sdk/types/tvl.ts +4 -0
  256. package/src/sdk/utils/AddressMap.ts +111 -0
  257. package/src/sdk/utils/bytes32ToString.ts +6 -0
  258. package/src/sdk/utils/childLogger.ts +8 -0
  259. package/src/sdk/utils/createRawTx.ts +86 -0
  260. package/src/sdk/utils/etherscan.ts +42 -0
  261. package/src/sdk/utils/filterDust.ts +20 -0
  262. package/src/sdk/utils/formatter.ts +124 -0
  263. package/src/sdk/utils/index.ts +10 -0
  264. package/src/sdk/utils/internal/Hooks.ts +51 -0
  265. package/src/sdk/utils/internal/index.ts +1 -0
  266. package/src/sdk/utils/json.ts +27 -0
  267. package/src/sdk/utils/mappers.ts +38 -0
  268. package/src/sdk/utils/retry.ts +24 -0
  269. package/src/sdk/utils/viem/detectNetwork.ts +27 -0
  270. package/src/sdk/utils/viem/index.ts +3 -0
  271. package/src/sdk/utils/viem/sendRawTx.ts +36 -0
  272. package/src/sdk/utils/viem/simulateMulticall.ts +262 -0
  273. package/tsconfig.build.json +4 -0
  274. package/tsconfig.json +16 -0
  275. package/tsup.config.ts +77 -0
@@ -0,0 +1,167 @@
1
+ import { readFile, writeFile } from "node:fs/promises";
2
+
3
+ import type { Address } from "viem";
4
+ import { isAddress, parseEther, stringToHex } from "viem";
5
+
6
+ import { iAddressProviderV300Abi } from "../abi/v300";
7
+ import { iAddressProviderV310Abi } from "../abi/v310";
8
+ import type { ILogger } from "../sdk";
9
+ import { ADDRESS_PROVIDER, GearboxSDK, json_stringify } from "../sdk";
10
+ import { createAnvilClient } from "./createAnvilClient";
11
+
12
+ export interface SDKExampleOptions {
13
+ addressProvider?: string;
14
+ addressProviderJson?: string;
15
+ marketConfigurators: Address[];
16
+ anvilUrl?: string;
17
+ outFile?: string;
18
+ }
19
+
20
+ export class SDKExample {
21
+ #sdk?: GearboxSDK;
22
+ #logger?: ILogger;
23
+
24
+ constructor(logger?: ILogger) {
25
+ this.#logger = logger;
26
+ }
27
+
28
+ public async run(opts: SDKExampleOptions) {
29
+ const {
30
+ addressProvider: ap,
31
+ addressProviderJson,
32
+ marketConfigurators,
33
+ anvilUrl = "http://127.0.0.1:8545",
34
+ outFile,
35
+ } = opts;
36
+ const addressProvider = await this.#readConfigAddress(
37
+ "addressProvider",
38
+ ap,
39
+ addressProviderJson,
40
+ );
41
+
42
+ this.#sdk = await GearboxSDK.attach({
43
+ rpcURLs: [anvilUrl],
44
+ timeout: 480_000,
45
+ addressProvider,
46
+ logger: this.#logger,
47
+ ignoreUpdateablePrices: false,
48
+ marketConfigurators,
49
+ });
50
+ this.#logger?.info("attached sdk");
51
+ try {
52
+ await this.#sdk.marketRegister.loadZappers();
53
+ } catch (e) {
54
+ this.#logger?.error(`failed to load zappers: ${e}`);
55
+ }
56
+
57
+ await Promise.allSettled(
58
+ this.#sdk.marketRegister.marketConfigurators.map(m =>
59
+ m.loadCuratorName(),
60
+ ),
61
+ );
62
+ this.#logger?.info("loaded curator names");
63
+
64
+ if (outFile) {
65
+ try {
66
+ await writeFile(
67
+ outFile,
68
+ json_stringify(this.#sdk.stateHuman()),
69
+ "utf-8",
70
+ );
71
+ } catch (e) {
72
+ this.#logger?.error(`failed to write to ${outFile}: ${e}`);
73
+ }
74
+ }
75
+ }
76
+
77
+ public async migrateFaucet(addressProvider: Address): Promise<void> {
78
+ try {
79
+ await this.#migrateFaucet(addressProvider);
80
+ this.#logger?.info("faucet migrated successfully");
81
+ } catch (e) {
82
+ this.#logger?.error(`faucet migration failed: ${e}`);
83
+ }
84
+ }
85
+
86
+ async #readConfigAddress(
87
+ name: string,
88
+ value?: string,
89
+ file?: string,
90
+ ): Promise<Address> {
91
+ let result = value;
92
+
93
+ if (!result) {
94
+ if (!file) {
95
+ throw new Error(`${name} is not specified`);
96
+ }
97
+
98
+ this.#logger?.debug(`reading ${name} json ${file}`);
99
+ const apFile = await readFile(file, "utf-8").then(JSON.parse);
100
+ result = apFile[name];
101
+ }
102
+ if (!result) {
103
+ throw new Error(`${name} is not specified`);
104
+ }
105
+ if (!isAddress(result)) {
106
+ throw new Error(`${name} is not a valid address: ${result}`);
107
+ }
108
+
109
+ this.#logger?.info(`using ${name} ${result}`);
110
+ return result;
111
+ }
112
+
113
+ /**
114
+ * Migrates faucet from address provider v3 to v3.1
115
+ * @param addressProvider 3.1 address provider
116
+ */
117
+ async #migrateFaucet(addressProvider: Address): Promise<void> {
118
+ const anvil = createAnvilClient({
119
+ chain: this.sdk.provider.chain,
120
+ transport: this.sdk.provider.transport,
121
+ });
122
+
123
+ const [faucetAddr, owner] = await anvil.multicall({
124
+ contracts: [
125
+ {
126
+ abi: iAddressProviderV300Abi,
127
+ address: ADDRESS_PROVIDER[this.sdk.provider.networkType],
128
+ functionName: "getAddressOrRevert",
129
+ args: [stringToHex("FAUCET", { size: 32 }), 0n],
130
+ },
131
+ {
132
+ abi: iAddressProviderV310Abi,
133
+ address: addressProvider,
134
+ functionName: "owner",
135
+ args: [],
136
+ },
137
+ ],
138
+ allowFailure: false,
139
+ });
140
+ this.#logger?.debug(`faucet address: ${faucetAddr}, owner: ${owner}`);
141
+ await anvil.impersonateAccount({ address: owner });
142
+ await anvil.setBalance({
143
+ address: owner,
144
+ value: parseEther("100"),
145
+ });
146
+ const hash = await anvil.writeContract({
147
+ chain: anvil.chain,
148
+ account: owner,
149
+ address: addressProvider,
150
+ abi: iAddressProviderV310Abi,
151
+ functionName: "setAddress",
152
+ args: [stringToHex("FAUCET", { size: 32 }), faucetAddr, true],
153
+ });
154
+ const receipt = await anvil.waitForTransactionReceipt({ hash });
155
+ await anvil.stopImpersonatingAccount({ address: owner });
156
+ if (receipt.status === "reverted") {
157
+ throw new Error("faucet migration reverted");
158
+ }
159
+ }
160
+
161
+ public get sdk(): GearboxSDK {
162
+ if (!this.#sdk) {
163
+ throw new Error("sdk is not attached");
164
+ }
165
+ return this.#sdk;
166
+ }
167
+ }
package/src/dev/abi.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { parseAbi } from "viem";
2
+
3
+ export const iaclTraitAbi = parseAbi([
4
+ "function acl() external view returns (address)",
5
+ ]);
6
+
7
+ export const iOwnableAbi = parseAbi([
8
+ "function owner() external view returns (address)",
9
+ ]);
10
+
11
+ export const iDegenNftv2Abi = parseAbi([
12
+ "function minter() external view returns (address)",
13
+ "function mint(address to, uint256 amount) external",
14
+ ]);
@@ -0,0 +1,77 @@
1
+ import type { Address } from "viem";
2
+
3
+ import type { CreditAccountData, GearboxSDK, ILogger } from "../sdk";
4
+ import { PERCENTAGE_FACTOR, WAD } from "../sdk";
5
+
6
+ /**
7
+ * Given credit accounts, calculates new liquidation thresholds that needs to be set to drop account health factor a bit to make it eligible for partial liquidation
8
+ * @param ca
9
+ */
10
+ export async function calcLiquidatableLTs(
11
+ sdk: GearboxSDK,
12
+ ca: CreditAccountData,
13
+ factor = 9990n,
14
+ logger?: ILogger,
15
+ ): Promise<Record<Address, number>> {
16
+ const cm = sdk.marketRegister.findCreditManager(ca.creditManager);
17
+ const market = sdk.marketRegister.findByCreditManager(ca.creditManager);
18
+
19
+ // Sort account tokens by weighted value descending, but underlying token comes last
20
+ const weightedBalances = ca.tokens
21
+ .filter(({ token, balance }) => {
22
+ const minBalance =
23
+ 10n ** BigInt(Math.max(8, sdk.tokensMeta.decimals(token)) - 8);
24
+ return balance > minBalance;
25
+ })
26
+ .map(t => {
27
+ const { token, balance } = t;
28
+ const balanceU = market.priceOracle.convertToUnderlying(token, balance);
29
+ const lt = BigInt(cm.creditManager.liquidationThresholds.mustGet(token));
30
+ return {
31
+ token,
32
+ weightedBalance: (balanceU * lt) / PERCENTAGE_FACTOR,
33
+ lt,
34
+ };
35
+ })
36
+ .sort((a, b) => {
37
+ if (a.token === ca.underlying) return 1;
38
+ if (b.token === ca.underlying) return -1;
39
+ return b.weightedBalance > a.weightedBalance ? 1 : -1;
40
+ });
41
+
42
+ // LTnew = LT * k, where
43
+ //
44
+ // totalDebt - B_underlying * LT_underlying
45
+ // k = -------------------------------------------------------------
46
+ // sum(p * b* LT)
47
+ let divisor = 0n;
48
+ let dividend =
49
+ (factor * (ca.debt + ca.accruedInterest + ca.accruedFees)) /
50
+ PERCENTAGE_FACTOR; // TODO: USDT fee
51
+ for (const { token, weightedBalance } of weightedBalances) {
52
+ if (token === ca.underlying) {
53
+ dividend -= weightedBalance;
54
+ } else {
55
+ divisor += weightedBalance;
56
+ }
57
+ }
58
+ if (divisor === 0n) {
59
+ throw new Error("warning: assets have zero weighted value in underlying");
60
+ }
61
+ if (dividend <= 0n) {
62
+ throw new Error(`warning: account balance in underlying covers debt`);
63
+ }
64
+ const k = (WAD * dividend) / divisor;
65
+
66
+ const result: Record<Address, number> = {};
67
+ for (const { token, lt: oldLT } of weightedBalances) {
68
+ if (token !== ca.underlying) {
69
+ const newLT = (oldLT * k) / WAD;
70
+ logger?.debug(
71
+ `proposed ${sdk.tokensMeta.symbol(token)} LT change: ${oldLT} => ${newLT} `,
72
+ );
73
+ result[token] = Number(newLT);
74
+ }
75
+ }
76
+ return result;
77
+ }
@@ -0,0 +1,155 @@
1
+ import type {
2
+ Block,
3
+ Chain,
4
+ Client,
5
+ Hex,
6
+ Prettify,
7
+ PublicClient,
8
+ TestActions,
9
+ TestRpcSchema,
10
+ Transport,
11
+ WalletClient,
12
+ } from "viem";
13
+ import { createTestClient, publicActions, toHex, walletActions } from "viem";
14
+
15
+ export interface AnvilNodeInfo {
16
+ currentBlockNumber: string; // hexutil.Big is a big number in hex format
17
+ currentBlockTimestamp: number;
18
+ currentBlockHash: string;
19
+ hardFork: string;
20
+ transactionOrder: string;
21
+ environment: {
22
+ baseFee: string; // big.Int is a big number, represented as string in JSON
23
+ chainId: number;
24
+ gasLimit: string;
25
+ gasPrice: string;
26
+ };
27
+ forkConfig: {
28
+ forkUrl: string;
29
+ forkBlockNumber: string;
30
+ forkRetryBackoff: number;
31
+ };
32
+ }
33
+
34
+ export type AnvilRPCSchema = [
35
+ ...TestRpcSchema<"anvil">,
36
+ {
37
+ Method: "anvil_nodeInfo";
38
+ Parameters: [];
39
+ ReturnType: AnvilNodeInfo;
40
+ },
41
+ {
42
+ Method: "evm_mine_detailed";
43
+ Parameters: [Hex];
44
+ ReturnType: Block<Hex>[];
45
+ },
46
+ ];
47
+
48
+ // eslint-disable-next-line @typescript-eslint/consistent-type-definitions
49
+ export type AnvilActions = {
50
+ anvilNodeInfo: () => Promise<AnvilNodeInfo>;
51
+ isAnvil: () => Promise<boolean>;
52
+ evmMineDetailed: (
53
+ /**
54
+ * Block timestamp in seconds
55
+ */
56
+ timestamp: bigint | number,
57
+ ) => Promise<Block<Hex> | undefined>;
58
+ };
59
+
60
+ export type AnvilClient = Prettify<
61
+ { mode: "anvil" } & Client<
62
+ Transport,
63
+ Chain,
64
+ undefined,
65
+ AnvilRPCSchema,
66
+ AnvilActions & TestActions
67
+ >
68
+ > &
69
+ PublicClient &
70
+ WalletClient;
71
+
72
+ export interface AnvilClientConfig<
73
+ transport extends Transport = Transport,
74
+ chain extends Chain | undefined = Chain | undefined,
75
+ > {
76
+ transport: transport;
77
+ chain?: chain;
78
+ }
79
+
80
+ export function createAnvilClient({
81
+ chain,
82
+ transport,
83
+ }: AnvilClientConfig): AnvilClient {
84
+ return createTestClient<"anvil", Transport, Chain, undefined, AnvilRPCSchema>(
85
+ {
86
+ chain,
87
+ mode: "anvil",
88
+ transport,
89
+ cacheTime: 0,
90
+ pollingInterval: 50,
91
+ },
92
+ )
93
+ .extend(publicActions)
94
+ .extend(walletActions)
95
+ .extend(client => ({
96
+ anvilNodeInfo: () => anvilNodeInfo(client),
97
+ isAnvil: () => isAnvil(client),
98
+ evmMineDetailed: (timestamp: bigint | number) =>
99
+ evmMineDetailed(client, timestamp),
100
+ })) as any;
101
+ }
102
+
103
+ /**
104
+ * View action to detect if client is an anvil client
105
+ * @param client
106
+ * @returns
107
+ */
108
+ export async function isAnvil(
109
+ client: Client<any, any, any, AnvilRPCSchema, any>,
110
+ ): Promise<boolean> {
111
+ try {
112
+ const resp = await client.request({
113
+ method: "anvil_nodeInfo",
114
+ params: [],
115
+ });
116
+ return !!resp.currentBlockNumber;
117
+ } catch {
118
+ return false;
119
+ }
120
+ }
121
+
122
+ /**
123
+ * Anvil node info
124
+ * @param client
125
+ * @returns
126
+ */
127
+ export async function anvilNodeInfo(
128
+ client: Client<any, any, any, AnvilRPCSchema, any>,
129
+ ): Promise<AnvilNodeInfo> {
130
+ return client.request({
131
+ method: "anvil_nodeInfo",
132
+ params: [],
133
+ });
134
+ }
135
+
136
+ /**
137
+ * Safely tries to mine block with given timestamp
138
+ * @param client
139
+ * @param timestamp in seconds
140
+ * @returns
141
+ */
142
+ export async function evmMineDetailed(
143
+ client: Client<any, any, any, AnvilRPCSchema, any>,
144
+ timestamp: bigint | number,
145
+ ): Promise<Block<Hex> | undefined> {
146
+ try {
147
+ const [block] = await client.request({
148
+ method: "evm_mine_detailed",
149
+ params: [toHex(timestamp)],
150
+ });
151
+ return block;
152
+ } catch {
153
+ return undefined;
154
+ }
155
+ }
@@ -0,0 +1,7 @@
1
+ export * from "./AccountOpener";
2
+ export * from "./calcLiquidatableLTs";
3
+ export * from "./createAnvilClient";
4
+ export * from "./PriceFeedStore";
5
+ export * from "./SDKExample";
6
+ export * from "./setLTs";
7
+ export * from "./setLTZero";
@@ -0,0 +1,127 @@
1
+ import { parseEther } from "viem";
2
+
3
+ import { iCreditConfiguratorV300Abi, iCreditManagerV300Abi } from "../abi/v300";
4
+ import type { CreditManagerState, ILogger } from "../sdk";
5
+ import { PERCENTAGE_FACTOR } from "../sdk";
6
+ import { iaclTraitAbi, iOwnableAbi } from "./abi";
7
+ import type { AnvilClient } from "./createAnvilClient";
8
+
9
+ type ZeroLTCMSlice = Pick<
10
+ CreditManagerState,
11
+ | "creditConfigurator"
12
+ | "feeInterest"
13
+ | "liquidationDiscount"
14
+ | "feeLiquidationExpired"
15
+ | "liquidationDiscountExpired"
16
+ | "feeLiquidation"
17
+ | "name"
18
+ | "underlying"
19
+ | "baseParams"
20
+ >;
21
+
22
+ export async function setLTZero(
23
+ anvil: AnvilClient,
24
+ cm: ZeroLTCMSlice,
25
+ logger?: ILogger,
26
+ ): Promise<void> {
27
+ const aclAddr = await anvil.readContract({
28
+ address: cm.creditConfigurator,
29
+ abi: iaclTraitAbi,
30
+ functionName: "acl",
31
+ });
32
+ const configuratorAddr = await anvil.readContract({
33
+ address: aclAddr,
34
+ abi: iOwnableAbi,
35
+ functionName: "owner",
36
+ });
37
+
38
+ await anvil.impersonateAccount({
39
+ address: configuratorAddr,
40
+ });
41
+ await anvil.setBalance({
42
+ address: configuratorAddr,
43
+ value: parseEther("100"),
44
+ });
45
+
46
+ let hash = await anvil.writeContract({
47
+ chain: anvil.chain,
48
+ address: cm.creditConfigurator,
49
+ account: configuratorAddr,
50
+ abi: iCreditConfiguratorV300Abi,
51
+ functionName: "setFees",
52
+ args: [
53
+ cm.feeInterest,
54
+ cm.liquidationDiscount - 1,
55
+ Number(PERCENTAGE_FACTOR) - cm.liquidationDiscount,
56
+ cm.feeLiquidationExpired,
57
+ cm.liquidationDiscountExpired,
58
+ ],
59
+ });
60
+ await anvil.waitForTransactionReceipt({ hash });
61
+
62
+ logger?.debug(`[${cm.name}] setFees part 2`);
63
+ hash = await anvil.writeContract({
64
+ chain: anvil.chain,
65
+ address: cm.creditConfigurator,
66
+ account: configuratorAddr,
67
+ abi: iCreditConfiguratorV300Abi,
68
+ functionName: "setFees",
69
+ args: [
70
+ cm.feeInterest,
71
+ cm.feeLiquidation,
72
+ Number(PERCENTAGE_FACTOR) - cm.liquidationDiscount,
73
+ cm.feeLiquidationExpired,
74
+ cm.liquidationDiscountExpired,
75
+ ],
76
+ });
77
+ await anvil.waitForTransactionReceipt({ hash });
78
+
79
+ logger?.debug(`[${cm.name}] setFees done`);
80
+
81
+ await anvil.impersonateAccount({
82
+ address: cm.creditConfigurator,
83
+ });
84
+ await anvil.setBalance({
85
+ address: cm.creditConfigurator,
86
+ value: parseEther("100"),
87
+ });
88
+ logger?.debug(
89
+ `[${cm.name}] impresonating creditConfigurator ${cm.creditConfigurator}`,
90
+ );
91
+
92
+ logger?.debug(`[${cm.name}] setting liquidation threshold`);
93
+ hash = await anvil.writeContract({
94
+ chain: anvil.chain,
95
+ address: cm.baseParams.addr,
96
+ account: cm.creditConfigurator,
97
+ abi: iCreditManagerV300Abi,
98
+ functionName: "setCollateralTokenData",
99
+ args: [cm.underlying, 1, 1, Number(2n ** 40n - 1n), 0],
100
+ });
101
+ await anvil.waitForTransactionReceipt({ hash });
102
+
103
+ logger?.debug(`[${cm.name}] setting configurator ${cm.creditConfigurator}`);
104
+ hash = await anvil.writeContract({
105
+ chain: anvil.chain,
106
+ address: cm.baseParams.addr,
107
+ account: cm.creditConfigurator,
108
+ abi: iCreditManagerV300Abi,
109
+ functionName: "setCreditConfigurator",
110
+ args: [cm.creditConfigurator],
111
+ });
112
+ await anvil.waitForTransactionReceipt({ hash });
113
+
114
+ logger?.debug(`[${cm.name}] done`);
115
+ await anvil.stopImpersonatingAccount({
116
+ address: cm.creditConfigurator,
117
+ });
118
+ await anvil.stopImpersonatingAccount({ address: configuratorAddr });
119
+
120
+ /// Testing that LT is 1
121
+ // logger?.debug(`[${cm.name}] zero lt self-checking`);
122
+ // const cm2 = await dc300.read.getCreditManagerData([cm.addr]);
123
+ // if (cm2.liquidationThresholds.some(lt => lt > 1n)) {
124
+ // throw new Error("LT is not 1");
125
+ // }
126
+ // logger?.info(`[${cm.name}] zero lt OK`);
127
+ }
@@ -0,0 +1,68 @@
1
+ import type { Address } from "viem";
2
+ import { parseEther } from "viem";
3
+
4
+ import { iCreditConfiguratorV300Abi } from "../abi/v300";
5
+ import { iCreditManagerV310Abi } from "../abi/v310";
6
+ import type { ILogger } from "../sdk";
7
+ import { iaclTraitAbi, iOwnableAbi } from "./abi";
8
+ import type { AnvilClient } from "./createAnvilClient";
9
+
10
+ export interface SetLTsCMSlice {
11
+ creditConfigurator: Address;
12
+ address: Address;
13
+ }
14
+ /**
15
+ * Helper function to set liquidation thresholds on credit manager via anvil impersonation
16
+ * @param sdk
17
+ * @param cm
18
+ * @param newLTs
19
+ */
20
+ export async function setLTs(
21
+ anvil: AnvilClient,
22
+ cm: SetLTsCMSlice,
23
+ newLTs: Record<Address, number>,
24
+ logger?: ILogger,
25
+ ): Promise<void> {
26
+ const aclAddr = await anvil.readContract({
27
+ address: cm.creditConfigurator,
28
+ abi: iaclTraitAbi,
29
+ functionName: "acl",
30
+ });
31
+ const configuratorAddr = await anvil.readContract({
32
+ address: aclAddr,
33
+ abi: iOwnableAbi,
34
+ functionName: "owner",
35
+ });
36
+
37
+ await anvil.impersonateAccount({
38
+ address: configuratorAddr,
39
+ });
40
+ await anvil.setBalance({
41
+ address: configuratorAddr,
42
+ value: parseEther("100"),
43
+ });
44
+ for (const [t, lt] of Object.entries(newLTs)) {
45
+ try {
46
+ await anvil.writeContract({
47
+ chain: anvil.chain,
48
+ address: cm.creditConfigurator,
49
+ account: configuratorAddr,
50
+ abi: iCreditConfiguratorV300Abi,
51
+ functionName: "setLiquidationThreshold",
52
+ args: [t as Address, lt],
53
+ });
54
+ const newLT = await anvil.readContract({
55
+ address: cm.address,
56
+ abi: iCreditManagerV310Abi,
57
+ functionName: "liquidationThresholds",
58
+ args: [t as Address],
59
+ });
60
+ logger?.debug(`set ${t} LT to ${newLT}`);
61
+ } catch {
62
+ // in case when we try to set token that's not present
63
+ }
64
+ }
65
+ await anvil.stopImpersonatingAccount({
66
+ address: configuratorAddr,
67
+ });
68
+ }