@gearbox-protocol/sdk 1.26.1 → 1.27.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.
Files changed (43) hide show
  1. package/contracts/AdapterData.sol +76 -239
  2. package/contracts/AdapterType.sol +23 -23
  3. package/contracts/PriceFeedDataLive.sol +369 -284
  4. package/contracts/PriceFeedType.sol +19 -18
  5. package/contracts/SupportedContracts.sol +110 -262
  6. package/contracts/Tokens.sol +106 -90
  7. package/contracts/TokensData.sol +197 -664
  8. package/lib/apy/curveAPY.js +1 -1
  9. package/lib/apy/yearnAPY.js +1 -1
  10. package/lib/contracts/contracts.d.ts +21 -2
  11. package/lib/contracts/contracts.js +102 -2
  12. package/lib/contracts/contractsRegister.js +1 -1
  13. package/lib/contracts/protocols.d.ts +3 -1
  14. package/lib/contracts/protocols.js +10 -0
  15. package/lib/core/creditSession.js +1 -1
  16. package/lib/index.d.ts +1 -1
  17. package/lib/index.js +2 -5
  18. package/lib/oracles/oracles.d.ts +20 -6
  19. package/lib/oracles/oracles.js +4 -3
  20. package/lib/oracles/priceFeeds.js +106 -52
  21. package/lib/oracles/priceFeeds.spec.d.ts +1 -0
  22. package/lib/oracles/priceFeeds.spec.js +135 -0
  23. package/lib/parsers/txParser.js +2 -2
  24. package/lib/pathfinder/tradeTypes.d.ts +25 -2
  25. package/lib/pathfinder/tradeTypes.js +5 -0
  26. package/lib/tokens/aave.d.ts +23 -0
  27. package/lib/tokens/aave.js +119 -0
  28. package/lib/tokens/compound.d.ts +13 -0
  29. package/lib/tokens/compound.js +61 -0
  30. package/lib/tokens/decimals.js +13 -0
  31. package/lib/tokens/normal.d.ts +1 -1
  32. package/lib/tokens/normal.js +16 -0
  33. package/lib/tokens/token.d.ts +4 -2
  34. package/lib/tokens/token.js +43 -4
  35. package/lib/tokens/tokenType.d.ts +4 -2
  36. package/lib/tokens/tokenType.js +3 -1
  37. package/lib/tokens/tokens.spec.d.ts +1 -0
  38. package/lib/tokens/tokens.spec.js +110 -0
  39. package/lib/utils/mappers.d.ts +6 -5
  40. package/lib/utils/mappers.js +11 -12
  41. package/lib/utils/multicall.d.ts +14 -0
  42. package/lib/utils/multicall.js +34 -1
  43. package/package.json +3 -2
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const ethers_1 = require("ethers");
7
+ const chains_1 = require("../core/chains");
8
+ const types_1 = require("../types");
9
+ const multicall_1 = __importDefault(require("../utils/multicall"));
10
+ const token_1 = require("./token");
11
+ const erc20 = types_1.IERC20Metadata__factory.createInterface();
12
+ const EXCEPTIONS_IN_SYMBOLS = {
13
+ Mainnet: {
14
+ // Our Symbol <-> On-chain Symbol
15
+ [token_1.tokenDataByNetwork.Mainnet.STETH]: "stETH",
16
+ },
17
+ Arbitrum: {
18
+ // Our Symbol <-> On-chain Symbol
19
+ [token_1.tokenDataByNetwork.Arbitrum.crvUSDTWBTCWETH]: "crv3crypto",
20
+ [token_1.tokenDataByNetwork.Arbitrum["50OHM_50WETH"]]: "50WETH_50OHM",
21
+ },
22
+ };
23
+ class TokenSuite {
24
+ provider;
25
+ network;
26
+ calls;
27
+ responses = {};
28
+ constructor(network) {
29
+ this.network = network;
30
+ const url = process.env[`${network.toUpperCase()}_TESTS_FORK`];
31
+ if (!url) {
32
+ throw new Error(`${network} provder not found in env`);
33
+ }
34
+ this.provider = new ethers_1.ethers.providers.StaticJsonRpcProvider(url, chains_1.CHAINS[network]);
35
+ // Omit NOT DEPLOYED
36
+ const entries = Object.entries(token_1.tokenDataByNetwork[network]).filter(([_, addr]) => addr?.startsWith("0x"));
37
+ this.calls = entries.map(([symbol, address]) => ({
38
+ address,
39
+ interface: erc20,
40
+ method: "symbol()",
41
+ key: symbol,
42
+ }));
43
+ }
44
+ async fetchSymbols() {
45
+ // even safe multicall fails when one of addresses is an EOA and not contract address
46
+ if (this.network === "Arbitrum") {
47
+ for (const call of this.calls) {
48
+ const c = types_1.IERC20Metadata__factory.connect(call.address, this.provider);
49
+ try {
50
+ const s = await c.symbol();
51
+ this.responses[call.key] = {
52
+ address: call.address,
53
+ symbol: this.sanitize(s),
54
+ };
55
+ }
56
+ catch (e) {
57
+ this.responses[call.key] = {
58
+ address: call.address,
59
+ error: e,
60
+ };
61
+ }
62
+ }
63
+ }
64
+ else {
65
+ const resps = await (0, multicall_1.default)(this.calls, this.provider);
66
+ for (let i = 0; i < resps.length; i++) {
67
+ const call = this.calls[i];
68
+ const resp = resps[i];
69
+ this.responses[call.key] = {
70
+ address: call.address,
71
+ symbol: resp.error ? undefined : this.sanitize(resp.value ?? ""),
72
+ error: resp.error ? new Error("multicall error") : undefined,
73
+ };
74
+ }
75
+ }
76
+ }
77
+ /**
78
+ * Given <symbol, address> token map on our sdk, asserts that symbol found on chain for this address is the same
79
+ * Takes into account some exceptions
80
+ * @param sdkSymbol Symbol of token in SDK
81
+ */
82
+ assertSymbol(sdkSymbol) {
83
+ const r = this.responses[sdkSymbol];
84
+ if (r.error) {
85
+ throw new Error(`failed to verify ${sdkSymbol} on address ${r.address}: ${console.error}`);
86
+ }
87
+ const expectedSymbol = EXCEPTIONS_IN_SYMBOLS[this.network][r.address] ?? sdkSymbol;
88
+ if (r.symbol !== expectedSymbol) {
89
+ throw new Error(`Expected ${expectedSymbol} but found ${r.symbol} at ${r.address}`);
90
+ }
91
+ }
92
+ sanitize(symbol) {
93
+ return symbol.replace(/\-f$/, "").replaceAll("-", "_");
94
+ }
95
+ }
96
+ describe("Tokens", () => {
97
+ const suites = chains_1.supportedChains.map(n => new TokenSuite(n));
98
+ before(async function () {
99
+ this.timeout(60000);
100
+ await Promise.all(suites.map(s => s.fetchSymbols()));
101
+ });
102
+ suites.forEach(suite => {
103
+ suite.calls.forEach(call => {
104
+ // eslint-disable-next-line max-nested-callbacks
105
+ it(`${call.key} on ${suite.network}`, () => {
106
+ suite.assertSymbol(call.key);
107
+ });
108
+ });
109
+ });
110
+ });
@@ -1,7 +1,8 @@
1
1
  type SupportedValue = string | number;
