@glowlabs-org/utils 0.1.3 → 0.1.5
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.
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.js +118 -34
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/lib/create-weekly-report/index.d.ts +3 -2
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +118 -35
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/create-weekly-report/index.d.ts +3 -2
- package/package.json +3 -2
- package/src/index.ts +4 -1
- package/src/lib/create-weekly-report/index.ts +150 -52
@@ -14,7 +14,7 @@ export type CreateWeeklyReportArgs = {
|
|
14
14
|
gcaUrls: string[];
|
15
15
|
apiUrl: string;
|
16
16
|
};
|
17
|
-
export declare function
|
17
|
+
export declare function createWeeklyReportLegacy(args: CreateWeeklyReportArgs): Promise<{
|
18
18
|
headlineStats: {
|
19
19
|
weekNumber: number;
|
20
20
|
totalCreditsProduced: string;
|
@@ -36,7 +36,8 @@ export declare function createWeeklyReport({ week, gcaUrls, apiUrl, }: CreateWee
|
|
36
36
|
}[];
|
37
37
|
farms: import("./types").Farm[];
|
38
38
|
rawData: import("./types").GCAServerResponse;
|
39
|
-
}
|
39
|
+
}>;
|
40
|
+
export declare function createWeeklyReport({ week, gcaUrls, apiUrl, }: CreateWeeklyReportArgs): Promise<{
|
40
41
|
headlineStats: {
|
41
42
|
weekNumber: number;
|
42
43
|
totalCreditsProduced: string;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@glowlabs-org/utils",
|
3
|
-
"version": "0.1.
|
3
|
+
"version": "0.1.5",
|
4
4
|
"description": "A library containing all typechain types and addresses relating to the glow guarded launch",
|
5
5
|
"keywords": [],
|
6
6
|
"author": "",
|
@@ -42,6 +42,7 @@
|
|
42
42
|
},
|
43
43
|
"scripts": {
|
44
44
|
"test": "echo \"Error: no test specified\" && exit 1",
|
45
|
-
"build": "rollup -c"
|
45
|
+
"build": "rollup -c",
|
46
|
+
"start": "ts-node scripts/index.ts"
|
46
47
|
}
|
47
48
|
}
|
package/src/index.ts
CHANGED
@@ -1,3 +1,6 @@
|
|
1
1
|
export * from "./lib/create-weekly-report/types/index";
|
2
2
|
export * from "./constants/index";
|
3
|
-
export {
|
3
|
+
export {
|
4
|
+
createWeeklyReport,
|
5
|
+
createWeeklyReportLegacy,
|
6
|
+
} from "./lib/create-weekly-report/index";
|
@@ -39,7 +39,7 @@ export type CreateWeeklyReportArgs = {
|
|
39
39
|
apiUrl: string;
|
40
40
|
};
|
41
41
|
|
42
|
-
async function createWeeklyReportLegacy(args: CreateWeeklyReportArgs) {
|
42
|
+
export async function createWeeklyReportLegacy(args: CreateWeeklyReportArgs) {
|
43
43
|
const mapLegacy = new Map<string, MerkleLeafIntermediary>();
|
44
44
|
|
45
45
|
function addValueToMapLegacy(
|
@@ -149,11 +149,6 @@ async function createWeeklyReportLegacy(args: CreateWeeklyReportArgs) {
|
|
149
149
|
usdgWeight <= 0 &&
|
150
150
|
rewardSplit.usdgSplitPercent > 0
|
151
151
|
) {
|
152
|
-
console.log(
|
153
|
-
farm.carbonCreditsProduced,
|
154
|
-
usdgWeight,
|
155
|
-
rewardSplit.usdgSplitPercent
|
156
|
-
);
|
157
152
|
throw new Error(
|
158
153
|
"USDG weight is less than 0 and carbon credits produced is greater than 0"
|
159
154
|
);
|
@@ -163,11 +158,6 @@ async function createWeeklyReportLegacy(args: CreateWeeklyReportArgs) {
|
|
163
158
|
glowWeight <= 0 &&
|
164
159
|
rewardSplit.glowSplitPercent > 0
|
165
160
|
) {
|
166
|
-
console.log(
|
167
|
-
farm.weeklyPayment,
|
168
|
-
glowWeight,
|
169
|
-
rewardSplit.glowSplitPercent
|
170
|
-
);
|
171
161
|
throw new Error(
|
172
162
|
"Glow weight is less than 0 and weekly payment is greater than 0"
|
173
163
|
);
|
@@ -178,11 +168,6 @@ async function createWeeklyReportLegacy(args: CreateWeeklyReportArgs) {
|
|
178
168
|
usdgWeight <= 0 &&
|
179
169
|
rewardSplit.usdgSplitPercent > 0
|
180
170
|
) {
|
181
|
-
console.log(
|
182
|
-
farm.carbonCreditsProduced,
|
183
|
-
usdgWeight.toString(),
|
184
|
-
rewardSplit.usdgSplitPercent
|
185
|
-
);
|
186
171
|
throw new Error(
|
187
172
|
`USDG weight is less than or equal to 0 and carbon credits produced is greater than 0 for farm ${farm.shortId}`
|
188
173
|
);
|
@@ -192,11 +177,6 @@ async function createWeeklyReportLegacy(args: CreateWeeklyReportArgs) {
|
|
192
177
|
glowWeight <= 0 &&
|
193
178
|
rewardSplit.glowSplitPercent > 0
|
194
179
|
) {
|
195
|
-
console.log(
|
196
|
-
farm.weeklyPayment,
|
197
|
-
glowWeight.toString(),
|
198
|
-
rewardSplit.glowSplitPercent
|
199
|
-
);
|
200
180
|
throw new Error(
|
201
181
|
`Glow weight is less than or equal to 0 and weekly payment is greater than 0 for farm ${farm.shortId}`
|
202
182
|
);
|
@@ -372,12 +352,9 @@ export async function createWeeklyReport({
|
|
372
352
|
gcaUrls,
|
373
353
|
apiUrl,
|
374
354
|
}: CreateWeeklyReportArgs) {
|
375
|
-
if (week < 72) {
|
376
|
-
return createWeeklyReportLegacy({ week, gcaUrls, apiUrl });
|
377
|
-
}
|
378
|
-
|
379
355
|
const map = new Map<string, MerkleLeaf>();
|
380
356
|
|
357
|
+
// Fetch active farms for the week (source of truth) and audits for the week.
|
381
358
|
const [apiResponse, auditsRes] = await Promise.all([
|
382
359
|
fetchFarmsForWeek(week, gcaUrls, apiUrl),
|
383
360
|
axios.get<Audit[]>(
|
@@ -385,38 +362,119 @@ export async function createWeeklyReport({
|
|
385
362
|
),
|
386
363
|
]);
|
387
364
|
|
388
|
-
const farms = apiResponse.filteredFarms;
|
389
|
-
const audits = auditsRes.data;
|
365
|
+
const farms = apiResponse.filteredFarms; // List of farms active this week.
|
366
|
+
const audits = auditsRes.data; // Audits potentially containing adjusted credits.
|
390
367
|
const rawData = apiResponse.rawData;
|
391
368
|
|
369
|
+
// Map to store the final adjusted credit (as bigint) for each active farm shortId.
|
392
370
|
const shortIdToAdjustedCredit = new Map<string, bigint>();
|
371
|
+
// Set to track shortIds that have been assigned a credit from a valid audit to prevent duplicates.
|
372
|
+
const processedAuditShortIds = new Set<string>();
|
373
|
+
// Set of shortIds from the active farms list for quick lookup.
|
374
|
+
const farmShortIds = new Set(farms.map((f) => String(f.shortId)));
|
393
375
|
|
376
|
+
// Process each audit to extract adjusted credit values for active farms.
|
394
377
|
for (const audit of audits) {
|
395
378
|
const activeShortIds = audit.activeShortIds ?? [];
|
396
379
|
const adjustedCredit =
|
397
380
|
audit.summary?.carbonFootprintAndProduction?.adjustedWeeklyCarbonCredit?.trim();
|
398
381
|
|
382
|
+
// Basic validation: Ensure the audit has a valid numeric credit and lists associated shortIds.
|
399
383
|
if (!adjustedCredit || !NUMERIC_REGEX.test(adjustedCredit))
|
400
384
|
throw new Error(
|
401
385
|
`Invalid adjustedWeeklyCarbonCredit for audit ${audit.id}`
|
402
386
|
);
|
403
387
|
if (activeShortIds.length === 0)
|
404
|
-
throw new Error(`
|
388
|
+
throw new Error(`Audit ${audit.id} has empty activeShortIds`);
|
389
|
+
|
390
|
+
// Separate the shortIds listed in the audit into those that are active this week and those that are not.
|
391
|
+
const auditActiveFarmSids: string[] = [];
|
392
|
+
const auditInactiveFarmSids: string[] = [];
|
393
|
+
for (const sid of activeShortIds) {
|
394
|
+
const sidString = String(sid);
|
395
|
+
if (farmShortIds.has(sidString)) {
|
396
|
+
auditActiveFarmSids.push(sidString);
|
397
|
+
} else {
|
398
|
+
auditInactiveFarmSids.push(sidString);
|
399
|
+
}
|
400
|
+
}
|
401
|
+
|
402
|
+
// --- Audit Validity Checks ---
|
405
403
|
|
406
|
-
|
404
|
+
// Data Integrity Check: An audit for credit distribution should not mix active and inactive farms for the current week.
|
405
|
+
if (auditActiveFarmSids.length > 0 && auditInactiveFarmSids.length > 0) {
|
406
|
+
throw new Error(
|
407
|
+
`Audit ${
|
408
|
+
audit.id
|
409
|
+
} for week ${week} contains a mix of active farms (${auditActiveFarmSids.join(
|
410
|
+
", "
|
411
|
+
)}) and inactive farms (${auditInactiveFarmSids.join(
|
412
|
+
", "
|
413
|
+
)}). Audits should only contain active farms when distributing credits.`
|
414
|
+
);
|
415
|
+
}
|
416
|
+
|
417
|
+
// Skip Audit: If the audit only contains shortIds that are not active this week, it's irrelevant for this report.
|
418
|
+
if (auditActiveFarmSids.length === 0) {
|
419
|
+
continue; // Move to the next audit.
|
420
|
+
}
|
421
|
+
|
422
|
+
// --- Process Valid Audit for Active Farms ---
|
423
|
+
|
424
|
+
// Calculate the credit share per active farm within this audit.
|
425
|
+
const splitValue = new Decimal(adjustedCredit).div(
|
426
|
+
auditActiveFarmSids.length // Divide only by the count of *active* farms found in this audit.
|
427
|
+
);
|
428
|
+
|
429
|
+
// Sanity Check: Ensure the calculated split is not zero.
|
407
430
|
if (splitValue.isZero())
|
408
431
|
throw new Error(
|
409
|
-
`Zero adjustedWeeklyCarbonCredit split in audit ${audit.id}`
|
432
|
+
`Zero adjustedWeeklyCarbonCredit split for active farms in audit ${audit.id}`
|
410
433
|
);
|
411
434
|
|
435
|
+
// Convert the decimal split value to a bigint using the defined precision.
|
412
436
|
const splitBigInt = toBigInt(splitValue, USDG_WEIGHT_DECIMAL_PRECISION);
|
413
|
-
|
414
|
-
|
437
|
+
|
438
|
+
// Dust Check: Ensure that the conversion to bigint didn't truncate the value to zero.
|
439
|
+
if (splitBigInt === BigInt(0)) {
|
440
|
+
throw new Error(
|
441
|
+
`Adjusted credit split for audit ${
|
442
|
+
audit.id
|
443
|
+
} resulted in zero BigInt after conversion for precision ${USDG_WEIGHT_DECIMAL_PRECISION}. Original split value: ${splitValue.toString()}. This might indicate dust loss.`
|
444
|
+
);
|
445
|
+
}
|
446
|
+
|
447
|
+
// Distribute the calculated split value to each active farm associated with this audit.
|
448
|
+
for (const sidString of auditActiveFarmSids) {
|
449
|
+
// Duplicate Check: Ensure this shortId hasn't already received credit from another valid audit this week.
|
450
|
+
if (processedAuditShortIds.has(sidString)) {
|
451
|
+
throw new Error(
|
452
|
+
`ShortId ${sidString} found in multiple valid audits for week ${week}`
|
453
|
+
);
|
454
|
+
}
|
455
|
+
processedAuditShortIds.add(sidString); // Mark this shortId as processed.
|
456
|
+
|
457
|
+
// Store the adjusted credit for this active farm.
|
458
|
+
shortIdToAdjustedCredit.set(sidString, splitBigInt);
|
459
|
+
}
|
460
|
+
} // End of loop through audits.
|
461
|
+
|
462
|
+
// Final Validation: Ensure every farm considered active for this week received an adjusted credit value from a valid audit.
|
463
|
+
for (const farmId of farmShortIds) {
|
464
|
+
if (!shortIdToAdjustedCredit.has(farmId)) {
|
465
|
+
throw new Error(
|
466
|
+
`Farm ${farmId} is active for week ${week} but has no corresponding adjusted credit found in any valid audit.`
|
467
|
+
);
|
468
|
+
}
|
415
469
|
}
|
416
470
|
|
417
|
-
|
471
|
+
// --- Start Calculation of Merkle Tree Weights ---
|
418
472
|
|
473
|
+
let totalCreditsProduced18dp = BigInt(0); // Raw total from farm data, for reporting/comparison.
|
474
|
+
|
475
|
+
// Iterate through each active farm to calculate its contribution to the Merkle tree leaves.
|
419
476
|
for (const farm of farms) {
|
477
|
+
// Basic checks for farm data consistency.
|
420
478
|
if (farm.status === "Unassigned") {
|
421
479
|
throw new Error(`farm ${farm.shortId} is unassigned`);
|
422
480
|
}
|
@@ -433,11 +491,13 @@ export async function createWeeklyReport({
|
|
433
491
|
);
|
434
492
|
}
|
435
493
|
|
494
|
+
// Accumulate the reported carbon credits (18 decimal places).
|
436
495
|
totalCreditsProduced18dp += parseUnits(
|
437
496
|
customToFixed(farm.carbonCreditsProduced, 18),
|
438
497
|
18
|
439
498
|
);
|
440
499
|
|
500
|
+
// Validate reward split percentages add up to 1 (within tolerance).
|
441
501
|
const sumGlow = farm.rewardSplits.reduce(
|
442
502
|
(acc: number, r: any) => acc + r.glowSplitPercent,
|
443
503
|
0
|
@@ -452,49 +512,62 @@ export async function createWeeklyReport({
|
|
452
512
|
if (Math.abs(sumUSDG - 1) > percentTolerance)
|
453
513
|
throw new Error(`USDG splits ≠1 for farm ${farm.shortId}`);
|
454
514
|
|
515
|
+
// Get the base GLOW payment for the farm, converted to bigint with appropriate precision.
|
455
516
|
const glowBase = parseUnits(
|
456
517
|
customToFixed(farm.weeklyPayment, GLOW_WEIGHT_DECIMAL_PRECISION),
|
457
518
|
GLOW_WEIGHT_DECIMAL_PRECISION
|
458
519
|
);
|
459
520
|
|
521
|
+
// Retrieve the pre-calculated adjusted credit for this farm. Should always exist due to prior checks.
|
460
522
|
const adjustedCreditBigInt =
|
461
523
|
shortIdToAdjustedCredit.get(String(farm.shortId)) ?? BigInt(0);
|
462
524
|
|
525
|
+
// Sanity check (likely redundant due to earlier checks, but safe).
|
463
526
|
if (adjustedCreditBigInt <= BigInt(0))
|
464
527
|
throw new Error(
|
465
528
|
`Adjusted credit is less than or equal to 0 for farm ${farm.shortId}`
|
466
529
|
);
|
467
530
|
|
531
|
+
// Process each reward split recipient for this farm.
|
468
532
|
for (const split of farm.rewardSplits) {
|
533
|
+
// Calculate the GLOW weight for this recipient based on the farm's weekly payment and split percentage.
|
469
534
|
const glowWeight = multiplyBigIntByDecimalPercentage(
|
470
535
|
glowBase,
|
471
536
|
GLOW_WEIGHT_DECIMAL_PRECISION,
|
472
537
|
split.glowSplitPercent
|
473
538
|
);
|
539
|
+
// Calculate the USDG weight for this recipient based on the farm's *adjusted* credit and split percentage.
|
474
540
|
const usdgWeight = multiplyBigIntByDecimalPercentage(
|
475
541
|
adjustedCreditBigInt,
|
476
542
|
USDG_WEIGHT_DECIMAL_PRECISION,
|
477
543
|
split.usdgSplitPercent
|
478
544
|
);
|
479
545
|
|
546
|
+
// Dust Loss Checks: Ensure non-zero percentages didn't result in zero weight due to precision limits.
|
480
547
|
if (
|
481
548
|
split.usdgSplitPercent > 0 &&
|
482
549
|
adjustedCreditBigInt > BigInt(0) &&
|
483
550
|
usdgWeight === BigInt(0)
|
484
551
|
)
|
485
|
-
throw new Error(
|
552
|
+
throw new Error(
|
553
|
+
`USDG dust lost for farm ${farm.shortId} wallet ${split.walletAddress}`
|
554
|
+
);
|
486
555
|
if (
|
487
556
|
split.glowSplitPercent > 0 &&
|
488
557
|
glowBase > BigInt(0) &&
|
489
558
|
glowWeight === BigInt(0)
|
490
559
|
)
|
491
|
-
throw new Error(
|
560
|
+
throw new Error(
|
561
|
+
`Glow dust lost for farm ${farm.shortId} wallet ${split.walletAddress}`
|
562
|
+
);
|
492
563
|
|
564
|
+
// Overflow Check: Ensure individual leaf weights don't exceed the maximum allowed.
|
493
565
|
if (glowWeight > MAX_WEIGHT || usdgWeight > MAX_WEIGHT)
|
494
566
|
throw new Error(
|
495
567
|
`Leaf weight overflow on wallet ${split.walletAddress}`
|
496
568
|
);
|
497
569
|
|
570
|
+
// Accumulate the calculated weights into the map for the recipient wallet.
|
498
571
|
accumulateLeafWeights(
|
499
572
|
split.walletAddress,
|
500
573
|
{ wallet: split.walletAddress, glowWeight, usdgWeight },
|
@@ -503,27 +576,33 @@ export async function createWeeklyReport({
|
|
503
576
|
}
|
504
577
|
}
|
505
578
|
|
579
|
+
// --- Finalize Merkle Tree and Generate Report Data ---
|
580
|
+
|
581
|
+
// Convert the accumulated weights map into the final list of leaves for the tree.
|
506
582
|
const finalizedLeaves: FinalizedLeaf[] = Array.from(map.values()).map(
|
507
583
|
({ wallet, glowWeight, usdgWeight }) => ({
|
508
584
|
wallet,
|
509
|
-
glowWeight: glowWeight.toString(),
|
585
|
+
glowWeight: glowWeight.toString(), // Convert BigInts to strings for hashing/reporting.
|
510
586
|
usdgWeight: usdgWeight.toString(),
|
511
587
|
})
|
512
588
|
);
|
513
589
|
|
590
|
+
// Hash each leaf according to the defined structure.
|
514
591
|
const hashedLeaves = finalizedLeaves.map((leaf) =>
|
515
592
|
hashLeaf({
|
516
593
|
address: leaf.wallet,
|
517
594
|
glowWeight: leaf.glowWeight,
|
518
|
-
usdcWeight: leaf.usdgWeight,
|
595
|
+
usdcWeight: leaf.usdgWeight, // Note: Parameter name inconsistency (usdc vs usdg)
|
519
596
|
})
|
520
597
|
);
|
521
598
|
|
599
|
+
// Build the Merkle tree.
|
522
600
|
const merkleTree = new MerkleTree(hashedLeaves, ethers.utils.keccak256, {
|
523
|
-
sort: true,
|
601
|
+
sort: true, // Ensure consistent tree structure.
|
524
602
|
});
|
525
|
-
const merkleRoot = merkleTree.getHexRoot();
|
603
|
+
const merkleRoot = merkleTree.getHexRoot(); // Get the root hash.
|
526
604
|
|
605
|
+
// Calculate the total weights across all finalized leaves.
|
527
606
|
const totalGlowWeight = finalizedLeaves.reduce(
|
528
607
|
(acc, { glowWeight }) => acc.add(glowWeight),
|
529
608
|
ethers.BigNumber.from(0)
|
@@ -533,23 +612,29 @@ export async function createWeeklyReport({
|
|
533
612
|
ethers.BigNumber.from(0)
|
534
613
|
);
|
535
614
|
|
615
|
+
// Total Weight Overflow Checks: Ensure sums don't exceed maximum.
|
536
616
|
if (totalGlowWeight.toBigInt() > MAX_WEIGHT)
|
537
617
|
throw new Error("Total glow weight overflow");
|
538
618
|
if (totalUSDGWeight.toBigInt() > MAX_WEIGHT)
|
539
619
|
throw new Error("Total USDG weight overflow");
|
540
620
|
|
621
|
+
// Generate Merkle proofs for each leaf and verify them.
|
541
622
|
const leavesWithProofs = finalizedLeaves.map((leaf) => {
|
542
623
|
const hashed = hashLeaf({
|
543
624
|
address: leaf.wallet,
|
544
625
|
glowWeight: leaf.glowWeight,
|
545
|
-
usdcWeight: leaf.usdgWeight,
|
626
|
+
usdcWeight: leaf.usdgWeight, // Note: Parameter name inconsistency
|
546
627
|
});
|
547
628
|
const proof = merkleTree.getHexProof(hashed);
|
548
629
|
if (!merkleTree.verify(proof, hashed, merkleRoot))
|
630
|
+
// Verify proof against the calculated root.
|
549
631
|
throw new Error("Invalid proof for " + leaf.wallet);
|
550
632
|
return { ...leaf, proof };
|
551
633
|
});
|
552
634
|
|
635
|
+
// --- Sanity Checks on Final Weights ---
|
636
|
+
|
637
|
+
// Verify that summing weights from leavesWithProofs matches the earlier reduce calculation.
|
553
638
|
const glowSumProofLoop = leavesWithProofs.reduce(
|
554
639
|
(acc, l) => acc.add(l.glowWeight),
|
555
640
|
ethers.BigNumber.from(0)
|
@@ -572,22 +657,25 @@ export async function createWeeklyReport({
|
|
572
657
|
throw new Error("USDG sum mismatch");
|
573
658
|
}
|
574
659
|
|
660
|
+
// Calculate the total expected credits based on the adjusted values used.
|
575
661
|
const totalExpectedCredits = farms.reduce((acc: Decimal, f: any) => {
|
576
662
|
const adj = shortIdToAdjustedCredit.get(String(f.shortId)) ?? BigInt(0);
|
577
663
|
return acc.plus(fromBigInt(adj, USDG_WEIGHT_DECIMAL_PRECISION));
|
578
664
|
}, new Decimal(0));
|
579
665
|
|
666
|
+
// Convert total USDG weight back to human-readable decimal for deviation check.
|
580
667
|
const totalUSDGWeightHuman = new Decimal(
|
581
668
|
formatUnits(
|
582
669
|
BigInt(totalUSDGWeight.toString()),
|
583
670
|
USDG_WEIGHT_DECIMAL_PRECISION
|
584
671
|
)
|
585
672
|
);
|
673
|
+
// Check deviation between total adjusted credits used and the final sum of USDG weights.
|
586
674
|
if (
|
587
675
|
greaterThanMaxDeviation(
|
588
676
|
totalExpectedCredits.toNumber(),
|
589
677
|
totalUSDGWeightHuman.toNumber(),
|
590
|
-
0.001
|
678
|
+
0.001 // 0.1% tolerance
|
591
679
|
)
|
592
680
|
) {
|
593
681
|
console.error(
|
@@ -599,21 +687,24 @@ export async function createWeeklyReport({
|
|
599
687
|
throw new Error("totalExpectedCredits vs USDG weight deviation >0.1% ");
|
600
688
|
}
|
601
689
|
|
690
|
+
// Convert total Glow weight back to human-readable decimal.
|
602
691
|
const totalGlowWeightHuman = new Decimal(
|
603
692
|
formatUnits(
|
604
693
|
BigInt(totalGlowWeight.toString()),
|
605
694
|
GLOW_WEIGHT_DECIMAL_PRECISION
|
606
695
|
)
|
607
696
|
);
|
697
|
+
// Sum the original weekly protocol fee payments from farm data.
|
608
698
|
const totalProtocolFeePayments = farms.reduce(
|
609
699
|
(acc: number, f: any) => acc + f.weeklyPayment,
|
610
700
|
0
|
611
701
|
);
|
702
|
+
// Check deviation between total glow weight and total protocol fees paid.
|
612
703
|
if (
|
613
704
|
greaterThanMaxDeviation(
|
614
705
|
totalGlowWeightHuman.toNumber(),
|
615
706
|
totalProtocolFeePayments,
|
616
|
-
0.001
|
707
|
+
0.001 // 0.1% tolerance
|
617
708
|
)
|
618
709
|
) {
|
619
710
|
console.error(
|
@@ -625,12 +716,15 @@ export async function createWeeklyReport({
|
|
625
716
|
throw new Error("totalGlowWeight vs protocol fees deviation >0.1% ");
|
626
717
|
}
|
627
718
|
|
719
|
+
// --- Prepare Output Data ---
|
720
|
+
|
721
|
+
// Key statistics for the report.
|
628
722
|
const headlineStats = {
|
629
723
|
weekNumber: week,
|
630
|
-
totalCreditsProduced: formatUnits(totalCreditsProduced18dp, 18),
|
724
|
+
totalCreditsProduced: formatUnits(totalCreditsProduced18dp, 18), // Original reported total
|
631
725
|
totalCreditsProducedBN: totalCreditsProduced18dp.toString(),
|
632
|
-
totalGlowWeightInFinalized: totalGlowWeight.toString(),
|
633
|
-
totalGlowWeightHuman: totalGlowWeightHuman.toString(),
|
726
|
+
totalGlowWeightInFinalized: totalGlowWeight.toString(), // Total weight as BigNumber string
|
727
|
+
totalGlowWeightHuman: totalGlowWeightHuman.toString(), // Total weight as human-readable decimal
|
634
728
|
totalUSDGWeightInFinalized: totalUSDGWeight.toString(),
|
635
729
|
totalUSDGWeightHuman: totalUSDGWeightHuman.toString(),
|
636
730
|
root: merkleRoot,
|
@@ -638,6 +732,7 @@ export async function createWeeklyReport({
|
|
638
732
|
usdgWeightDecimals: USDG_WEIGHT_DECIMAL_PRECISION,
|
639
733
|
};
|
640
734
|
|
735
|
+
// List of shortIds and their final adjusted credit value (human-readable).
|
641
736
|
const shortIdAdjustedList = Array.from(shortIdToAdjustedCredit.entries()).map(
|
642
737
|
([shortId, creditBigInt]) => ({
|
643
738
|
shortId,
|
@@ -648,6 +743,7 @@ export async function createWeeklyReport({
|
|
648
743
|
})
|
649
744
|
);
|
650
745
|
|
746
|
+
// Detailed comparison between originally reported credits and adjusted credits for each farm.
|
651
747
|
const creditsDeviationList = farms.map((farm: any) => {
|
652
748
|
const adj = shortIdToAdjustedCredit.get(String(farm.shortId)) ?? BigInt(0);
|
653
749
|
const adjusted = fromBigInt(adj, USDG_WEIGHT_DECIMAL_PRECISION);
|
@@ -655,6 +751,7 @@ export async function createWeeklyReport({
|
|
655
751
|
let deviation: Decimal;
|
656
752
|
let absDeviation: Decimal;
|
657
753
|
let deviationPercent: Decimal;
|
754
|
+
// Handle division by zero if produced is zero.
|
658
755
|
if (produced.isZero() && adjusted.isZero()) {
|
659
756
|
deviation = new Decimal(0);
|
660
757
|
absDeviation = new Decimal(0);
|
@@ -663,7 +760,7 @@ export async function createWeeklyReport({
|
|
663
760
|
deviation = produced.minus(adjusted);
|
664
761
|
absDeviation = deviation.abs();
|
665
762
|
deviationPercent = deviation
|
666
|
-
.div(produced.isZero() ? 1 : produced)
|
763
|
+
.div(produced.isZero() ? 1 : produced) // Avoid division by zero
|
667
764
|
.mul(100);
|
668
765
|
}
|
669
766
|
return {
|
@@ -676,13 +773,14 @@ export async function createWeeklyReport({
|
|
676
773
|
};
|
677
774
|
});
|
678
775
|
|
776
|
+
// Return all calculated data.
|
679
777
|
return {
|
680
778
|
headlineStats,
|
681
|
-
finalizedLeaves,
|
682
|
-
leavesWithProofs,
|
683
|
-
farms,
|
684
|
-
rawData,
|
685
|
-
shortIdAdjustedList,
|
686
|
-
creditsDeviationList,
|
779
|
+
finalizedLeaves, // Leaves without proofs (for potential use cases)
|
780
|
+
leavesWithProofs, // Leaves with proofs (primary data for distribution)
|
781
|
+
farms, // Original filtered farm data
|
782
|
+
rawData, // Raw GCA responses
|
783
|
+
shortIdAdjustedList, // List of adjusted credits per farm
|
784
|
+
creditsDeviationList, // Detailed deviation report per farm
|
687
785
|
};
|
688
786
|
}
|