@gearbox-protocol/sdk 8.9.0 → 8.10.0

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.
@@ -117,6 +117,12 @@ class AccountOpener extends import_sdk.SDKConstruct {
117
117
  }
118
118
  }
119
119
  this.#logger?.info(`opened ${success}/${targets.length} accounts`);
120
+ try {
121
+ await this.#directlyDistributeTokens(results);
122
+ this.#logger?.info("distributed direct transfer tokens");
123
+ } catch (e) {
124
+ this.#logger?.error(`failed to distribute tokens: ${e}`);
125
+ }
120
126
  return results;
121
127
  }
122
128
  async #openAccount(input, index, total) {
@@ -503,6 +509,87 @@ class AccountOpener extends import_sdk.SDKConstruct {
503
509
  });
504
510
  return acc;
505
511
  }
512
+ /**
513
+ * Claims tokens from faucet, uniformly distributes them to accounts
514
+ * @param targets
515
+ * @returns
516
+ */
517
+ async #directlyDistributeTokens(targets) {
518
+ const tokens = new import_sdk.AddressSet(
519
+ targets.flatMap((t) => t.input.directTransfer ?? [])
520
+ );
521
+ if (tokens.size === 0) {
522
+ return;
523
+ }
524
+ const distributorKey = (0, import_accounts.generatePrivateKey)();
525
+ const distributor = (0, import_accounts.privateKeyToAccount)(distributorKey);
526
+ await this.#anvil.setBalance({
527
+ address: distributor.address,
528
+ value: (0, import_viem.parseEther)("100")
529
+ });
530
+ await (0, import_claimFromFaucet.claimFromFaucet)({
531
+ publicClient: this.#anvil,
532
+ wallet: this.#anvil,
533
+ faucet: this.faucet,
534
+ amountUSD: (minAmountUSD) => minAmountUSD * BigInt(targets.length),
535
+ claimer: distributor,
536
+ role: "reward token distributor",
537
+ logger: this.#logger
538
+ });
539
+ const actualBalances = await this.#anvil.multicall({
540
+ contracts: tokens.map(
541
+ (token) => ({
542
+ address: token,
543
+ abi: import_viem.erc20Abi,
544
+ functionName: "balanceOf",
545
+ args: [distributor.address]
546
+ })
547
+ ),
548
+ allowFailure: false
549
+ });
550
+ const tokensArr = tokens.asArray();
551
+ for (let i = 0; i < tokensArr.length; i++) {
552
+ const token = tokensArr[i];
553
+ const balance = actualBalances[i];
554
+ this.#logger?.debug(`${token} balance: ${balance}`);
555
+ }
556
+ for (const { account, input } of targets) {
557
+ if (!account) {
558
+ continue;
559
+ }
560
+ const directTransfer = new import_sdk.AddressSet(input.directTransfer);
561
+ for (let i = 0; i < tokensArr.length; i++) {
562
+ const token = tokensArr[i];
563
+ if (!directTransfer.has(token)) {
564
+ continue;
565
+ }
566
+ const balance = actualBalances[i] / BigInt(targets.length);
567
+ this.#logger?.debug(
568
+ `sending ${balance} ${token} to ${account.creditAccount}`
569
+ );
570
+ const hash = await this.#anvil.writeContract({
571
+ account: distributor,
572
+ address: token,
573
+ abi: import_viem.erc20Abi,
574
+ functionName: "transfer",
575
+ args: [account.creditAccount, balance],
576
+ chain: this.#anvil.chain
577
+ });
578
+ const receipt = await this.#anvil.waitForTransactionReceipt({
579
+ hash
580
+ });
581
+ if (receipt.status === "reverted") {
582
+ this.#logger?.error(
583
+ `failed to send ${token} to ${account.creditAccount}, tx ${hash} reverted`
584
+ );
585
+ } else {
586
+ this.#logger?.debug(
587
+ `sent ${token} to ${account.creditAccount}, tx: ${hash}`
588
+ );
589
+ }
590
+ }
591
+ }
592
+ }
506
593
  #getCollateralQuota(cm, collateral, collateralAmount, debt, logger) {
