@lidofinance/lsv-cli 1.8.0 → 1.10.0-alpha.1

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 (86) hide show
  1. package/README.md +9 -1
  2. package/dist/abi/defi-wrapper/MellowStrategy.d.ts +429 -0
  3. package/dist/abi/defi-wrapper/MellowStrategy.js +892 -0
  4. package/dist/abi/defi-wrapper/MellowStrategy.js.map +1 -0
  5. package/dist/abi/defi-wrapper/index.d.ts +1 -0
  6. package/dist/abi/defi-wrapper/index.js +1 -0
  7. package/dist/abi/defi-wrapper/index.js.map +1 -1
  8. package/dist/configs/constants.d.ts +7 -1
  9. package/dist/features/consolidation.d.ts +2 -3
  10. package/dist/features/consolidation.js +60 -32
  11. package/dist/features/consolidation.js.map +1 -1
  12. package/dist/features/defi-wrapper/timelock.d.ts +8928 -2
  13. package/dist/features/defi-wrapper/timelock.js +82 -8
  14. package/dist/features/defi-wrapper/timelock.js.map +1 -1
  15. package/dist/programs/defi-wrapper/use-cases/timelock-governance/common/read.js +22 -4
  16. package/dist/programs/defi-wrapper/use-cases/timelock-governance/common/read.js.map +1 -1
  17. package/dist/programs/defi-wrapper/use-cases/timelock-governance/common/write.js +194 -16
  18. package/dist/programs/defi-wrapper/use-cases/timelock-governance/common/write.js.map +1 -1
  19. package/dist/programs/use-cases/consolidation/write.js +4 -4
  20. package/dist/programs/use-cases/consolidation/write.js.map +1 -1
  21. package/dist/programs/use-cases/metrics/read.js +4 -4
  22. package/dist/programs/use-cases/metrics/read.js.map +1 -1
  23. package/dist/programs/use-cases/report/read.js +4 -4
  24. package/dist/programs/use-cases/report/read.js.map +1 -1
  25. package/dist/providers/wallet.d.ts +2905 -8441
  26. package/dist/tests/fixtures/consolidation-fixtures.js +1 -0
  27. package/dist/tests/fixtures/consolidation-fixtures.js.map +1 -1
  28. package/dist/tests/integration/helpers/test-client.d.ts +2071 -5761
  29. package/dist/tests/utils/consolidation-fee-exemption-calc.test.d.ts +1 -0
  30. package/dist/tests/utils/consolidation-fee-exemption-calc.test.js +145 -0
  31. package/dist/tests/utils/consolidation-fee-exemption-calc.test.js.map +1 -0
  32. package/dist/tests/utils/consolidation-fee-exemption-confirm.test.d.ts +1 -0
  33. package/dist/tests/utils/consolidation-fee-exemption-confirm.test.js +118 -0
  34. package/dist/tests/utils/consolidation-fee-exemption-confirm.test.js.map +1 -0
  35. package/dist/tests/utils/consolidation-fee-exemption.test.d.ts +1 -0
  36. package/dist/tests/utils/consolidation-fee-exemption.test.js +168 -0
  37. package/dist/tests/utils/consolidation-fee-exemption.test.js.map +1 -0
  38. package/dist/tests/utils/first-validator-gindex.test.d.ts +1 -0
  39. package/dist/tests/utils/first-validator-gindex.test.js +48 -0
  40. package/dist/tests/utils/first-validator-gindex.test.js.map +1 -0
  41. package/dist/tests/utils/ipfs-security.test.js +130 -3
  42. package/dist/tests/utils/ipfs-security.test.js.map +1 -1
  43. package/dist/tests/utils/ipfs.test.js +40 -12
  44. package/dist/tests/utils/ipfs.test.js.map +1 -1
  45. package/dist/tests/utils/parse-abi-arguments.test.d.ts +1 -0
  46. package/dist/tests/utils/parse-abi-arguments.test.js +399 -0
  47. package/dist/tests/utils/parse-abi-arguments.test.js.map +1 -0
  48. package/dist/tests/utils/stream-helpers.d.ts +1 -0
  49. package/dist/tests/utils/stream-helpers.js +11 -0
  50. package/dist/tests/utils/stream-helpers.js.map +1 -0
  51. package/dist/utils/consolidation/confirms.js +19 -8
  52. package/dist/utils/consolidation/confirms.js.map +1 -1
  53. package/dist/utils/consolidation/fee-exemption.d.ts +19 -0
  54. package/dist/utils/consolidation/fee-exemption.js +70 -0
  55. package/dist/utils/consolidation/fee-exemption.js.map +1 -0
  56. package/dist/utils/consolidation/index.d.ts +1 -0
  57. package/dist/utils/consolidation/index.js +1 -0
  58. package/dist/utils/consolidation/index.js.map +1 -1
  59. package/dist/utils/consolidation/pubkeys.js +2 -0
  60. package/dist/utils/consolidation/pubkeys.js.map +1 -1
  61. package/dist/utils/consolidation/types.d.ts +1 -0
  62. package/dist/utils/consolidation/validator-info.d.ts +2 -1
  63. package/dist/utils/consolidation/validator-info.js +6 -0
  64. package/dist/utils/consolidation/validator-info.js.map +1 -1
  65. package/dist/utils/env.d.ts +1 -0
  66. package/dist/utils/env.js +8 -0
  67. package/dist/utils/env.js.map +1 -0
  68. package/dist/utils/ipfs.d.ts +10 -3
  69. package/dist/utils/ipfs.js +109 -27
  70. package/dist/utils/ipfs.js.map +1 -1
  71. package/dist/utils/parse-abi-arguments.d.ts +24 -0
  72. package/dist/utils/parse-abi-arguments.js +159 -0
  73. package/dist/utils/parse-abi-arguments.js.map +1 -0
  74. package/dist/utils/proof/constants.d.ts +1 -0
  75. package/dist/utils/proof/constants.js +1 -0
  76. package/dist/utils/proof/constants.js.map +1 -1
  77. package/dist/utils/proof/first-validator-gindex.js +27 -13
  78. package/dist/utils/proof/first-validator-gindex.js.map +1 -1
  79. package/dist/utils/proof/proofs.d.ts +1 -1
  80. package/dist/utils/proof/proofs.js +1 -1
  81. package/dist/utils/proof/proofs.js.map +1 -1
  82. package/dist/utils/rate-limit.d.ts +9 -0
  83. package/dist/utils/rate-limit.js +1 -6
  84. package/dist/utils/rate-limit.js.map +1 -1
  85. package/dist/version/index.js +1 -1
  86. package/package.json +20 -16
