From b016609eda49e78e285aca93d83987d13bc8085b Mon Sep 17 00:00:00 2001 From: Nick Poulden Date: Wed, 18 Oct 2023 16:49:25 -0600 Subject: [PATCH 1/7] Daily stats WIP --- ...01723589-Data.js => 1697660889338-Data.js} | 28 ++- schema-oeth.graphql | 98 ++++++++++ schema.graphql | 98 ++++++++++ src/main.ts | 11 +- src/model/generated/index.ts | 4 + .../oethCollateralDailyStat.model.ts | 41 +++++ src/model/generated/oethDailyStat.model.ts | 91 +++++++++ .../generated/oethStrategyDailyStat.model.ts | 33 ++++ .../oethStrategyHoldingDailyStat.model.ts | 35 ++++ src/post-processors/daily-stats/index.ts | 1 + src/post-processors/daily-stats/oeth.ts | 173 ++++++++++++++++++ 11 files changed, 606 insertions(+), 7 deletions(-) rename db/migrations/{1697501723589-Data.js => 1697660889338-Data.js} (87%) create mode 100644 src/model/generated/oethCollateralDailyStat.model.ts create mode 100644 src/model/generated/oethDailyStat.model.ts create mode 100644 src/model/generated/oethStrategyDailyStat.model.ts create mode 100644 src/model/generated/oethStrategyHoldingDailyStat.model.ts create mode 100644 src/post-processors/daily-stats/index.ts create mode 100644 src/post-processors/daily-stats/oeth.ts diff --git a/db/migrations/1697501723589-Data.js b/db/migrations/1697660889338-Data.js similarity index 87% rename from db/migrations/1697501723589-Data.js rename to db/migrations/1697660889338-Data.js index 82fa31ce..17f7c5e3 100644 --- a/db/migrations/1697501723589-Data.js +++ b/db/migrations/1697660889338-Data.js @@ -1,5 +1,5 @@ -module.exports = class Data1697501723589 { - name = 'Data1697501723589' +module.exports = class Data1697660889338 { + name = 'Data1697660889338' 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"))`) @@ -48,6 +48,15 @@ module.exports = class Data1697501723589 { await db.query(`CREATE TABLE "oeth_balancer_meta_pool_strategy" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "total" numeric NOT NULL, "r_eth" numeric NOT NULL, "weth" numeric NOT NULL, CONSTRAINT "PK_6ddf5b8ba878e6d706e59bd6de0" PRIMARY KEY ("id"))`) await db.query(`CREATE INDEX "IDX_5e7ef383756fa18cb602f50089" ON "oeth_balancer_meta_pool_strategy" ("timestamp") `) 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 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") `) + await db.query(`CREATE TABLE "oeth_daily_stat" ("id" character varying NOT NULL, "block_number" integer NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "apr" numeric NOT NULL, "apy" numeric NOT NULL, "apy7_day_avg" numeric NOT NULL, "apy14_day_avg" numeric NOT NULL, "apy30_day_avg" numeric NOT NULL, "total_supply" numeric NOT NULL, "total_supply_usd" numeric NOT NULL, "rebasing_supply" numeric NOT NULL, "non_rebasing_supply" numeric NOT NULL, "amo_supply" numeric NOT NULL, "yield" numeric NOT NULL, "fees" numeric NOT NULL, "revenue" numeric NOT NULL, "revenue7_day_avg" numeric NOT NULL, "revenue7_day_total" numeric NOT NULL, "revenue_all_time" numeric NOT NULL, "peg_price" numeric NOT NULL, CONSTRAINT "PK_9144a02ab13b1baa818a7d5eae5" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_98d9001013aa37425ca47b7126" ON "oeth_daily_stat" ("block_number") `) + await db.query(`CREATE INDEX "IDX_c3e66051c7df4efd6a8fa8f9c1" ON "oeth_daily_stat" ("timestamp") `) await db.query(`CREATE TABLE "ogv" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "circulating" numeric NOT NULL, "total" numeric NOT NULL, CONSTRAINT "PK_f16038abf451ce82bd03ea54ee7" PRIMARY KEY ("id"))`) await db.query(`CREATE INDEX "IDX_2418a8b8b92b2f5977be761cf9" ON "ogv" ("timestamp") `) await db.query(`CREATE INDEX "IDX_b8f20bcf48e4aa77e0f48d77db" ON "ogv" ("block_number") `) @@ -112,6 +121,9 @@ module.exports = class Data1697501723589 { await db.query(`ALTER TABLE "oeth_history" ADD CONSTRAINT "FK_94e47c4c49128c78f60b185b46b" FOREIGN KEY ("address_id") REFERENCES "oeth_address"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) await db.query(`ALTER TABLE "oeth_rebase" ADD CONSTRAINT "FK_3331819842173de7c27c046547a" FOREIGN KEY ("apy_id") REFERENCES "oethapy"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) await db.query(`ALTER TABLE "oeth_rebase_option" ADD CONSTRAINT "FK_034428879698039839b4ba6ffe8" FOREIGN KEY ("address_id") REFERENCES "oeth_address"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) + await db.query(`ALTER TABLE "oeth_strategy_holding_daily_stat" ADD CONSTRAINT "FK_4e867f220975e615e6077d860c1" FOREIGN KEY ("strategy_daily_stat_id_id") REFERENCES "oeth_strategy_daily_stat"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) + await db.query(`ALTER TABLE "oeth_strategy_daily_stat" ADD CONSTRAINT "FK_6c7096c96a000d8471256ca8fc3" FOREIGN KEY ("daily_stat_id_id") REFERENCES "oeth_daily_stat"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) + await db.query(`ALTER TABLE "oeth_collateral_daily_stat" ADD CONSTRAINT "FK_a90045de50406be7bd56efd3ea4" FOREIGN KEY ("daily_stat_id_id") REFERENCES "oeth_daily_stat"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) await db.query(`ALTER TABLE "ousd_history" ADD CONSTRAINT "FK_70291ea600c0c4d67d9bfe6a6bf" FOREIGN KEY ("address_id") REFERENCES "ousd_address"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) await db.query(`ALTER TABLE "ousd_rebase" ADD CONSTRAINT "FK_427468c97f9838b804efd6c8e55" FOREIGN KEY ("apy_id") REFERENCES "ousdapy"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) await db.query(`ALTER TABLE "ousd_rebase_option" ADD CONSTRAINT "FK_b04173f9349ddd991a3b60e914a" FOREIGN KEY ("address_id") REFERENCES "ousd_address"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) @@ -164,6 +176,15 @@ module.exports = class Data1697501723589 { await db.query(`DROP TABLE "oeth_balancer_meta_pool_strategy"`) await db.query(`DROP INDEX "public"."IDX_5e7ef383756fa18cb602f50089"`) await db.query(`DROP INDEX "public"."IDX_11d344b3e0e03cdb6697dd61f7"`) + await db.query(`DROP TABLE "oeth_strategy_holding_daily_stat"`) + await db.query(`DROP INDEX "public"."IDX_4e867f220975e615e6077d860c"`) + await db.query(`DROP TABLE "oeth_strategy_daily_stat"`) + await db.query(`DROP INDEX "public"."IDX_6c7096c96a000d8471256ca8fc"`) + await db.query(`DROP TABLE "oeth_collateral_daily_stat"`) + await db.query(`DROP INDEX "public"."IDX_a90045de50406be7bd56efd3ea"`) + await db.query(`DROP TABLE "oeth_daily_stat"`) + await db.query(`DROP INDEX "public"."IDX_98d9001013aa37425ca47b7126"`) + await db.query(`DROP INDEX "public"."IDX_c3e66051c7df4efd6a8fa8f9c1"`) await db.query(`DROP TABLE "ogv"`) await db.query(`DROP INDEX "public"."IDX_2418a8b8b92b2f5977be761cf9"`) await db.query(`DROP INDEX "public"."IDX_b8f20bcf48e4aa77e0f48d77db"`) @@ -228,6 +249,9 @@ module.exports = class Data1697501723589 { await db.query(`ALTER TABLE "oeth_history" DROP CONSTRAINT "FK_94e47c4c49128c78f60b185b46b"`) await db.query(`ALTER TABLE "oeth_rebase" DROP CONSTRAINT "FK_3331819842173de7c27c046547a"`) await db.query(`ALTER TABLE "oeth_rebase_option" DROP CONSTRAINT "FK_034428879698039839b4ba6ffe8"`) + await db.query(`ALTER TABLE "oeth_strategy_holding_daily_stat" DROP CONSTRAINT "FK_4e867f220975e615e6077d860c1"`) + await db.query(`ALTER TABLE "oeth_strategy_daily_stat" DROP CONSTRAINT "FK_6c7096c96a000d8471256ca8fc3"`) + await db.query(`ALTER TABLE "oeth_collateral_daily_stat" DROP CONSTRAINT "FK_a90045de50406be7bd56efd3ea4"`) await db.query(`ALTER TABLE "ousd_history" DROP CONSTRAINT "FK_70291ea600c0c4d67d9bfe6a6bf"`) await db.query(`ALTER TABLE "ousd_rebase" DROP CONSTRAINT "FK_427468c97f9838b804efd6c8e55"`) await db.query(`ALTER TABLE "ousd_rebase_option" DROP CONSTRAINT "FK_b04173f9349ddd991a3b60e914a"`) diff --git a/schema-oeth.graphql b/schema-oeth.graphql index 94363edc..ff18fd93 100644 --- a/schema-oeth.graphql +++ b/schema-oeth.graphql @@ -148,3 +148,101 @@ type OETHBalancerMetaPoolStrategy @entity { rETH: BigInt! weth: BigInt! } + +type OETHDailyStat @entity { + id: ID! + """ + Timestamp, eg 2023-10-17 + """ + blockNumber: Int! @index + """ + Last block number stats were updated + """ + timestamp: DateTime! @index + """ + Timestamp of block number stats were updated + """ + apr: Float! + apy: Float! + apy7DayAvg: Float! + apy14DayAvg: Float! + apy30DayAvg: Float! + + totalSupply: BigInt! + totalSupplyUSD: Float! + rebasingSupply: BigInt! + nonRebasingSupply: BigInt! + amoSupply: BigInt! + + yield: BigInt! + fees: BigInt! + revenue: BigInt! + revenue7DayAvg: BigInt! + revenue7DayTotal: BigInt! + revenueAllTime: BigInt! + + pegPrice: BigInt! + """ + Price of OETH in ETH + """ + strategies: [OETHStrategyDailyStat] @derivedFrom(field: "dailyStatId") + collateral: [OETHCollateralDailyStat] @derivedFrom(field: "dailyStatId") +} + +type OETHStrategyDailyStat @entity { + id: ID! + dailyStatId: OETHDailyStat! + total: BigInt! + """ + Sum of tokens in strategy + """ + tvl: BigInt! + """ + Total ETH value + """ + holdings: [OETHStrategyHoldingDailyStat] + @derivedFrom(field: "strategyDailyStatId") +} + +type OETHStrategyHoldingDailyStat @entity { + id: ID! + strategyDailyStatId: OETHStrategyDailyStat! + """ + Token symbol + """ + symbol: String! + + """ + Amount held + """ + amount: BigInt! + + """ + Total ETH value + """ + value: BigInt! +} + +type OETHCollateralDailyStat @entity { + id: ID! + dailyStatId: OETHDailyStat! @index + """ + Token symbol + """ + symbol: String! + + """ + Amount held + """ + amount: BigInt! + + """ + Price in ETH + """ + price: BigInt! + + """ + Total ETH value + """ + value: BigInt! +} diff --git a/schema.graphql b/schema.graphql index 3f387663..7d1209e8 100644 --- a/schema.graphql +++ b/schema.graphql @@ -189,6 +189,104 @@ type OETHBalancerMetaPoolStrategy @entity { rETH: BigInt! weth: BigInt! } + +type OETHDailyStat @entity { + id: ID! + """ + Timestamp, eg 2023-10-17 + """ + blockNumber: Int! @index + """ + Last block number stats were updated + """ + timestamp: DateTime! @index + """ + Timestamp of block number stats were updated + """ + apr: Float! + apy: Float! + apy7DayAvg: Float! + apy14DayAvg: Float! + apy30DayAvg: Float! + + totalSupply: BigInt! + totalSupplyUSD: Float! + rebasingSupply: BigInt! + nonRebasingSupply: BigInt! + amoSupply: BigInt! + + yield: BigInt! + fees: BigInt! + revenue: BigInt! + revenue7DayAvg: BigInt! + revenue7DayTotal: BigInt! + revenueAllTime: BigInt! + + pegPrice: BigInt! + """ + Price of OETH in ETH + """ + strategies: [OETHStrategyDailyStat] @derivedFrom(field: "dailyStatId") + collateral: [OETHCollateralDailyStat] @derivedFrom(field: "dailyStatId") +} + +type OETHStrategyDailyStat @entity { + id: ID! + dailyStatId: OETHDailyStat! + total: BigInt! + """ + Sum of tokens in strategy + """ + tvl: BigInt! + """ + Total ETH value + """ + holdings: [OETHStrategyHoldingDailyStat] + @derivedFrom(field: "strategyDailyStatId") +} + +type OETHStrategyHoldingDailyStat @entity { + id: ID! + strategyDailyStatId: OETHStrategyDailyStat! + """ + Token symbol + """ + symbol: String! + + """ + Amount held + """ + amount: BigInt! + + """ + Total ETH value + """ + value: BigInt! +} + +type OETHCollateralDailyStat @entity { + id: ID! + dailyStatId: OETHDailyStat! @index + """ + Token symbol + """ + symbol: String! + + """ + Amount held + """ + amount: BigInt! + + """ + Price in ETH + """ + price: BigInt! + + """ + Total ETH value + """ + value: BigInt! +} # OGV Price (5m?) # OGV Market Cap (5m?) # OGV Circulating Supply diff --git a/src/main.ts b/src/main.ts index 7f0bf03c..561babc2 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,3 +1,4 @@ +import * as dailyStats from './post-processors/daily-stats' import * as exchangeRates from './post-processors/exchange-rates' import { run } from './processor' import * as curve from './processors/curve' @@ -26,10 +27,10 @@ run([ curveLp, balancerMetaPoolStrategy, ], - postProcessors: [exchangeRates], - }, - { - name: 'ousd', - processors: [ousd], + postProcessors: [exchangeRates, dailyStats], }, + // { + // name: 'ousd', + // processors: [ousd], + // }, ]) diff --git a/src/model/generated/index.ts b/src/model/generated/index.ts index 43b7e16d..fb64d743 100644 --- a/src/model/generated/index.ts +++ b/src/model/generated/index.ts @@ -14,6 +14,10 @@ export * from "./oethFraxStaking.model" export * from "./oethMorphoAave.model" export * from "./dripper.model" export * from "./oethBalancerMetaPoolStrategy.model" +export * from "./oethDailyStat.model" +export * from "./oethStrategyDailyStat.model" +export * from "./oethStrategyHoldingDailyStat.model" +export * from "./oethCollateralDailyStat.model" export * from "./ogv.model" export * from "./stakedOgv.model" export * from "./ogvGovernance.model" diff --git a/src/model/generated/oethCollateralDailyStat.model.ts b/src/model/generated/oethCollateralDailyStat.model.ts new file mode 100644 index 00000000..cd3922ed --- /dev/null +++ b/src/model/generated/oethCollateralDailyStat.model.ts @@ -0,0 +1,41 @@ +import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, ManyToOne as ManyToOne_, Index as Index_} from "typeorm" +import * as marshal from "./marshal" +import {OETHDailyStat} from "./oethDailyStat.model" + +@Entity_() +export class OETHCollateralDailyStat { + constructor(props?: Partial) { + Object.assign(this, props) + } + + @PrimaryColumn_() + id!: string + + @Index_() + @ManyToOne_(() => OETHDailyStat, {nullable: true}) + dailyStatId!: OETHDailyStat + + /** + * Token symbol + */ + @Column_("text", {nullable: false}) + symbol!: string + + /** + * Amount held + */ + @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) + amount!: bigint + + /** + * Price in ETH + */ + @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) + price!: bigint + + /** + * Total ETH value + */ + @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) + value!: bigint +} diff --git a/src/model/generated/oethDailyStat.model.ts b/src/model/generated/oethDailyStat.model.ts new file mode 100644 index 00000000..85dbc3b8 --- /dev/null +++ b/src/model/generated/oethDailyStat.model.ts @@ -0,0 +1,91 @@ +import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, Index as Index_, OneToMany as OneToMany_} from "typeorm" +import * as marshal from "./marshal" +import {OETHStrategyDailyStat} from "./oethStrategyDailyStat.model" +import {OETHCollateralDailyStat} from "./oethCollateralDailyStat.model" + +@Entity_() +export class OETHDailyStat { + constructor(props?: Partial) { + Object.assign(this, props) + } + + @PrimaryColumn_() + id!: string + + /** + * Timestamp, eg 2023-10-17 + */ + @Index_() + @Column_("int4", {nullable: false}) + blockNumber!: number + + /** + * Last block number stats were updated + */ + @Index_() + @Column_("timestamp with time zone", {nullable: false}) + timestamp!: Date + + /** + * Timestamp of block number stats were updated + */ + @Column_("numeric", {transformer: marshal.floatTransformer, nullable: false}) + apr!: number + + @Column_("numeric", {transformer: marshal.floatTransformer, nullable: false}) + apy!: number + + @Column_("numeric", {transformer: marshal.floatTransformer, nullable: false}) + apy7DayAvg!: number + + @Column_("numeric", {transformer: marshal.floatTransformer, nullable: false}) + apy14DayAvg!: number + + @Column_("numeric", {transformer: marshal.floatTransformer, nullable: false}) + apy30DayAvg!: number + + @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) + totalSupply!: bigint + + @Column_("numeric", {transformer: marshal.floatTransformer, nullable: false}) + totalSupplyUSD!: number + + @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) + rebasingSupply!: bigint + + @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) + nonRebasingSupply!: bigint + + @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) + amoSupply!: bigint + + @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) + yield!: bigint + + @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) + fees!: bigint + + @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) + revenue!: bigint + + @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) + revenue7DayAvg!: bigint + + @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) + revenue7DayTotal!: bigint + + @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) + revenueAllTime!: bigint + + @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) + pegPrice!: bigint + + /** + * Price of OETH in ETH + */ + @OneToMany_(() => OETHStrategyDailyStat, e => e.dailyStatId) + strategies!: OETHStrategyDailyStat[] + + @OneToMany_(() => OETHCollateralDailyStat, e => e.dailyStatId) + collateral!: OETHCollateralDailyStat[] +} diff --git a/src/model/generated/oethStrategyDailyStat.model.ts b/src/model/generated/oethStrategyDailyStat.model.ts new file mode 100644 index 00000000..53372934 --- /dev/null +++ b/src/model/generated/oethStrategyDailyStat.model.ts @@ -0,0 +1,33 @@ +import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, ManyToOne as ManyToOne_, Index as Index_, OneToMany as OneToMany_} from "typeorm" +import * as marshal from "./marshal" +import {OETHDailyStat} from "./oethDailyStat.model" +import {OETHStrategyHoldingDailyStat} from "./oethStrategyHoldingDailyStat.model" + +@Entity_() +export class OETHStrategyDailyStat { + constructor(props?: Partial) { + Object.assign(this, props) + } + + @PrimaryColumn_() + id!: string + + @Index_() + @ManyToOne_(() => OETHDailyStat, {nullable: true}) + dailyStatId!: OETHDailyStat + + @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) + total!: bigint + + /** + * Sum of tokens in strategy + */ + @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) + tvl!: bigint + + /** + * Total ETH value + */ + @OneToMany_(() => OETHStrategyHoldingDailyStat, e => e.strategyDailyStatId) + holdings!: OETHStrategyHoldingDailyStat[] +} diff --git a/src/model/generated/oethStrategyHoldingDailyStat.model.ts b/src/model/generated/oethStrategyHoldingDailyStat.model.ts new file mode 100644 index 00000000..fa1423c1 --- /dev/null +++ b/src/model/generated/oethStrategyHoldingDailyStat.model.ts @@ -0,0 +1,35 @@ +import {Entity as Entity_, Column as Column_, PrimaryColumn as PrimaryColumn_, ManyToOne as ManyToOne_, Index as Index_} from "typeorm" +import * as marshal from "./marshal" +import {OETHStrategyDailyStat} from "./oethStrategyDailyStat.model" + +@Entity_() +export class OETHStrategyHoldingDailyStat { + constructor(props?: Partial) { + Object.assign(this, props) + } + + @PrimaryColumn_() + id!: string + + @Index_() + @ManyToOne_(() => OETHStrategyDailyStat, {nullable: true}) + strategyDailyStatId!: OETHStrategyDailyStat + + /** + * Token symbol + */ + @Column_("text", {nullable: false}) + symbol!: string + + /** + * Amount held + */ + @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) + amount!: bigint + + /** + * Total ETH value + */ + @Column_("numeric", {transformer: marshal.bigintTransformer, nullable: false}) + value!: bigint +} diff --git a/src/post-processors/daily-stats/index.ts b/src/post-processors/daily-stats/index.ts new file mode 100644 index 00000000..526449ec --- /dev/null +++ b/src/post-processors/daily-stats/index.ts @@ -0,0 +1 @@ +export * from './oeth' diff --git a/src/post-processors/daily-stats/oeth.ts b/src/post-processors/daily-stats/oeth.ts new file mode 100644 index 00000000..2af6ffd1 --- /dev/null +++ b/src/post-processors/daily-stats/oeth.ts @@ -0,0 +1,173 @@ +import { EntityManager, FindOptionsOrderValue, LessThanOrEqual } from 'typeorm' + +import { + OETH, + OETHAPY, + OETHBalancerMetaPoolStrategy, + OETHCollateralDailyStat, + OETHCurveLP, + OETHDailyStat, + OETHFraxStaking, + OETHMorphoAave, + OETHVault, +} from '../../model' +import { Context } from '../../processor' + +export const process = async (ctx: Context) => { + const firstBlockTimestamp = new Date(ctx.blocks[0]?.header.timestamp) + + const firstBlock = ctx.blocks[0] + const lastBlock = ctx.blocks[ctx.blocks.length - 1] + const lastDailyStat = await ctx.store.findOne(OETHDailyStat, { + where: { timestamp: LessThanOrEqual(firstBlockTimestamp) }, + order: { id: 'desc' }, + }) + + const startTimestamp = Math.min( + lastDailyStat?.timestamp.getTime() || Date.now(), + firstBlock.header.timestamp, + ) + const endTimestamp = lastBlock?.header.timestamp || Date.now() + + const days = getStartOfDays(startTimestamp, endTimestamp) + + const dailyStats = [] as OETHDailyStat[] + const dailyCollateralStats = [] as OETHCollateralDailyStat[] + for (const day of days) { + const dailyStatInserts = await updateDailyStats(ctx, day) + if (dailyStatInserts) { + dailyStats.push(dailyStatInserts.dailyStat) + dailyCollateralStats.push(...dailyStatInserts.dailyCollateralStats) + } + } + + await ctx.store.upsert(dailyStats) + await ctx.store.upsert(dailyCollateralStats) +} + +async function updateDailyStats(ctx: Context, date: Date) { + const queryParams = { + where: { timestamp: LessThanOrEqual(date) }, + order: { timestamp: 'desc' as FindOptionsOrderValue }, + } + const lastApy = await ctx.store.findOne(OETHAPY, queryParams) + const lastOeth = await ctx.store.findOne(OETH, queryParams) + const lastCurve = await ctx.store.findOne(OETHCurveLP, queryParams) + const lastVault = await ctx.store.findOne(OETHVault, queryParams) + const lastBalancer = await ctx.store.findOne( + OETHBalancerMetaPoolStrategy, + queryParams, + ) + const lastFrax = await ctx.store.findOne(OETHFraxStaking, queryParams) + const lastMorpho = await ctx.store.findOne(OETHMorphoAave, queryParams) + + const allEntities = [lastApy, lastOeth] + if (!allEntities.every((entity) => !!entity)) { + return null + } + + console.log({ + lastApy, + lastOeth, + lastCurve, + lastVault, + lastBalancer, + lastFrax, + lastMorpho, + }) + + const entityManager = ( + ctx.store as unknown as { em: () => EntityManager } + ).em() + + const end = new Date(date) + end.setUTCHours(23, 59, 59, 0) + const yieldStats = await entityManager.query(yieldStatsQuery, [end]) + + const mostRecentEntity = allEntities.reduce((highest, current) => { + if (!highest || !current) return current + return current.blockNumber > highest.blockNumber ? current : highest + }) + + const id = date.toISOString().substring(0, 10) + + const dailyStat = new OETHDailyStat({ + id, + blockNumber: mostRecentEntity?.blockNumber, + timestamp: mostRecentEntity?.timestamp, + + apr: lastApy?.apr, + apy: lastApy?.apy, + apy7DayAvg: lastApy?.apy7DayAvg, + apy14DayAvg: lastApy?.apy14DayAvg, + apy30DayAvg: lastApy?.apy30DayAvg, + + totalSupply: lastOeth?.totalSupply, + totalSupplyUSD: 0, + rebasingSupply: lastOeth?.rebasingSupply, + nonRebasingSupply: lastOeth?.nonRebasingSupply, + amoSupply: lastCurve?.oethOwned, + + yield: yieldStats[0].total_yield || 0n, + fees: yieldStats[0].total_fees || 0n, + revenue: yieldStats[0].total_revenue || 0n, + revenue7DayAvg: BigInt(yieldStats[1].total_revenue || 0n) / 7n, + revenue7DayTotal: yieldStats[1].total_revenue || 0n, + revenueAllTime: yieldStats[2].total_revenue || 0n, + + pegPrice: 0n, + }) + + const dailyCollateralStats = [ + new OETHCollateralDailyStat({ + id: `${id}-ETH`, + dailyStatId: id as unknown as OETHDailyStat, + symbol: 'ETH', + amount: 0n, + price: 0n, + value: 0n, + }), + ] + + return { dailyStat, dailyCollateralStats } +} + +function getStartOfDays(startTimestamp: number, endTimestamp: number): Date[] { + const dayMilliseconds = 24 * 60 * 60 * 1000 // Number of milliseconds in a day + let startTimestampStart = new Date(startTimestamp) + startTimestampStart.setUTCHours(0, 0, 0, 0) + + let currentTimestamp = startTimestampStart.getTime() + let dates: Date[] = [] + + while (currentTimestamp <= endTimestamp) { + let date = new Date(currentTimestamp) + date.setUTCHours(0, 0, 0, 0) // Set to start of the day + dates.push(date) + + currentTimestamp += dayMilliseconds // Move to the next day + } + + return dates +} + +const yieldStatsQuery = ` +-- Results for 1 day +SELECT '1 day' as period, SUM(fee) as total_fees, SUM(yield) as total_yield, SUM(yield - fee) as total_revenue +FROM oeth_rebase +WHERE timestamp BETWEEN ($1::timestamp - interval '1 day') AND $1::timestamp + +UNION ALL + +-- Results for 7 days +SELECT '7 days' as period, SUM(fee) as total_fees, SUM(yield) as total_yield, SUM(yield - fee) as total_revenue +FROM oeth_rebase +WHERE timestamp BETWEEN ($1::timestamp - interval '7 days') AND $1::timestamp + +UNION ALL + +-- Results for all time up to the end date +SELECT 'all time' as period, SUM(fee) as total_fees, SUM(yield) as total_yield, SUM(yield - fee) as total_revenue +FROM oeth_rebase +WHERE timestamp <= $1::timestamp +` From 5395f9137f8e678aa9fd852e873a8e8efd415a29 Mon Sep 17 00:00:00 2001 From: Nick Poulden Date: Thu, 19 Oct 2023 12:17:08 -0600 Subject: [PATCH 2/7] More stats --- src/post-processors/daily-stats/oeth.ts | 215 ++++++++++++++++++++++-- 1 file changed, 197 insertions(+), 18 deletions(-) diff --git a/src/post-processors/daily-stats/oeth.ts b/src/post-processors/daily-stats/oeth.ts index 2af6ffd1..4ba478de 100644 --- a/src/post-processors/daily-stats/oeth.ts +++ b/src/post-processors/daily-stats/oeth.ts @@ -9,6 +9,8 @@ import { OETHDailyStat, OETHFraxStaking, OETHMorphoAave, + OETHStrategyDailyStat, + OETHStrategyHoldingDailyStat, OETHVault, } from '../../model' import { Context } from '../../processor' @@ -33,16 +35,23 @@ export const process = async (ctx: Context) => { const dailyStats = [] as OETHDailyStat[] const dailyCollateralStats = [] as OETHCollateralDailyStat[] + const dailyStrategyStats = [] as OETHStrategyDailyStat[] + const dailyHoldingsStats = [] as OETHStrategyHoldingDailyStat[] + for (const day of days) { const dailyStatInserts = await updateDailyStats(ctx, day) if (dailyStatInserts) { dailyStats.push(dailyStatInserts.dailyStat) dailyCollateralStats.push(...dailyStatInserts.dailyCollateralStats) + dailyStrategyStats.push(...dailyStatInserts.dailyStrategyStats) + dailyHoldingsStats.push(...dailyStatInserts.dailyStrategyHoldingsStats) } } await ctx.store.upsert(dailyStats) await ctx.store.upsert(dailyCollateralStats) + await ctx.store.upsert(dailyStrategyStats) + await ctx.store.upsert(dailyHoldingsStats) } async function updateDailyStats(ctx: Context, date: Date) { @@ -50,16 +59,24 @@ async function updateDailyStats(ctx: Context, date: Date) { where: { timestamp: LessThanOrEqual(date) }, order: { timestamp: 'desc' as FindOptionsOrderValue }, } - const lastApy = await ctx.store.findOne(OETHAPY, queryParams) - const lastOeth = await ctx.store.findOne(OETH, queryParams) - const lastCurve = await ctx.store.findOne(OETHCurveLP, queryParams) - const lastVault = await ctx.store.findOne(OETHVault, queryParams) - const lastBalancer = await ctx.store.findOne( - OETHBalancerMetaPoolStrategy, - queryParams, - ) - const lastFrax = await ctx.store.findOne(OETHFraxStaking, queryParams) - const lastMorpho = await ctx.store.findOne(OETHMorphoAave, queryParams) + + const [ + lastApy, + lastOeth, + lastCurve, + lastVault, + lastBalancer, + lastFrax, + lastMorpho, + ] = await Promise.all([ + ctx.store.findOne(OETHAPY, queryParams), + ctx.store.findOne(OETH, queryParams), + ctx.store.findOne(OETHCurveLP, queryParams), + ctx.store.findOne(OETHVault, queryParams), + ctx.store.findOne(OETHBalancerMetaPoolStrategy, queryParams), + ctx.store.findOne(OETHFraxStaking, queryParams), + ctx.store.findOne(OETHMorphoAave, queryParams), + ]) const allEntities = [lastApy, lastOeth] if (!allEntities.every((entity) => !!entity)) { @@ -102,11 +119,11 @@ async function updateDailyStats(ctx: Context, date: Date) { apy14DayAvg: lastApy?.apy14DayAvg, apy30DayAvg: lastApy?.apy30DayAvg, - totalSupply: lastOeth?.totalSupply, + totalSupply: lastOeth?.totalSupply || 0n, totalSupplyUSD: 0, - rebasingSupply: lastOeth?.rebasingSupply, - nonRebasingSupply: lastOeth?.nonRebasingSupply, - amoSupply: lastCurve?.oethOwned, + rebasingSupply: lastOeth?.rebasingSupply || 0n, + nonRebasingSupply: lastOeth?.nonRebasingSupply || 0n, + amoSupply: lastCurve?.oethOwned || 0n, yield: yieldStats[0].total_yield || 0n, fees: yieldStats[0].total_fees || 0n, @@ -118,18 +135,180 @@ async function updateDailyStats(ctx: Context, date: Date) { pegPrice: 0n, }) + // Collateral totals + const ETH = lastCurve?.ethOwned || 0n + const WETH = + (lastVault?.weth || 0n) + + (lastMorpho?.weth || 0n) + + (lastBalancer?.weth || 0n) + const stETH = lastVault?.stETH || 0n + const rETH = (lastVault?.rETH || 0n) + (lastBalancer?.rETH || 0n) + const frxETH = (lastVault?.frxETH || 0n) + (lastFrax?.frxETH || 0n) + + const totalCollateral = ETH + WETH + frxETH + stETH + rETH + console.log({ + date, + totalCollateral, + totalSupply: dailyStat.totalSupply, + }) + + // Strategy totals + const vaultTotal = + (lastVault?.frxETH || 0n) + + (lastVault?.weth || 0n) + + (lastVault?.stETH || 0n) + + (lastVault?.rETH || 0n) + + const balancerTotal = (lastBalancer?.weth || 0n) + (lastBalancer?.rETH || 0n) + + const dailyStrategyStats = [ + new OETHStrategyDailyStat({ + id: `${id}-CURVE`, + dailyStatId: id as unknown as OETHDailyStat, + tvl: lastCurve?.ethOwned || 0n, + total: lastCurve?.ethOwned || 0n, + }), + new OETHStrategyDailyStat({ + id: `${id}-VAULT`, + dailyStatId: id as unknown as OETHDailyStat, + tvl: vaultTotal, + total: vaultTotal, + }), + new OETHStrategyDailyStat({ + id: `${id}-BALANCER`, + dailyStatId: id as unknown as OETHDailyStat, + tvl: balancerTotal, + total: balancerTotal, + }), + new OETHStrategyDailyStat({ + id: `${id}-FRAX`, + dailyStatId: id as unknown as OETHDailyStat, + tvl: lastFrax?.frxETH || 0n, + total: lastFrax?.frxETH || 0n, + }), + new OETHStrategyDailyStat({ + id: `${id}-MORPHO`, + dailyStatId: id as unknown as OETHDailyStat, + tvl: lastMorpho?.weth || 0n, + total: lastMorpho?.weth || 0n, + }), + ] + + const dailyStrategyHoldingsStats = [ + new OETHStrategyHoldingDailyStat({ + id: `${id}-CURVE-ETH`, + strategyDailyStatId: `${id}-CURVE` as unknown as OETHStrategyDailyStat, + symbol: 'ETH', + amount: lastCurve?.eth || 0n, + value: lastCurve?.eth || 0n, + }), + new OETHStrategyHoldingDailyStat({ + id: `${id}-VAULT-WETH`, + strategyDailyStatId: `${id}-VAULT` as unknown as OETHStrategyDailyStat, + symbol: 'WETH', + amount: lastVault?.weth || 0n, + value: lastVault?.weth || 0n, + }), + new OETHStrategyHoldingDailyStat({ + id: `${id}-VAULT-FRXETH`, + strategyDailyStatId: `${id}-VAULT` as unknown as OETHStrategyDailyStat, + symbol: 'FRXETH', + amount: lastVault?.frxETH || 0n, + value: lastVault?.frxETH || 0n, + }), + new OETHStrategyHoldingDailyStat({ + id: `${id}-VAULT-STETH`, + strategyDailyStatId: `${id}-VAULT` as unknown as OETHStrategyDailyStat, + symbol: 'STETH', + amount: lastVault?.stETH || 0n, + value: lastVault?.stETH || 0n, + }), + new OETHStrategyHoldingDailyStat({ + id: `${id}-VAULT-RETH`, + strategyDailyStatId: `${id}-VAULT` as unknown as OETHStrategyDailyStat, + symbol: 'RETH', + amount: lastVault?.rETH || 0n, + value: lastVault?.rETH || 0n, + }), + new OETHStrategyHoldingDailyStat({ + id: `${id}-BALANCER-RETH`, + strategyDailyStatId: `${id}-BALANCER` as unknown as OETHStrategyDailyStat, + symbol: 'RETH', + amount: lastBalancer?.rETH || 0n, + value: lastBalancer?.rETH || 0n, + }), + new OETHStrategyHoldingDailyStat({ + id: `${id}-BALANCER-WETH`, + strategyDailyStatId: `${id}-BALANCER` as unknown as OETHStrategyDailyStat, + symbol: 'WETH', + amount: lastBalancer?.weth || 0n, + value: lastBalancer?.weth || 0n, + }), + new OETHStrategyHoldingDailyStat({ + id: `${id}-FRAX-FRXETH`, + strategyDailyStatId: `${id}-FRAX` as unknown as OETHStrategyDailyStat, + symbol: 'FRXETH', + amount: lastFrax?.frxETH || 0n, + value: lastFrax?.frxETH || 0n, + }), + new OETHStrategyHoldingDailyStat({ + id: `${id}-MORPHO-WETH`, + strategyDailyStatId: `${id}-MORPHO` as unknown as OETHStrategyDailyStat, + symbol: 'WETH', + amount: lastMorpho?.weth || 0n, + value: lastMorpho?.weth || 0n, + }), + ] + const dailyCollateralStats = [ new OETHCollateralDailyStat({ id: `${id}-ETH`, dailyStatId: id as unknown as OETHDailyStat, symbol: 'ETH', - amount: 0n, - price: 0n, - value: 0n, + amount: ETH, + price: 1n, + value: ETH, + }), + new OETHCollateralDailyStat({ + id: `${id}-WETH`, + dailyStatId: id as unknown as OETHDailyStat, + symbol: 'WETH', + amount: WETH, + price: 1n, + value: WETH, + }), + new OETHCollateralDailyStat({ + id: `${id}-STETH`, + dailyStatId: id as unknown as OETHDailyStat, + symbol: 'STETH', + amount: stETH, + price: 1n, + value: stETH, + }), + new OETHCollateralDailyStat({ + id: `${id}-RETH`, + dailyStatId: id as unknown as OETHDailyStat, + symbol: 'RETH', + amount: rETH, + price: 1n, + value: rETH, + }), + new OETHCollateralDailyStat({ + id: `${id}-FRXETH`, + dailyStatId: id as unknown as OETHDailyStat, + symbol: 'FRXETH', + amount: frxETH, + price: 1n, + value: frxETH, }), ] - return { dailyStat, dailyCollateralStats } + return { + dailyStat, + dailyCollateralStats, + dailyStrategyStats, + dailyStrategyHoldingsStats, + } } function getStartOfDays(startTimestamp: number, endTimestamp: number): Date[] { From 10a6e7672a3f764b167f975e45cf6c474ddebb8e Mon Sep 17 00:00:00 2001 From: Nick Poulden Date: Thu, 19 Oct 2023 13:36:03 -0600 Subject: [PATCH 3/7] wip --- src/post-processors/daily-stats/oeth.ts | 33 +++++++++++++++++++++---- src/processors/oeth/vault.ts | 1 + 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/post-processors/daily-stats/oeth.ts b/src/post-processors/daily-stats/oeth.ts index 4ba478de..f8b1262a 100644 --- a/src/post-processors/daily-stats/oeth.ts +++ b/src/post-processors/daily-stats/oeth.ts @@ -1,4 +1,5 @@ import { EntityManager, FindOptionsOrderValue, LessThanOrEqual } from 'typeorm' +import { formatEther } from 'viem' import { OETH, @@ -146,11 +147,19 @@ async function updateDailyStats(ctx: Context, date: Date) { const frxETH = (lastVault?.frxETH || 0n) + (lastFrax?.frxETH || 0n) const totalCollateral = ETH + WETH + frxETH + stETH + rETH - console.log({ - date, - totalCollateral, - totalSupply: dailyStat.totalSupply, - }) + + console.log(`Day: ${date}`) + log([ + ['Total Supply', dailyStat.totalSupply], + ['Total Collateral', totalCollateral], + ['Difference', dailyStat.totalSupply - totalCollateral], + ['Total ETH', ETH], + ['Total WETH', WETH], + ['Total stETH', stETH], + ['Total rETH', rETH], + ['Total frxETH', frxETH], + ]) + // Strategy totals const vaultTotal = @@ -350,3 +359,17 @@ SELECT 'all time' as period, SUM(fee) as total_fees, SUM(yield) as total_yield, FROM oeth_rebase WHERE timestamp <= $1::timestamp ` + +function log(entries: [string, bigint][]): void { + // Find the longest label for alignment + const maxLength = Math.max(...entries.map((entry) => entry[0].length)) + + const lines = entries.map(([label, value]) => { + // Format the value + const formattedValue = Number(formatEther(value)).toFixed(3) + // Right-align the label and value + return `${label.padEnd(maxLength)} ${formattedValue.padStart(10)}` + }) + + console.log(`${lines.join('\n')}\n`) +} diff --git a/src/processors/oeth/vault.ts b/src/processors/oeth/vault.ts index 37817b94..2ecea91a 100644 --- a/src/processors/oeth/vault.ts +++ b/src/processors/oeth/vault.ts @@ -117,6 +117,7 @@ const getLatestOETHVault = async ( ) let vault = current if (!vault) { + console.log('ENSURE EXCHANGE RATES') result.promises.push( ensureExchangeRates(ctx, block, [ ['ETH', 'USD'], From 68893a1de73b972b49a6e4beaa0b94fd627ad1c4 Mon Sep 17 00:00:00 2001 From: Nick Poulden Date: Thu, 19 Oct 2023 15:07:43 -0600 Subject: [PATCH 4/7] RETH fix --- src/post-processors/daily-stats/oeth.ts | 26 ++++++++++++++++++------- src/processors/oeth/vault.ts | 1 - 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/post-processors/daily-stats/oeth.ts b/src/post-processors/daily-stats/oeth.ts index f8b1262a..8a4343ce 100644 --- a/src/post-processors/daily-stats/oeth.ts +++ b/src/post-processors/daily-stats/oeth.ts @@ -2,6 +2,7 @@ import { EntityManager, FindOptionsOrderValue, LessThanOrEqual } from 'typeorm' import { formatEther } from 'viem' import { + ExchangeRate, OETH, OETHAPY, OETHBalancerMetaPoolStrategy, @@ -69,6 +70,7 @@ async function updateDailyStats(ctx: Context, date: Date) { lastBalancer, lastFrax, lastMorpho, + lastRethExchangeRate, ] = await Promise.all([ ctx.store.findOne(OETHAPY, queryParams), ctx.store.findOne(OETH, queryParams), @@ -77,6 +79,10 @@ async function updateDailyStats(ctx: Context, date: Date) { ctx.store.findOne(OETHBalancerMetaPoolStrategy, queryParams), ctx.store.findOne(OETHFraxStaking, queryParams), ctx.store.findOne(OETHMorphoAave, queryParams), + ctx.store.findOne(ExchangeRate, { + where: { timestamp: LessThanOrEqual(date), pair: 'ETH_rETH' }, + order: { timestamp: 'desc' as FindOptionsOrderValue }, + }), ]) const allEntities = [lastApy, lastOeth] @@ -92,6 +98,7 @@ async function updateDailyStats(ctx: Context, date: Date) { lastBalancer, lastFrax, lastMorpho, + lastRethExchangeRate, }) const entityManager = ( @@ -138,12 +145,17 @@ async function updateDailyStats(ctx: Context, date: Date) { // Collateral totals const ETH = lastCurve?.ethOwned || 0n + const OETHOwned = lastCurve?.oethOwned || 0n const WETH = (lastVault?.weth || 0n) + (lastMorpho?.weth || 0n) + (lastBalancer?.weth || 0n) const stETH = lastVault?.stETH || 0n - const rETH = (lastVault?.rETH || 0n) + (lastBalancer?.rETH || 0n) + + const rETHRaw = (lastVault?.rETH || 0n) + (lastBalancer?.rETH || 0n) + const rethExchRate = lastRethExchangeRate?.rate || 1000000000000000000n + const rETH = (rETHRaw * rethExchRate) / 1000000000000000000n + const frxETH = (lastVault?.frxETH || 0n) + (lastFrax?.frxETH || 0n) const totalCollateral = ETH + WETH + frxETH + stETH + rETH @@ -151,8 +163,9 @@ async function updateDailyStats(ctx: Context, date: Date) { console.log(`Day: ${date}`) log([ ['Total Supply', dailyStat.totalSupply], + ['Circulating Supply', dailyStat.totalSupply - OETHOwned], ['Total Collateral', totalCollateral], - ['Difference', dailyStat.totalSupply - totalCollateral], + ['Difference', dailyStat.totalSupply - OETHOwned - totalCollateral], ['Total ETH', ETH], ['Total WETH', WETH], ['Total stETH', stETH], @@ -160,7 +173,6 @@ async function updateDailyStats(ctx: Context, date: Date) { ['Total frxETH', frxETH], ]) - // Strategy totals const vaultTotal = (lastVault?.frxETH || 0n) + @@ -237,14 +249,14 @@ async function updateDailyStats(ctx: Context, date: Date) { strategyDailyStatId: `${id}-VAULT` as unknown as OETHStrategyDailyStat, symbol: 'RETH', amount: lastVault?.rETH || 0n, - value: lastVault?.rETH || 0n, + value: ((lastVault?.rETH || 0n) * rethExchRate) / 1000000000000000000n, }), new OETHStrategyHoldingDailyStat({ id: `${id}-BALANCER-RETH`, strategyDailyStatId: `${id}-BALANCER` as unknown as OETHStrategyDailyStat, symbol: 'RETH', amount: lastBalancer?.rETH || 0n, - value: lastBalancer?.rETH || 0n, + value: ((lastBalancer?.rETH || 0n) * rethExchRate) / 1000000000000000000n, }), new OETHStrategyHoldingDailyStat({ id: `${id}-BALANCER-WETH`, @@ -299,8 +311,8 @@ async function updateDailyStats(ctx: Context, date: Date) { dailyStatId: id as unknown as OETHDailyStat, symbol: 'RETH', amount: rETH, - price: 1n, - value: rETH, + price: rethExchRate, + value: (rETH * rethExchRate) / 1000000000000000000n, }), new OETHCollateralDailyStat({ id: `${id}-FRXETH`, diff --git a/src/processors/oeth/vault.ts b/src/processors/oeth/vault.ts index 2ecea91a..37817b94 100644 --- a/src/processors/oeth/vault.ts +++ b/src/processors/oeth/vault.ts @@ -117,7 +117,6 @@ const getLatestOETHVault = async ( ) let vault = current if (!vault) { - console.log('ENSURE EXCHANGE RATES') result.promises.push( ensureExchangeRates(ctx, block, [ ['ETH', 'USD'], From 810c742de735a883d1fa9017a3c6e0443bb2875c Mon Sep 17 00:00:00 2001 From: Nick Poulden Date: Mon, 23 Oct 2023 10:12:40 -0600 Subject: [PATCH 5/7] Log sfrx --- src/main.ts | 3 ++- src/post-processors/daily-stats/oeth.ts | 17 ++++++++++++----- src/processors/oeth/vault.ts | 2 ++ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/main.ts b/src/main.ts index 4b702e68..15e28250 100644 --- a/src/main.ts +++ b/src/main.ts @@ -31,7 +31,8 @@ run([ balancerMetaPoolStrategy, ], postProcessors: [exchangeRates, dailyStats], - validators: [validateOeth], + // validators: [validateOeth], + validators: [], }, // { // name: 'ousd', diff --git a/src/post-processors/daily-stats/oeth.ts b/src/post-processors/daily-stats/oeth.ts index 3870ed47..8e9fb9cc 100644 --- a/src/post-processors/daily-stats/oeth.ts +++ b/src/post-processors/daily-stats/oeth.ts @@ -104,6 +104,7 @@ async function updateDailyStats(ctx: Context, date: Date) { lastFrax, lastMorpho, lastRethExchangeRate, + lastSfrxEthExchangeRate, }) const entityManager = ( @@ -163,9 +164,8 @@ async function updateDailyStats(ctx: Context, date: Date) { const sfrxEthExchRate = lastSfrxEthExchangeRate?.rate || 1000000000000000000n const sfrxETH = lastFrax?.sfrxETH || 0n - const frxETH = - (lastVault?.frxETH || 0n) + - (sfrxETH * sfrxEthExchRate) / 1000000000000000000n + const convertedSfrxEth = (sfrxETH * sfrxEthExchRate) / 1000000000000000000n + const frxETH = (lastVault?.frxETH || 0n) + convertedSfrxEth const totalCollateral = ETH + WETH + frxETH + stETH + rETH @@ -180,6 +180,9 @@ async function updateDailyStats(ctx: Context, date: Date) { ['Total stETH', stETH], ['Total rETH', rETH], ['Total frxETH', frxETH], + ['', null], + ['Vault frxETH', lastVault?.frxETH || 0n], + ['Total sfrxETH', sfrxETH], ]) // Strategy totals @@ -381,13 +384,17 @@ FROM oeth_rebase WHERE timestamp <= $1::timestamp ` -function log(entries: [string, bigint][]): void { +function log(entries: [string, bigint | null][]): void { + if (!entries) { + console.log('') + return + } // Find the longest label for alignment const maxLength = Math.max(...entries.map((entry) => entry[0].length)) const lines = entries.map(([label, value]) => { // Format the value - const formattedValue = Number(formatEther(value)).toFixed(3) + const formattedValue = value ? Number(formatEther(value)).toFixed(3) : '' // Right-align the label and value return `${label.padEnd(maxLength)} ${formattedValue.padStart(10)}` }) diff --git a/src/processors/oeth/vault.ts b/src/processors/oeth/vault.ts index 3b09e2b5..ed35d781 100644 --- a/src/processors/oeth/vault.ts +++ b/src/processors/oeth/vault.ts @@ -104,6 +104,8 @@ const processTransfer = async ( vault.rETH = await vaultContract.checkBalance(RETH_ADDRESS) vault.stETH = await vaultContract.checkBalance(STETH_ADDRESS) vault.frxETH = await vaultContract.checkBalance(FRXETH_ADDRESS) + console.log('Header', block.header) + console.log('Vault frxEth', vault.frxETH.toString()) } const getLatestOETHVault = async ( From 39614c7698f61b2c65671ae91ebd93da48dc45cb Mon Sep 17 00:00:00 2001 From: Nick Poulden Date: Mon, 23 Oct 2023 13:04:36 -0600 Subject: [PATCH 6/7] DB --- db/migrations/1698085073897-Data.js | 11 -- db/migrations/1698085120905-Data.js | 271 ++++++++++++++++++++++++++++ 2 files changed, 271 insertions(+), 11 deletions(-) delete mode 100644 db/migrations/1698085073897-Data.js create mode 100644 db/migrations/1698085120905-Data.js diff --git a/db/migrations/1698085073897-Data.js b/db/migrations/1698085073897-Data.js deleted file mode 100644 index 7a39949e..00000000 --- a/db/migrations/1698085073897-Data.js +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = class Data1698085073897 { - name = 'Data1698085073897' - - async up(db) { - await db.query(`ALTER TABLE "oeth_balancer_meta_pool_strategy" DROP COLUMN "total"`) - } - - async down(db) { - await db.query(`ALTER TABLE "oeth_balancer_meta_pool_strategy" ADD "total" numeric NOT NULL`) - } -} diff --git a/db/migrations/1698085120905-Data.js b/db/migrations/1698085120905-Data.js new file mode 100644 index 00000000..d366e328 --- /dev/null +++ b/db/migrations/1698085120905-Data.js @@ -0,0 +1,271 @@ +module.exports = class Data1698085120905 { + name = 'Data1698085120905' + + 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"))`) + await db.query(`CREATE INDEX "IDX_9e23a3f1bf3634820c873a0fe8" ON "exchange_rate" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_c61a93768eed9e58ce399bbe01" ON "exchange_rate" ("block_number") `) + await db.query(`CREATE TABLE "balance" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "token" text NOT NULL, "address" text NOT NULL, "balance" numeric NOT NULL, CONSTRAINT "PK_079dddd31a81672e8143a649ca0" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_a956b410c329b8eca7898c3c51" ON "balance" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_6b451b59c9f6a6fdd685f530b2" ON "balance" ("block_number") `) + await db.query(`CREATE TABLE "strategy_balance" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "strategy" text NOT NULL, "asset" text NOT NULL, "balance" numeric NOT NULL, CONSTRAINT "PK_ca6f93229d1392e9546d01dae4f" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_0113bf0b63183bea0d22cd0d08" ON "strategy_balance" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_a88065dcd92011698bbe7df7b1" ON "strategy_balance" ("block_number") `) + await db.query(`CREATE TABLE "curve_pool_balance" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "address" text NOT NULL, "balance0" numeric NOT NULL, "balance1" numeric NOT NULL, "balance2" numeric NOT NULL, CONSTRAINT "PK_40412750bb910ca560aa084dd88" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_ffb0d0f86f03faacef7cb3e092" ON "curve_pool_balance" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_db5522c865eb8ed76fa7aeb4a8" ON "curve_pool_balance" ("block_number") `) + await db.query(`CREATE TABLE "oeth" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "total_supply" numeric NOT NULL, "rebasing_supply" numeric NOT NULL, "non_rebasing_supply" numeric NOT NULL, CONSTRAINT "PK_de1d885501070dbd1ab6f8577ba" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_5b81a67229bac2d68e0dc92cc4" ON "oeth" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_408e5f79f83093aa5cf2b0ea32" ON "oeth" ("block_number") `) + await db.query(`CREATE TABLE "oeth_history" ("id" character varying NOT NULL, "value" numeric NOT NULL, "balance" numeric NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "tx_hash" text NOT NULL, "type" character varying(8) NOT NULL, "address_id" character varying, CONSTRAINT "PK_2c7e7571cd9ea02b07a27a303f3" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_94e47c4c49128c78f60b185b46" ON "oeth_history" ("address_id") `) + await db.query(`CREATE INDEX "IDX_96956b1c8d29eb7066a97d5ea7" ON "oeth_history" ("block_number") `) + await db.query(`CREATE INDEX "IDX_b14170bdb7fbc0775bf55df15d" ON "oeth_history" ("tx_hash") `) + await db.query(`CREATE TABLE "oeth_address" ("id" character varying NOT NULL, "is_contract" boolean NOT NULL, "rebasing_option" character varying(6) NOT NULL, "balance" numeric NOT NULL, "earned" numeric NOT NULL, "credits" numeric NOT NULL, "last_updated" TIMESTAMP WITH TIME ZONE NOT NULL, CONSTRAINT "PK_92a966afe47d584af73ce77a1cd" PRIMARY KEY ("id"))`) + await db.query(`CREATE TABLE "oethapy" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "tx_hash" text NOT NULL, "apr" numeric NOT NULL, "apy" numeric NOT NULL, "apy7_day_avg" numeric NOT NULL, "apy14_day_avg" numeric NOT NULL, "apy30_day_avg" numeric NOT NULL, "rebasing_credits_per_token" numeric NOT NULL, CONSTRAINT "PK_8dbb4d04591848361200f18f62a" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_b1a448045d1ed9d655b679a371" ON "oethapy" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_6b8a7a706a0701e659a7d81508" ON "oethapy" ("block_number") `) + await db.query(`CREATE INDEX "IDX_c0c03168bb0139e3cffda4f00e" ON "oethapy" ("tx_hash") `) + await db.query(`CREATE TABLE "oeth_rebase" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "tx_hash" text NOT NULL, "total_supply" numeric NOT NULL, "rebasing_credits" numeric NOT NULL, "rebasing_credits_per_token" numeric NOT NULL, "fee" numeric NOT NULL, "yield" numeric NOT NULL, "apy_id" character varying, CONSTRAINT "PK_5f8f4dd071caf685b4ac2d54de3" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_fbb7b3f2fff9896eb683b86de7" ON "oeth_rebase" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_d3255d02d9407bba89380d01fa" ON "oeth_rebase" ("block_number") `) + await db.query(`CREATE INDEX "IDX_8b6bb0243472af88612fe6a01f" ON "oeth_rebase" ("tx_hash") `) + await db.query(`CREATE INDEX "IDX_3331819842173de7c27c046547" ON "oeth_rebase" ("apy_id") `) + await db.query(`CREATE TABLE "oeth_rebase_option" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "tx_hash" text NOT NULL, "status" character varying(6) NOT NULL, "address_id" character varying, CONSTRAINT "PK_32971725d5523200b4b3b7c07e5" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_1fc6bbd88037bfbf4361776909" ON "oeth_rebase_option" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_cbb7ceb49ef7c45432d0171296" ON "oeth_rebase_option" ("block_number") `) + await db.query(`CREATE INDEX "IDX_355826dadaacc5ae2d63c82f28" ON "oeth_rebase_option" ("tx_hash") `) + await db.query(`CREATE INDEX "IDX_034428879698039839b4ba6ffe" ON "oeth_rebase_option" ("address_id") `) + await db.query(`CREATE TABLE "oeth_vault" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "weth" numeric NOT NULL, "st_eth" numeric NOT NULL, "r_eth" numeric NOT NULL, "frx_eth" numeric NOT NULL, CONSTRAINT "PK_9debaa84944fe2be9dc4219ba8f" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_d6298a294864b4eaf793cf35a4" ON "oeth_vault" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_e20cb507a673817b2c68720415" ON "oeth_vault" ("block_number") `) + await db.query(`CREATE TABLE "oeth_curve_lp" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "total_supply" numeric NOT NULL, "eth" numeric NOT NULL, "oeth" numeric NOT NULL, "total_supply_owned" numeric NOT NULL, "eth_owned" numeric NOT NULL, "oeth_owned" numeric NOT NULL, CONSTRAINT "PK_2b055044664e80f44d6172fdf54" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_d9bbd20e888fa1b4b2c5d2f039" ON "oeth_curve_lp" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_7617d593c36dce1b1565a8d74a" ON "oeth_curve_lp" ("block_number") `) + await db.query(`CREATE TABLE "oeth_frax_staking" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "sfrx_eth" numeric NOT NULL, CONSTRAINT "PK_694f53c8600ae88c7bdcf7305dd" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_ce6c2c65e90967dfeaac97025b" ON "oeth_frax_staking" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_1a7f7d650390e2f9c212651e05" ON "oeth_frax_staking" ("block_number") `) + await db.query(`CREATE TABLE "oeth_morpho_aave" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "weth" numeric NOT NULL, CONSTRAINT "PK_86de8f846e9335c92b8ad7df3a1" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_25e239b985844f1d33fac79981" ON "oeth_morpho_aave" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_a6662224e95eb6921bb14cb5f9" ON "oeth_morpho_aave" ("block_number") `) + await db.query(`CREATE TABLE "dripper" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "weth" numeric NOT NULL, CONSTRAINT "PK_74fd102c8d1c60f4b1650a61ffc" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_88c58f8948c3294c2a9e2791dc" ON "dripper" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_06822c0a260797711acc9023d5" ON "dripper" ("block_number") `) + await db.query(`CREATE TABLE "oeth_balancer_meta_pool_strategy" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "r_eth" numeric NOT NULL, "weth" numeric NOT NULL, CONSTRAINT "PK_6ddf5b8ba878e6d706e59bd6de0" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_5e7ef383756fa18cb602f50089" ON "oeth_balancer_meta_pool_strategy" ("timestamp") `) + 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 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") `) + await db.query(`CREATE TABLE "oeth_daily_stat" ("id" character varying NOT NULL, "block_number" integer NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "apr" numeric NOT NULL, "apy" numeric NOT NULL, "apy7_day_avg" numeric NOT NULL, "apy14_day_avg" numeric NOT NULL, "apy30_day_avg" numeric NOT NULL, "total_supply" numeric NOT NULL, "total_supply_usd" numeric NOT NULL, "rebasing_supply" numeric NOT NULL, "non_rebasing_supply" numeric NOT NULL, "amo_supply" numeric NOT NULL, "yield" numeric NOT NULL, "fees" numeric NOT NULL, "revenue" numeric NOT NULL, "revenue7_day_avg" numeric NOT NULL, "revenue7_day_total" numeric NOT NULL, "revenue_all_time" numeric NOT NULL, "peg_price" numeric NOT NULL, CONSTRAINT "PK_9144a02ab13b1baa818a7d5eae5" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_98d9001013aa37425ca47b7126" ON "oeth_daily_stat" ("block_number") `) + await db.query(`CREATE INDEX "IDX_c3e66051c7df4efd6a8fa8f9c1" ON "oeth_daily_stat" ("timestamp") `) + await db.query(`CREATE TABLE "ogv" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "circulating" numeric NOT NULL, "total" numeric NOT NULL, CONSTRAINT "PK_f16038abf451ce82bd03ea54ee7" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_2418a8b8b92b2f5977be761cf9" ON "ogv" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_b8f20bcf48e4aa77e0f48d77db" ON "ogv" ("block_number") `) + await db.query(`CREATE TABLE "staked_ogv" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "total" numeric NOT NULL, "apy" numeric NOT NULL, CONSTRAINT "PK_b135611d9aab36c7889982c3be8" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_533195c60cfaef9e118789dee9" ON "staked_ogv" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_d601233411a33212b9d616aab0" ON "staked_ogv" ("block_number") `) + await db.query(`CREATE TABLE "ogv_governance" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "registered_voters" integer NOT NULL, "open_source_contributors" integer NOT NULL, "improvement_proposals" integer NOT NULL, CONSTRAINT "PK_b22758cd4ee8ff92c1b7ee0cf20" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_a0329e7109d5959b9aa3d9d374" ON "ogv_governance" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_63cd1ca46771965c68f6b85898" ON "ogv_governance" ("block_number") `) + await db.query(`CREATE TABLE "ousd" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "total_supply" numeric NOT NULL, "rebasing_supply" numeric NOT NULL, "non_rebasing_supply" numeric NOT NULL, CONSTRAINT "PK_acecae4a20bc14b22d9f6738d8d" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_c8d1e285213b445b088805ac7c" ON "ousd" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_806949dd853b7e8acab5d03b81" ON "ousd" ("block_number") `) + await db.query(`CREATE TABLE "ousd_history" ("id" character varying NOT NULL, "value" numeric NOT NULL, "balance" numeric NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "tx_hash" text NOT NULL, "type" character varying(8) NOT NULL, "address_id" character varying, CONSTRAINT "PK_dcbe3223b67f92d9ad4cffe8a7c" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_70291ea600c0c4d67d9bfe6a6b" ON "ousd_history" ("address_id") `) + await db.query(`CREATE INDEX "IDX_4d00d283e1ce3209dc43a0313c" ON "ousd_history" ("block_number") `) + await db.query(`CREATE INDEX "IDX_0c25caa59aa053a688a723d160" ON "ousd_history" ("tx_hash") `) + await db.query(`CREATE TABLE "ousd_address" ("id" character varying NOT NULL, "is_contract" boolean NOT NULL, "rebasing_option" character varying(6) NOT NULL, "balance" numeric NOT NULL, "earned" numeric NOT NULL, "credits" numeric NOT NULL, "last_updated" TIMESTAMP WITH TIME ZONE NOT NULL, CONSTRAINT "PK_bb061344757ede566d62854af6a" PRIMARY KEY ("id"))`) + await db.query(`CREATE TABLE "ousdapy" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "tx_hash" text NOT NULL, "apr" numeric NOT NULL, "apy" numeric NOT NULL, "apy7_day_avg" numeric NOT NULL, "apy14_day_avg" numeric NOT NULL, "apy30_day_avg" numeric NOT NULL, "rebasing_credits_per_token" numeric NOT NULL, CONSTRAINT "PK_d9889b7153efc82dbe88f9a7a33" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_c514963f42908ce84d65a84a77" ON "ousdapy" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_4f606414b3b5ce1a366bd0fbf6" ON "ousdapy" ("block_number") `) + await db.query(`CREATE INDEX "IDX_0e84a81a109b66fe6f01f77c74" ON "ousdapy" ("tx_hash") `) + await db.query(`CREATE TABLE "ousd_rebase" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "tx_hash" text NOT NULL, "total_supply" numeric NOT NULL, "rebasing_credits" numeric NOT NULL, "rebasing_credits_per_token" numeric NOT NULL, "fee" numeric NOT NULL, "yield" numeric NOT NULL, "apy_id" character varying, CONSTRAINT "PK_04cf0de72399a99798dde61b237" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_f8eb4a16ce58a146b3227ee21a" ON "ousd_rebase" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_3fb03b1a410e64c7367226d0b6" ON "ousd_rebase" ("block_number") `) + await db.query(`CREATE INDEX "IDX_1a76c478199672aaeec340f619" ON "ousd_rebase" ("tx_hash") `) + await db.query(`CREATE INDEX "IDX_427468c97f9838b804efd6c8e5" ON "ousd_rebase" ("apy_id") `) + await db.query(`CREATE TABLE "ousd_rebase_option" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "tx_hash" text NOT NULL, "status" character varying(6) NOT NULL, "address_id" character varying, CONSTRAINT "PK_d684f90866027104f3c929dfe10" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_64bd23947dc4c67e3b6a3f9352" ON "ousd_rebase_option" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_9b774e46b8b1cf7f828133809a" ON "ousd_rebase_option" ("block_number") `) + await db.query(`CREATE INDEX "IDX_4e95bf069de04533d83a9a97fd" ON "ousd_rebase_option" ("tx_hash") `) + await db.query(`CREATE INDEX "IDX_b04173f9349ddd991a3b60e914" ON "ousd_rebase_option" ("address_id") `) + await db.query(`CREATE TABLE "ousd_vault" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "dai" numeric NOT NULL, "usdt" numeric NOT NULL, "usdc" numeric NOT NULL, CONSTRAINT "PK_343f5538c71a1cd78f1659ef9d3" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_6860186ea2f56e2c7d54c22107" ON "ousd_vault" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_0d0a7113a505cf7f7adea9ca81" ON "ousd_vault" ("block_number") `) + await db.query(`CREATE TABLE "ousd_morpho_aave" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "dai" numeric NOT NULL, "usdt" numeric NOT NULL, "usdc" numeric NOT NULL, CONSTRAINT "PK_60676cde905a822ba73ff3a5c85" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_78e0701c2e9a28242db37bd8f8" ON "ousd_morpho_aave" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_46ccf673b376d654052fbd53e6" ON "ousd_morpho_aave" ("block_number") `) + await db.query(`CREATE TABLE "ousd_morpho_compound" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "dai" numeric NOT NULL, "usdt" numeric NOT NULL, "usdc" numeric NOT NULL, CONSTRAINT "PK_5f715d53ef8fc0fad595cacf4fa" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_9e7bd0d8ae23b877d5979ef80c" ON "ousd_morpho_compound" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_0bb3a0ad84071f1d80f6d4e90f" ON "ousd_morpho_compound" ("block_number") `) + await db.query(`CREATE TABLE "maker_dsr_strategy" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "dai" numeric NOT NULL, CONSTRAINT "PK_196da2d6910009ae04e3542fe22" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_a35308a3c5dbaab2d321eb1525" ON "maker_dsr_strategy" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_844b219d8faf9b1d24ab2dba9a" ON "maker_dsr_strategy" ("block_number") `) + await db.query(`CREATE TABLE "ousd_flux_strategy" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "dai" numeric NOT NULL, "usdt" numeric NOT NULL, "usdc" numeric NOT NULL, CONSTRAINT "PK_ac977221429e50e4de1ce253a8b" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_5b165b5d30b13e363d33a66e14" ON "ousd_flux_strategy" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_80f3392968fde7b99cccb805ac" ON "ousd_flux_strategy" ("block_number") `) + await db.query(`CREATE TABLE "ousd_compound_strategy" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "dai" numeric NOT NULL, "usdt" numeric NOT NULL, "usdc" numeric NOT NULL, CONSTRAINT "PK_9030e82bf3479d03c04e0d1919c" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_6920b1db5dc577295ac4d1379d" ON "ousd_compound_strategy" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_89c6d7d3104bd36dc88a37add4" ON "ousd_compound_strategy" ("block_number") `) + await db.query(`CREATE TABLE "ousd_convex_strategy" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "dai" numeric NOT NULL, "usdt" numeric NOT NULL, "usdc" numeric NOT NULL, CONSTRAINT "PK_2b8f6e749e15e49d8816f1ac949" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_2deac473cd0b2dd7082e7da148" ON "ousd_convex_strategy" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_157bf74171817dc5c60ee37036" ON "ousd_convex_strategy" ("block_number") `) + await db.query(`CREATE TABLE "ousd_aave_strategy" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "dai" numeric NOT NULL, "usdt" numeric NOT NULL, "usdc" numeric NOT NULL, CONSTRAINT "PK_b4b7ac6e395aa722df500f93623" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_ca34b5a0a33bc9abdd8213c2fa" ON "ousd_aave_strategy" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_dacd7c98223d7bc8be074d71e4" ON "ousd_aave_strategy" ("block_number") `) + await db.query(`CREATE TABLE "ousd_meta_strategy" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "dai" numeric NOT NULL, "usdt" numeric NOT NULL, "usdc" numeric NOT NULL, CONSTRAINT "PK_d99170af73d86fe74460bbfacc4" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_7e998dcf775263bc5df76ef987" ON "ousd_meta_strategy" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_55ce185680512d6a5b9fb0af89" ON "ousd_meta_strategy" ("block_number") `) + await db.query(`CREATE TABLE "ousd_convex_lusd_plus3_crv" ("id" character varying NOT NULL, "timestamp" TIMESTAMP WITH TIME ZONE NOT NULL, "block_number" integer NOT NULL, "dai" numeric NOT NULL, "usdt" numeric NOT NULL, "usdc" numeric NOT NULL, CONSTRAINT "PK_47290aa5dfa3cc5595f468e2f39" PRIMARY KEY ("id"))`) + await db.query(`CREATE INDEX "IDX_0783af95efb35fb3f13cde1656" ON "ousd_convex_lusd_plus3_crv" ("timestamp") `) + await db.query(`CREATE INDEX "IDX_74ae01fb596a4f2733087ba454" ON "ousd_convex_lusd_plus3_crv" ("block_number") `) + await db.query(`ALTER TABLE "oeth_history" ADD CONSTRAINT "FK_94e47c4c49128c78f60b185b46b" FOREIGN KEY ("address_id") REFERENCES "oeth_address"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) + await db.query(`ALTER TABLE "oeth_rebase" ADD CONSTRAINT "FK_3331819842173de7c27c046547a" FOREIGN KEY ("apy_id") REFERENCES "oethapy"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) + await db.query(`ALTER TABLE "oeth_rebase_option" ADD CONSTRAINT "FK_034428879698039839b4ba6ffe8" FOREIGN KEY ("address_id") REFERENCES "oeth_address"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) + await db.query(`ALTER TABLE "oeth_strategy_holding_daily_stat" ADD CONSTRAINT "FK_4e867f220975e615e6077d860c1" FOREIGN KEY ("strategy_daily_stat_id_id") REFERENCES "oeth_strategy_daily_stat"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) + await db.query(`ALTER TABLE "oeth_strategy_daily_stat" ADD CONSTRAINT "FK_6c7096c96a000d8471256ca8fc3" FOREIGN KEY ("daily_stat_id_id") REFERENCES "oeth_daily_stat"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) + await db.query(`ALTER TABLE "oeth_collateral_daily_stat" ADD CONSTRAINT "FK_a90045de50406be7bd56efd3ea4" FOREIGN KEY ("daily_stat_id_id") REFERENCES "oeth_daily_stat"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) + await db.query(`ALTER TABLE "ousd_history" ADD CONSTRAINT "FK_70291ea600c0c4d67d9bfe6a6bf" FOREIGN KEY ("address_id") REFERENCES "ousd_address"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) + await db.query(`ALTER TABLE "ousd_rebase" ADD CONSTRAINT "FK_427468c97f9838b804efd6c8e55" FOREIGN KEY ("apy_id") REFERENCES "ousdapy"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) + await db.query(`ALTER TABLE "ousd_rebase_option" ADD CONSTRAINT "FK_b04173f9349ddd991a3b60e914a" FOREIGN KEY ("address_id") REFERENCES "ousd_address"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`) + } + + async down(db) { + await db.query(`DROP TABLE "exchange_rate"`) + await db.query(`DROP INDEX "public"."IDX_9e23a3f1bf3634820c873a0fe8"`) + await db.query(`DROP INDEX "public"."IDX_c61a93768eed9e58ce399bbe01"`) + await db.query(`DROP TABLE "balance"`) + await db.query(`DROP INDEX "public"."IDX_a956b410c329b8eca7898c3c51"`) + await db.query(`DROP INDEX "public"."IDX_6b451b59c9f6a6fdd685f530b2"`) + await db.query(`DROP TABLE "strategy_balance"`) + await db.query(`DROP INDEX "public"."IDX_0113bf0b63183bea0d22cd0d08"`) + await db.query(`DROP INDEX "public"."IDX_a88065dcd92011698bbe7df7b1"`) + await db.query(`DROP TABLE "curve_pool_balance"`) + await db.query(`DROP INDEX "public"."IDX_ffb0d0f86f03faacef7cb3e092"`) + await db.query(`DROP INDEX "public"."IDX_db5522c865eb8ed76fa7aeb4a8"`) + await db.query(`DROP TABLE "oeth"`) + await db.query(`DROP INDEX "public"."IDX_5b81a67229bac2d68e0dc92cc4"`) + await db.query(`DROP INDEX "public"."IDX_408e5f79f83093aa5cf2b0ea32"`) + await db.query(`DROP TABLE "oeth_history"`) + await db.query(`DROP INDEX "public"."IDX_94e47c4c49128c78f60b185b46"`) + await db.query(`DROP INDEX "public"."IDX_96956b1c8d29eb7066a97d5ea7"`) + await db.query(`DROP INDEX "public"."IDX_b14170bdb7fbc0775bf55df15d"`) + await db.query(`DROP TABLE "oeth_address"`) + await db.query(`DROP TABLE "oethapy"`) + await db.query(`DROP INDEX "public"."IDX_b1a448045d1ed9d655b679a371"`) + await db.query(`DROP INDEX "public"."IDX_6b8a7a706a0701e659a7d81508"`) + await db.query(`DROP INDEX "public"."IDX_c0c03168bb0139e3cffda4f00e"`) + await db.query(`DROP TABLE "oeth_rebase"`) + await db.query(`DROP INDEX "public"."IDX_fbb7b3f2fff9896eb683b86de7"`) + await db.query(`DROP INDEX "public"."IDX_d3255d02d9407bba89380d01fa"`) + await db.query(`DROP INDEX "public"."IDX_8b6bb0243472af88612fe6a01f"`) + await db.query(`DROP INDEX "public"."IDX_3331819842173de7c27c046547"`) + await db.query(`DROP TABLE "oeth_rebase_option"`) + await db.query(`DROP INDEX "public"."IDX_1fc6bbd88037bfbf4361776909"`) + await db.query(`DROP INDEX "public"."IDX_cbb7ceb49ef7c45432d0171296"`) + await db.query(`DROP INDEX "public"."IDX_355826dadaacc5ae2d63c82f28"`) + await db.query(`DROP INDEX "public"."IDX_034428879698039839b4ba6ffe"`) + await db.query(`DROP TABLE "oeth_vault"`) + await db.query(`DROP INDEX "public"."IDX_d6298a294864b4eaf793cf35a4"`) + await db.query(`DROP INDEX "public"."IDX_e20cb507a673817b2c68720415"`) + await db.query(`DROP TABLE "oeth_curve_lp"`) + await db.query(`DROP INDEX "public"."IDX_d9bbd20e888fa1b4b2c5d2f039"`) + await db.query(`DROP INDEX "public"."IDX_7617d593c36dce1b1565a8d74a"`) + await db.query(`DROP TABLE "oeth_frax_staking"`) + await db.query(`DROP INDEX "public"."IDX_ce6c2c65e90967dfeaac97025b"`) + await db.query(`DROP INDEX "public"."IDX_1a7f7d650390e2f9c212651e05"`) + await db.query(`DROP TABLE "oeth_morpho_aave"`) + await db.query(`DROP INDEX "public"."IDX_25e239b985844f1d33fac79981"`) + await db.query(`DROP INDEX "public"."IDX_a6662224e95eb6921bb14cb5f9"`) + await db.query(`DROP TABLE "dripper"`) + await db.query(`DROP INDEX "public"."IDX_88c58f8948c3294c2a9e2791dc"`) + await db.query(`DROP INDEX "public"."IDX_06822c0a260797711acc9023d5"`) + await db.query(`DROP TABLE "oeth_balancer_meta_pool_strategy"`) + await db.query(`DROP INDEX "public"."IDX_5e7ef383756fa18cb602f50089"`) + await db.query(`DROP INDEX "public"."IDX_11d344b3e0e03cdb6697dd61f7"`) + await db.query(`DROP TABLE "oeth_strategy_holding_daily_stat"`) + await db.query(`DROP INDEX "public"."IDX_4e867f220975e615e6077d860c"`) + await db.query(`DROP TABLE "oeth_strategy_daily_stat"`) + await db.query(`DROP INDEX "public"."IDX_6c7096c96a000d8471256ca8fc"`) + await db.query(`DROP TABLE "oeth_collateral_daily_stat"`) + await db.query(`DROP INDEX "public"."IDX_a90045de50406be7bd56efd3ea"`) + await db.query(`DROP TABLE "oeth_daily_stat"`) + await db.query(`DROP INDEX "public"."IDX_98d9001013aa37425ca47b7126"`) + await db.query(`DROP INDEX "public"."IDX_c3e66051c7df4efd6a8fa8f9c1"`) + await db.query(`DROP TABLE "ogv"`) + await db.query(`DROP INDEX "public"."IDX_2418a8b8b92b2f5977be761cf9"`) + await db.query(`DROP INDEX "public"."IDX_b8f20bcf48e4aa77e0f48d77db"`) + await db.query(`DROP TABLE "staked_ogv"`) + await db.query(`DROP INDEX "public"."IDX_533195c60cfaef9e118789dee9"`) + await db.query(`DROP INDEX "public"."IDX_d601233411a33212b9d616aab0"`) + await db.query(`DROP TABLE "ogv_governance"`) + await db.query(`DROP INDEX "public"."IDX_a0329e7109d5959b9aa3d9d374"`) + await db.query(`DROP INDEX "public"."IDX_63cd1ca46771965c68f6b85898"`) + await db.query(`DROP TABLE "ousd"`) + await db.query(`DROP INDEX "public"."IDX_c8d1e285213b445b088805ac7c"`) + await db.query(`DROP INDEX "public"."IDX_806949dd853b7e8acab5d03b81"`) + await db.query(`DROP TABLE "ousd_history"`) + await db.query(`DROP INDEX "public"."IDX_70291ea600c0c4d67d9bfe6a6b"`) + await db.query(`DROP INDEX "public"."IDX_4d00d283e1ce3209dc43a0313c"`) + await db.query(`DROP INDEX "public"."IDX_0c25caa59aa053a688a723d160"`) + await db.query(`DROP TABLE "ousd_address"`) + await db.query(`DROP TABLE "ousdapy"`) + await db.query(`DROP INDEX "public"."IDX_c514963f42908ce84d65a84a77"`) + await db.query(`DROP INDEX "public"."IDX_4f606414b3b5ce1a366bd0fbf6"`) + await db.query(`DROP INDEX "public"."IDX_0e84a81a109b66fe6f01f77c74"`) + await db.query(`DROP TABLE "ousd_rebase"`) + await db.query(`DROP INDEX "public"."IDX_f8eb4a16ce58a146b3227ee21a"`) + await db.query(`DROP INDEX "public"."IDX_3fb03b1a410e64c7367226d0b6"`) + await db.query(`DROP INDEX "public"."IDX_1a76c478199672aaeec340f619"`) + await db.query(`DROP INDEX "public"."IDX_427468c97f9838b804efd6c8e5"`) + await db.query(`DROP TABLE "ousd_rebase_option"`) + await db.query(`DROP INDEX "public"."IDX_64bd23947dc4c67e3b6a3f9352"`) + await db.query(`DROP INDEX "public"."IDX_9b774e46b8b1cf7f828133809a"`) + await db.query(`DROP INDEX "public"."IDX_4e95bf069de04533d83a9a97fd"`) + await db.query(`DROP INDEX "public"."IDX_b04173f9349ddd991a3b60e914"`) + await db.query(`DROP TABLE "ousd_vault"`) + await db.query(`DROP INDEX "public"."IDX_6860186ea2f56e2c7d54c22107"`) + await db.query(`DROP INDEX "public"."IDX_0d0a7113a505cf7f7adea9ca81"`) + await db.query(`DROP TABLE "ousd_morpho_aave"`) + await db.query(`DROP INDEX "public"."IDX_78e0701c2e9a28242db37bd8f8"`) + await db.query(`DROP INDEX "public"."IDX_46ccf673b376d654052fbd53e6"`) + await db.query(`DROP TABLE "ousd_morpho_compound"`) + await db.query(`DROP INDEX "public"."IDX_9e7bd0d8ae23b877d5979ef80c"`) + await db.query(`DROP INDEX "public"."IDX_0bb3a0ad84071f1d80f6d4e90f"`) + await db.query(`DROP TABLE "maker_dsr_strategy"`) + await db.query(`DROP INDEX "public"."IDX_a35308a3c5dbaab2d321eb1525"`) + await db.query(`DROP INDEX "public"."IDX_844b219d8faf9b1d24ab2dba9a"`) + await db.query(`DROP TABLE "ousd_flux_strategy"`) + await db.query(`DROP INDEX "public"."IDX_5b165b5d30b13e363d33a66e14"`) + await db.query(`DROP INDEX "public"."IDX_80f3392968fde7b99cccb805ac"`) + await db.query(`DROP TABLE "ousd_compound_strategy"`) + await db.query(`DROP INDEX "public"."IDX_6920b1db5dc577295ac4d1379d"`) + await db.query(`DROP INDEX "public"."IDX_89c6d7d3104bd36dc88a37add4"`) + await db.query(`DROP TABLE "ousd_convex_strategy"`) + await db.query(`DROP INDEX "public"."IDX_2deac473cd0b2dd7082e7da148"`) + await db.query(`DROP INDEX "public"."IDX_157bf74171817dc5c60ee37036"`) + await db.query(`DROP TABLE "ousd_aave_strategy"`) + await db.query(`DROP INDEX "public"."IDX_ca34b5a0a33bc9abdd8213c2fa"`) + await db.query(`DROP INDEX "public"."IDX_dacd7c98223d7bc8be074d71e4"`) + await db.query(`DROP TABLE "ousd_meta_strategy"`) + await db.query(`DROP INDEX "public"."IDX_7e998dcf775263bc5df76ef987"`) + await db.query(`DROP INDEX "public"."IDX_55ce185680512d6a5b9fb0af89"`) + await db.query(`DROP TABLE "ousd_convex_lusd_plus3_crv"`) + await db.query(`DROP INDEX "public"."IDX_0783af95efb35fb3f13cde1656"`) + await db.query(`DROP INDEX "public"."IDX_74ae01fb596a4f2733087ba454"`) + await db.query(`ALTER TABLE "oeth_history" DROP CONSTRAINT "FK_94e47c4c49128c78f60b185b46b"`) + await db.query(`ALTER TABLE "oeth_rebase" DROP CONSTRAINT "FK_3331819842173de7c27c046547a"`) + await db.query(`ALTER TABLE "oeth_rebase_option" DROP CONSTRAINT "FK_034428879698039839b4ba6ffe8"`) + await db.query(`ALTER TABLE "oeth_strategy_holding_daily_stat" DROP CONSTRAINT "FK_4e867f220975e615e6077d860c1"`) + await db.query(`ALTER TABLE "oeth_strategy_daily_stat" DROP CONSTRAINT "FK_6c7096c96a000d8471256ca8fc3"`) + await db.query(`ALTER TABLE "oeth_collateral_daily_stat" DROP CONSTRAINT "FK_a90045de50406be7bd56efd3ea4"`) + await db.query(`ALTER TABLE "ousd_history" DROP CONSTRAINT "FK_70291ea600c0c4d67d9bfe6a6bf"`) + await db.query(`ALTER TABLE "ousd_rebase" DROP CONSTRAINT "FK_427468c97f9838b804efd6c8e55"`) + await db.query(`ALTER TABLE "ousd_rebase_option" DROP CONSTRAINT "FK_b04173f9349ddd991a3b60e914a"`) + } +} From ffba8438fca69a9c5f15cf5ea6577de3e016a059 Mon Sep 17 00:00:00 2001 From: Chris Jacobs Date: Mon, 23 Oct 2023 13:16:10 -0700 Subject: [PATCH 7/7] review daily stats, rename a few things, test performance --- .../daily-stats/{oeth.ts => daily-stats.ts} | 105 ++++++++++-------- src/post-processors/daily-stats/index.ts | 2 +- src/processor.ts | 1 - 3 files changed, 61 insertions(+), 47 deletions(-) rename src/post-processors/daily-stats/{oeth.ts => daily-stats.ts} (83%) diff --git a/src/post-processors/daily-stats/oeth.ts b/src/post-processors/daily-stats/daily-stats.ts similarity index 83% rename from src/post-processors/daily-stats/oeth.ts rename to src/post-processors/daily-stats/daily-stats.ts index 8e9fb9cc..a09a1ad0 100644 --- a/src/post-processors/daily-stats/oeth.ts +++ b/src/post-processors/daily-stats/daily-stats.ts @@ -1,3 +1,4 @@ +import dayjs from 'dayjs' import { EntityManager, FindOptionsOrderValue, LessThanOrEqual } from 'typeorm' import { formatEther } from 'viem' @@ -17,13 +18,17 @@ import { } from '../../model' import { Context } from '../../processor' +export const from = 16933090 // https://etherscan.io/tx/0x3b4ece4f5fef04bf7ceaec4f6c6edf700540d7597589f8da0e3a8c94264a3b50 + export const process = async (ctx: Context) => { - const firstBlockTimestamp = new Date(ctx.blocks[0]?.header.timestamp) + const firstBlockTimestamp = ctx.blocks.find((b) => b.header.height >= from) + ?.header.timestamp + if (!firstBlockTimestamp) return const firstBlock = ctx.blocks[0] const lastBlock = ctx.blocks[ctx.blocks.length - 1] const lastDailyStat = await ctx.store.findOne(OETHDailyStat, { - where: { timestamp: LessThanOrEqual(firstBlockTimestamp) }, + where: { timestamp: LessThanOrEqual(new Date(firstBlockTimestamp)) }, order: { id: 'desc' }, }) @@ -51,9 +56,11 @@ export const process = async (ctx: Context) => { } await ctx.store.upsert(dailyStats) - await ctx.store.upsert(dailyCollateralStats) - await ctx.store.upsert(dailyStrategyStats) - await ctx.store.upsert(dailyHoldingsStats) + await Promise.all([ + ctx.store.upsert(dailyCollateralStats), + ctx.store.upsert(dailyStrategyStats), + ctx.store.upsert(dailyHoldingsStats), + ]) } async function updateDailyStats(ctx: Context, date: Date) { @@ -70,8 +77,8 @@ async function updateDailyStats(ctx: Context, date: Date) { lastBalancer, lastFrax, lastMorpho, - lastRethExchangeRate, - lastSfrxEthExchangeRate, + lastRethRate, + lastSfrxEthRate, ] = await Promise.all([ ctx.store.findOne(OETHAPY, queryParams), ctx.store.findOne(OETH, queryParams), @@ -90,30 +97,37 @@ async function updateDailyStats(ctx: Context, date: Date) { }), ]) + // Do we have any useful data yet? const allEntities = [lastApy, lastOeth] if (!allEntities.every((entity) => !!entity)) { return null } - console.log({ - lastApy, - lastOeth, - lastCurve, - lastVault, - lastBalancer, - lastFrax, - lastMorpho, - lastRethExchangeRate, - lastSfrxEthExchangeRate, - }) + // console.log({ + // lastApy, + // lastOeth, + // lastCurve, + // lastVault, + // lastBalancer, + // lastFrax, + // lastMorpho, + // lastRethExchangeRate, + // lastSfrxEthExchangeRate, + // }) const entityManager = ( ctx.store as unknown as { em: () => EntityManager } ).em() - const end = new Date(date) - end.setUTCHours(23, 59, 59, 0) - const yieldStats = await entityManager.query(yieldStatsQuery, [end]) + const end = dayjs(date).endOf('day').toDate() + const yieldStats = await entityManager.query< + { + period: string + total_yield: bigint + total_fees: bigint + total_revenue: bigint + }[] + >(yieldStatsQuery, [end]) const mostRecentEntity = allEntities.reduce((highest, current) => { if (!highest || !current) return current @@ -159,31 +173,32 @@ async function updateDailyStats(ctx: Context, date: Date) { const stETH = lastVault?.stETH || 0n const rETHRaw = (lastVault?.rETH || 0n) + (lastBalancer?.rETH || 0n) - const rethExchRate = lastRethExchangeRate?.rate || 1000000000000000000n - const rETH = (rETHRaw * rethExchRate) / 1000000000000000000n + const rethRate = lastRethRate?.rate || 1000000000000000000n + const rETH = (rETHRaw * rethRate) / 1000000000000000000n - const sfrxEthExchRate = lastSfrxEthExchangeRate?.rate || 1000000000000000000n + const sfrxEthExchangeRate = lastSfrxEthRate?.rate || 1000000000000000000n const sfrxETH = lastFrax?.sfrxETH || 0n - const convertedSfrxEth = (sfrxETH * sfrxEthExchRate) / 1000000000000000000n + const convertedSfrxEth = + (sfrxETH * sfrxEthExchangeRate) / 1000000000000000000n const frxETH = (lastVault?.frxETH || 0n) + convertedSfrxEth const totalCollateral = ETH + WETH + frxETH + stETH + rETH - console.log(`Day: ${date}`) - log([ - ['Total Supply', dailyStat.totalSupply], - ['Circulating Supply', dailyStat.totalSupply - OETHOwned], - ['Total Collateral', totalCollateral], - ['Difference', dailyStat.totalSupply - OETHOwned - totalCollateral], - ['Total ETH', ETH], - ['Total WETH', WETH], - ['Total stETH', stETH], - ['Total rETH', rETH], - ['Total frxETH', frxETH], - ['', null], - ['Vault frxETH', lastVault?.frxETH || 0n], - ['Total sfrxETH', sfrxETH], - ]) + // console.log(`Day: ${date}`) + // log([ + // ['Total Supply', dailyStat.totalSupply], + // ['Circulating Supply', dailyStat.totalSupply - OETHOwned], + // ['Total Collateral', totalCollateral], + // ['Difference', dailyStat.totalSupply - OETHOwned - totalCollateral], + // ['Total ETH', ETH], + // ['Total WETH', WETH], + // ['Total stETH', stETH], + // ['Total rETH', rETH], + // ['Total frxETH', frxETH], + // ['', null], + // ['Vault frxETH', lastVault?.frxETH || 0n], + // ['Total sfrxETH', sfrxETH], + // ]) // Strategy totals const vaultTotal = @@ -261,14 +276,14 @@ async function updateDailyStats(ctx: Context, date: Date) { strategyDailyStatId: `${id}-VAULT` as unknown as OETHStrategyDailyStat, symbol: 'RETH', amount: lastVault?.rETH || 0n, - value: ((lastVault?.rETH || 0n) * rethExchRate) / 1000000000000000000n, + value: ((lastVault?.rETH || 0n) * rethRate) / 1000000000000000000n, }), new OETHStrategyHoldingDailyStat({ id: `${id}-BALANCER-RETH`, strategyDailyStatId: `${id}-BALANCER` as unknown as OETHStrategyDailyStat, symbol: 'RETH', amount: lastBalancer?.rETH || 0n, - value: ((lastBalancer?.rETH || 0n) * rethExchRate) / 1000000000000000000n, + value: ((lastBalancer?.rETH || 0n) * rethRate) / 1000000000000000000n, }), new OETHStrategyHoldingDailyStat({ id: `${id}-BALANCER-WETH`, @@ -282,7 +297,7 @@ async function updateDailyStats(ctx: Context, date: Date) { strategyDailyStatId: `${id}-FRAX` as unknown as OETHStrategyDailyStat, symbol: 'SFRXETH', amount: lastFrax?.sfrxETH || 0n, - value: (sfrxETH * sfrxEthExchRate) / 1000000000000000000n, + value: (sfrxETH * sfrxEthExchangeRate) / 1000000000000000000n, }), new OETHStrategyHoldingDailyStat({ id: `${id}-MORPHO-WETH`, @@ -323,8 +338,8 @@ async function updateDailyStats(ctx: Context, date: Date) { dailyStatId: id as unknown as OETHDailyStat, symbol: 'RETH', amount: rETH, - price: rethExchRate, - value: (rETH * rethExchRate) / 1000000000000000000n, + price: rethRate, + value: (rETH * rethRate) / 1000000000000000000n, }), new OETHCollateralDailyStat({ id: `${id}-FRXETH`, diff --git a/src/post-processors/daily-stats/index.ts b/src/post-processors/daily-stats/index.ts index 526449ec..966fdd9a 100644 --- a/src/post-processors/daily-stats/index.ts +++ b/src/post-processors/daily-stats/index.ts @@ -1 +1 @@ -export * from './oeth' +export * from './daily-stats' diff --git a/src/processor.ts b/src/processor.ts index f34d7f1a..583ca3c8 100644 --- a/src/processor.ts +++ b/src/processor.ts @@ -51,7 +51,6 @@ export const createSquidProcessor = () => callValue: true, callInput: true, createResultAddress: true, - // action: true, }, })