Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/bright-foxes-dance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@namehash/ens-referrals": minor
---

Rename rev-share-limit API fields for clarity: `minQualifiedRevenueContribution` → `minBaseRevenueContribution`, `qualifiedRevenueShare` → `maxBaseRevenueShare`, `standardAwardValue` → `uncappedAwardValue`, `awardPoolApproxValue` → `cappedAwardValue`. Rename `totalAwardPoolValue` → `awardPool` for both rev-share-limit and pie-split rules. Extract the previously hardcoded `BASE_REVENUE_CONTRIBUTION_PER_YEAR` constant into a per-edition `baseAnnualRevenueContribution` rule field.
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ export const emptyReferralLeaderboard: ReferrerLeaderboardPieSplit = {
awardModel: ReferralProgramAwardModels.PieSplit,
rules: {
awardModel: ReferralProgramAwardModels.PieSplit,
totalAwardPoolValue: parseUsdc("10000"),
awardPool: parseUsdc("10000"),
maxQualifiedReferrers: 10,
startTime: 1735689600,
endTime: 1767225599,
Expand All @@ -205,7 +205,7 @@ export const populatedReferrerLeaderboard: ReferrerLeaderboardPieSplit = {
awardModel: ReferralProgramAwardModels.PieSplit,
rules: {
awardModel: ReferralProgramAwardModels.PieSplit,
totalAwardPoolValue: parseUsdc("10000"),
awardPool: parseUsdc("10000"),
maxQualifiedReferrers: 10,
startTime: 1735689600,
endTime: 1767225599,
Expand Down Expand Up @@ -698,7 +698,7 @@ export const referrerLeaderboardPageResponseOk = {
awardModel: ReferralProgramAwardModels.PieSplit,
rules: {
awardModel: ReferralProgramAwardModels.PieSplit,
totalAwardPoolValue: parseUsdc("10000"),
awardPool: parseUsdc("10000"),
maxQualifiedReferrers: 10,
startTime: 1735689600,
endTime: 1767225599,
Expand Down
8 changes: 4 additions & 4 deletions packages/ens-referrals/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,11 @@ if (response.responseCode === ReferrerLeaderboardPageResponseCodes.Ok) {

if (leaderboardPage.awardModel === ReferralProgramAwardModels.RevShareLimit) {
console.log(
`Min Qualified Revenue Contribution: ${leaderboardPage.rules.minQualifiedRevenueContribution}`,
`Min Base Revenue Contribution: ${leaderboardPage.rules.minBaseRevenueContribution}`,
);
console.log(`Qualified Revenue Share: ${leaderboardPage.rules.qualifiedRevenueShare}`);
console.log(`Max Base Revenue Share: ${leaderboardPage.rules.maxBaseRevenueShare}`);
console.log(
`Tentative award for the best referrer: ${firstReferrer !== null ? firstReferrer.awardPoolApproxValue : noReferrersFallback}`,
`Tentative award for the top ranked referrer: ${firstReferrer !== null ? firstReferrer.cappedAwardValue : noReferrersFallback}`,
);
}
}
Expand Down Expand Up @@ -146,7 +146,7 @@ if (response.responseCode === ReferrerMetricsEditionsResponseCodes.Ok) {
console.log(
`Referrer's total base revenue contribution: ${detail.referrer.totalBaseRevenueContribution}`,
);
console.log(`Referrer's standard award value: ${detail.referrer.standardAwardValue}`);
console.log(`Referrer's uncapped award value: ${detail.referrer.uncappedAwardValue}`);
}
}
}
Expand Down
58 changes: 32 additions & 26 deletions packages/ens-referrals/src/v1/api/zod-schemas.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ describe("makeReferralProgramEditionConfigSetArraySchema", () => {
displayName: "December 2025",
rules: {
awardModel: ReferralProgramAwardModels.PieSplit,
totalAwardPoolValue: parseUsdc("1000"),
awardPool: parseUsdc("1000"),
maxQualifiedReferrers: 100,
startTime: 1000000,
endTime: 2000000,
Expand All @@ -43,9 +43,10 @@ describe("makeReferralProgramEditionConfigSetArraySchema", () => {
displayName: "January 2026",
rules: {
awardModel: ReferralProgramAwardModels.RevShareLimit,
totalAwardPoolValue: parseUsdc("500"),
minQualifiedRevenueContribution: parseUsdc("10"),
qualifiedRevenueShare: 0.5,
awardPool: parseUsdc("500"),
minBaseRevenueContribution: parseUsdc("10"),
baseAnnualRevenueContribution: parseUsdc("5"),
maxBaseRevenueShare: 0.5,
startTime: 1000000,
endTime: 2000000,
subregistryId,
Expand Down Expand Up @@ -92,14 +93,16 @@ describe("makeReferralProgramEditionConfigSetArraySchema", () => {

const rules = revShareLimit!.rules as {
awardModel: typeof ReferralProgramAwardModels.RevShareLimit;
totalAwardPoolValue: { amount: bigint; currency: string };
minQualifiedRevenueContribution: { amount: bigint; currency: string };
qualifiedRevenueShare: number;
awardPool: { amount: bigint; currency: string };
minBaseRevenueContribution: { amount: bigint; currency: string };
baseAnnualRevenueContribution: { amount: bigint; currency: string };
maxBaseRevenueShare: number;
};
expect(rules.totalAwardPoolValue).toBeDefined();
expect(rules.minQualifiedRevenueContribution).toBeDefined();
expect(typeof rules.qualifiedRevenueShare).toBe("number");
expect(rules.qualifiedRevenueShare).toBe(0.5);
expect(rules.awardPool).toBeDefined();
expect(rules.minBaseRevenueContribution).toBeDefined();
expect(rules.baseAnnualRevenueContribution).toBeDefined();
expect(typeof rules.maxBaseRevenueShare).toBe("number");
expect(rules.maxBaseRevenueShare).toBe(0.5);
expect(revShareLimit!.rules.areAwardsDistributed).toBe(
revShareLimitEdition.rules.areAwardsDistributed,
);
Expand Down Expand Up @@ -189,7 +192,7 @@ describe("makeReferrerLeaderboardPageSchema", () => {
awardModel: ReferralProgramAwardModels.PieSplit,
rules: {
awardModel: ReferralProgramAwardModels.PieSplit,
totalAwardPoolValue: parseUsdc("1000"),
awardPool: parseUsdc("1000"),
maxQualifiedReferrers: 100,
startTime: 1000000,
endTime: 2000000,
Expand All @@ -214,9 +217,10 @@ describe("makeReferrerLeaderboardPageSchema", () => {
awardModel: ReferralProgramAwardModels.RevShareLimit,
rules: {
awardModel: ReferralProgramAwardModels.RevShareLimit,
totalAwardPoolValue: parseUsdc("2000"),
minQualifiedRevenueContribution: parseUsdc("10"),
qualifiedRevenueShare: 0.5,
awardPool: parseUsdc("2000"),
minBaseRevenueContribution: parseUsdc("10"),
baseAnnualRevenueContribution: parseUsdc("5"),
maxBaseRevenueShare: 0.5,
startTime: 1000000,
endTime: 2000000,
subregistryId,
Expand Down Expand Up @@ -275,7 +279,7 @@ describe("makeReferrerLeaderboardPageSchema", () => {
...pieSplitLeaderboardPage,
rules: {
...pieSplitLeaderboardPage.rules,
totalAwardPoolValue: { amount: "not-a-number", currency: CurrencyIds.USDC },
awardPool: { amount: "not-a-number", currency: CurrencyIds.USDC },
},
};

Expand Down Expand Up @@ -307,7 +311,7 @@ describe("makeReferralProgramEditionSummarySchema", () => {
status: ReferralProgramEditionStatuses.Active,
rules: {
awardModel: ReferralProgramAwardModels.PieSplit,
totalAwardPoolValue: parseUsdc("1000"),
awardPool: parseUsdc("1000"),
maxQualifiedReferrers: 100,
startTime: 1000000,
endTime: 2000000,
Expand All @@ -324,9 +328,10 @@ describe("makeReferralProgramEditionSummarySchema", () => {
status: ReferralProgramEditionStatuses.Active,
rules: {
awardModel: ReferralProgramAwardModels.RevShareLimit,
totalAwardPoolValue: parseUsdc("2000"),
minQualifiedRevenueContribution: parseUsdc("10"),
qualifiedRevenueShare: 0.5,
awardPool: parseUsdc("2000"),
minBaseRevenueContribution: parseUsdc("10"),
baseAnnualRevenueContribution: parseUsdc("5"),
maxBaseRevenueShare: 0.5,
startTime: 1000000,
endTime: 2000000,
subregistryId,
Expand Down Expand Up @@ -423,7 +428,7 @@ describe("makeReferrerEditionMetricsSchema", () => {

const pieSplitRules = {
awardModel: ReferralProgramAwardModels.PieSplit,
totalAwardPoolValue: parseUsdc("1000"),
awardPool: parseUsdc("1000"),
maxQualifiedReferrers: 100,
startTime: 1000000,
endTime: 2000000,
Expand Down Expand Up @@ -506,9 +511,10 @@ describe("makeReferrerEditionMetricsSchema", () => {
type: ReferrerEditionMetricsTypeIds.Ranked,
rules: {
awardModel: ReferralProgramAwardModels.RevShareLimit,
totalAwardPoolValue: parseUsdc("2000"),
minQualifiedRevenueContribution: parseUsdc("10"),
qualifiedRevenueShare: 0.5,
awardPool: parseUsdc("2000"),
minBaseRevenueContribution: parseUsdc("10"),
baseAnnualRevenueContribution: parseUsdc("5"),
maxBaseRevenueShare: 0.5,
startTime: 1000000,
endTime: 2000000,
subregistryId,
Expand All @@ -523,8 +529,8 @@ describe("makeReferrerEditionMetricsSchema", () => {
totalBaseRevenueContribution: parseUsdc("150"),
rank: 1,
isQualified: true,
standardAwardValue: parseUsdc("200"),
awardPoolApproxValue: parseUsdc("200"),
uncappedAwardValue: parseUsdc("200"),
cappedAwardValue: parseUsdc("200"),
isAdminDisqualified: false,
adminDisqualificationReason: null,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export function serializeReferralProgramRulesPieSplit(
): SerializedReferralProgramRulesPieSplit {
return {
awardModel: rules.awardModel,
totalAwardPoolValue: serializePriceUsdc(rules.totalAwardPoolValue),
awardPool: serializePriceUsdc(rules.awardPool),
maxQualifiedReferrers: rules.maxQualifiedReferrers,
startTime: rules.startTime,
endTime: rules.endTime,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import type { ReferralProgramRulesPieSplit } from "../rules";
* Serialized representation of {@link ReferralProgramRulesPieSplit}.
*/
export interface SerializedReferralProgramRulesPieSplit
extends Omit<ReferralProgramRulesPieSplit, "totalAwardPoolValue" | "rulesUrl"> {
totalAwardPoolValue: SerializedPriceUsdc;
extends Omit<ReferralProgramRulesPieSplit, "awardPool" | "rulesUrl"> {
awardPool: SerializedPriceUsdc;
rulesUrl: string;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export const makeReferralProgramRulesPieSplitSchema = (
) =>
makeBaseReferralProgramRulesSchema(valueLabel).safeExtend({
awardModel: z.literal(ReferralProgramAwardModels.PieSplit),
totalAwardPoolValue: makePriceUsdcSchema(`${valueLabel}.totalAwardPoolValue`),
awardPool: makePriceUsdcSchema(`${valueLabel}.awardPool`),
maxQualifiedReferrers: makeNonNegativeIntegerSchema(`${valueLabel}.maxQualifiedReferrers`),
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,10 @@ export interface AwardedReferrerMetricsPieSplit extends RankedReferrerMetricsPie
awardPoolShare: number;

/**
* The approximate USDC value of the referrer's share of the {@link ReferralProgramRulesPieSplit.totalAwardPoolValue}.
* The approximate USDC value of the referrer's share of the {@link ReferralProgramRulesPieSplit.awardPool}.
*
* @invariant Guaranteed to be a valid PriceUsdc with amount between 0 and {@link ReferralProgramRulesPieSplit.totalAwardPoolValue.amount} (inclusive)
* @invariant Calculated as: `awardPoolShare` * {@link ReferralProgramRulesPieSplit.totalAwardPoolValue.amount}
* @invariant Guaranteed to be a valid PriceUsdc with amount between 0 and {@link ReferralProgramRulesPieSplit.awardPool.amount} (inclusive)
* @invariant Calculated as: `awardPoolShare` * {@link ReferralProgramRulesPieSplit.awardPool.amount}
*/
awardPoolApproxValue: PriceUsdc;
}
Expand All @@ -197,9 +197,9 @@ export const validateAwardedReferrerMetricsPieSplit = (
referrer.awardPoolApproxValue,
);

if (referrer.awardPoolApproxValue.amount > rules.totalAwardPoolValue.amount) {
if (referrer.awardPoolApproxValue.amount > rules.awardPool.amount) {
throw new Error(
`AwardedReferrerMetricsPieSplit: awardPoolApproxValue.amount ${referrer.awardPoolApproxValue.amount.toString()} exceeds totalAwardPoolValue.amount ${rules.totalAwardPoolValue.amount.toString()}.`,
`AwardedReferrerMetricsPieSplit: awardPoolApproxValue.amount ${referrer.awardPoolApproxValue.amount.toString()} exceeds awardPool.amount ${rules.awardPool.amount.toString()}.`,
);
}
};
Expand All @@ -211,8 +211,8 @@ export const buildAwardedReferrerMetricsPieSplit = (
): AwardedReferrerMetricsPieSplit => {
const awardPoolShare = calcReferrerAwardPoolSharePieSplit(referrer, aggregatedMetrics);

// Calculate the approximate USDC value by multiplying the share by the total award pool value
const awardPoolApproxValue = scalePrice(rules.totalAwardPoolValue, awardPoolShare);
// Calculate the approximate USDC value by multiplying the share by the award pool
const awardPoolApproxValue = scalePrice(rules.awardPool, awardPoolShare);

const result = {
...referrer,
Expand Down
12 changes: 5 additions & 7 deletions packages/ens-referrals/src/v1/award-models/pie-split/rules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ export interface ReferralProgramRulesPieSplit extends BaseReferralProgramRules {
awardModel: typeof ReferralProgramAwardModels.PieSplit;

/**
* The total value of the award pool in USDC.
* The award pool in USDC.
*
* NOTE: Awards will actually be distributed in $ENS tokens.
*/
totalAwardPoolValue: PriceUsdc;
awardPool: PriceUsdc;

/**
* The maximum number of referrers that will qualify to receive a non-zero `awardPoolShare`.
Expand All @@ -33,17 +33,15 @@ export interface ReferralProgramRulesPieSplit extends BaseReferralProgramRules {
}

export const validateReferralProgramRulesPieSplit = (rules: ReferralProgramRulesPieSplit): void => {
makePriceUsdcSchema("ReferralProgramRulesPieSplit.totalAwardPoolValue").parse(
rules.totalAwardPoolValue,
);
makePriceUsdcSchema("ReferralProgramRulesPieSplit.awardPool").parse(rules.awardPool);

validateNonNegativeInteger(rules.maxQualifiedReferrers);

validateBaseReferralProgramRules(rules);
};

export const buildReferralProgramRulesPieSplit = (
totalAwardPoolValue: PriceUsdc,
awardPool: PriceUsdc,
maxQualifiedReferrers: number,
startTime: UnixTimestamp,
endTime: UnixTimestamp,
Expand All @@ -53,7 +51,7 @@ export const buildReferralProgramRulesPieSplit = (
): ReferralProgramRulesPieSplit => {
const result = {
awardModel: ReferralProgramAwardModels.PieSplit,
totalAwardPoolValue,
awardPool,
maxQualifiedReferrers,
startTime,
endTime,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ export function serializeReferralProgramRulesRevShareLimit(
): SerializedReferralProgramRulesRevShareLimit {
return {
awardModel: rules.awardModel,
totalAwardPoolValue: serializePriceUsdc(rules.totalAwardPoolValue),
minQualifiedRevenueContribution: serializePriceUsdc(rules.minQualifiedRevenueContribution),
qualifiedRevenueShare: rules.qualifiedRevenueShare,
awardPool: serializePriceUsdc(rules.awardPool),
minBaseRevenueContribution: serializePriceUsdc(rules.minBaseRevenueContribution),
baseAnnualRevenueContribution: serializePriceUsdc(rules.baseAnnualRevenueContribution),
maxBaseRevenueShare: rules.maxBaseRevenueShare,
startTime: rules.startTime,
endTime: rules.endTime,
subregistryId: rules.subregistryId,
Expand Down Expand Up @@ -74,8 +75,8 @@ export function serializeAwardedReferrerMetricsRevShareLimit(
totalBaseRevenueContribution: serializePriceUsdc(metrics.totalBaseRevenueContribution),
rank: metrics.rank,
isQualified: metrics.isQualified,
standardAwardValue: serializePriceUsdc(metrics.standardAwardValue),
awardPoolApproxValue: serializePriceUsdc(metrics.awardPoolApproxValue),
uncappedAwardValue: serializePriceUsdc(metrics.uncappedAwardValue),
cappedAwardValue: serializePriceUsdc(metrics.cappedAwardValue),
isAdminDisqualified: metrics.isAdminDisqualified,
adminDisqualificationReason: metrics.adminDisqualificationReason,
};
Expand All @@ -95,8 +96,8 @@ export function serializeUnrankedReferrerMetricsRevShareLimit(
totalBaseRevenueContribution: serializePriceUsdc(metrics.totalBaseRevenueContribution),
rank: metrics.rank,
isQualified: metrics.isQualified,
standardAwardValue: serializePriceUsdc(metrics.standardAwardValue),
awardPoolApproxValue: serializePriceUsdc(metrics.awardPoolApproxValue),
uncappedAwardValue: serializePriceUsdc(metrics.uncappedAwardValue),
cappedAwardValue: serializePriceUsdc(metrics.cappedAwardValue),
isAdminDisqualified: metrics.isAdminDisqualified,
adminDisqualificationReason: metrics.adminDisqualificationReason,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@ import type { ReferralProgramRulesRevShareLimit } from "../rules";
export interface SerializedReferralProgramRulesRevShareLimit
extends Omit<
ReferralProgramRulesRevShareLimit,
"totalAwardPoolValue" | "minQualifiedRevenueContribution" | "rulesUrl"
"awardPool" | "minBaseRevenueContribution" | "baseAnnualRevenueContribution" | "rulesUrl"
> {
totalAwardPoolValue: SerializedPriceUsdc;
minQualifiedRevenueContribution: SerializedPriceUsdc;
awardPool: SerializedPriceUsdc;
minBaseRevenueContribution: SerializedPriceUsdc;
baseAnnualRevenueContribution: SerializedPriceUsdc;
rulesUrl: string;
}

Expand All @@ -47,13 +48,13 @@ export interface SerializedAwardedReferrerMetricsRevShareLimit
AwardedReferrerMetricsRevShareLimit,
| "totalRevenueContribution"
| "totalBaseRevenueContribution"
| "standardAwardValue"
| "awardPoolApproxValue"
| "uncappedAwardValue"
| "cappedAwardValue"
> {
totalRevenueContribution: SerializedPriceEth;
totalBaseRevenueContribution: SerializedPriceUsdc;
standardAwardValue: SerializedPriceUsdc;
awardPoolApproxValue: SerializedPriceUsdc;
uncappedAwardValue: SerializedPriceUsdc;
cappedAwardValue: SerializedPriceUsdc;
}

/**
Expand All @@ -64,13 +65,13 @@ export interface SerializedUnrankedReferrerMetricsRevShareLimit
UnrankedReferrerMetricsRevShareLimit,
| "totalRevenueContribution"
| "totalBaseRevenueContribution"
| "standardAwardValue"
| "awardPoolApproxValue"
| "uncappedAwardValue"
| "cappedAwardValue"
> {
totalRevenueContribution: SerializedPriceEth;
totalBaseRevenueContribution: SerializedPriceUsdc;
standardAwardValue: SerializedPriceUsdc;
awardPoolApproxValue: SerializedPriceUsdc;
uncappedAwardValue: SerializedPriceUsdc;
cappedAwardValue: SerializedPriceUsdc;
}

/**
Expand Down
Loading
Loading