From 51c08d7a9add824eaeb33df589083af5a590aa53 Mon Sep 17 00:00:00 2001 From: Soil King <157099073+soilking@users.noreply.github.com> Date: Wed, 10 Apr 2024 16:11:11 -0700 Subject: [PATCH] subgraph: seed gauge silo hourly/daily snapshots --- projects/subgraph-beanstalk/schema.graphql | 70 +++++++++++++++++++ .../subgraph-beanstalk/src/GaugeHandler.ts | 43 +++++++++++- .../src/utils/SiloEntities.ts | 6 ++ projects/subgraph-beanstalk/subgraph.yaml | 2 +- .../tests/SeedGauge.test.ts | 1 + 5 files changed, 118 insertions(+), 4 deletions(-) diff --git a/projects/subgraph-beanstalk/schema.graphql b/projects/subgraph-beanstalk/schema.graphql index 70cfdbae0c..ed24c2e57c 100644 --- a/projects/subgraph-beanstalk/schema.graphql +++ b/projects/subgraph-beanstalk/schema.graphql @@ -157,6 +157,10 @@ type SiloHourlySnapshot @entity { grownStalkPerBdvPerSeason: BigInt! "Point in time current roots balance" roots: BigInt! + "[Seed Gauge] Stalk that is currently Germinating" + germinatingStalk: BigInt! + "[Seed Gauge] Current target ratio of Bean to LP deposits" + beanToMaxLpGpPerBdvRatio: BigInt "Point in time cumulative total for bean mints sent to the silo" beanMints: BigInt! "Point in time current number of active farmers deposited in the silo" @@ -171,6 +175,8 @@ type SiloHourlySnapshot @entity { deltaSeeds: BigInt! "Point in time delta roots balance" deltaRoots: BigInt! + "Point in time germinating stalk balance" + deltaGerminatingStalk: BigInt! "Point in time delta total for bean mints sent to the silo" deltaBeanMints: BigInt! "Point in time delta number of active farmers deposited in the silo" @@ -202,6 +208,10 @@ type SiloDailySnapshot @entity { grownStalkPerBdvPerSeason: BigInt! "Point in time current roots balance" roots: BigInt! + "[Seed Gauge] Stalk that is currently Germinating" + germinatingStalk: BigInt! + "[Seed Gauge] Current target ratio of Bean to LP deposits" + beanToMaxLpGpPerBdvRatio: BigInt "Point in time cumulative total for bean mints sent to the silo" beanMints: BigInt! "Point in time current number of active farmers deposited in the silo" @@ -216,6 +226,8 @@ type SiloDailySnapshot @entity { deltaSeeds: BigInt! "Point in time delta roots balance" deltaRoots: BigInt! + "Point in time germinating stalk balance" + deltaGerminatingStalk: BigInt! "Point in time delta total for bean mints sent to the silo" deltaBeanMints: BigInt! "Point in time delta number of active farmers deposited in the silo" @@ -364,6 +376,64 @@ type WhitelistTokenSetting @entity { optimalPercentDepositedBdv: BigInt "Last timestamp entity was updated" updatedAt: BigInt! + "Link to hourly snapshot data" + hourlySnapshots: [WhitelistTokenHourlySnapshot!]! @derivedFrom(field: "token") + "Link to daily snapshot data" + dailySnapshots: [WhitelistTokenDailySnapshot!]! @derivedFrom(field: "token") +} + +type WhitelistTokenHourlySnapshot @entity { + "Token address - Season" + id: Bytes! + "WhitelistTokenSetting associated with this snapshot" + token: WhitelistTokenSetting! + "Encoded BDV selector" + selector: Bytes! + "[Seed Gauge] Encoded Gauge Point selector" + gpSelector: Bytes + "[Seed Gauge] Encoded Liquidity Weight selector" + lwSelector: Bytes + "Represents how much Stalk one BDV of the underlying deposited token grows each season." + stalkEarnedPerSeason: BigInt! + "The stalk per BDV that the silo grants in exchange for depositing this token." + stalkIssuedPerBdv: BigInt! + "The last season in which the stalkEarnedPerSeason for this token was updated." + milestoneSeason: Int! + "[Seed Gauge] Current Gauge Points" + gaugePoints: BigInt + "[Seed Gauge] The current optimal targeted distribution of BDV for this whitelisted asset" + optimalPercentDepositedBdv: BigInt + "Timestamp of initial snapshot creation" + createdAt: BigInt! + "Timestamp of last entity update" + updatedAt: BigInt! +} + +type WhitelistTokenDailySnapshot @entity { + "Token address - Unix Timestamp" + id: Bytes! + "WhitelistTokenSetting associated with this snapshot" + token: WhitelistTokenSetting! + "Encoded BDV selector" + selector: Bytes! + "[Seed Gauge] Encoded Gauge Point selector" + gpSelector: Bytes + "[Seed Gauge] Encoded Liquidity Weight selector" + lwSelector: Bytes + "Represents how much Stalk one BDV of the underlying deposited token grows each season." + stalkEarnedPerSeason: BigInt! + "The stalk per BDV that the silo grants in exchange for depositing this token." + stalkIssuedPerBdv: BigInt! + "The last season in which the stalkEarnedPerSeason for this token was updated." + milestoneSeason: Int! + "[Seed Gauge] Current Gauge Points" + gaugePoints: BigInt + "[Seed Gauge] The current optimal targeted distribution of BDV for this whitelisted asset" + optimalPercentDepositedBdv: BigInt + "Timestamp of initial snapshot creation" + createdAt: BigInt! + "Timestamp of last entity update" + updatedAt: BigInt! } type Field @entity { diff --git a/projects/subgraph-beanstalk/src/GaugeHandler.ts b/projects/subgraph-beanstalk/src/GaugeHandler.ts index 60f485a229..ade0c189c2 100644 --- a/projects/subgraph-beanstalk/src/GaugeHandler.ts +++ b/projects/subgraph-beanstalk/src/GaugeHandler.ts @@ -9,8 +9,14 @@ import { WhitelistToken } from "../generated/BIP42-SeedGauge/Beanstalk"; import { handleRateChange } from "./utils/Field"; -import { loadWhitelistTokenSetting } from "./utils/SiloEntities"; -import { loadSilo, loadSiloHourlySnapshot } from "./utils/SiloEntities"; +import { loadBeanstalk } from "./utils/Beanstalk"; +import { loadSilo, loadSiloHourlySnapshot, loadSiloDailySnapshot, loadWhitelistTokenSetting } from "./utils/SiloEntities"; +import { Address } from "@graphprotocol/graph-ts"; + +function currentSeason(beanstalk: Address): i32 { + let beanstalkEntity = loadBeanstalk(beanstalk); + return beanstalkEntity.lastSeason; +} export function handleTemperatureChange(event: TemperatureChange): void { handleRateChange(event.address, event.block, event.params.season, event.params.caseId, event.params.absChange); @@ -29,8 +35,12 @@ export function handleBeanToMaxLpGpPerBdvRatioChange(event: BeanToMaxLpGpPerBdvR silo.save(); let siloHourly = loadSiloHourlySnapshot(event.address, event.params.season.toI32(), event.block.timestamp); + let siloDaily = loadSiloDailySnapshot(event.address, event.block.timestamp); + siloHourly.beanToMaxLpGpPerBdvRatio = silo.beanToMaxLpGpPerBdvRatio; siloHourly.caseId = event.params.caseId; + siloDaily.beanToMaxLpGpPerBdvRatio = silo.beanToMaxLpGpPerBdvRatio; siloHourly.save(); + siloDaily.save(); } export function handleGaugePointChange(event: GaugePointChange): void { @@ -38,12 +48,21 @@ export function handleGaugePointChange(event: GaugePointChange): void { siloSettings.gaugePoints = event.params.gaugePoints; siloSettings.updatedAt = event.block.timestamp; siloSettings.save(); + // TODO: daily } export function handleUpdateAverageStalkPerBdvPerSeason(event: UpdateAverageStalkPerBdvPerSeason): void { let silo = loadSilo(event.address); - silo.grownStalkPerBdvPerSeason = event.params.newStalkPerBdvPerSeason; + + // grownStalkPerBdvPerSeason variable currently stores overall, not per bdv + silo.grownStalkPerBdvPerSeason = silo.depositedBDV.times(event.params.newStalkPerBdvPerSeason); silo.save(); + let siloHourly = loadSiloHourlySnapshot(event.address, currentSeason(event.address), event.block.timestamp); + let siloDaily = loadSiloDailySnapshot(event.address, event.block.timestamp); + siloHourly.grownStalkPerBdvPerSeason = silo.grownStalkPerBdvPerSeason; + siloDaily.grownStalkPerBdvPerSeason = silo.grownStalkPerBdvPerSeason; + siloHourly.save(); + siloDaily.save(); } // GERMINATING STALK // @@ -52,12 +71,30 @@ export function handleFarmerGerminatingStalkBalanceChanged(event: FarmerGerminat let farmerSilo = loadSilo(event.params.account); farmerSilo.germinatingStalk = farmerSilo.germinatingStalk.plus(event.params.delta); farmerSilo.save(); + + let siloHourly = loadSiloHourlySnapshot(event.params.account, currentSeason(event.address), event.block.timestamp); + let siloDaily = loadSiloDailySnapshot(event.params.account, event.block.timestamp); + siloHourly.germinatingStalk = farmerSilo.germinatingStalk; + siloHourly.deltaGerminatingStalk = siloHourly.deltaGerminatingStalk.plus(event.params.delta); + siloDaily.germinatingStalk = farmerSilo.germinatingStalk; + siloDaily.deltaGerminatingStalk = siloDaily.deltaGerminatingStalk.plus(event.params.delta); + siloHourly.save(); + siloDaily.save(); } export function handleTotalGerminatingBalanceChanged(event: TotalGerminatingBalanceChanged): void { let silo = loadSilo(event.address); silo.germinatingStalk = silo.germinatingStalk.plus(event.params.delta); silo.save(); + + let siloHourly = loadSiloHourlySnapshot(event.address, currentSeason(event.address), event.block.timestamp); + let siloDaily = loadSiloDailySnapshot(event.address, event.block.timestamp); + siloHourly.germinatingStalk = silo.germinatingStalk; + siloHourly.deltaGerminatingStalk = siloHourly.deltaGerminatingStalk.plus(event.params.delta); + siloDaily.germinatingStalk = silo.germinatingStalk; + siloDaily.deltaGerminatingStalk = siloDaily.deltaGerminatingStalk.plus(event.params.delta); + siloHourly.save(); + siloDaily.save(); } // WHITELIST / GAUGE CONFIGURATION SETTINGS // diff --git a/projects/subgraph-beanstalk/src/utils/SiloEntities.ts b/projects/subgraph-beanstalk/src/utils/SiloEntities.ts index 0da37aae63..11be8b384a 100644 --- a/projects/subgraph-beanstalk/src/utils/SiloEntities.ts +++ b/projects/subgraph-beanstalk/src/utils/SiloEntities.ts @@ -57,6 +57,8 @@ export function loadSiloHourlySnapshot(account: Address, season: i32, timestamp: snapshot.seeds = silo.seeds; snapshot.grownStalkPerBdvPerSeason = silo.grownStalkPerBdvPerSeason; snapshot.roots = silo.roots; + snapshot.germinatingStalk = silo.germinatingStalk; + snapshot.beanToMaxLpGpPerBdvRatio = silo.beanToMaxLpGpPerBdvRatio; snapshot.beanMints = silo.beanMints; snapshot.activeFarmers = silo.activeFarmers; snapshot.deltaDepositedBDV = ZERO_BI; @@ -64,6 +66,7 @@ export function loadSiloHourlySnapshot(account: Address, season: i32, timestamp: snapshot.deltaPlantableStalk = ZERO_BI; snapshot.deltaSeeds = ZERO_BI; snapshot.deltaRoots = ZERO_BI; + snapshot.deltaGerminatingStalk = ZERO_BI; snapshot.deltaBeanMints = ZERO_BI; snapshot.deltaActiveFarmers = 0; snapshot.createdAt = BigInt.fromString(hour); @@ -88,6 +91,8 @@ export function loadSiloDailySnapshot(account: Address, timestamp: BigInt): Silo snapshot.seeds = silo.seeds; snapshot.grownStalkPerBdvPerSeason = silo.grownStalkPerBdvPerSeason; snapshot.roots = silo.roots; + snapshot.germinatingStalk = silo.germinatingStalk; + snapshot.beanToMaxLpGpPerBdvRatio = silo.beanToMaxLpGpPerBdvRatio; snapshot.beanMints = silo.beanMints; snapshot.activeFarmers = silo.activeFarmers; snapshot.deltaDepositedBDV = ZERO_BI; @@ -95,6 +100,7 @@ export function loadSiloDailySnapshot(account: Address, timestamp: BigInt): Silo snapshot.deltaPlantableStalk = ZERO_BI; snapshot.deltaSeeds = ZERO_BI; snapshot.deltaRoots = ZERO_BI; + snapshot.deltaGerminatingStalk = ZERO_BI; snapshot.deltaBeanMints = ZERO_BI; snapshot.deltaActiveFarmers = 0; snapshot.createdAt = BigInt.fromString(day); diff --git a/projects/subgraph-beanstalk/subgraph.yaml b/projects/subgraph-beanstalk/subgraph.yaml index 3921a37601..f624267d11 100644 --- a/projects/subgraph-beanstalk/subgraph.yaml +++ b/projects/subgraph-beanstalk/subgraph.yaml @@ -740,7 +740,7 @@ dataSources: source: address: "0xC1E088fC1323b20BCBee9bd1B9fC9546db5624C5" abi: Beanstalk - startBlock: 18522900 + startBlock: 19628074 mapping: kind: ethereum/events apiVersion: 0.0.6 diff --git a/projects/subgraph-beanstalk/tests/SeedGauge.test.ts b/projects/subgraph-beanstalk/tests/SeedGauge.test.ts index a62abd2a49..4d9f2e26ee 100644 --- a/projects/subgraph-beanstalk/tests/SeedGauge.test.ts +++ b/projects/subgraph-beanstalk/tests/SeedGauge.test.ts @@ -90,6 +90,7 @@ describe("Seed Gauge", () => { test("event: UpdateAverageStalkPerBdvPerSeason", () => { handleUpdateAverageStalkPerBdvPerSeason(createUpdateAverageStalkPerBdvPerSeasonEvent(BigInt.fromU32(3456))); + // TODO: Update this to expect that value times total bdv deposited assert.fieldEquals("Silo", BEANSTALK.toHexString(), "grownStalkPerBdvPerSeason", "3456"); }); });