507
594
  const {
508
595
  underlying,
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var AddressSet_exports = {};
20
+ __export(AddressSet_exports, {
21
+ AddressSet: () => AddressSet
22
+ });
23
+ module.exports = __toCommonJS(AddressSet_exports);
24
+ var import_viem = require("viem");
25
+ class AddressSet extends Set {
26
+ constructor(entries) {
27
+ super(Array.from(entries ?? []).map((a) => (0, import_viem.getAddress)(a)));
28
+ }
29
+ add(value) {
30
+ return super.add((0, import_viem.getAddress)(value));
31
+ }
32
+ delete(value) {
33
+ return super.delete((0, import_viem.getAddress)(value));
34
+ }
35
+ has(value) {
36
+ return super.has((0, import_viem.getAddress)(value));
37
+ }
38
+ asArray() {
39
+ return Array.from(this);
40
+ }
41
+ map(fn) {
42
+ return this.asArray().map(fn);
43
+ }
44
+ }
45
+ // Annotate the CommonJS export names for ESM import in node:
46
+ 0 && (module.exports = {
47
+ AddressSet
48
+ });
@@ -16,6 +16,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
16
16
  var utils_exports = {};
17
17
  module.exports = __toCommonJS(utils_exports);
18
18
  __reExport(utils_exports, require("./AddressMap.js"), module.exports);
19
+ __reExport(utils_exports, require("./AddressSet.js"), module.exports);
19
20
  __reExport(utils_exports, require("./bytes32ToString.js"), module.exports);
20
21
  __reExport(utils_exports, require("./childLogger.js"), module.exports);
21
22
  __reExport(utils_exports, require("./createRawTx.js"), module.exports);
@@ -32,6 +33,7 @@ __reExport(utils_exports, require("./zod.js"), module.exports);
32
33
  // Annotate the CommonJS export names for ESM import in node:
33
34
  0 && (module.exports = {
34
35
  ...require("./AddressMap.js"),
36
+ ...require("./AddressSet.js"),
35
37
  ...require("./bytes32ToString.js"),
36
38
  ...require("./childLogger.js"),
37
39
  ...require("./createRawTx.js"),
@@ -1,10 +1,17 @@
1
- import { BaseError, isAddress, parseEther, parseEventLogs } from "viem";
1
+ import {
2
+ BaseError,
3
+ erc20Abi,
4
+ isAddress,
5
+ parseEther,
6
+ parseEventLogs
7
+ } from "viem";
2
8
  import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
3
9
  import { ierc20Abi } from "../abi/iERC20.js";
4
10
  import { iCreditFacadeV300Abi, iPoolV300Abi } from "../abi/v300.js";
5
11
  import {
6
12
  ADDRESS_0X0,
7
13
  AddressMap,
14
+ AddressSet,
8
15
  childLogger,
9
16
  formatBN,
10
17
  MAX_UINT256,
@@ -102,6 +109,12 @@ class AccountOpener extends SDKConstruct {
102
109
  }
103
110
  }
104
111
  this.#logger?.info(`opened ${success}/${targets.length} accounts`);
112
+ try {
113
+ await this.#directlyDistributeTokens(results);
114
+ this.#logger?.info("distributed direct transfer tokens");
115
+ } catch (e) {
116
+ this.#logger?.error(`failed to distribute tokens: ${e}`);
117
+ }
105
118
  return results;
106
119
  }
107
120
  async #openAccount(input, index, total) {
@@ -488,6 +501,87 @@ class AccountOpener extends SDKConstruct {
488
501
  });
489
502
  return acc;
490
503
  }
