@gearbox-protocol/sdk 1.6.6 → 1.7.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.
@@ -0,0 +1,30 @@
1
+ import { providers, Signer } from "ethers";
2
+ import { CreditAccountData } from "../core/creditAccount";
3
+ import { CreditManagerData } from "../core/creditManager";
4
+ export declare type CreditAccountHash = string;
5
+ export interface CreditManagerUpdate {
6
+ updated: Array<CreditAccountHash>;
7
+ deleted: Array<CreditAccountHash>;
8
+ }
9
+ export declare class CreditAccountWatcher {
10
+ static IERC20: import("../types/@openzeppelin/contracts/token/ERC20/IERC20").IERC20Interface;
11
+ static creditManagerInterface: import("../types/contracts/interfaces/ICreditManagerV2.sol/ICreditManagerV2").ICreditManagerV2Interface;
12
+ static creditFacadeInterface: import("../types/contracts/interfaces/ICreditFacade.sol/ICreditFacade").ICreditFacadeInterface;
13
+ /**
14
+ * Gets hashes of all opened credit accounts at toBlock (or "latest" by default)
15
+ * @param creditManager CreditManagerData of desired CreditManager to check
16
+ * @param provider Ethers provider or signer to get an access
17
+ * @param toBlock Optional. Set the last block you;d like to get opened accounts
18
+ * @returns Arrays of hashes for opened accounts
19
+ */
20
+ static getOpenAccounts(creditManager: CreditManagerData, provider: providers.Provider | Signer, toBlock?: number): Promise<Array<CreditAccountHash>>;
21
+ static batchCreditAccountLoad(accs: Array<CreditAccountHash>, dataCompressor: string, signer: Signer | providers.Provider, atBlock?: number): Promise<Array<CreditAccountData>>;
22
+ /**
23
+ * Tracks block logs and detects whichj acccounts were changed (created / modified) and which were deleted
24
+ * @param logs Logs from last N blocks
25
+ * @param creditManagers Array of CreditManager data which account it should track
26
+ * @returns CreditManagerUpdate which contains updated (created / modified) and deleted accounts
27
+ */
28
+ static detectChanges(logs: Array<providers.Log>, creditManagers: Array<CreditManagerData>): CreditManagerUpdate;
29
+ static trackDirectTransfers(freshLogs: Array<providers.Log>, tokensToTrack: Array<string>, accounts: Array<CreditAccountData>): Array<CreditAccountHash>;
30
+ }
@@ -0,0 +1,255 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (_) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.CreditAccountWatcher = void 0;
40
+ var creditAccount_1 = require("../core/creditAccount");
41
+ var types_1 = require("../types");
42
+ var multicall_1 = require("../utils/multicall");
43
+ var CreditAccountWatcher = /** @class */ (function () {
44
+ function CreditAccountWatcher() {
45
+ }
46
+ /**
47
+ * Gets hashes of all opened credit accounts at toBlock (or "latest" by default)
48
+ * @param creditManager CreditManagerData of desired CreditManager to check
49
+ * @param provider Ethers provider or signer to get an access
50
+ * @param toBlock Optional. Set the last block you;d like to get opened accounts
51
+ * @returns Arrays of hashes for opened accounts
52
+ */
53
+ CreditAccountWatcher.getOpenAccounts = function (creditManager, provider, toBlock) {
54
+ return __awaiter(this, void 0, void 0, function () {
55
+ var eventsByDate, addToEvents, accounts, creditFacade, cf, _a, openEvents, closeEvents, liquidateEvents, liquidateExpiredEvents;
56
+ return __generator(this, function (_b) {
57
+ switch (_b.label) {
58
+ case 0:
59
+ if (creditManager.version !== 2)
60
+ throw new Error("Works for V2 only");
61
+ eventsByDate = [];
62
+ addToEvents = function (e, address, operation) {
63
+ eventsByDate.push({
64
+ time: e.blockNumber * 100000 + e.logIndex,
65
+ address: address,
66
+ operation: operation,
67
+ });
68
+ };
69
+ accounts = new Set();
70
+ creditFacade = creditManager.creditFacade;
71
+ cf = types_1.ICreditFacade__factory.connect(creditFacade, provider);
72
+ return [4 /*yield*/, Promise.all([
73
+ cf.queryFilter(cf.filters.OpenCreditAccount(), undefined, toBlock),
74
+ cf.queryFilter(cf.filters.CloseCreditAccount(), undefined, toBlock),
75
+ cf.queryFilter(cf.filters.LiquidateCreditAccount(), undefined, toBlock),
76
+ cf.queryFilter(cf.filters.LiquidateExpiredCreditAccount(), undefined, toBlock),
77
+ ])];
78
+ case 1:
79
+ _a = _b.sent(), openEvents = _a[0], closeEvents = _a[1], liquidateEvents = _a[2], liquidateExpiredEvents = _a[3];
80
+ openEvents.forEach(function (e) {
81
+ addToEvents(e, e.args.onBehalfOf, "add");
82
+ });
83
+ closeEvents.forEach(function (e) {
84
+ addToEvents(e, e.args.borrower, "delete");
85
+ });
86
+ liquidateEvents.forEach(function (e) {
87
+ addToEvents(e, e.args.borrower, "delete");
88
+ });
89
+ liquidateExpiredEvents.forEach(function (e) {
90
+ addToEvents(e, e.args.borrower, "delete");
91
+ });
92
+ eventsByDate
93
+ .sort(function (a, b) {
94
+ return a.time > b.time ? 1 : -1;
95
+ })
96
+ .forEach(function (e) {
97
+ if (e.operation === "add") {
98
+ accounts.add(e.address);
99
+ }
100
+ else {
101
+ accounts.delete(e.address);
102
+ }
103
+ });
104
+ return [2 /*return*/, Array.from(accounts.values()).map(function (borrower) {
105
+ return creditAccount_1.CreditAccountData.hash(creditManager.address, borrower);
106
+ })];
107
+ }
108
+ });
109
+ });
110
+ };
111
+ CreditAccountWatcher.batchCreditAccountLoad = function (accs, dataCompressor, signer, atBlock) {
112
+ return __awaiter(this, void 0, void 0, function () {
113
+ var dcmc, chunkSize, calls, i, chunk, data;
114
+ return __generator(this, function (_a) {
115
+ switch (_a.label) {
116
+ case 0:
117
+ dcmc = new multicall_1.MultiCallContract(dataCompressor, types_1.IDataCompressor__factory.createInterface(), signer);
118
+ chunkSize = 1000;
119
+ calls = [];
120
+ for (i = 0; i < accs.length; i++) {
121
+ chunk = accs.slice(i * chunkSize, (i + 1) * chunkSize);
122
+ calls[i] = chunk.map(function (c) {
123
+ return {
124
+ method: "getCreditAccountData(address,address)",
125
+ params: c.split(":"),
126
+ };
127
+ });
128
+ }
129
+ return [4 /*yield*/, Promise.all(calls.map(function (c) { return dcmc.call(c, { blockTag: atBlock }); }))];
130
+ case 1:
131
+ data = _a.sent();
132
+ return [2 /*return*/, data.flat().map(function (c) { return new creditAccount_1.CreditAccountData(c); })];
133
+ }
134
+ });
135
+ });
136
+ };
137
+ /**
138
+ * Tracks block logs and detects whichj acccounts were changed (created / modified) and which were deleted
139
+ * @param logs Logs from last N blocks
140
+ * @param creditManagers Array of CreditManager data which account it should track
141
+ * @returns CreditManagerUpdate which contains updated (created / modified) and deleted accounts
142
+ */
143
+ CreditAccountWatcher.detectChanges = function (logs, creditManagers) {
144
+ var cms = creditManagers.map(function (c) { return c.address; });
145
+ var cfs = creditManagers.map(function (c) { return c.creditFacade; });
146
+ var cfToCm = creditManagers.reduce(function (acc, item) {
147
+ acc[item.creditFacade] = item.address;
148
+ return acc;
149
+ }, {});
150
+ var trackers = {};
151
+ cms.forEach(function (cm) {
152
+ trackers[cm] = {
153
+ updated: new Set(),
154
+ deleted: new Set(),
155
+ };
156
+ });
157
+ for (var _i = 0, logs_1 = logs; _i < logs_1.length; _i++) {
158
+ var log = logs_1[_i];
159
+ var logAddr = log.address.toLowerCase();
160
+ if (cms.includes(logAddr)) {
161
+ var _a = CreditAccountWatcher.creditManagerInterface.parseLog(log), name = _a.name, args = _a.args;
162
+ if (name === "ExecuteOrder") {
163
+ var borrower = args.borrower;
164
+ if (!borrower)
165
+ throw new Error("Cant parser event ".concat(log));
166
+ /// Excludes credit facade which represents borrower in multicall
167
+ if (!cfs.includes(borrower.toLowerCase())) {
168
+ trackers[logAddr].updated.add(borrower);
169
+ }
170
+ }
171
+ }
172
+ else if (cfs.includes(logAddr)) {
173
+ var _b = CreditAccountWatcher.creditFacadeInterface.parseLog(log), name = _b.name, args = _b.args;
174
+ switch (name) {
175
+ case "OpenCreditAccount":
176
+ case "AddCollateral": {
177
+ var onBehalfOf = args.onBehalfOf;
178
+ if (!onBehalfOf)
179
+ throw new Error("Cant parser event ".concat(log));
180
+ trackers[cfToCm[logAddr]].updated.add(onBehalfOf);
181
+ break;
182
+ }
183
+ case "DecreaseBorrowedAmount":
184
+ case "IncreaseBorrowedAmount":
185
+ case "TokenDisabled":
186
+ case "TokenEnabled":
187
+ case "MultiCallStarted": {
188
+ var borrower = args.borrower;
189
+ if (!borrower)
190
+ throw new Error("Cant parser event ".concat(log));
191
+ trackers[cfToCm[logAddr]].updated.add(borrower);
192
+ break;
193
+ }
194
+ case "CloseCreditAccount":
195
+ case "LiquidateCreditAccount":
196
+ case "LiquidateExpiredCreditAccount": {
197
+ var borrower = args.borrower;
198
+ if (!borrower)
199
+ throw new Error("Cant parser event ".concat(log));
200
+ trackers[cfToCm[logAddr]].updated.delete(borrower);
201
+ trackers[cfToCm[logAddr]].deleted.add(borrower);
202
+ break;
203
+ }
204
+ case "TransferAccount": {
205
+ var oldOwner = args.oldOwner, newOwner = args.newOwner;
206
+ if (!oldOwner || !newOwner)
207
+ throw new Error("Cant parser event ".concat(log));
208
+ trackers[cfToCm[logAddr]].updated.delete(oldOwner);
209
+ trackers[cfToCm[logAddr]].updated.add(newOwner);
210
+ trackers[cfToCm[logAddr]].deleted.add(oldOwner);
211
+ }
212
+ }
213
+ }
214
+ }
215
+ var result = {
216
+ updated: [],
217
+ deleted: [],
218
+ };
219
+ cms.forEach(function (cm) {
220
+ trackers[cm].updated.forEach(function (borrower) {
221
+ result.updated.push(creditAccount_1.CreditAccountData.hash(cm, borrower));
222
+ });
223
+ trackers[cm].deleted.forEach(function (borrower) {
224
+ result.deleted.push(creditAccount_1.CreditAccountData.hash(cm, borrower));
225
+ });
226
+ });
227
+ return result;
228
+ };
229
+ CreditAccountWatcher.trackDirectTransfers = function (freshLogs, tokensToTrack, accounts) {
230
+ var tkns = tokensToTrack.map(function (t) { return t.toLowerCase(); });
231
+ var accAddresses = [];
232
+ var accToCa = {};
233
+ var modified = new Set();
234
+ accounts.forEach(function (ca) {
235
+ accAddresses.push(ca.addr);
236
+ accToCa[ca.addr] = ca;
237
+ });
238
+ for (var _i = 0, freshLogs_1 = freshLogs; _i < freshLogs_1.length; _i++) {
239
+ var log = freshLogs_1[_i];
240
+ if (tkns.includes(log.address.toLocaleLowerCase())) {
241
+ var _a = CreditAccountWatcher.IERC20.parseLog(log), name = _a.name, args = _a.args;
242
+ if (name === "Transfer" &&
243
+ accAddresses.includes(args.to.toLowerCase())) {
244
+ modified.add(accToCa[args.to.toLowerCase()].hash());
245
+ }
246
+ }
247
+ }
248
+ return Array.from(modified);
249
+ };
250
+ CreditAccountWatcher.IERC20 = types_1.IERC20__factory.createInterface();
251
+ CreditAccountWatcher.creditManagerInterface = types_1.ICreditManagerV2__factory.createInterface();
252
+ CreditAccountWatcher.creditFacadeInterface = types_1.ICreditFacade__factory.createInterface();
253
+ return CreditAccountWatcher;
254
+ }());
255
+ exports.CreditAccountWatcher = CreditAccountWatcher;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var chai_1 = require("chai");
4
+ var ethers_1 = require("ethers");
5
+ var constants_1 = require("../core/constants");
6
+ var types_1 = require("../types");
7
+ var creditAccountWatcher_1 = require("./creditAccountWatcher");
8
+ var CREDIT_MANAGER_ADDRESS = constants_1.DUMB_ADDRESS;
9
+ var CREDIT_FACADE_ADDRESS = "0xcb9a588a47dd0393af3d0d5f86e6f1c8fd252c48";
10
+ var BORROWER = "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266";
11
+ var expectedHash = "".concat(CREDIT_MANAGER_ADDRESS.toLowerCase(), ":").concat(BORROWER.toLowerCase());
12
+ var creditManagerInterface = types_1.ICreditManagerV2__factory.createInterface();
13
+ var creditFacadeInterface = types_1.ICreditFacade__factory.createInterface();
14
+ var cmDumb = {
15
+ address: CREDIT_MANAGER_ADDRESS.toLowerCase(),
16
+ creditFacade: CREDIT_FACADE_ADDRESS.toLowerCase(),
17
+ };
18
+ var encode = function (abiType, value) {
19
+ return ethers_1.utils.defaultAbiCoder.encode([abiType], [value]);
20
+ };
21
+ var makeLog = function (address, topics, data) {
22
+ if (data === void 0) { data = constants_1.ADDRESS_0X0; }
23
+ return {
24
+ blockNumber: 0,
25
+ blockHash: "",
26
+ transactionIndex: 0,
27
+ removed: false,
28
+ address: address,
29
+ data: data,
30
+ topics: topics,
31
+ transactionHash: "",
32
+ logIndex: 0,
33
+ };
34
+ };
35
+ var openLog = makeLog(CREDIT_FACADE_ADDRESS, [
36
+ creditFacadeInterface.getEventTopic("OpenCreditAccount"),
37
+ encode("address", BORROWER),
38
+ encode("address", constants_1.DUMB_ADDRESS),
39
+ ], ethers_1.utils.defaultAbiCoder.encode(["uint256", "uint16"], [10, 10]));
40
+ var closeLog = makeLog(CREDIT_FACADE_ADDRESS, [
41
+ creditFacadeInterface.getEventTopic("CloseCreditAccount"),
42
+ encode("address", BORROWER),
43
+ encode("address", constants_1.DUMB_ADDRESS),
44
+ encode("address", constants_1.DUMB_ADDRESS),
45
+ ]);
46
+ describe("CreditAccountTracker test", function () {
47
+ it("detects update events correctly", function () {
48
+ (0, chai_1.expect)(creditAccountWatcher_1.CreditAccountWatcher.detectChanges([openLog], [cmDumb])).to.be.eql({
49
+ updated: [expectedHash],
50
+ deleted: [],
51
+ });
52
+ var log = makeLog(CREDIT_FACADE_ADDRESS, [
53
+ creditFacadeInterface.getEventTopic("IncreaseBorrowedAmount"),
54
+ encode("address", BORROWER),
55
+ ], ethers_1.utils.defaultAbiCoder.encode(["uint256"], [10]));
56
+ (0, chai_1.expect)(creditAccountWatcher_1.CreditAccountWatcher.detectChanges([log], [cmDumb])).to.be.eql({
57
+ updated: [expectedHash],
58
+ deleted: [],
59
+ });
60
+ log = makeLog(CREDIT_FACADE_ADDRESS, [
61
+ creditFacadeInterface.getEventTopic("DecreaseBorrowedAmount"),
62
+ encode("address", BORROWER),
63
+ ], ethers_1.utils.defaultAbiCoder.encode(["uint256"], [10]));
64
+ (0, chai_1.expect)(creditAccountWatcher_1.CreditAccountWatcher.detectChanges([log], [cmDumb])).to.be.eql({
65
+ updated: [expectedHash],
66
+ deleted: [],
67
+ });
68
+ log = makeLog(CREDIT_FACADE_ADDRESS, [
69
+ creditFacadeInterface.getEventTopic("AddCollateral"),
70
+ encode("address", BORROWER),
71
+ encode("address", constants_1.DUMB_ADDRESS),
72
+ ], ethers_1.utils.defaultAbiCoder.encode(["uint256"], [10]));
73
+ (0, chai_1.expect)(creditAccountWatcher_1.CreditAccountWatcher.detectChanges([log], [cmDumb])).to.be.eql({
74
+ updated: [expectedHash],
75
+ deleted: [],
76
+ });
77
+ log = makeLog(CREDIT_FACADE_ADDRESS, [
78
+ creditFacadeInterface.getEventTopic("MultiCallStarted"),
79
+ encode("address", BORROWER),
80
+ ]);
81
+ (0, chai_1.expect)(creditAccountWatcher_1.CreditAccountWatcher.detectChanges([log], [cmDumb])).to.be.eql({
82
+ updated: [expectedHash],
83
+ deleted: [],
84
+ });
85
+ log = makeLog(CREDIT_FACADE_ADDRESS, [
86
+ creditFacadeInterface.getEventTopic("TokenEnabled"),
87
+ encode("address", BORROWER),
88
+ encode("address", constants_1.DUMB_ADDRESS),
89
+ ]);
90
+ (0, chai_1.expect)(creditAccountWatcher_1.CreditAccountWatcher.detectChanges([log], [cmDumb])).to.be.eql({
91
+ updated: [expectedHash],
92
+ deleted: [],
93
+ });
94
+ log = makeLog(CREDIT_FACADE_ADDRESS, [
95
+ creditFacadeInterface.getEventTopic("TokenDisabled"),
96
+ encode("address", BORROWER),
97
+ encode("address", constants_1.DUMB_ADDRESS),
98
+ ]);
99
+ (0, chai_1.expect)(creditAccountWatcher_1.CreditAccountWatcher.detectChanges([log], [cmDumb])).to.be.eql({
100
+ updated: [expectedHash],
101
+ deleted: [],
102
+ });
103
+ log = makeLog(CREDIT_MANAGER_ADDRESS, [
104
+ creditManagerInterface.getEventTopic("ExecuteOrder"),
105
+ encode("address", BORROWER),
106
+ encode("address", constants_1.DUMB_ADDRESS),
107
+ ]);
108
+ (0, chai_1.expect)(creditAccountWatcher_1.CreditAccountWatcher.detectChanges([log], [cmDumb])).to.be.eql({
109
+ updated: [expectedHash],
110
+ deleted: [],
111
+ });
112
+ });
113
+ //
114
+ // DELETED
115
+ //
116
+ it("detects delete events correctly", function () {
117
+ (0, chai_1.expect)(creditAccountWatcher_1.CreditAccountWatcher.detectChanges([closeLog], [cmDumb])).to.be.eql({
118
+ updated: [],
119
+ deleted: [expectedHash],
120
+ });
121
+ var log = makeLog(CREDIT_FACADE_ADDRESS, [
122
+ creditFacadeInterface.getEventTopic("LiquidateCreditAccount"),
123
+ encode("address", BORROWER),
124
+ encode("address", constants_1.DUMB_ADDRESS),
125
+ encode("address", constants_1.DUMB_ADDRESS),
126
+ encode("address", constants_1.DUMB_ADDRESS),
127
+ ], ethers_1.utils.defaultAbiCoder.encode(["uint256"], [10]));
128
+ (0, chai_1.expect)(creditAccountWatcher_1.CreditAccountWatcher.detectChanges([log], [cmDumb])).to.be.eql({
129
+ updated: [],
130
+ deleted: [expectedHash],
131
+ });
132
+ log = makeLog(CREDIT_FACADE_ADDRESS, [
133
+ creditFacadeInterface.getEventTopic("LiquidateExpiredCreditAccount"),
134
+ encode("address", BORROWER),
135
+ encode("address", constants_1.DUMB_ADDRESS),
136
+ encode("address", constants_1.DUMB_ADDRESS),
137
+ encode("address", constants_1.DUMB_ADDRESS),
138
+ ], ethers_1.utils.defaultAbiCoder.encode(["uint256"], [10]));
139
+ (0, chai_1.expect)(creditAccountWatcher_1.CreditAccountWatcher.detectChanges([log], [cmDumb])).to.be.eql({
140
+ updated: [],
141
+ deleted: [expectedHash],
142
+ });
143
+ });
144
+ it("doesn't make duplicated", function () {
145
+ (0, chai_1.expect)(creditAccountWatcher_1.CreditAccountWatcher.detectChanges([openLog, openLog, openLog], [cmDumb])).to.be.eql({
146
+ updated: [expectedHash],
147
+ deleted: [],
148
+ });
149
+ (0, chai_1.expect)(creditAccountWatcher_1.CreditAccountWatcher.detectChanges([closeLog, closeLog, closeLog], [cmDumb])).to.be.eql({
150
+ updated: [],
151
+ deleted: [expectedHash],
152
+ });
153
+ });
154
+ it("updates accounts were created and deleted in the batch", function () {
155
+ (0, chai_1.expect)(creditAccountWatcher_1.CreditAccountWatcher.detectChanges([openLog, closeLog], [cmDumb])).to.be.eql({
156
+ updated: [],
157
+ deleted: [expectedHash],
158
+ });
159
+ (0, chai_1.expect)(creditAccountWatcher_1.CreditAccountWatcher.detectChanges([openLog, closeLog, openLog], [cmDumb])).to.be.eql({
160
+ updated: [expectedHash],
161
+ deleted: [expectedHash],
162
+ });
163
+ });
164
+ it("TransferAccount works correctly", function () {
165
+ var transferLog = makeLog(CREDIT_FACADE_ADDRESS, [
166
+ creditFacadeInterface.getEventTopic("TransferAccount"),
167
+ encode("address", BORROWER),
168
+ encode("address", constants_1.DUMB_ADDRESS),
169
+ ]);
170
+ (0, chai_1.expect)(creditAccountWatcher_1.CreditAccountWatcher.detectChanges([openLog, transferLog], [cmDumb])).to.be.eql({
171
+ updated: [
172
+ "".concat(CREDIT_MANAGER_ADDRESS.toLowerCase(), ":").concat(constants_1.DUMB_ADDRESS.toLowerCase()),
173
+ ],
174
+ deleted: [expectedHash],
175
+ });
176
+ });
177
+ });
@@ -0,0 +1,8 @@
1
+ import { providers, Signer } from "ethers";
2
+ import { CreditManagerData } from "../core/creditManager";
3
+ export declare class CreditManagerWatcher {
4
+ static creditManagerInterface: import("../types/contracts/interfaces/ICreditManagerV2.sol/ICreditManagerV2").ICreditManagerV2Interface;
5
+ static creditConfiguratorInterface: import("../types/contracts/interfaces/ICreditConfigurator.sol/ICreditConfigurator").ICreditConfiguratorInterface;
6
+ static getV2CreditManagers(dataCompressor: string, signer: Signer | providers.Provider, atBlock?: number): Promise<Record<string, CreditManagerData>>;
7
+ static detectConfigChanges(freshLogs: Array<providers.Log>, creditManagers: Array<CreditManagerData>): boolean;
8
+ }
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (_) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.CreditManagerWatcher = void 0;
40
+ var creditManager_1 = require("../core/creditManager");
41
+ var types_1 = require("../types");
42
+ var CreditManagerWatcher = /** @class */ (function () {
43
+ function CreditManagerWatcher() {
44
+ }
45
+ CreditManagerWatcher.getV2CreditManagers = function (dataCompressor, signer, atBlock) {
46
+ return __awaiter(this, void 0, void 0, function () {
47
+ var creditManagers, creditManagersPayload;
48
+ return __generator(this, function (_a) {
49
+ switch (_a.label) {
50
+ case 0:
51
+ creditManagers = {};
52
+ return [4 /*yield*/, types_1.IDataCompressor__factory.connect(dataCompressor, signer).getCreditManagersList({ blockTag: atBlock })];
53
+ case 1:
54
+ creditManagersPayload = _a.sent();
55
+ creditManagersPayload
56
+ .filter(function (c) { return c.version === 2; })
57
+ .forEach(function (c) {
58
+ creditManagers[c.addr.toLowerCase()] = new creditManager_1.CreditManagerData(c);
59
+ });
60
+ return [2 /*return*/, creditManagers];
61
+ }
62
+ });
63
+ });
64
+ };
65
+ CreditManagerWatcher.detectConfigChanges = function (freshLogs, creditManagers) {
66
+ var cms = creditManagers.map(function (c) { return c.address; });
67
+ var ccs = creditManagers.map(function (c) { return c.creditConfigurator; });
68
+ for (var _i = 0, freshLogs_1 = freshLogs; _i < freshLogs_1.length; _i++) {
69
+ var log = freshLogs_1[_i];
70
+ if (cms.includes(log.address.toLowerCase())) {
71
+ var name = CreditManagerWatcher.creditManagerInterface.parseLog(log).name;
72
+ if (name === "NewConfigurator") {
73
+ return true;
74
+ }
75
+ }
76
+ if (ccs.includes(log.address.toLowerCase())) {
77
+ return true;
78
+ }
79
+ }
80
+ return false;
81
+ };
82
+ CreditManagerWatcher.creditManagerInterface = types_1.ICreditManagerV2__factory.createInterface();
83
+ CreditManagerWatcher.creditConfiguratorInterface = types_1.ICreditConfigurator__factory.createInterface();
84
+ return CreditManagerWatcher;
85
+ }());
86
+ exports.CreditManagerWatcher = CreditManagerWatcher;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var chai_1 = require("chai");
4
+ var ethers_1 = require("ethers");
5
+ var constants_1 = require("../core/constants");
6
+ var types_1 = require("../types");
7
+ var creditManagerWatcher_1 = require("./creditManagerWatcher");
8
+ var CREDIT_MANAGER_ADDRESS = constants_1.DUMB_ADDRESS;
9
+ var CREDIT_CONFIGIURATOR_ADDRESS = "0xcb9a588a47dd0393af3d0d5f86e6f1c8fd252c48";
10
+ var cmDumb = {
11
+ address: CREDIT_MANAGER_ADDRESS.toLowerCase(),
12
+ creditConfigurator: CREDIT_CONFIGIURATOR_ADDRESS.toLowerCase(),
13
+ };
14
+ var encode = function (abiType, value) {
15
+ return ethers_1.utils.defaultAbiCoder.encode([abiType], [value]);
16
+ };
17
+ var makeLog = function (address, topics, data) {
18
+ if (data === void 0) { data = constants_1.ADDRESS_0X0; }
19
+ return {
20
+ blockNumber: 0,
21
+ blockHash: "",
22
+ transactionIndex: 0,
23
+ removed: false,
24
+ address: address,
25
+ data: data,
26
+ topics: topics,
27
+ transactionHash: "",
28
+ logIndex: 0,
29
+ };
30
+ };
31
+ describe("CreditManagerTracker test", function () {
32
+ it("detects CreditManager events correctly", function () {
33
+ var creditManagerInterface = types_1.ICreditManagerV2__factory.createInterface();
34
+ var log = makeLog(CREDIT_MANAGER_ADDRESS, [
35
+ creditManagerInterface.getEventTopic("NewConfigurator"),
36
+ encode("address", constants_1.DUMB_ADDRESS),
37
+ ]);
38
+ (0, chai_1.expect)(creditManagerWatcher_1.CreditManagerWatcher.detectConfigChanges([log], [cmDumb])).to.be.eq(true);
39
+ log = makeLog(CREDIT_MANAGER_ADDRESS, [
40
+ creditManagerInterface.getEventTopic("ExecuteOrder"),
41
+ encode("address", constants_1.DUMB_ADDRESS),
42
+ encode("address", constants_1.DUMB_ADDRESS),
43
+ ]);
44
+ (0, chai_1.expect)(creditManagerWatcher_1.CreditManagerWatcher.detectConfigChanges([log], [cmDumb])).to.be.eq(false);
45
+ });
46
+ it("detects CreditConfigurator events correctly", function () {
47
+ var ccInterface = types_1.ICreditConfigurator__factory.createInterface();
48
+ var log = makeLog(CREDIT_CONFIGIURATOR_ADDRESS, [
49
+ ccInterface.getEventTopic("TokenLiquidationThresholdUpdated"),
50
+ encode("address", constants_1.DUMB_ADDRESS),
51
+ ], encode("uint16", 122));
52
+ (0, chai_1.expect)(creditManagerWatcher_1.CreditManagerWatcher.detectConfigChanges([log], [cmDumb])).to.be.eq(true);
53
+ log = makeLog(CREDIT_CONFIGIURATOR_ADDRESS, [
54
+ ccInterface.getEventTopic("TokenAllowed"),
55
+ encode("address", constants_1.DUMB_ADDRESS),
56
+ ]);
57
+ (0, chai_1.expect)(creditManagerWatcher_1.CreditManagerWatcher.detectConfigChanges([log], [cmDumb])).to.be.eq(true);
58
+ log = makeLog(CREDIT_CONFIGIURATOR_ADDRESS, [
59
+ ccInterface.getEventTopic("TokenForbidden"),
60
+ encode("address", constants_1.DUMB_ADDRESS),
61
+ ]);
62
+ (0, chai_1.expect)(creditManagerWatcher_1.CreditManagerWatcher.detectConfigChanges([log], [cmDumb])).to.be.eq(true);
63
+ log = makeLog(CREDIT_CONFIGIURATOR_ADDRESS, [
64
+ ccInterface.getEventTopic("ContractAllowed"),
65
+ encode("address", constants_1.DUMB_ADDRESS),
66
+ encode("address", constants_1.DUMB_ADDRESS),
67
+ ]);
68
+ (0, chai_1.expect)(creditManagerWatcher_1.CreditManagerWatcher.detectConfigChanges([log], [cmDumb])).to.be.eq(true);
69
+ log = makeLog(CREDIT_CONFIGIURATOR_ADDRESS, [
70
+ ccInterface.getEventTopic("ContractForbidden"),
71
+ encode("address", constants_1.DUMB_ADDRESS),
72
+ ]);
73
+ (0, chai_1.expect)(creditManagerWatcher_1.CreditManagerWatcher.detectConfigChanges([log], [cmDumb])).to.be.eq(true);
74
+ log = makeLog(CREDIT_CONFIGIURATOR_ADDRESS, [ccInterface.getEventTopic("LimitsUpdated")], ethers_1.utils.defaultAbiCoder.encode(["uint256", "uint256"], [50, 200]));
75
+ (0, chai_1.expect)(creditManagerWatcher_1.CreditManagerWatcher.detectConfigChanges([log], [cmDumb])).to.be.eq(true);
76
+ log = makeLog(CREDIT_CONFIGIURATOR_ADDRESS, [ccInterface.getEventTopic("FeesUpdated")], ethers_1.utils.defaultAbiCoder.encode(["uint16", "uint16", "uint16", "uint16", "uint16"], [50, 50, 50, 50, 50]));
77
+ (0, chai_1.expect)(creditManagerWatcher_1.CreditManagerWatcher.detectConfigChanges([log], [cmDumb])).to.be.eq(true);
78
+ log = makeLog(CREDIT_CONFIGIURATOR_ADDRESS, [
79
+ ccInterface.getEventTopic("PriceOracleUpgraded"),
80
+ encode("address", constants_1.DUMB_ADDRESS),
81
+ ]);
82
+ (0, chai_1.expect)(creditManagerWatcher_1.CreditManagerWatcher.detectConfigChanges([log], [cmDumb])).to.be.eq(true);
83
+ log = makeLog(CREDIT_CONFIGIURATOR_ADDRESS, [
84
+ ccInterface.getEventTopic("CreditFacadeUpgraded"),
85
+ encode("address", constants_1.DUMB_ADDRESS),
86
+ ]);
87
+ (0, chai_1.expect)(creditManagerWatcher_1.CreditManagerWatcher.detectConfigChanges([log], [cmDumb])).to.be.eq(true);
88
+ log = makeLog(CREDIT_CONFIGIURATOR_ADDRESS, [
89
+ ccInterface.getEventTopic("CreditConfiguratorUpgraded"),
90
+ encode("address", constants_1.DUMB_ADDRESS),
91
+ ]);
92
+ (0, chai_1.expect)(creditManagerWatcher_1.CreditManagerWatcher.detectConfigChanges([log], [cmDumb])).to.be.eq(true);
93
+ log = makeLog(CREDIT_CONFIGIURATOR_ADDRESS, [ccInterface.getEventTopic("IncreaseDebtForbiddenModeChanged")], encode("bool", true));
94
+ (0, chai_1.expect)(creditManagerWatcher_1.CreditManagerWatcher.detectConfigChanges([log], [cmDumb])).to.be.eq(true);
95
+ log = makeLog(CREDIT_CONFIGIURATOR_ADDRESS, [ccInterface.getEventTopic("LimitPerBlockUpdated")], encode("uint128", 122));
96
+ (0, chai_1.expect)(creditManagerWatcher_1.CreditManagerWatcher.detectConfigChanges([log], [cmDumb])).to.be.eq(true);
97
+ log = makeLog(CREDIT_CONFIGIURATOR_ADDRESS, [ccInterface.getEventTopic("AddedToUpgradeable")], encode("address", constants_1.DUMB_ADDRESS));
98
+ (0, chai_1.expect)(creditManagerWatcher_1.CreditManagerWatcher.detectConfigChanges([log], [cmDumb])).to.be.eq(true);
99
+ log = makeLog(CREDIT_CONFIGIURATOR_ADDRESS, [ccInterface.getEventTopic("RemovedFromUpgradeable")], encode("address", constants_1.DUMB_ADDRESS));
100
+ (0, chai_1.expect)(creditManagerWatcher_1.CreditManagerWatcher.detectConfigChanges([log], [cmDumb])).to.be.eq(true);
101
+ log = makeLog(CREDIT_CONFIGIURATOR_ADDRESS, [ccInterface.getEventTopic("ExpirationDateUpdated")], encode("uint40", Math.floor(Date.now() / 1000)));
102
+ (0, chai_1.expect)(creditManagerWatcher_1.CreditManagerWatcher.detectConfigChanges([log], [cmDumb])).to.be.eq(true);
103
+ log = makeLog(CREDIT_CONFIGIURATOR_ADDRESS, [ccInterface.getEventTopic("MaxEnabledTokensUpdated")], encode("uint8", 14));
104
+ (0, chai_1.expect)(creditManagerWatcher_1.CreditManagerWatcher.detectConfigChanges([log], [cmDumb])).to.be.eq(true);
105
+ log = makeLog(CREDIT_CONFIGIURATOR_ADDRESS, [ccInterface.getEventTopic("EmergencyLiquidatorAdded")], encode("address", constants_1.DUMB_ADDRESS));
106
+ (0, chai_1.expect)(creditManagerWatcher_1.CreditManagerWatcher.detectConfigChanges([log], [cmDumb])).to.be.eq(true);
107
+ log = makeLog(CREDIT_CONFIGIURATOR_ADDRESS, [ccInterface.getEventTopic("EmergencyLiquidatorRemoved")], encode("address", constants_1.DUMB_ADDRESS));
108
+ (0, chai_1.expect)(creditManagerWatcher_1.CreditManagerWatcher.detectConfigChanges([log], [cmDumb])).to.be.eq(true);
109
+ });
110
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gearbox-protocol/sdk",
3
- "version": "1.6.6",
3
+ "version": "1.7.0",
4
4
  "description": "Gearbox SDK",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",