2
- declare const objectEntries: <K extends SupportedValue, T>(o: Record<K, T>) => [K, T][];
3
- declare const swapKeyValue: <K extends SupportedValue, T extends SupportedValue>(o: Record<K, T>) => Record<T, K>;
4
- declare const keyToLowercase: <K extends SupportedValue, T>(o: Record<K, T>) => Record<K, T>;
5
- declare const filterEmptyKeys: <K extends SupportedValue, T>(o: Record<K, T>) => Record<K, T>;
2
+ export declare class TypedObjectUtils {
3
+ static entries: <K extends SupportedValue, T>(o: Record<K, T>) => [K, T][];
4
+ static fromEntries: <K extends SupportedValue, T>(o: [K, T][]) => Record<K, T>;
5
+ static swapKeyValue: <K extends SupportedValue, T extends SupportedValue>(o: Record<K, T>) => Record<T, K>;
6
+ static keyToLowercase: <K extends SupportedValue, T>(o: Record<K, T>) => Record<K, T>;
7
+ }
6
8
  export type { SupportedValue };
7
- export { filterEmptyKeys, keyToLowercase, objectEntries, swapKeyValue };
@@ -1,14 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.swapKeyValue = exports.objectEntries = exports.keyToLowercase = exports.filterEmptyKeys = void 0;
4
- const objectEntries = (o) => Object.entries(o);
5
- exports.objectEntries = objectEntries;
6
- const swapKeyValue = (o) => objectEntries(o).reduce((acc, [key, value]) => ({ ...acc, [value]: key }), {});
7
- exports.swapKeyValue = swapKeyValue;
8
- const keyToLowercase = (o) => objectEntries(o).reduce((acc, [key, value]) => {
9
- const keyTransformed = typeof key === "string" ? key.toLowerCase() : key;
10
- return { ...acc, [keyTransformed]: value };
11
- }, {});
12
- exports.keyToLowercase = keyToLowercase;
13
- const filterEmptyKeys = (o) => objectEntries(o).reduce((acc, [key, value]) => (key ? { ...acc, [key]: value } : acc), {});
14
- exports.filterEmptyKeys = filterEmptyKeys;
3
+ exports.TypedObjectUtils = void 0;
4
+ class TypedObjectUtils {
5
+ static entries = (o) => Object.entries(o);
6
+ static fromEntries = (o) => Object.fromEntries(o);
7
+ static swapKeyValue = (o) => TypedObjectUtils.entries(o).reduce((acc, [key, value]) => ({ ...acc, [value]: key }), {});
8
+ static keyToLowercase = (o) => TypedObjectUtils.entries(o).reduce((acc, [key, value]) => {
9
+ const keyTransformed = typeof key === "string" ? key.toLowerCase() : key;
10
+ return { ...acc, [keyTransformed]: value };
11
+ }, {});
12
+ }
13
+ exports.TypedObjectUtils = TypedObjectUtils;
@@ -10,7 +10,21 @@ export interface MCall<T extends ethers.utils.Interface> {
10
10
  method: keyof T["functions"];
11
11
  params?: any;
12
12
  }