504
+ /**
505
+ * Claims tokens from faucet, uniformly distributes them to accounts
506
+ * @param targets
507
+ * @returns
508
+ */
509
+ async #directlyDistributeTokens(targets) {
510
+ const tokens = new AddressSet(
511
+ targets.flatMap((t) => t.input.directTransfer ?? [])
512
+ );
513
+ if (tokens.size === 0) {
514
+ return;
515
+ }
516
+ const distributorKey = generatePrivateKey();
517
+ const distributor = privateKeyToAccount(distributorKey);
518
+ await this.#anvil.setBalance({
519
+ address: distributor.address,
520
+ value: parseEther("100")
521
+ });
522
+ await claimFromFaucet({
523
+ publicClient: this.#anvil,
524
+ wallet: this.#anvil,
525
+ faucet: this.faucet,
526
+ amountUSD: (minAmountUSD) => minAmountUSD * BigInt(targets.length),
527
+ claimer: distributor,
528
+ role: "reward token distributor",
529
+ logger: this.#logger
530
+ });
531
+ const actualBalances = await this.#anvil.multicall({
532
+ contracts: tokens.map(
533
+ (token) => ({
534
+ address: token,
535
+ abi: erc20Abi,
536
+ functionName: "balanceOf",
537
+ args: [distributor.address]
538
+ })
539
+ ),
540
+ allowFailure: false
541
+ });
542
+ const tokensArr = tokens.asArray();
543
+ for (let i = 0; i < tokensArr.length; i++) {
544
+ const token = tokensArr[i];
545
+ const balance = actualBalances[i];
546
+ this.#logger?.debug(`${token} balance: ${balance}`);
547
+ }
548
+ for (const { account, input } of targets) {
549
+ if (!account) {
550
+ continue;
551
+ }
552
+ const directTransfer = new AddressSet(input.directTransfer);
553
+ for (let i = 0; i < tokensArr.length; i++) {
554
+ const token = tokensArr[i];
555
+ if (!directTransfer.has(token)) {
556
+ continue;
557
+ }
558
+ const balance = actualBalances[i] / BigInt(targets.length);
559
+ this.#logger?.debug(
560
+ `sending ${balance} ${token} to ${account.creditAccount}`
561
+ );
562
+ const hash = await this.#anvil.writeContract({
563
+ account: distributor,
564
+ address: token,
565
+ abi: erc20Abi,
566
+ functionName: "transfer",
567
+ args: [account.creditAccount, balance],
568
+ chain: this.#anvil.chain
569
+ });
570
+ const receipt = await this.#anvil.waitForTransactionReceipt({
571
+ hash
572
+ });
573
+ if (receipt.status === "reverted") {
574
+ this.#logger?.error(
575
+ `failed to send ${token} to ${account.creditAccount}, tx ${hash} reverted`
576
+ );
577
+ } else {
578
+ this.#logger?.debug(
579
+ `sent ${token} to ${account.creditAccount}, tx: ${hash}`
580
+ );
581
+ }
582
+ }
583
+ }
584
+ }
491
585
  #getCollateralQuota(cm, collateral, collateralAmount, debt, logger) {
492
586
  const {
493
587
  underlying,
@@ -0,0 +1,24 @@
1
+ import { getAddress } from "viem";
2
+ class AddressSet extends Set {
3
+ constructor(entries) {
4
+ super(Array.from(entries ?? []).map((a) => getAddress(a)));
5
+ }
6
+ add(value) {
7
+ return super.add(getAddress(value));
8
+ }
9
+ delete(value) {
10
+ return super.delete(getAddress(value));
11
+ }
12
+ has(value) {
13
+ return super.has(getAddress(value));
14
+ }
15
+ asArray() {
16
+ return Array.from(this);
17
+ }
18
+ map(fn) {
19
+ return this.asArray().map(fn);
20
+ }
21
+ }
22
+ export {
23
+ AddressSet
24
+ };
@@ -1,4 +1,5 @@
1
1
  export * from "./AddressMap.js";
2
+ export * from "./AddressSet.js";
2
3
  export * from "./bytes32ToString.js";
3
4
  export * from "./childLogger.js";
4
5
  export * from "./createRawTx.js";
@@ -25,6 +25,10 @@ export interface TargetAccount {
25
25
  * TODO: not implemented
26
26
  */
27
27
  collateral?: Address;
28
+ /**
29
+ * These tokens will be transferred directly from faucet to credit account
30
+ */
31
+ directTransfer?: Address[];
28
32
  leverage?: number;
29
33
  slippage?: number;
30
34
  }
@@ -0,0 +1,9 @@
1
+ import { type Address } from "viem";
2
+ export declare class AddressSet extends Set<Address> {
3
+ constructor(entries?: Iterable<Address>);
4
+ add(value: Address): this;
5
+ delete(value: Address): boolean;
6
+ has(value: Address): boolean;
7
+ asArray(): Address[];
8
+ map<T>(fn: (address: Address) => T): T[];
9
+ }
@@ -1,4 +1,5 @@
1
1
  export * from "./AddressMap.js";
2
+ export * from "./AddressSet.js";
2
3
  export * from "./bytes32ToString.js";
3
4
  export * from "./childLogger.js";
4
5
  export * from "./createRawTx.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gearbox-protocol/sdk",
3
- "version": "8.9.0",
3
+ "version": "8.10.0",
4
4
  "description": "Gearbox SDK",
5
5
  "license": "MIT",
6
6
  "main": "./dist/cjs/sdk/index.js",