Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Real metric names #99

Merged
merged 12 commits into from
Jul 29, 2024
34 changes: 7 additions & 27 deletions packages/nextjs/app/types/OSO.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,12 @@
export interface OSOResponse {
onchain_metrics_by_project_v1: OnchainMetricsByProject[];
}

// This data is easy to get right now so we can use it for testing if necessary - We will remove later when the actual data is available
export interface OnchainMetricsByProject {
active_contract_count_90_days: number;
address_count: number;
address_count_90_days: number;
days_since_first_transaction: number;
display_name: string;
event_source: string;
gas_fees_sum: number;
gas_fees_sum_6_months: number;
high_activity_address_count_90_days: number;
low_activity_address_count_90_days: number;
medium_activity_address_count_90_days: number;
multi_project_address_count_90_days: number;
new_address_count_90_days: number;
project_id: string;
project_name: string;
project_namespace: string;
project_source: string;
returning_address_count_90_days: number;
transaction_count: number;
transaction_count_6_months: number;
onchain_metrics_by_project_v1: RF4ImpactMetricsByProject[];
}

// These are the actual metrics we will be using when the data is provided by OSO
export interface RF4ImpactMetricsByProject {
project_id: string;
project_name: string;
check_oss_requirements: boolean;
application_id: string; // Application ID: A unique project application id (generated by Agora).
is_oss: boolean; // Eligible for OSS Multiplier: Whether the project's contract code and GitHub repo(s) were approved by the review committee as meeting open source software (OSS) requirements.
gas_fees: number; //**Gas Fees**: Sum of a project's total contribution to gas fees across the Superchain. Gas fees are the primary recurring revenue source for the Superchain and a key indicator of aggregate blockspace demand. A project’s gas fee contribution is influenced by its total volume of contract interactions, the computational complexity of those interactions, and the state of the underlying gas market at the time of those transactions. In the long run, gas fees are what will power Retro Funding and enable it to continue in perpetuity. All members of the Superchain have committed at least 15% of their gross profit from gas fees to Retro Funding. Supporting projects that generate revenue in the form of gas fees helps power the economic engine of the Superchain.
transaction_count: number; //**Total Transactions**: Count of a project’s transactions over the RF4 scope period October 2023 - June 2024. Optimism is a Layer 2 roll-up designed to improve the transaction throughput and reduce the fees on Ethereum. Layer 2s are crucial for scaling Ethereum because they help address the network's congestion issues without compromising its security or decentralization. Transaction counts are an important indicator for assessing the adoption and usage of all the new blockspace made available by the Superchain. Projects that have a sustained, high transaction count provide a clear signal of network growth and blockspace demand.
trusted_transaction_count: number; //**Interactions from Trusted Optimism Users**: Count of a project’s transactions performed by trusted users, over the RF4 scope period October 2023 - June 2024. Bots, airdrop farming, and sybil attacks are longstanding problems in crypto. There are several teams in the Optimism ecosystem building reputation models for labeling “trusted users” in a privacy-preserving way. This metric aggregates reputation data from multiple platforms ([Farcaster](https://docs.farcaster.xyz/learn/architecture/hubs), [Passport](https://www.passport.xyz/), [EigenTrust by Karma3Labs](https://docs.karma3labs.com/eigentrust)) and only considers transactions that come from trusted users, a small subset of all active addresses on the Superchain. By tracking interactions specifically from trusted users, we gain a picture of blockspace demand that is less influenced by the effects of bots / farmers / sybils.
Expand All @@ -43,4 +19,8 @@ export interface RF4ImpactMetricsByProject {
recurring_addresses: number; //**Recurring Addresses**: Count of addresses that have interacted with the project in at least 3 separate months over the RF4 scope period (October 2023 - June 2024). Recurring addresses are a proxy for recurring users. It is especially relevant to projects where users may explicitly choose to interact with the project from a distinct addresses in order to preserve their privacy. By counting the number of distinct addresses that have interacted with a project over the course of at least three distinct calendar months during the RF4 scope period, this metric provides a view of user quality that complements metrics derived from the "trusted user" model. A high count of recurring addresses signals strong project loyalty and a good user experience.
trusted_recurring_users: number; //**Trusted Recurring Users**: Count of trusted users who have interacted with the project in at least 3 separate months over the RF4 scope period (October 2023 - June 2024). Many crypto natives are curious to try out new protocols. But churn and user retention are major issues. Recurring users represent the most loyal and committed segment of a project's user base. This metric considers users who have interacted with a project over the course of at least three distinct calendar months during the RF4 scope period. Thus, it is intended to reflect sustained interest and ongoing engagement over time. A high count of recurring users signals strong project loyalty and a good user experience, and helps separate the fads from the future.
power_user_addresses: number; //**Power User Addresses**: Count of 'power user' addresses that have interacted with the project over the RF4 scope period (October 2023 - June 2024). This metric reflects the degree which a project has attracted attention from the most active and engaged users on the Superchain. A `power user` is defined as an address that has made at least 100 transactions, across at least 10 different projects, on at least 30 days, over the RF4 scope period. A project is counted by this metric if has at least one interaction from a power user. Power users are critical early adopters for the ecosystem.
openrank_trusted_users_count: number; // OpenRank Trusted Users: Count of addresses in the badgeholder "web of trust" who have interacted with the project over the RF4 scope period (October 2023 - June 2024). EigenTrust, aka OpenRank, is a reputation algorithm being applied by Karma3Labs to the Farcaster social graph. To seed the "web of trust", we begin with a list of 132 badgeholder addresses, look up their Farcaster IDs (present for 68 of the 132 addresses), and use OpenRank to identify those users' 100 closest connections. The result is a set of around 5000 addresses that have the closest social connection to the badgeholder community. Finally, we counts the number of addresses in the web of trust who have interacted with a given project. Note: this is an experimental metric designed and results in an even smaller but potentially higher signal subset of users than the "trusted user" model applied elsewhere.
log_gas_fees: number; // LOGSCALE: Gas Fees: Sum of a project's total contribution to gas fees across the Superchain over the RF4 scope period October 2023 - June 2024, adjusted to a logarithmic scale. Gas fees are the primary recurring revenue source for the Superchain and a key indicator of aggregate blockspace demand. A project’s gas fee contribution is influenced by its total volume of contract interactions, the computational complexity of those interactions, and the state of the underlying gas market at the time of those transactions. In the long run, gas fees are what will power Retro Funding and enable it to continue in perpetuity. All members of the Superchain have committed at least 15% of their gross profit from gas fees to Retro Funding. Supporting projects that generate revenue in the form of gas fees helps power the economic engine of the Superchain. This indicator is transformed to a logarithmic scale (log10(gas_fees + 1)). Logarithmic scales are useful for metrics that span several orders of magnitude such as gas fees and transactions and have strong compounding effects. On a log scale, a project with an impact metric value of 100 (10^2) is 2X more impactful than one with a value of 10 (10^1), not 10X. Badgeholders are advised to use either a log scale or a normal (linear) scale in their ballots, not both.
log_transaction_count: number; // LOGSCALE: Total Transactions: Count of a project’s transactions over the RF4 scope period October 2023 - June 2024, adjusted to a logarithmic scale. Optimism is a Layer 2 roll-up designed to improve the transaction throughput and reduce the fees on Ethereum. Layer 2s are crucial for scaling Ethereum because they help address the network's congestion issues without compromising its security or decentralization. Transaction counts are an important indicator for assessing the adoption and usage of all the new blockspace made available by the Superchain. Projects that have a sustained, high transaction count provide a clear signal of network growth and blockspace demand. This indicator includes successful transactions with a to_address owned by the project, as well as internal transactions that originate from one of the project's contracts and interact with the canonical EntryPoint (EIP 4337) contracts. This indicator is transformed to a logarithmic scale (log10(gas_fees + 1)). Logarithmic scales are useful for metrics that span several orders of magnitude such as gas fees and transactions and have strong compounding effects. On a log scale, a project with an impact metric value of 100 (10^2) is 2X more impactful than one with a value of 10 (10^1), not 10X. Badgeholders are advised to use either a log scale or a normal (linear) scale in their ballots, not both.
log_trusted_transaction_count: number; // LOGSCALE: Interactions from Trusted Optimism Users: Count of a project’s transactions performed by trusted users over the RF4 scope period October 2023 - June 2024, adjusted to a logarithmic scale. Bots, airdrop farming, and sybil attacks are longstanding problems in crypto. This metric is designed to filter out these types of interactions and focus on the activity of a small subset of trusted users (less than 5% of all active addresses on the Superchain). By tracking interactions specifically from trusted users, we gain a picture of blockspace demand that is less influenced by the effects of bots / farmers / sybils. A "trusted user" represents an address linked to an account the meets a certain threshold of reputation. Currently, there are several teams in the Optimism ecosystem building reputation models in a privacy-preserving way. This metric aggregates reputation data from multiple platforms (Farcaster, Passport, EigenTrust by Karma3Labs), and the Optimist NFT collection. In order to be consider a trusted user, an address must meet at least two of the following requirements as of 2024-05-21: have a Farcaster ID of 20939, have a Passport score of 20 points or higher, have a Karma3Labs EigenTrust GlobalRank in the top 42,000 of Farcaster users, hold an Optimist NFT in their wallet, or qualified for at least two (out of four) Optimism airdrops. This indicator is transformed to a logarithmic scale (log10(gas_fees + 1)). Logarithmic scales are useful for metrics that span several orders of magnitude such as gas fees and transactions and have strong compounding effects. On a log scale, a project with an impact metric value of 100 (10^2) is 2X more impactful than one with a value of 10 (10^1), not 10X. Badgeholders are advised to use either a log scale or a normal (linear) scale in their ballots, not both.
}
3 changes: 2 additions & 1 deletion packages/nextjs/pages/api/etl/impact_metric_weights.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"recurring_addresses": 5.163663192473145,
"openrank_trusted_users_count": 4.054655175020334,
"trusted_recurring_users": 8.666799294102633,
"log_transaction_count": 4.441688461052498
"log_transaction_count": 4.441688461052498,
"impact_index": 1.0
escottalexander marked this conversation as resolved.
Show resolved Hide resolved
}
}
13 changes: 8 additions & 5 deletions packages/nextjs/pages/api/etl/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import weightingsJSON from "./weightings.json";
import weightData from "./impact_metric_weights.json";
import { FlattenMaps, Types, startSession } from "mongoose";
escottalexander marked this conversation as resolved.
Show resolved Hide resolved
import type { NextApiRequest, NextApiResponse } from "next";
import { OnchainMetricsByProject } from "~~/app/types/OSO";
import { RF4ImpactMetricsByProject } from "~~/app/types/OSO";
import dbConnect from "~~/services/mongodb/dbConnect";
import ETLLog from "~~/services/mongodb/models/etlLog";
import GlobalScore, { TempGlobalScore } from "~~/services/mongodb/models/globalScore";
Expand All @@ -10,6 +10,8 @@ import Project from "~~/services/mongodb/models/project";
import ProjectMovement, { IProjectMovement, TempProjectMovement } from "~~/services/mongodb/models/projectMovement";
import ProjectScore, { IProjectScore, TempProjectScore } from "~~/services/mongodb/models/projectScore";