@@ -0,0 +1,399 @@
1
+ import { describe, test, expect } from 'vitest';
2
+ import { parseAbiArguments } from '../../utils/parse-abi-arguments.js';
3
+ const fn = (inputs) => ({
4
+ type: 'function',
5
+ name: 'test',
6
+ inputs,
7
+ outputs: [],
8
+ stateMutability: 'nonpayable',
9
+ });
10
+ const ADDR = '0x0000000000000000000000000000000000000001';
11
+ // --- parseAbiArguments (top-level) ---
12
+ describe('parseAbiArguments', () => {
13
+ test('throws on argument count mismatch (too few)', () => {
14
+ const abi = fn([{ name: 'a', type: 'uint256' }]);
15
+ expect(() => parseAbiArguments(abi, [])).toThrow(/argument count mismatch/i);
16
+ });
17
+ test('throws on argument count mismatch (too many)', () => {
18
+ const abi = fn([]);
19
+ expect(() => parseAbiArguments(abi, ['1'])).toThrow(/argument count mismatch/i);
20
+ });
21
+ test('returns empty array for zero-arg function', () => {
22
+ expect(parseAbiArguments(fn([]), [])).toEqual([]);
23
+ });
24
+ test('parses multiple inputs of different types', () => {
25
+ const abi = fn([
26
+ { name: 'to', type: 'address' },
27
+ { name: 'amount', type: 'uint256' },
28
+ { name: 'flag', type: 'bool' },
29
+ ]);
30
+ expect(parseAbiArguments(abi, [ADDR, '1000', 'true'])).toEqual([
31
+ ADDR,
32
+ 1000n,
33
+ true,
34
+ ]);
35
+ });
36
+ });
37
+ // --- address ---
38
+ describe('address', () => {
39
+ test('valid address passes through', () => {
40
+ const abi = fn([{ name: 'x', type: 'address' }]);
41
+ expect(parseAbiArguments(abi, [ADDR])).toEqual([ADDR]);
42
+ });
43
+ test('invalid address throws', () => {
44
+ const abi = fn([{ name: 'x', type: 'address' }]);
45
+ expect(() => parseAbiArguments(abi, ['0x123'])).toThrow(/invalid address/i);
46
+ });
47
+ test('non-hex string throws', () => {
48
+ const abi = fn([{ name: 'x', type: 'address' }]);
49
+ expect(() => parseAbiArguments(abi, ['notanaddress'])).toThrow();
50
+ });
51
+ });
52
+ // --- bool ---
53
+ describe('bool', () => {
54
+ test('"true" parses to boolean true', () => {
55
+ const abi = fn([{ name: 'x', type: 'bool' }]);
56
+ expect(parseAbiArguments(abi, ['true'])).toEqual([true]);
57
+ });
58
+ test('"false" parses to boolean false', () => {
59
+ const abi = fn([{ name: 'x', type: 'bool' }]);
60
+ expect(parseAbiArguments(abi, ['false'])).toEqual([false]);
61
+ });
62
+ test('invalid bool value throws', () => {
63
+ const abi = fn([{ name: 'x', type: 'bool' }]);
64
+ expect(() => parseAbiArguments(abi, ['yes'])).toThrow(/invalid bool/i);
65
+ });
66
+ test('"1" is not accepted as bool', () => {
67
+ const abi = fn([{ name: 'x', type: 'bool' }]);
68
+ expect(() => parseAbiArguments(abi, ['1'])).toThrow();
69
+ });
70
+ });
71
+ // --- uint / int ---
72
+ describe('uint / int', () => {
73
+ test('uint256: positive integer', () => {
74
+ const abi = fn([{ name: 'x', type: 'uint256' }]);
75
+ expect(parseAbiArguments(abi, ['42'])).toEqual([42n]);
76
+ });
77
+ test('uint256: zero is valid', () => {
78
+ const abi = fn([{ name: 'x', type: 'uint256' }]);
79
+ expect(parseAbiArguments(abi, ['0'])).toEqual([0n]);
80
+ });
81
+ test('uint256: large value stays precise', () => {
82
+ const abi = fn([{ name: 'x', type: 'uint256' }]);
83
+ const big = '1000000000000000000';
84
+ expect(parseAbiArguments(abi, [big])).toEqual([1000000000000000000n]);
85
+ });
86
+ test('uint256: negative value throws', () => {
87
+ const abi = fn([{ name: 'x', type: 'uint256' }]);
88
+ expect(() => parseAbiArguments(abi, ['-1'])).toThrow(/unsigned integer cannot be negative/i);
89
+ });
90
+ test('uint8: alias works (startsWith uint)', () => {
91
+ const abi = fn([{ name: 'x', type: 'uint8' }]);
92
+ expect(parseAbiArguments(abi, ['255'])).toEqual([255n]);
93
+ });
94
+ test('int256: negative value is valid', () => {
95
+ const abi = fn([{ name: 'x', type: 'int256' }]);
96
+ expect(parseAbiArguments(abi, ['-1000'])).toEqual([-1000n]);
97
+ });
98
+ test('int8: positive and negative', () => {
99
+ const abi = fn([{ name: 'x', type: 'int8' }]);
100
+ expect(parseAbiArguments(abi, ['-128'])).toEqual([-128n]);
101
+ });
102
+ test('non-numeric string throws', () => {
103
+ const abi = fn([{ name: 'x', type: 'uint256' }]);
104
+ expect(() => parseAbiArguments(abi, ['abc'])).toThrow();
105
+ });
106
+ });
107
+ // --- bytesN (fixed-size) ---
108
+ describe('bytesN', () => {
109
+ test('bytes32: correct-size hex passes', () => {
110
+ const value = `0x${'aa'.repeat(32)}`;
111
+ const abi = fn([{ name: 'x', type: 'bytes32' }]);
112
+ expect(parseAbiArguments(abi, [value])).toEqual([value]);
113
+ });
114
+ test('bytes1: single byte passes', () => {
115
+ const abi = fn([{ name: 'x', type: 'bytes1' }]);
116
+ expect(parseAbiArguments(abi, ['0xff'])).toEqual(['0xff']);
117
+ });
118
+ test('bytes32: wrong size throws', () => {
119
+ const abi = fn([{ name: 'x', type: 'bytes32' }]);
120
+ expect(() => parseAbiArguments(abi, ['0xdead'])).toThrow(/expected 32 bytes/i);
121
+ });
122
+ test('bytes32: non-hex throws', () => {
123
+ const abi = fn([{ name: 'x', type: 'bytes32' }]);
124
+ expect(() => parseAbiArguments(abi, ['notahex'])).toThrow(/invalid hex/i);
125
+ });
126
+ test('bytes4: correct size', () => {
127
+ const abi = fn([{ name: 'x', type: 'bytes4' }]);
128
+ expect(parseAbiArguments(abi, ['0xdeadbeef'])).toEqual(['0xdeadbeef']);
129
+ });
130
+ });
131
+ // --- bytes (dynamic) ---
132
+ describe('bytes', () => {
133
+ test('valid hex passes', () => {
134
+ const abi = fn([{ name: 'x', type: 'bytes' }]);
135
+ expect(parseAbiArguments(abi, ['0xdeadbeef'])).toEqual(['0xdeadbeef']);
136
+ });
137
+ test('empty bytes (0x) is valid', () => {
138
+ const abi = fn([{ name: 'x', type: 'bytes' }]);
139
+ expect(parseAbiArguments(abi, ['0x'])).toEqual(['0x']);
140
+ });
141
+ test('non-hex string throws', () => {
142
+ const abi = fn([{ name: 'x', type: 'bytes' }]);
143
+ expect(() => parseAbiArguments(abi, ['hello'])).toThrow(/invalid hex/i);
144
+ });
145
+ });
146
+ // --- string ---
147
+ describe('string', () => {
148
+ test('any string passes through unchanged', () => {
149
+ const abi = fn([{ name: 'x', type: 'string' }]);
150
+ expect(parseAbiArguments(abi, ['hello world'])).toEqual(['hello world']);
151
+ });
152
+ test('empty string is valid', () => {
153
+ const abi = fn([{ name: 'x', type: 'string' }]);
154
+ expect(parseAbiArguments(abi, [''])).toEqual(['']);
155
+ });
156
+ });
157
+ // --- fixed-size arrays ---
158
+ describe('fixed-size array', () => {
159
+ test('uint256[3]: correct elements parsed as bigints', () => {
160
+ const abi = fn([{ name: 'x', type: 'uint256[3]' }]);
161
+ expect(parseAbiArguments(abi, ['[1,2,3]'])).toEqual([[1n, 2n, 3n]]);
162
+ });
163
+ test('uint256[3]: wrong length throws', () => {
164
+ const abi = fn([{ name: 'x', type: 'uint256[3]' }]);
165
+ expect(() => parseAbiArguments(abi, ['[1,2]'])).toThrow(/length/i);
166
+ });
167
+ test('address[2]: elements parsed as addresses', () => {
168
+ const abi = fn([{ name: 'x', type: 'address[2]' }]);
169
+ expect(parseAbiArguments(abi, [
170
+ `[${JSON.stringify(ADDR)},${JSON.stringify(ADDR)}]`,
171
+ ])).toEqual([[ADDR, ADDR]]);
172
+ });
173
+ test('bool[2]: elements parsed as booleans', () => {
174
+ const abi = fn([{ name: 'x', type: 'bool[2]' }]);
175
+ expect(parseAbiArguments(abi, ['[true,false]'])).toEqual([[true, false]]);
176
+ });
177
+ // Acceptance test — exposes String([]) bug
178
+ test('uint256[2][2]: nested fixed array parsed correctly', () => {
179
+ const abi = fn([{ name: 'x', type: 'uint256[2][2]' }]);
180
+ expect(parseAbiArguments(abi, ['[[1,2],[3,4]]'])).toEqual([
181
+ [
182
+ [1n, 2n],
183
+ [3n, 4n],
184
+ ],
185
+ ]);
186
+ });
187
+ test('non-array JSON value throws (line 78)', () => {
188
+ const abi = fn([{ name: 'x', type: 'uint256[3]' }]);
189
+ expect(() => parseAbiArguments(abi, ['42'])).toThrow(/expected a json array/i);
190
+ });
191
+ });
192
+ // --- dynamic arrays ---
193
+ describe('dynamic array', () => {
194
+ test('uint256[]: empty array', () => {
195
+ const abi = fn([{ name: 'x', type: 'uint256[]' }]);
196
+ expect(parseAbiArguments(abi, ['[]'])).toEqual([[]]);
197
+ });
198
+ test('uint256[]: multiple elements', () => {
199
+ const abi = fn([{ name: 'x', type: 'uint256[]' }]);
200
+ expect(parseAbiArguments(abi, ['[10,20,30]'])).toEqual([[10n, 20n, 30n]]);
201
+ });
202
+ test('address[]: array of addresses', () => {
203
+ const abi = fn([{ name: 'x', type: 'address[]' }]);
204
+ expect(parseAbiArguments(abi, [`[${JSON.stringify(ADDR)}]`])).toEqual([
205
+ [ADDR],
206
+ ]);
207
+ });
208
+ test('string[]: array of strings', () => {
209
+ const abi = fn([{ name: 'x', type: 'string[]' }]);
210
+ expect(parseAbiArguments(abi, ['["foo","bar"]'])).toEqual([['foo', 'bar']]);
211
+ });
212
+ test('non-array JSON value throws (line 101)', () => {
213
+ const abi = fn([{ name: 'x', type: 'uint256[]' }]);
214
+ expect(() => parseAbiArguments(abi, ['"notanarray"'])).toThrow(/expected a json array/i);
215
+ });
216
+ // Acceptance test — exposes String([]) bug
217
+ test('uint256[][]: nested dynamic array parsed correctly', () => {
218
+ const abi = fn([{ name: 'x', type: 'uint256[][]' }]);
219
+ expect(parseAbiArguments(abi, ['[[1,2],[3,4,5]]'])).toEqual([
220
+ [
221
+ [1n, 2n],
222
+ [3n, 4n, 5n],
223
+ ],
224
+ ]);
225
+ });
226
+ // Acceptance test — exposes String([]) bug
227
+ test('uint256[2][]: mixed fixed/dynamic nested array', () => {
228
+ const abi = fn([{ name: 'x', type: 'uint256[2][]' }]);
229
+ expect(parseAbiArguments(abi, ['[[1,2],[3,4]]'])).toEqual([
230
+ [
231
+ [1n, 2n],
232
+ [3n, 4n],
233
+ ],
234
+ ]);
235
+ });
236
+ });
237
+ // --- tuple ---
238
+ describe('tuple (struct)', () => {
239
+ const tupleParam = {
240
+ name: 'data',
241
+ type: 'tuple',
242
+ components: [
243
+ { name: 'addr', type: 'address' },
244
+ { name: 'amount', type: 'uint256' },
245
+ { name: 'flag', type: 'bool' },
246
+ ],
247
+ };
248
+ test('object representation: all fields parsed', () => {
249
+ const abi = fn([tupleParam]);
250
+ const input = JSON.stringify({ addr: ADDR, amount: '999', flag: 'true' });
251
+ expect(parseAbiArguments(abi, [input])).toEqual([
252
+ { addr: ADDR, amount: 999n, flag: true },
253
+ ]);
254
+ });
255
+ test('array representation: positional fields parsed', () => {
256
+ const abi = fn([tupleParam]);
257
+ const input = JSON.stringify([ADDR, '50', 'false']);
258
+ expect(parseAbiArguments(abi, [input])).toEqual([
259
+ { addr: ADDR, amount: 50n, flag: false },
260
+ ]);
261
+ });
262
+ test('array representation: wrong field count throws', () => {
263
+ const abi = fn([tupleParam]);
264
+ expect(() => parseAbiArguments(abi, [`[${JSON.stringify(ADDR)}]`])).toThrow(/expects.*fields/i);
265
+ });
266
+ test('object representation: missing field throws', () => {
267
+ const abi = fn([tupleParam]);
268
+ const input = JSON.stringify({ addr: ADDR, amount: '1' });
269
+ expect(() => parseAbiArguments(abi, [input])).toThrow(/missing field/i);
270
+ });
271
+ test('invalid JSON throws', () => {
272
+ const abi = fn([tupleParam]);
273
+ expect(() => parseAbiArguments(abi, ['{not json'])).toThrow(/invalid json/i);
274
+ });
275
+ test('non-array non-object value throws', () => {
276
+ const abi = fn([tupleParam]);
277
+ expect(() => parseAbiArguments(abi, ['42'])).toThrow(/expected json object or array/i);
278
+ });
279
+ test('array representation with unnamed component uses numeric index key (line 140)', () => {
280
+ const param = {
281
+ name: 'data',
282
+ type: 'tuple',
283
+ components: [{ type: 'uint256' }, { type: 'bool' }],
284
+ };
285
+ const abi = fn([param]);
286
+ // Component has no name — array form should use index as key
287
+ expect(parseAbiArguments(abi, ['[42, true]'])).toEqual([
288
+ { 0: 42n, 1: true },
289
+ ]);
290
+ });
291
+ test('tuple with no components throws', () => {
292
+ const bare = { name: 'x', type: 'tuple' };
293
+ const abi = fn([bare]);
294
+ expect(() => parseAbiArguments(abi, ['{}'])).toThrow(/no components/i);
295
+ });
296
+ test('tuple component with no name throws when using object form (line 153)', () => {
297
+ const param = {
298
+ name: 'data',
299
+ type: 'tuple',
300
+ components: [{ type: 'uint256' }],
301
+ };
302
+ const abi = fn([param]);
303
+ expect(() => parseAbiArguments(abi, ['{"": 1}'])).toThrow(/tuple component has no name/i);
304
+ });
305
+ // Acceptance test — exposes String({}) bug
306
+ test('tuple[]: array of tuples parsed correctly', () => {
307
+ const param = {
308
+ name: 'items',
309
+ type: 'tuple[]',
310
+ components: [
311
+ { name: 'id', type: 'uint256' },
312
+ { name: 'owner', type: 'address' },
313
+ ],
314
+ };
315
+ const abi = fn([param]);
316
+ const input = JSON.stringify([
317
+ { id: '1', owner: ADDR },
318
+ { id: '2', owner: ADDR },
319
+ ]);
320
+ expect(parseAbiArguments(abi, [input])).toEqual([
321
+ [
322
+ { id: 1n, owner: ADDR },
323
+ { id: 2n, owner: ADDR },
324
+ ],
325
+ ]);
326
+ });
327
+ // Acceptance test — exposes String({}) bug on nested tuple
328
+ test('nested tuple (tuple within tuple) parsed correctly', () => {
329
+ const param = {
330
+ name: 'outer',
331
+ type: 'tuple',
332
+ components: [
333
+ { name: 'value', type: 'uint256' },
334
+ {
335
+ name: 'inner',
336
+ type: 'tuple',
337
+ components: [
338
+ { name: 'x', type: 'uint256' },
339
+ { name: 'y', type: 'uint256' },
340
+ ],
341
+ },
342
+ ],
343
+ };
344
+ const abi = fn([param]);
345
+ const input = JSON.stringify({ value: '10', inner: { x: '1', y: '2' } });
346
+ expect(parseAbiArguments(abi, [input])).toEqual([
347
+ { value: 10n, inner: { x: 1n, y: 2n } },
348
+ ]);
349
+ });
350
+ });
351
+ // --- unsupported type ---
352
+ describe('unsupported type', () => {
353
+ test('unknown type throws', () => {
354
+ const abi = fn([{ name: 'x', type: 'function' }]);
355
+ expect(() => parseAbiArguments(abi, ['0x'])).toThrow(/unsupported abi type/i);
356
+ });
357
+ });
358
+ // --- error message format ---
359
+ describe('error message wrapping', () => {
360
+ test('error includes param name and type', () => {
361
+ const abi = fn([{ name: 'myParam', type: 'uint256' }]);
362
+ let caught;
363
+ try {
364
+ parseAbiArguments(abi, ['notanumber']);
365
+ }
366
+ catch (e) {
367
+ caught = e;
368
+ }
369
+ expect(caught?.message).toMatch(/param.*myParam/i);
370
+ expect(caught?.message).toMatch(/type.*uint256/i);
371
+ });
372
+ test('unnamed param falls back to <unnamed> in error message (line 179)', () => {
373
+ // Directly exercise the unnamed-param branch by passing a nameless input
374
+ const abi = {
375
+ type: 'function',
376
+ name: 'test',
377
+ inputs: [{ type: 'uint256' }],
378
+ outputs: [],
379
+ stateMutability: 'nonpayable',
380
+ };
381
+ expect(() => parseAbiArguments(abi, ['abc'])).toThrow(/<unnamed>/);
382
+ });
383
+ test('already-wrapped error is re-thrown without double-wrapping (line 182)', () => {
384
+ // uint256[][] with an invalid leaf value: the innermost error gets wrapped once,
385
+ // then re-thrown (not re-wrapped) by each outer level.
386
+ const abi = fn([{ name: 'x', type: 'uint256[][]' }]);
387
+ let caught;
388
+ try {
389
+ parseAbiArguments(abi, ['[["abc"]]']);
390
+ }
391
+ catch (e) {
392
+ caught = e;
393
+ }
394
+ // Should contain exactly one [param: block, not nested duplicates
395
+ const matches = caught?.message.match(/\[param:/g);
396
+ expect(matches).toHaveLength(1);
397
+ });
398
+ });
399
+ //# sourceMappingURL=parse-abi-arguments.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-abi-arguments.test.js","sourceRoot":"","sources":["../../../tests/utils/parse-abi-arguments.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare const streamOf: (bytes: Uint8Array, chunkSize?: number) => ReadableStream<Uint8Array<ArrayBufferLike>>;
@@ -0,0 +1,11 @@
1
+ // Build a ReadableStream response body from bytes, chunked so tests exercise
2
+ // multi-read streaming. Default chunk keeps small payloads a single read.
3
+ export const streamOf = (bytes, chunkSize = 64 * 1024) => new ReadableStream({
4
+ start(controller) {
5
+ for (let i = 0; i < bytes.length; i += chunkSize) {
6
+ controller.enqueue(bytes.slice(i, i + chunkSize));
7
+ }
8
+ controller.close();
9
+ },
10
+ });
11
+ //# sourceMappingURL=stream-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-helpers.js","sourceRoot":"","sources":["../../../tests/utils/stream-helpers.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,0EAA0E;AAC1E,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAiB,EAAE,SAAS,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,CACnE,IAAI,cAAc,CAAa;IAC7B,KAAK,CAAC,UAAU;QACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;YACjD,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;QACpD,CAAC;QACD,UAAU,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;CACF,CAAC,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { formatEther } from 'viem';
2
- import { logCancel, confirmOperation } from '../index.js';
2
+ import { logCancel, logError, confirmOperation } from '../index.js';
3
+ import { consolidatedBalance } from './validator-info.js';
3
4
  export const confirmToConsolidate = async (targetAndSourceValidators, dashboard) => {
4
5
  const lines = [
5
6
  'Are you sure you want to consolidate the following validators?\n',
@@ -18,16 +19,26 @@ export const confirmToConsolidate = async (targetAndSourceValidators, dashboard)
18
19
  };
19
20
  export const calculateAndConfirmFeeExemption = async (targetAndSourceValidators) => {
20
21
  let feeExemption = 0n;
21
- for (const [, { sourceValidators }] of targetAndSourceValidators) {
22
+ for (const [target, { sourceValidators }] of targetAndSourceValidators) {
22
23
  for (const [source, sourceValidatorInfo] of sourceValidators) {
23
24
  if (sourceValidatorInfo.status === 'active_ongoing') {
24
- feeExemption += sourceValidatorInfo.effectiveBalance;
25
+ feeExemption += consolidatedBalance(sourceValidatorInfo);
26
+ continue;
27
+ }
28
+ // a slashed source is skipped by the consensus layer, so nothing reaches the vault
29
+ if (sourceValidatorInfo.slashed) {
30
+ logError(`Validator ${source} is slashed: its balance will not reach the vault, so it is not exempted.`);
31
+ continue;
25
32
  }
26
- else {
27
- const confirm = await confirmOperation(`Validator with this pubkey ${source} is not in active state. Should we consider its balance for fee exemption?`);
28
- if (confirm) {
29
- feeExemption += sourceValidatorInfo.effectiveBalance;
30
- }
33
+ // an exit epoch is set both by an accepted consolidation request and by a
34
+ // voluntary/triggered exit, and the two need opposite answers here only the
35
+ // operator knows which one applies, so ask instead of guessing
36
+ const confirm = await confirmOperation(`Validator ${source} is not active (status: ${sourceValidatorInfo.status}), balance ${formatEther(sourceValidatorInfo.balance)} ETH.
37
+ Answer yes only if its consolidation into ${target} was already requested — then that balance still reaches the vault and needs the exemption.
38
+ Answer no if it is exiting for any other reason — then the balance goes to its own withdrawal credentials and must not be exempted.
39
+ Count this validator towards the fee exemption?`);
40
+ if (confirm) {
41
+ feeExemption += consolidatedBalance(sourceValidatorInfo);
31
42
  }
32
43
  }
33
44
  }
@@ -1 +1 @@
1
- {"version":3,"file":"confirms.js","sourceRoot":"","sources":["../../../utils/consolidation/confirms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,WAAW,EAAE,MAAM,MAAM,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAIpD,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EACvC,yBAAoD,EACpD,SAAkB,EACH,EAAE;IACjB,MAAM,KAAK,GAAa;QACtB,kEAAkE;KACnE,CAAC;IACF,KAAK,MAAM,CAAC,MAAM,EAAE,EAAE,gBAAgB,EAAE,CAAC,IAAI,yBAAyB,EAAE,CAAC;QACvE,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,gBAAgB,EAAE,CAAC;YACxC,KAAK,CAAC,IAAI,CAAC,WAAW,MAAM,aAAa,MAAM,IAAI,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,cAAc,SAAS,EAAE,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAEzD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,SAAS,CAAC,4CAA4C,CAAC,CAAC;QAExD,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,+BAA+B,GAAG,KAAK,EAClD,yBAAoD,EACnC,EAAE;IACnB,IAAI,YAAY,GAAG,EAAE,CAAC;IAEtB,KAAK,MAAM,CAAC,EAAE,EAAE,gBAAgB,EAAE,CAAC,IAAI,yBAAyB,EAAE,CAAC;QACjE,KAAK,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,IAAI,gBAAgB,EAAE,CAAC;YAC7D,IAAI,mBAAmB,CAAC,MAAM,KAAK,gBAAgB,EAAE,CAAC;gBACpD,YAAY,IAAI,mBAAmB,CAAC,gBAAgB,CAAC;YACvD,CAAC;iBAAM,CAAC;gBACN,MAAM,OAAO,GAAG,MAAM,gBAAgB,CACpC,8BAA8B,MAAM,4EAA4E,CACjH,CAAC;gBACF,IAAI,OAAO,EAAE,CAAC;oBACZ,YAAY,IAAI,mBAAmB,CAAC,gBAAgB,CAAC;gBACvD,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,mBAAmB,GAAG,MAAM,gBAAgB,CAChD,kBAAkB,WAAW,CAAC,YAAY,CAAC,iBAAiB,CAC7D,CAAC;IAEF,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACzB,SAAS,CAAC,2CAA2C,CAAC,CAAC;QAEvD,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC,CAAC"}
1
+ {"version":3,"file":"confirms.js","sourceRoot":"","sources":["../../../utils/consolidation/confirms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,WAAW,EAAE,MAAM,MAAM,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAG9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EACvC,yBAAoD,EACpD,SAAkB,EACH,EAAE;IACjB,MAAM,KAAK,GAAa;QACtB,kEAAkE;KACnE,CAAC;IACF,KAAK,MAAM,CAAC,MAAM,EAAE,EAAE,gBAAgB,EAAE,CAAC,IAAI,yBAAyB,EAAE,CAAC;QACvE,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,gBAAgB,EAAE,CAAC;YACxC,KAAK,CAAC,IAAI,CAAC,WAAW,MAAM,aAAa,MAAM,IAAI,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,cAAc,SAAS,EAAE,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAEzD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,SAAS,CAAC,4CAA4C,CAAC,CAAC;QAExD,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,+BAA+B,GAAG,KAAK,EAClD,yBAAoD,EACnC,EAAE;IACnB,IAAI,YAAY,GAAG,EAAE,CAAC;IAEtB,KAAK,MAAM,CAAC,MAAM,EAAE,EAAE,gBAAgB,EAAE,CAAC,IAAI,yBAAyB,EAAE,CAAC;QACvE,KAAK,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,IAAI,gBAAgB,EAAE,CAAC;YAC7D,IAAI,mBAAmB,CAAC,MAAM,KAAK,gBAAgB,EAAE,CAAC;gBACpD,YAAY,IAAI,mBAAmB,CAAC,mBAAmB,CAAC,CAAC;gBACzD,SAAS;YACX,CAAC;YAED,mFAAmF;YACnF,IAAI,mBAAmB,CAAC,OAAO,EAAE,CAAC;gBAChC,QAAQ,CACN,aAAa,MAAM,2EAA2E,CAC/F,CAAC;gBACF,SAAS;YACX,CAAC;YAED,0EAA0E;YAC1E,8EAA8E;YAC9E,+DAA+D;YAC/D,MAAM,OAAO,GAAG,MAAM,gBAAgB,CACpC,aAAa,MAAM,2BAA2B,mBAAmB,CAAC,MAAM,cAAc,WAAW,CAAC,mBAAmB,CAAC,OAAO,CAAC;gDACtF,MAAM;;oDAEF,CAC7C,CAAC;YACF,IAAI,OAAO,EAAE,CAAC;gBACZ,YAAY,IAAI,mBAAmB,CAAC,mBAAmB,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,mBAAmB,GAAG,MAAM,gBAAgB,CAChD,kBAAkB,WAAW,CAAC,YAAY,CAAC,iBAAiB,CAC7D,CAAC;IAEF,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACzB,SAAS,CAAC,2CAA2C,CAAC,CAAC;QAEvD,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { Address, Hex } from 'viem';
2
+ export declare const FEE_EXEMPTION_DUPLICATE_LOOKBACK_SEC: bigint;
3
+ export type SettledGrowthSetLog = {
4
+ transactionHash: Hex;
5
+ blockNumber: bigint;
6
+ args: {
7
+ oldSettledGrowth: bigint;
8
+ newSettledGrowth: bigint;
9
+ };
10
+ };
11
+ export type FeeExemptionMatch = {
12
+ txHash: Hex;
13
+ blockNumber: bigint;
14
+ delta: bigint;
15
+ timestamp: bigint;
16
+ };
17
+ export declare const matchFeeExemptionLogs: (settledGrowthLogs: SettledGrowthSetLog[], correctionTxHashes: Set<Hex>, amount: bigint) => Omit<FeeExemptionMatch, "timestamp">[];
18
+ export declare const formatFeeExemptionMatch: (match: FeeExemptionMatch) => string;
19
+ export declare const findRecentFeeExemptions: (dashboard: Address, amount: bigint, lookbackSec?: bigint) => Promise<FeeExemptionMatch[]>;
@@ -0,0 +1,70 @@
1
+ import { formatEther } from 'viem';
2
+ import { getPublicClient } from '../../providers/index.js';
3
+ import { DashboardAbi } from '../../abi/index.js';
4
+ import { bigIntMax, bigIntMin } from '../big-int.js';
5
+ const AVG_BLOCK_TIME_SEC = 12n;
6
+ // providers commonly cap eth_getLogs at 10k blocks
7
+ const MAX_LOG_RANGE_BLOCKS = 10000n;
8
+ // retries happen within hours; a wider window matches the previous batch's
9
+ // exemption instead, since batch amounts are round and repeat
10
+ export const FEE_EXEMPTION_DUPLICATE_LOOKBACK_SEC = 24n * 60n * 60n; // 24 hours
11
+ // disburseFee also emits SettledGrowthSet; only corrections emit CorrectionTimestampUpdated
12
+ export const matchFeeExemptionLogs = (settledGrowthLogs, correctionTxHashes, amount) => settledGrowthLogs
13
+ .filter((log) => correctionTxHashes.has(log.transactionHash))
14
+ .map((log) => ({
15
+ txHash: log.transactionHash,
16
+ blockNumber: log.blockNumber,
17
+ delta: log.args.newSettledGrowth - log.args.oldSettledGrowth,
18
+ }))
19
+ .filter((match) => match.delta === amount);
20
+ // viem does not validate log envelope fields at runtime
21
+ export const formatFeeExemptionMatch = (match) => {
22
+ const txHash = /^0x[0-9a-fA-F]{64}$/.test(match.txHash)
23
+ ? match.txHash
24
+ : '<invalid tx hash from RPC>';
25
+ const timestampMs = Number(match.timestamp) * 1000;
26
+ const at = Number.isSafeInteger(timestampMs)
27
+ ? new Date(timestampMs).toISOString()
28
+ : '<invalid timestamp from RPC>';
29
+ return `${formatEther(match.delta)} ETH in tx ${txHash} at ${at}`;
30
+ };
31
+ export const findRecentFeeExemptions = async (dashboard, amount, lookbackSec = FEE_EXEMPTION_DUPLICATE_LOOKBACK_SEC) => {
32
+ const publicClient = await getPublicClient();
33
+ const currentBlock = await publicClient.getBlockNumber();
34
+ const lookbackBlocks = lookbackSec / AVG_BLOCK_TIME_SEC;
35
+ const fromBlock = bigIntMax(currentBlock - lookbackBlocks, 0n);
36
+ const settledGrowthLogs = [];
37
+ const correctionLogs = [];
38
+ for (let chunkStart = fromBlock; chunkStart <= currentBlock; chunkStart += MAX_LOG_RANGE_BLOCKS) {
39
+ const toBlock = bigIntMin(chunkStart + MAX_LOG_RANGE_BLOCKS - 1n, currentBlock);
40
+ const [chunkSettledGrowthLogs, chunkCorrectionLogs] = await Promise.all([
41
+ publicClient.getContractEvents({
42
+ address: dashboard,
43
+ abi: DashboardAbi,
44
+ eventName: 'SettledGrowthSet',
45
+ fromBlock: chunkStart,
46
+ toBlock,
47
+ strict: true,
48
+ }),
49
+ publicClient.getContractEvents({
50
+ address: dashboard,
51
+ abi: DashboardAbi,
52
+ eventName: 'CorrectionTimestampUpdated',
53
+ fromBlock: chunkStart,
54
+ toBlock,
55
+ strict: true,
56
+ }),
57
+ ]);
58
+ settledGrowthLogs.push(...chunkSettledGrowthLogs);
59
+ correctionLogs.push(...chunkCorrectionLogs);
60
+ }
61
+ const correctionTxHashes = new Set(correctionLogs.map((log) => log.transactionHash));
62
+ const matches = matchFeeExemptionLogs(settledGrowthLogs, correctionTxHashes, amount);
63
+ return Promise.all(matches.map(async (match) => {
64
+ const block = await publicClient.getBlock({
65
+ blockNumber: match.blockNumber,
66
+ });
67
+ return { ...match, timestamp: block.timestamp };
68
+ }));
69
+ };
70
+ //# sourceMappingURL=fee-exemption.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fee-exemption.js","sourceRoot":"","sources":["../../../utils/consolidation/fee-exemption.ts"],"names":[],"mappings":"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"}
@@ -3,4 +3,5 @@ export * from './validators-checks.js';
3
3
  export * from './validator-info.js';
4
4
  export * from './logs.js';
5
5
  export * from './confirms.js';
6
+ export * from './fee-exemption.js';
6
7
  export * from './pubkeys.js';
@@ -3,5 +3,6 @@ export * from './validators-checks.js';
3
3
  export * from './validator-info.js';
4
4
  export * from './logs.js';
5
5
  export * from './confirms.js';
6
+ export * from './fee-exemption.js';
6
7
  export * from './pubkeys.js';
7
8
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../utils/consolidation/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../utils/consolidation/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AACpC,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,cAAc,CAAC"}
@@ -25,6 +25,7 @@ export const addDummyTargetAndSourceValidator = (targetAndSourceValidators, feeE
25
25
  balance: feeExemption,
26
26
  index: '0',
27
27
  effectiveBalance: feeExemption,
28
+ slashed: false,
28
29
  },
29
30
  sourceValidators: new Map([
30
31
  [
@@ -34,6 +35,7 @@ export const addDummyTargetAndSourceValidator = (targetAndSourceValidators, feeE
34
35
  balance: feeExemption,
35
36
  index: '0',
36
37
  effectiveBalance: feeExemption,
38
+ slashed: false,
37
39
  },
38
40
  ],
39
41
  ]),