diff --git a/db/migrations/1698085120905-Data.js b/db/migrations/1698266502449-Data.js similarity index 99% rename from db/migrations/1698085120905-Data.js rename to db/migrations/1698266502449-Data.js index d366e328..dca5ce41 100644 --- a/db/migrations/1698085120905-Data.js +++ b/db/migrations/1698266502449-Data.js @@ -1,5 +1,5 @@ -module.exports = class Data1698085120905 { - name = 'Data1698085120905' +module.exports = class Data1698266502449 { + name = 'Data1698266502449' async up(db) { await db.query(`CREATE TABLE "exchange_rate" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "pair" text NOT NULL, "base" text NOT NULL, "quote" text NOT NULL, "rate" numeric NOT NULL, CONSTRAINT "PK_5c5d27d2b900ef6cdeef0398472" PRIMARY KEY ("id"))`) @@ -56,7 +56,7 @@ module.exports = class Data1698085120905 { await db.query(`CREATE INDEX "IDX_11d344b3e0e03cdb6697dd61f7" ON "oeth_balancer_meta_pool_strategy" ("block_number") `) await db.query(`CREATE TABLE "oeth_strategy_holding_daily_stat" ("id" character varying NOT NULL, "symbol" text NOT NULL, "amount" numeric NOT NULL, "value" numeric NOT NULL, "strategy_daily_stat_id_id" character varying, CONSTRAINT "PK_7f1a62da5e53cf264c2f39b4acf" PRIMARY KEY ("id"))`) await db.query(`CREATE INDEX "IDX_4e867f220975e615e6077d860c" ON "oeth_strategy_holding_daily_stat" ("strategy_daily_stat_id_id") `) - await db.query(`CREATE TABLE "oeth_strategy_daily_stat" ("id" character varying NOT NULL, "total" numeric NOT NULL, "tvl" numeric NOT NULL, "daily_stat_id_id" character varying, CONSTRAINT "PK_8af1a0c60e67b05baf928787a8e" PRIMARY KEY ("id"))`) + await db.query(`CREATE TABLE "oeth_strategy_daily_stat" ("id" character varying NOT NULL, "name" text NOT NULL, "total" numeric NOT NULL, "tvl" numeric NOT NULL, "daily_stat_id_id" character varying, CONSTRAINT "PK_8af1a0c60e67b05baf928787a8e" PRIMARY KEY ("id"))`) await db.query(`CREATE INDEX "IDX_6c7096c96a000d8471256ca8fc" ON "oeth_strategy_daily_stat" ("daily_stat_id_id") `) await db.query(`CREATE TABLE "oeth_collateral_daily_stat" ("id" character varying NOT NULL, "symbol" text NOT NULL, "amount" numeric NOT NULL, "price" numeric NOT NULL, "value" numeric NOT NULL, "daily_stat_id_id" character varying, CONSTRAINT "PK_5fb23d7bae30dffe4543e7aa069" PRIMARY KEY ("id"))`) await db.query(`CREATE INDEX "IDX_a90045de50406be7bd56efd3ea" ON "oeth_collateral_daily_stat" ("daily_stat_id_id") `) diff --git a/schema-oeth.graphql b/schema-oeth.graphql index fc35455f..a4df54ad 100644 --- a/schema-oeth.graphql +++ b/schema-oeth.graphql @@ -191,6 +191,7 @@ type OETHDailyStat @entity { type OETHStrategyDailyStat @entity { id: ID! dailyStatId: OETHDailyStat! + name: String! total: BigInt! """ Sum of tokens in strategy diff --git a/schema.graphql b/schema.graphql index a66887e1..cb1120cf 100644 --- a/schema.graphql +++ b/schema.graphql @@ -254,6 +254,7 @@ type OETHDailyStat @entity { type OETHStrategyDailyStat @entity { id: ID! dailyStatId: OETHDailyStat! + name: String! total: BigInt! """ Sum of tokens in strategy diff --git a/src/model/generated/oethStrategyDailyStat.model.ts b/src/model/generated/oethStrategyDailyStat.model.ts index 53372934..4c2d8ebd 100644 --- a/src/model/generated/oethStrategyDailyStat.model.ts +++ b/src/model/generated/oethStrategyDailyStat.model.ts @@ -16,6 +16,9 @@ export class OETHStrategyDailyStat { @ManyToOne_(() => OETHDailyStat, {nullable: true}) dailyStatId!: OETHDailyStat + @Column_("text", {nullable: false}) + name!: string + @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) total!: bigint diff --git a/src/post-processors/daily-stats/daily-stats.ts b/src/post-processors/daily-stats/daily-stats.ts index a09a1ad0..7ab18914 100644 --- a/src/post-processors/daily-stats/daily-stats.ts +++ b/src/post-processors/daily-stats/daily-stats.ts @@ -212,30 +212,35 @@ async function updateDailyStats(ctx: Context, date: Date) { const dailyStrategyStats = [ new OETHStrategyDailyStat({ id: `${id}-CURVE`, + name: 'CURVE', dailyStatId: id as unknown as OETHDailyStat, tvl: lastCurve?.ethOwned || 0n, total: lastCurve?.ethOwned || 0n, }), new OETHStrategyDailyStat({ id: `${id}-VAULT`, + name: 'VAULT', dailyStatId: id as unknown as OETHDailyStat, tvl: vaultTotal, total: vaultTotal, }), new OETHStrategyDailyStat({ id: `${id}-BALANCER`, + name: 'BALANCER', dailyStatId: id as unknown as OETHDailyStat, tvl: balancerTotal, total: balancerTotal, }), new OETHStrategyDailyStat({ id: `${id}-FRAX`, + name: 'FRAX', dailyStatId: id as unknown as OETHDailyStat, tvl: lastFrax?.sfrxETH || 0n, total: frxETH, }), new OETHStrategyDailyStat({ id: `${id}-MORPHO`, + name: 'MORPHO', dailyStatId: id as unknown as OETHDailyStat, tvl: lastMorpho?.weth || 0n, total: lastMorpho?.weth || 0n, diff --git a/src/server-extension/resolvers/index.ts b/src/server-extension/resolvers/index.ts deleted file mode 100644 index 1fa13d97..00000000 --- a/src/server-extension/resolvers/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { ProofOfYieldResolver } from './proof-of-yields' -export { ProofOfYieldByIdResolver } from './proof-of-yield-by-id' \ No newline at end of file diff --git a/src/server-extension/resolvers/proof-of-yield-by-id.ts b/src/server-extension/resolvers/proof-of-yield-by-id.ts deleted file mode 100644 index de454ee0..00000000 --- a/src/server-extension/resolvers/proof-of-yield-by-id.ts +++ /dev/null @@ -1,106 +0,0 @@ -import { - Arg, - Field, - ObjectType, - Query, - Resolver, - registerEnumType, -} from 'type-graphql' -import type { EntityManager } from 'typeorm' - -import { OETH } from '../../model' - -// Define custom GraphQL ObjectType of the query result -@ObjectType() -export class ProofOfYieldByIdResult { - @Field(() => String, { nullable: false }) - id!: string - - @Field(() => Date, { nullable: false }) - timestamp!: Date - - @Field(() => Number, { nullable: false }) - apy!: number - - @Field(() => BigInt, { nullable: false }) - yield!: bigint - - @Field(() => BigInt, { nullable: false }) - fees!: bigint - - @Field(() => BigInt, { nullable: false }) - totalSupply!: bigint - - @Field(() => BigInt, { nullable: false }) - rebasingSupply!: bigint - - @Field(() => BigInt, { nullable: false }) - nonRebasingSupply!: bigint - - @Field(() => BigInt, { nullable: false }) - amoSupply!: bigint - - constructor(props: Partial) { - Object.assign(this, props) - } -} - -@Resolver() -export class ProofOfYieldByIdResolver { - constructor(private tx: () => Promise) {} - - @Query(() => ProofOfYieldByIdResult, { nullable: true }) - async proofOfYieldById( - @Arg('id') id: string, - ): Promise { - if (!id) { - return null - } - - const manager = await this.tx() - - const sql = `SELECT - $1 as timestamp, - oeth_data.rebasing_supply AS "rebasingSupply", - oeth_data.total_supply AS "totalSupply", - oeth_data.non_rebasing_supply AS "nonRebasingSupply", - apy_data.apy7_day_avg as apy, - curve_data.oeth_owned AS "amoSupply", - rebase_data.total_yield as yield, - rebase_data.total_fees as fees - FROM - (SELECT 1) AS dummy -- A dummy table to ensure we always get a row - LEFT JOIN LATERAL ( - SELECT oeth.rebasing_supply, oeth.total_supply, oeth.non_rebasing_supply - FROM oeth - WHERE DATE(oeth.timestamp) <= $1 - ORDER BY oeth.timestamp DESC - LIMIT 1 - ) AS oeth_data ON TRUE - LEFT JOIN LATERAL ( - SELECT apy.apy7_day_avg - FROM apy - WHERE DATE(apy.timestamp) <= $1 - ORDER BY apy.timestamp DESC - LIMIT 1 - ) AS apy_data ON TRUE - LEFT JOIN LATERAL ( - SELECT c.oeth_owned - FROM curve_lp c - WHERE DATE(c.timestamp) <= $1 - ORDER BY c.timestamp DESC - LIMIT 1 - ) AS curve_data ON TRUE - LEFT JOIN ( - SELECT - DATE(timestamp) AS date, - SUM(yield - fee) AS total_yield, - SUM(fee) AS total_fees - FROM rebase - GROUP BY DATE(timestamp) - ) AS rebase_data ON rebase_data.date = $1;` - - const result = await manager.getRepository(OETH).query(sql, [id]) - return result?.[0] - } -} diff --git a/src/server-extension/resolvers/proof-of-yields.ts b/src/server-extension/resolvers/proof-of-yields.ts deleted file mode 100644 index 7712b116..00000000 --- a/src/server-extension/resolvers/proof-of-yields.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { - Arg, - Field, - ObjectType, - Query, - Resolver, - registerEnumType, -} from 'type-graphql' -import type { EntityManager } from 'typeorm' - -import { OETH } from '../../model' - -// Define custom GraphQL ObjectType of the query result -@ObjectType() -export class ProofOfYieldResult { - @Field(() => String, { nullable: false }) - id!: string - - @Field(() => Date, { nullable: false }) - timestamp!: Date - - @Field(() => Number, { nullable: false }) - apy!: number - - @Field(() => BigInt, { nullable: false }) - yield!: bigint - - @Field(() => BigInt, { nullable: false }) - rebasingSupply!: bigint - - constructor(props: Partial) { - Object.assign(this, props) - } -} - -export enum OrderBy { - id_ASC = 'id_ASC', - id_DESC = 'id_DESC', - timestamp_ASC = 'timestamp_ASC', - timestamp_DESC = 'timestamp_DESC', -} - -registerEnumType(OrderBy, { name: 'OrderBy' }) - -@Resolver() -export class ProofOfYieldResolver { - constructor(private tx: () => Promise) {} - - @Query(() => [ProofOfYieldResult]) - async proofOfYields( - @Arg('limit', { nullable: true, defaultValue: 20 }) limit: number, - @Arg('offset', { nullable: true, defaultValue: 0 }) offset: number, - @Arg('orderBy', (type) => OrderBy, { - nullable: true, - defaultValue: OrderBy.timestamp_DESC, - }) - orderBy: OrderBy, - ): Promise { - const manager = await this.tx() - - let orderClause = '' - switch (orderBy) { - case 'id_ASC': - orderClause = 'o.date ASC' - break - case 'id_DESC': - orderClause = 'o.date DESC' - break - case 'timestamp_ASC': - orderClause = 'o.date ASC' - break - case 'timestamp_DESC': - orderClause = 'o.date DESC' - break - default: - throw new Error('Invalid orderBy value') - } - - const sql = `WITH - oeth_aggregated AS ( - SELECT - DATE(timestamp) AS date, - MAX(rebasing_supply) AS max_rebasing_supply - FROM - oeth - GROUP BY - DATE(timestamp) - ), - - apy_aggregated AS ( - SELECT - DATE(timestamp) AS date, - MAX(apy7_day_avg) AS max_apy7_day_avg - FROM - apy - GROUP BY - DATE(timestamp) - ), - - rebase_aggregated AS ( - SELECT - DATE(timestamp) AS date, - SUM(yield - fee) AS total_yield - FROM - rebase - GROUP BY - DATE(timestamp) - ) - - SELECT - TO_CHAR(o.date, 'YYYY-MM-DD') as id, - o.date as timestamp, - a.max_apy7_day_avg as apy, - o.max_rebasing_supply as "rebasingSupply", - r.total_yield as yield - FROM - oeth_aggregated o - JOIN - apy_aggregated a ON o.date = a.date - LEFT JOIN - rebase_aggregated r ON o.date = r.date - ORDER BY ${orderClause} - LIMIT $1 OFFSET $2;` - - const result = await manager.getRepository(OETH).query(sql, [limit, offset]) - return result - } -}