const { metrics: weightingsJSON } = weightData;

// Vercel Serverless Function Config
export const config = {
maxDuration: 60, // seconds
Expand Down Expand Up @@ -47,8 +49,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
await TempProjectScore.deleteMany({});
await TempProjectMovement.deleteMany({});

// Get all the mapping data
// Get mapping of OSO project names to Agora application IDs
const { mapping } = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/stub/mapping`).then(res => res.json());

// Get metrics that are activated
const metrics = await Metric.findAllActivated();
if (!metrics) {
Expand All @@ -70,7 +73,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
if (!seriesResponse) {
throw new Error(`No OSO Data for ${day}`);
}
const osoData = seriesResponse.data as OnchainMetricsByProject[];
const osoData = seriesResponse.data as RF4ImpactMetricsByProject[];
console.log(`Processing OSO response for each project on ${day.toISOString().split("T")[0]}`);

const globalScoreData = Object.assign({}, metricNamesObj) as { [key in keyof Metrics]: number };
Expand All @@ -87,7 +90,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)

const projectMetrics = {} as { [key in keyof Metrics]: number };
for (const metric of metrics) {
const metricValue = project[metric.name as keyof OnchainMetricsByProject];
const metricValue = project[metric.name as keyof RF4ImpactMetricsByProject];
if (!isNaN(metricValue as number)) {
projectMetrics[metric.name as keyof Metrics] = parseInt(metricValue as string);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/nextjs/pages/api/stub/series/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import seriesJSON from "./series.json";
import type { NextApiRequest, NextApiResponse } from "next";
import { OnchainMetricsByProject } from "~~/app/types/OSO";
import { RF4ImpactMetricsByProject } from "~~/app/types/OSO";

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== "GET") {
return res.status(405).json({ message: "Method not allowed." });
}
const series = seriesJSON as { [key: string]: OnchainMetricsByProject[] };
const series = seriesJSON as { [key: string]: RF4ImpactMetricsByProject[] };
// check if date params are present
let { date = new Date().toUTCString() } = req.query;

Expand Down
Loading
Loading