13
+ export interface KeyedCall<T extends ethers.utils.Interface> extends MCall<T> {
14
+ key: string;
15
+ }
13
16
  export declare function multicall<R extends Array<any>>(calls: Array<MCall<any>>, p: Signer | ethers.providers.Provider, overrides?: CallOverrides): Promise<R>;
17
+ /**
18
+ * Like multicall from sdk, but uses tryAggregate instead of aggregate
19
+ * @param calls
20
+ * @param p
21
+ * @param overrides
22
+ * @returns
23
+ */
24
+ export default function safeMulticall<V = any, T extends MCall<any> = MCall<any>>(calls: T[], p: Signer | ethers.providers.Provider, overrides?: CallOverrides): Promise<Array<{
25
+ error: boolean;
26
+ value?: V;
27
+ }>>;
14
28
  export declare class MultiCallContract<T extends ethers.utils.Interface> {
15
29
  private readonly _address;
16
30
  private readonly _interface;
@@ -11,9 +11,42 @@ async function multicall(calls, p, overrides) {
11
11
  })), overrides || {});
12
12
  return returnData
13
13
  .map((d, num) => calls[num].interface.decodeFunctionResult(calls[num].method, d))
14
- .map(r => (Array.isArray(r) && r.length <= 1 ? r[0] : r));
14
+ .map(unwrapArray);
15
15
  }
16
16
  exports.multicall = multicall;
17
+ /**
18
+ * Like multicall from sdk, but uses tryAggregate instead of aggregate
19
+ * @param calls
20
+ * @param p
21
+ * @param overrides
22
+ * @returns
23
+ */
24
+ async function safeMulticall(calls, p, overrides) {
25
+ if (!calls.length) {
26
+ return [];
27
+ }
28
+ const multiCallContract = types_1.Multicall2__factory.connect("0xcA11bde05977b3631167028862bE2a173976CA11", p);
29
+ const resp = await multiCallContract.callStatic.tryAggregate(false, calls.map(c => ({
30
+ target: c.address,
31
+ callData: c.interface.encodeFunctionData(c.method, c.params),
32
+ })), overrides ?? {});
33
+ return resp.map((d, num) => ({
34
+ error: !d.success,
35
+ value: d.success
36
+ ? unwrapArray(calls[num].interface.decodeFunctionResult(calls[num].method, d.returnData))
37
+ : undefined,
38
+ }));
39
+ }
40
+ exports.default = safeMulticall;
41
+ function unwrapArray(data) {
42
+ if (!data) {
43
+ return data;
44
+ }
45
+ if (Array.isArray(data)) {
46
+ return data.length === 1 ? data[0] : data;
47
+ }
48
+ return data;
49
+ }
17
50
  class MultiCallContract {
18
51
  _address;
19
52
  _interface;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gearbox-protocol/sdk",
3
- "version": "1.26.1",
3
+ "version": "1.27.0",
4
4
  "description": "Gearbox SDK",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",
@@ -23,7 +23,7 @@
23
23
  "lint": "eslint \"**/*.ts\" --fix",
24
24
  "lint:ci": "eslint \"**/*.ts\"",
25
25
  "typecheck:ci": "tsc --noEmit",
26
- "test": "npx mocha --require ts-node/register src/**/*.spec.ts"
26
+ "test": "npx mocha -r ts-node/register -r dotenv/config src/**/*.spec.ts"
27
27
  },
28
28
  "dependencies": {
29
29
  "@types/deep-eql": "^4.0.0",
@@ -40,6 +40,7 @@
40
40
  "@typechain/ethers-v5": "10.0.0",
41
41
  "@types/chai": "^4.3.3",
42
42
  "@types/jest": "^28.1.7",
43
+ "@types/mocha": "^10.0.1",
43
44
  "@types/node": "^18.7.6",
44
45
  "@types/rimraf": "^3.0.2",
45
46
  "chai": "^4.3.6",