@namehash/ens-referrals 1.10.0 → 1.11.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.
package/dist/index.cjs CHANGED
@@ -69,6 +69,7 @@ __export(index_exports, {
69
69
  buildUnrankedReferrerMetricsPieSplit: () => buildUnrankedReferrerMetricsPieSplit,
70
70
  buildUnrankedReferrerMetricsRevShareCap: () => buildUnrankedReferrerMetricsRevShareCap,
71
71
  calcBaseReferralProgramEditionStatus: () => calcBaseReferralProgramEditionStatus,
72
+ calcBaseRevenueContribution: () => calcBaseRevenueContribution,
72
73
  calcReferralProgramEditionStatusPieSplit: () => calcReferralProgramEditionStatusPieSplit,
73
74
  calcReferralProgramEditionStatusRevShareCap: () => calcReferralProgramEditionStatusRevShareCap,
74
75
  calcReferrerAwardPoolSharePieSplit: () => calcReferrerAwardPoolSharePieSplit,
@@ -78,6 +79,7 @@ __export(index_exports, {
78
79
  deserializeReferralProgramEditionSummariesResponse: () => deserializeReferralProgramEditionSummariesResponse,
79
80
  deserializeReferrerLeaderboardPageResponse: () => deserializeReferrerLeaderboardPageResponse,
80
81
  deserializeReferrerMetricsEditionsResponse: () => deserializeReferrerMetricsEditionsResponse,
82
+ findOverlappingEditionPair: () => findOverlappingEditionPair,
81
83
  getReferrerEditionMetrics: () => getReferrerEditionMetrics,
82
84
  getReferrerLeaderboardPage: () => getReferrerLeaderboardPage,
83
85
  isFiniteNonNegativeNumber: () => isFiniteNonNegativeNumber,
@@ -477,7 +479,8 @@ function scaleBigintByNumber(value, scaleFactor) {
477
479
  var CurrencyIds = {
478
480
  ETH: "ETH",
479
481
  USDC: "USDC",
480
- DAI: "DAI"
482
+ DAI: "DAI",
483
+ ENSTokens: "ENSTokens"
481
484
  };
482
485
  var currencyInfo = {
483
486
  [CurrencyIds.ETH]: {
@@ -494,6 +497,11 @@ var currencyInfo = {
494
497
  id: CurrencyIds.DAI,
495
498
  name: "Dai Stablecoin",
496
499
  decimals: 18
500
+ },
501
+ [CurrencyIds.ENSTokens]: {
502
+ id: CurrencyIds.ENSTokens,
503
+ name: "$ENS Tokens",
504
+ decimals: 18
497
505
  }
498
506
  };
499
507
  function priceEth(amount) {
@@ -508,6 +516,45 @@ function priceUsdc(amount) {
508
516
  currency: CurrencyIds.USDC
509
517
  };
510
518
  }
519
+ function isPriceCurrencyEqual(priceA, priceB) {
520
+ return priceA.currency === priceB.currency;
521
+ }
522
+ function addPrices(...prices) {
523
+ const firstPrice = prices[0];
524
+ const allPricesInSameCurrency = prices.every((price) => isPriceCurrencyEqual(firstPrice, price));
525
+ if (allPricesInSameCurrency === false) {
526
+ throw new Error("All prices must have the same currency to be added together.");
527
+ }
528
+ const { currency } = firstPrice;
529
+ return prices.reduce(
530
+ (acc, price) => ({
531
+ amount: acc.amount + price.amount,
532
+ currency
533
+ }),
534
+ {
535
+ amount: 0n,
536
+ currency: firstPrice.currency
537
+ }
538
+ );
539
+ }
540
+ function subtractPrice(a, b) {
541
+ if (!isPriceCurrencyEqual(a, b)) {
542
+ throw new Error("All prices must have the same currency to be subtracted.");
543
+ }
544
+ const resultAmount = a.amount - b.amount;
545
+ if (resultAmount < 0n) {
546
+ throw new Error("subtractPrice result must be non-negative.");
547
+ }
548
+ return { amount: resultAmount, currency: a.currency };
549
+ }
550
+ function minPrice(...prices) {
551
+ const firstPrice = prices[0];
552
+ const allPricesInSameCurrency = prices.every((price) => isPriceCurrencyEqual(firstPrice, price));
553
+ if (allPricesInSameCurrency === false) {
554
+ throw new Error("All prices must have the same currency to be compared.");
555
+ }
556
+ return prices.reduce((acc, price) => price.amount < acc.amount ? price : acc);
557
+ }
511
558
  function scalePrice(price, scaleFactor) {
512
559
  const scaledAmount = scaleBigintByNumber(price.amount, scaleFactor);
513
560
  return {
@@ -589,6 +636,62 @@ var import_v43 = __toESM(require("zod/v4"), 1);
589
636
  // src/award-models/shared/api/zod-schemas.ts
590
637
  var import_v42 = __toESM(require("zod/v4"), 1);
591
638
 
639
+ // src/edition.ts
640
+ var REFERRAL_PROGRAM_EDITION_SLUG_PATTERN = /^[a-z0-9]+(-[a-z0-9]+)*$/;
641
+ function validateReferralProgramEditionConfigSet(configSet) {
642
+ const violation = Array.from(configSet.entries()).find(([key, config]) => key !== config.slug);
643
+ if (violation) {
644
+ const [key, config] = violation;
645
+ throw new Error(
646
+ `Edition config set invariant violation: map key "${key}" does not match config.slug "${config.slug}"`
647
+ );
648
+ }
649
+ const overlap = findOverlappingEditionPair(Array.from(configSet.values()));
650
+ if (overlap) {
651
+ const [a, b] = overlap;
652
+ throw new Error(
653
+ `Edition config set invariant violation: editions "${a.slug}" and "${b.slug}" have overlapping time ranges for subregistryId ${a.rules.subregistryId.chainId}:${a.rules.subregistryId.address} (startTime and endTime are inclusive)`
654
+ );
655
+ }
656
+ }
657
+ function findOverlappingEditionPair(editions) {
658
+ const byRegistry = /* @__PURE__ */ new Map();
659
+ for (const edition of editions) {
660
+ const key = `${edition.rules.subregistryId.chainId}:${edition.rules.subregistryId.address}`;
661
+ const group = byRegistry.get(key);
662
+ if (group) {
663
+ group.push(edition);
664
+ } else {
665
+ byRegistry.set(key, [edition]);
666
+ }
667
+ }
668
+ for (const group of byRegistry.values()) {
669
+ if (group.length < 2) continue;
670
+ group.sort((a, b) => a.rules.startTime - b.rules.startTime);
671
+ for (let i = 1; i < group.length; i++) {
672
+ const prev = group[i - 1];
673
+ const curr = group[i];
674
+ if (curr.rules.startTime <= prev.rules.endTime) {
675
+ return [prev, curr];
676
+ }
677
+ }
678
+ }
679
+ return null;
680
+ }
681
+ function buildReferralProgramEditionConfigSet(configs) {
682
+ const slugCounts = configs.reduce((counts, config) => {
683
+ counts.set(config.slug, (counts.get(config.slug) || 0) + 1);
684
+ return counts;
685
+ }, /* @__PURE__ */ new Map());
686
+ const duplicates = Array.from(slugCounts.entries()).filter(([_, count]) => count > 1).map(([slug, count]) => `"${slug}" (${count} occurrences)`);
687
+ if (duplicates.length > 0) {
688
+ throw new Error(`Duplicate edition config slugs detected: ${duplicates.join(", ")}`);
689
+ }
690
+ const configSet = new Map(configs.map((config) => [config.slug, config]));
691
+ validateReferralProgramEditionConfigSet(configSet);
692
+ return configSet;
693
+ }
694
+
592
695
  // src/number.ts
593
696
  var isInteger = (value) => {
594
697
  return Number.isInteger(value);
@@ -795,6 +898,15 @@ var calcBaseReferralProgramEditionStatus = (rules, now) => {
795
898
  };
796
899
 
797
900
  // src/award-models/shared/api/zod-schemas.ts
901
+ var makeReferralProgramEditionSlugSchema = (valueLabel = "ReferralProgramEditionSlug") => import_v42.default.string().min(1, `${valueLabel} must not be empty`).regex(
902
+ REFERRAL_PROGRAM_EDITION_SLUG_PATTERN,
903
+ `${valueLabel} must contain only lowercase letters, digits, and hyphens. Must not start or end with a hyphen.`
904
+ );
905
+ var makeBaseReferralProgramEditionConfigSchema = (valueLabel = "BaseReferralProgramEditionConfig") => import_v42.default.object({
906
+ slug: makeReferralProgramEditionSlugSchema(`${valueLabel}.slug`),
907
+ displayName: import_v42.default.string().min(1, `${valueLabel}.displayName must not be empty`),
908
+ rules: makeBaseReferralProgramRulesSchema(`${valueLabel}.rules`)
909
+ });
798
910
  var makeBaseReferralProgramRulesSchema = (valueLabel) => import_v42.default.object({
799
911
  awardModel: import_v42.default.string(),
800
912
  startTime: makeUnixTimestampSchema(`${valueLabel}.startTime`),
@@ -820,12 +932,9 @@ var makeReferrerLeaderboardPageContextSchema = (valueLabel = "ReferrerLeaderboar
820
932
  endIndex: import_v42.default.optional(makeNonNegativeIntegerSchema(`${valueLabel}.endIndex`))
821
933
  });
822
934
  var makeReferralProgramStatusSchema = (_valueLabel = "status") => import_v42.default.enum(ReferralProgramEditionStatuses);
823
- var makeBaseReferralProgramEditionSummarySchema = (valueLabel) => import_v42.default.object({
935
+ var makeBaseReferralProgramEditionSummarySchema = (valueLabel) => makeBaseReferralProgramEditionConfigSchema(valueLabel).safeExtend({
824
936
  awardModel: import_v42.default.string(),
825
- slug: import_v42.default.string().min(1, `${valueLabel}.slug must not be empty`),
826
- displayName: import_v42.default.string().min(1, `${valueLabel}.displayName must not be empty`),
827
- status: makeReferralProgramStatusSchema(`${valueLabel}.status`),
828
- rules: makeBaseReferralProgramRulesSchema(`${valueLabel}.rules`)
937
+ status: makeReferralProgramStatusSchema(`${valueLabel}.status`)
829
938
  });
830
939
  var makeBaseReferrerLeaderboardPageSchema = (valueLabel) => import_v42.default.object({
831
940
  awardModel: import_v42.default.string(),
@@ -1062,6 +1171,11 @@ var buildReferralProgramRulesRevShareCap = (awardPool, minBaseRevenueContributio
1062
1171
  validateReferralProgramRulesRevShareCap(result);
1063
1172
  return result;
1064
1173
  };
1174
+ function calcBaseRevenueContribution(rules, duration) {
1175
+ return priceUsdc(
1176
+ rules.baseAnnualRevenueContribution.amount * BigInt(duration) / BigInt(SECONDS_PER_YEAR)
1177
+ );
1178
+ }
1065
1179
  function isReferrerQualifiedRevShareCap(referrer, totalBaseRevenueContribution, rules) {
1066
1180
  const isAdminDisqualified = rules.adminActions.some(
1067
1181
  (a) => a.referrer === referrer && a.actionType === AdminActionTypes.Disqualification
@@ -1401,10 +1515,6 @@ var makeReferrerEditionMetricsSchema = (valueLabel = "ReferrerEditionMetrics") =
1401
1515
  };
1402
1516
  });
1403
1517
  };
1404
- var makeReferralProgramEditionSlugSchema = (valueLabel = "ReferralProgramEditionSlug") => import_v45.default.string().min(1, `${valueLabel} must not be empty`).regex(
1405
- /^[a-z0-9]+(-[a-z0-9]+)*$/,
1406
- `${valueLabel} must contain only lowercase letters, digits, and hyphens. Must not start or end with a hyphen.`
1407
- );
1408
1518
  var makeReferrerMetricsEditionsResponseOkSchema = (valueLabel = "ReferrerMetricsEditionsResponseOk") => import_v45.default.object({
1409
1519
  responseCode: import_v45.default.literal(ReferrerMetricsEditionsResponseCodes.Ok),
1410
1520
  data: import_v45.default.record(
@@ -1421,12 +1531,7 @@ var makeReferrerMetricsEditionsResponseSchema = (valueLabel = "ReferrerMetricsEd
1421
1531
  makeReferrerMetricsEditionsResponseOkSchema(valueLabel),
1422
1532
  makeReferrerMetricsEditionsResponseErrorSchema(valueLabel)
1423
1533
  ]);
1424
- var makeReferralProgramEditionConfigBaseSchema = (valueLabel) => import_v45.default.object({
1425
- slug: makeReferralProgramEditionSlugSchema(`${valueLabel}.slug`),
1426
- displayName: import_v45.default.string().min(1, `${valueLabel}.displayName must not be empty`),
1427
- rules: makeBaseReferralProgramRulesSchema(`${valueLabel}.rules`)
1428
- });
1429
- var makeReferralProgramEditionConfigSchema = (valueLabel = "ReferralProgramEditionConfig") => makeReferralProgramEditionConfigBaseSchema(valueLabel).safeExtend({
1534
+ var makeReferralProgramEditionConfigSchema = (valueLabel = "ReferralProgramEditionConfig") => makeBaseReferralProgramEditionConfigSchema(valueLabel).safeExtend({
1430
1535
  rules: makeReferralProgramRulesSchema(`${valueLabel}.rules`)
1431
1536
  });
1432
1537
  var makeReferralProgramEditionConfigSetArraySchema = (valueLabel = "ReferralProgramEditionConfigSetArray") => {
@@ -1437,7 +1542,7 @@ var makeReferralProgramEditionConfigSetArraySchema = (valueLabel = "ReferralProg
1437
1542
  const looseItemSchema = import_v45.default.looseObject({
1438
1543
  rules: import_v45.default.looseObject({ awardModel: import_v45.default.string() })
1439
1544
  });
1440
- const unrecognizedBaseSchema = makeReferralProgramEditionConfigBaseSchema(
1545
+ const unrecognizedBaseSchema = makeBaseReferralProgramEditionConfigSchema(
1441
1546
  `${valueLabel}[edition]`
1442
1547
  );
1443
1548
  return import_v45.default.array(looseItemSchema).transform((items, ctx) => {
@@ -1478,6 +1583,15 @@ var makeReferralProgramEditionConfigSetArraySchema = (valueLabel = "ReferralProg
1478
1583
  }
1479
1584
  slugs.add(edition.slug);
1480
1585
  }
1586
+ const overlap = findOverlappingEditionPair(result);
1587
+ if (overlap) {
1588
+ const [a, b] = overlap;
1589
+ ctx.addIssue({
1590
+ code: "custom",
1591
+ message: `${valueLabel}: editions "${a.slug}" and "${b.slug}" have overlapping time ranges for subregistryId ${a.rules.subregistryId.chainId}:${a.rules.subregistryId.address} (startTime and endTime are inclusive)`
1592
+ });
1593
+ return [];
1594
+ }
1481
1595
  return result;
1482
1596
  });
1483
1597
  };
@@ -1518,6 +1632,15 @@ var makeReferralProgramEditionSummarySchema = (valueLabel = "ReferralProgramEdit
1518
1632
  };
1519
1633
  var makeReferralProgramEditionSummariesDataSchema = (valueLabel = "ReferralProgramEditionSummariesData") => import_v45.default.object({
1520
1634
  editions: import_v45.default.array(makeReferralProgramEditionSummarySchema(`${valueLabel}.editions[edition]`))
1635
+ }).superRefine((data, ctx) => {
1636
+ const overlap = findOverlappingEditionPair(data.editions);
1637
+ if (!overlap) return;
1638
+ const [a, b] = overlap;
1639
+ ctx.addIssue({
1640
+ code: "custom",
1641
+ path: ["editions"],
1642
+ message: `${valueLabel}: editions "${a.slug}" and "${b.slug}" have overlapping time ranges for subregistryId ${a.rules.subregistryId.chainId}:${a.rules.subregistryId.address} (startTime and endTime are inclusive)`
1643
+ });
1521
1644
  });
1522
1645
  var makeReferralProgramEditionSummariesResponseOkSchema = (valueLabel = "ReferralProgramEditionSummariesResponseOk") => import_v45.default.object({
1523
1646
  responseCode: import_v45.default.literal(ReferralProgramEditionSummariesResponseCodes.Ok),
@@ -1997,31 +2120,6 @@ var buildAggregatedReferrerMetricsPieSplit = (referrers, rules) => {
1997
2120
  return result;
1998
2121
  };
1999
2122
 
2000
- // src/edition.ts
2001
- var REFERRAL_PROGRAM_EDITION_SLUG_PATTERN = /^[a-z0-9]+(-[a-z0-9]+)*$/;
2002
- function validateReferralProgramEditionConfigSet(configSet) {
2003
- const violation = Array.from(configSet.entries()).find(([key, config]) => key !== config.slug);
2004
- if (violation) {
2005
- const [key, config] = violation;
2006
- throw new Error(
2007
- `Edition config set invariant violation: map key "${key}" does not match config.slug "${config.slug}"`
2008
- );
2009
- }
2010
- }
2011
- function buildReferralProgramEditionConfigSet(configs) {
2012
- const slugCounts = configs.reduce((counts, config) => {
2013
- counts.set(config.slug, (counts.get(config.slug) || 0) + 1);
2014
- return counts;
2015
- }, /* @__PURE__ */ new Map());
2016
- const duplicates = Array.from(slugCounts.entries()).filter(([_, count]) => count > 1).map(([slug, count]) => `"${slug}" (${count} occurrences)`);
2017
- if (duplicates.length > 0) {
2018
- throw new Error(`Duplicate edition config slugs detected: ${duplicates.join(", ")}`);
2019
- }
2020
- const configSet = new Map(configs.map((config) => [config.slug, config]));
2021
- validateReferralProgramEditionConfigSet(configSet);
2022
- return configSet;
2023
- }
2024
-
2025
2123
  // src/award-models/shared/edition-summary.ts
2026
2124
  var validateBaseReferralProgramEditionSummary = (summary) => {
2027
2125
  if (!REFERRAL_PROGRAM_EDITION_SLUG_PATTERN.test(summary.slug)) {
@@ -2420,8 +2518,9 @@ var validateReferrerMetricsRevShareCap = (metrics, rules) => {
2420
2518
  makePriceUsdcSchema("ReferrerMetricsRevShareCap.totalBaseRevenueContribution").parse(
2421
2519
  metrics.totalBaseRevenueContribution
2422
2520
  );
2423
- const expectedTotalBaseRevenueContribution = priceUsdc(
2424
- rules.baseAnnualRevenueContribution.amount * BigInt(metrics.totalIncrementalDuration) / BigInt(SECONDS_PER_YEAR)
2521
+ const expectedTotalBaseRevenueContribution = calcBaseRevenueContribution(
2522
+ rules,
2523
+ metrics.totalIncrementalDuration
2425
2524
  );
2426
2525
  if (metrics.totalBaseRevenueContribution.amount !== expectedTotalBaseRevenueContribution.amount) {
2427
2526
  throw new Error(
@@ -2430,8 +2529,9 @@ var validateReferrerMetricsRevShareCap = (metrics, rules) => {
2430
2529
  }
2431
2530
  };
2432
2531
  var buildReferrerMetricsRevShareCap = (metrics, rules) => {
2433
- const totalBaseRevenueContribution = priceUsdc(
2434
- rules.baseAnnualRevenueContribution.amount * BigInt(metrics.totalIncrementalDuration) / BigInt(SECONDS_PER_YEAR)
2532
+ const totalBaseRevenueContribution = calcBaseRevenueContribution(
2533
+ rules,
2534
+ metrics.totalIncrementalDuration
2435
2535
  );
2436
2536
  const result = {
2437
2537
  ...metrics,
@@ -2605,71 +2705,71 @@ function sortReferralEvents(events) {
2605
2705
  }
2606
2706
 
2607
2707
  // src/award-models/rev-share-cap/leaderboard.ts
2608
- var bigintMin = (a, b) => a < b ? a : b;
2609
2708
  var buildReferrerLeaderboardRevShareCap = (events, rules, accurateAsOf) => {
2610
2709
  const sortedEvents = sortReferralEvents(events);
2611
2710
  const referrerStates = /* @__PURE__ */ new Map();
2612
- let awardPoolRemaining = rules.awardPool.amount;
2711
+ let awardPoolRemaining = rules.awardPool;
2613
2712
  for (const event of sortedEvents) {
2614
- const referrer = event.referrer;
2615
- let state = referrerStates.get(referrer);
2616
- if (!state) {
2617
- state = {
2713
+ const referrerId = event.referrer;
2714
+ let referrerState = referrerStates.get(referrerId);
2715
+ if (!referrerState) {
2716
+ referrerState = {
2618
2717
  totalReferrals: 0,
2619
2718
  totalIncrementalDuration: 0,
2620
- totalRevenueContributionAmount: 0n,
2621
- wasQualified: false,
2622
- cappedAwardAmount: 0n
2719
+ totalRevenueContribution: priceEth(0n),
2720
+ hasQualified: false,
2721
+ cappedAward: priceUsdc(0n)
2623
2722
  };
2624
- referrerStates.set(referrer, state);
2625
- }
2626
- state.totalReferrals += 1;
2627
- state.totalIncrementalDuration += event.incrementalDuration;
2628
- state.totalRevenueContributionAmount += event.incrementalRevenueContribution.amount;
2629
- const totalBaseRevenueAmount = rules.baseAnnualRevenueContribution.amount * BigInt(state.totalIncrementalDuration) / BigInt(SECONDS_PER_YEAR);
2630
- const isNowQualified = isReferrerQualifiedRevShareCap(
2631
- referrer,
2632
- priceUsdc(totalBaseRevenueAmount),
2633
- rules
2634
- );
2635
- if (isNowQualified && !state.wasQualified) {
2636
- const accumulatedUncappedAward = scalePrice(
2637
- priceUsdc(totalBaseRevenueAmount),
2638
- rules.maxBaseRevenueShare
2639
- ).amount;
2640
- const incrementalCappedAward = bigintMin(accumulatedUncappedAward, awardPoolRemaining);
2641
- state.cappedAwardAmount += incrementalCappedAward;
2642
- awardPoolRemaining -= incrementalCappedAward;
2643
- state.wasQualified = true;
2644
- } else if (state.wasQualified) {
2645
- const incrementalBaseRevenueAmount = rules.baseAnnualRevenueContribution.amount * BigInt(event.incrementalDuration) / BigInt(SECONDS_PER_YEAR);
2723
+ referrerStates.set(referrerId, referrerState);
2724
+ }
2725
+ referrerState.totalReferrals += 1;
2726
+ referrerState.totalIncrementalDuration += event.incrementalDuration;
2727
+ referrerState.totalRevenueContribution = addPrices(
2728
+ referrerState.totalRevenueContribution,
2729
+ event.incrementalRevenueContribution
2730
+ );
2731
+ const totalBaseRevenue = calcBaseRevenueContribution(
2732
+ rules,
2733
+ referrerState.totalIncrementalDuration
2734
+ );
2735
+ const isNowQualified = isReferrerQualifiedRevShareCap(referrerId, totalBaseRevenue, rules);
2736
+ if (isNowQualified && !referrerState.hasQualified) {
2737
+ const accumulatedUncappedAward = scalePrice(totalBaseRevenue, rules.maxBaseRevenueShare);
2738
+ const incrementalCappedAward = minPrice(accumulatedUncappedAward, awardPoolRemaining);
2739
+ referrerState.cappedAward = addPrices(referrerState.cappedAward, incrementalCappedAward);
2740
+ awardPoolRemaining = subtractPrice(awardPoolRemaining, incrementalCappedAward);
2741
+ referrerState.hasQualified = true;
2742
+ } else if (referrerState.hasQualified) {
2743
+ const incrementalBaseRevenue = calcBaseRevenueContribution(rules, event.incrementalDuration);
2646
2744
  const incrementalUncappedAward = scalePrice(
2647
- priceUsdc(incrementalBaseRevenueAmount),
2745
+ incrementalBaseRevenue,
2648
2746
  rules.maxBaseRevenueShare
2649
- ).amount;
2650
- const incrementalCappedAward = bigintMin(incrementalUncappedAward, awardPoolRemaining);
2651
- state.cappedAwardAmount += incrementalCappedAward;
2652
- awardPoolRemaining -= incrementalCappedAward;
2747
+ );
2748
+ const incrementalCappedAward = minPrice(incrementalUncappedAward, awardPoolRemaining);
2749
+ referrerState.cappedAward = addPrices(referrerState.cappedAward, incrementalCappedAward);
2750
+ awardPoolRemaining = subtractPrice(awardPoolRemaining, incrementalCappedAward);
2653
2751
  }
2654
2752
  }
2655
- const sortedEntries = [...referrerStates.entries()].sort(([a, stateA], [b, stateB]) => {
2656
- if (stateB.cappedAwardAmount !== stateA.cappedAwardAmount) {
2657
- return stateB.cappedAwardAmount > stateA.cappedAwardAmount ? 1 : -1;
2658
- }
2659
- if (stateB.totalIncrementalDuration !== stateA.totalIncrementalDuration) {
2660
- return stateB.totalIncrementalDuration - stateA.totalIncrementalDuration;
2753
+ const sortedEntries = [...referrerStates.entries()].sort(
2754
+ ([referrerIdA, referrerStateA], [referrerIdB, referrerStateB]) => {
2755
+ if (referrerStateB.cappedAward.amount !== referrerStateA.cappedAward.amount) {
2756
+ return referrerStateB.cappedAward.amount > referrerStateA.cappedAward.amount ? 1 : -1;
2757
+ }
2758
+ if (referrerStateB.totalIncrementalDuration !== referrerStateA.totalIncrementalDuration) {
2759
+ return referrerStateB.totalIncrementalDuration - referrerStateA.totalIncrementalDuration;
2760
+ }
2761
+ if (referrerIdB > referrerIdA) return 1;
2762
+ if (referrerIdB < referrerIdA) return -1;
2763
+ return 0;
2661
2764
  }
2662
- if (b > a) return 1;
2663
- if (b < a) return -1;
2664
- return 0;
2665
- });
2765
+ );
2666
2766
  const awardedReferrers = sortedEntries.map(
2667
- ([referrerAddr, state], index) => {
2767
+ ([referrerId, referrerState], index) => {
2668
2768
  const baseMetrics = buildReferrerMetrics(
2669
- referrerAddr,
2670
- state.totalReferrals,
2671
- state.totalIncrementalDuration,
2672
- priceEth(state.totalRevenueContributionAmount)
2769
+ referrerId,
2770
+ referrerState.totalReferrals,
2771
+ referrerState.totalIncrementalDuration,
2772
+ referrerState.totalRevenueContribution
2673
2773
  );
2674
2774
  const revShareMetrics = buildReferrerMetricsRevShareCap(baseMetrics, rules);
2675
2775
  const rankedMetrics = buildRankedReferrerMetricsRevShareCap(
@@ -2684,14 +2784,14 @@ var buildReferrerLeaderboardRevShareCap = (events, rules, accurateAsOf) => {
2684
2784
  return buildAwardedReferrerMetricsRevShareCap(
2685
2785
  rankedMetrics,
2686
2786
  uncappedAward,
2687
- priceUsdc(state.cappedAwardAmount),
2787
+ referrerState.cappedAward,
2688
2788
  rules
2689
2789
  );
2690
2790
  }
2691
2791
  );
2692
2792
  const aggregatedMetrics = buildAggregatedReferrerMetricsRevShareCap(
2693
2793
  awardedReferrers,
2694
- priceUsdc(awardPoolRemaining)
2794
+ awardPoolRemaining
2695
2795
  );
2696
2796
  const referrers = new Map(awardedReferrers.map((r) => [r.referrer, r]));
2697
2797
  return { awardModel: rules.awardModel, rules, aggregatedMetrics, referrers, accurateAsOf };