diff --git a/subgraph/base_sepolia/README.md b/subgraph/base_sepolia/README.md index d7eb4e2..5d209fd 100644 --- a/subgraph/base_sepolia/README.md +++ b/subgraph/base_sepolia/README.md @@ -6,4 +6,34 @@ yarn codegen yarn build yarn deploy -``` \ No newline at end of file +``` + +## queries + +for stats +``` +{ + stats(id:"0x01") { + harbTotalSupply + stakeTotalSupply + outstandingStake + totalMinted + mintedLastWeek + mintedLastDay + mintNextHourProjected + totalBurned + burnedLastWeek + burnedLastDay + burnNextHourProjected + totalTaxPaid + taxPaidLastWeek + taxPaidLastDay + taxNextHourProjected + totalUbiClaimed + ubiClaimedLastWeek + ubiClaimedLastDay + ubiNextHourProjected + } +} +``` + diff --git a/subgraph/base_sepolia/package.json b/subgraph/base_sepolia/package.json index 0586e82..4811d2a 100644 --- a/subgraph/base_sepolia/package.json +++ b/subgraph/base_sepolia/package.json @@ -19,5 +19,6 @@ "@types/node": "^20.11.30", "matchstick-as": "0.5.0", "typescript": "^5.4.3" - } + }, + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" } diff --git a/subgraph/base_sepolia/schema.graphql b/subgraph/base_sepolia/schema.graphql index 601f294..81d2da5 100644 --- a/subgraph/base_sepolia/schema.graphql +++ b/subgraph/base_sepolia/schema.graphql @@ -4,8 +4,9 @@ type Stats @entity { id: Bytes! - outstandingSupply: BigInt! # uint256 - activeSupply: BigInt! # uint256 + harbTotalSupply: BigInt! # uint256 + stakeTotalSupply: BigInt! # uint256 + outstandingStake: BigInt! # uint256 ringBuffer: [BigInt!]! # Ring buffer to store daily totals ringBufferPointer: Int! # Pointer to the current day in the ring buffer lastUpdatedHour: Int! # The last updated day boundary (timestamp in days) diff --git a/subgraph/base_sepolia/src/chains.ts b/subgraph/base_sepolia/src/chains.ts new file mode 100644 index 0000000..accc9a8 --- /dev/null +++ b/subgraph/base_sepolia/src/chains.ts @@ -0,0 +1,38 @@ +import { Address, dataSource } from '@graphprotocol/graph-ts' + +export enum ChainId { + BASE = 8453, + BASE_SEPOLIA = 84532, +} + +const BASE_NETWORK_NAME = 'base' +const BASE_SEPOLIA_NETWORK_NAME = 'base-sepolia' + + +export class SubgraphConfig { + + harbergAddress: Address + + stakeAddress: Address + +} + +export function getSubgraphConfig(): SubgraphConfig { + // Update this value to the corresponding chain you want to deploy + const selectedNetwork = dataSource.network() + + // subgraph does not support case switch with strings, hence this if else block + if (selectedNetwork == BASE_NETWORK_NAME) { + return { + harbergAddress: Address.fromString('0x1F98431c8aD98523631AE4a59f267346ea31F984'), + stakeAddress: Address.fromString('0x17c14d2c404d167802b16c450d3c99f88f2c4f4d'), + } + } else if (selectedNetwork == BASE_SEPOLIA_NETWORK_NAME) { + return { + harbergAddress: Address.fromString('0x54838DC097E7fC4736B801bF1c1FCf1597348265'), + stakeAddress: Address.fromString('0xd7728173F73C748944d29EA77b56f09b8FEc8F33'), + } + } else { + throw new Error('Unsupported Network') + } +} \ No newline at end of file diff --git a/subgraph/base_sepolia/src/harb.ts b/subgraph/base_sepolia/src/harb.ts index 81cbe17..4e940ba 100644 --- a/subgraph/base_sepolia/src/harb.ts +++ b/subgraph/base_sepolia/src/harb.ts @@ -1,19 +1,22 @@ import { Approval as ApprovalEvent, EIP712DomainChanged as EIP712DomainChangedEvent, - Transfer as TransferEvent + Transfer as TransferEvent, + Harb } from "../generated/Harb/Harb"; import { BigInt, Bytes, ethereum, Address, log } from "@graphprotocol/graph-ts"; -import { Stats } from "../generated/schema" +import { Stats } from "../generated/schema"; +let stakeTotalSupply: BigInt = BigInt.fromString("10000000000000000000000000"); // Helper function to get or create Stats entity function getOrCreateStats(): Stats { let stats = Stats.load(Bytes.fromHexString("0x01") as Bytes); if (stats == null) { stats = new Stats(Bytes.fromHexString("0x01") as Bytes); - stats.outstandingSupply = BigInt.zero(); - stats.activeSupply = BigInt.zero(); + stats.harbTotalSupply = BigInt.zero(); + stats.stakeTotalSupply = stakeTotalSupply; + stats.outstandingStake = BigInt.zero(); // Minted stats.totalMinted = BigInt.zero(); @@ -55,6 +58,8 @@ export function handleTransfer(event: TransferEvent): void { // Get a copy of the ring buffer let ringBuffer = stats.ringBuffer; + const harberg = Harb.bind(event.address); + if (event.params.from == TAX_POOL_ADDR) { // Update total UBI claimed stats.totalUbiClaimed = stats.totalUbiClaimed.plus(event.params.value); @@ -71,6 +76,8 @@ export function handleTransfer(event: TransferEvent): void { let mintBufferIndex = (stats.ringBufferPointer * 4) + 1; // Minted tokens are at index 1 ringBuffer[mintBufferIndex] = ringBuffer[mintBufferIndex].plus(event.params.value); + stats.harbTotalSupply = stats.harbTotalSupply.plus(event.params.value); + } else if (event.params.to == ZERO_ADDRESS) { // Burn event stats.totalBurned = stats.totalBurned.plus(event.params.value); @@ -79,6 +86,8 @@ export function handleTransfer(event: TransferEvent): void { let burnBufferIndex = (stats.ringBufferPointer * 4) + 2; // Burned tokens are at index 2 ringBuffer[burnBufferIndex] = ringBuffer[burnBufferIndex].plus(event.params.value); + stats.harbTotalSupply = stats.harbTotalSupply.minus(event.params.value); + } else if (event.params.to == TAX_POOL_ADDR) { // Tax paid event stats.totalTaxPaid = stats.totalTaxPaid.plus(event.params.value); diff --git a/subgraph/base_sepolia/src/stake.ts b/subgraph/base_sepolia/src/stake.ts index bcbd1e3..9bee784 100644 --- a/subgraph/base_sepolia/src/stake.ts +++ b/subgraph/base_sepolia/src/stake.ts @@ -6,14 +6,16 @@ import { PositionRateHiked as PositionRateHikedEvent, } from "../generated/Stake/Stake"; import { Harb } from "../generated/Harb/Harb"; +import { Stake } from "../generated/Stake/Stake"; +import { getSubgraphConfig, SubgraphConfig } from './chains'; import { BigDecimal, BigInt, Bytes } from "@graphprotocol/graph-ts"; -import { Position } from "../generated/schema"; +import { Position, Stats } from "../generated/schema"; let decimals: BigDecimal = BigDecimal.fromString("1000000000000000000"); let totalSupply: BigDecimal = BigDecimal.fromString("10000000000000000000000000"); let taxRates: Array = ["0.01", "0.03", "0.05", "0.08", "0.12", "0.18", "0.24", "0.30", "0.40", "0.50", "0.60", "0.80", "1", "1.3", "1.8", "2.5", "3.2", "4.2", "5.4", "7", "9.2", "12", "16", "20", "26", "34", "44", "57", "75", "97"]; -export function handlePositionCreated(event: PositionCreatedEvent): void { +export function handlePositionCreated(event: PositionCreatedEvent, subgraphConfig: SubgraphConfig = getSubgraphConfig()): void { let position = new Position(Bytes.fromI32(event.params.positionId.toI32())); position.owner = event.params.owner; position.share = event.params.share.toBigDecimal().div(totalSupply); @@ -25,20 +27,32 @@ export function handlePositionCreated(event: PositionCreatedEvent): void { position.snatched = 0; position.payout = BigInt.fromString("0"); position.taxPaid = BigInt.fromString("0"); - let harb = Harb.bind(event.address); + let harb = Harb.bind(subgraphConfig.harbergAddress); position.totalSupplyInit = harb.totalSupply(); position.save(); + let stake = Stake.bind(event.address); + let stats = Stats.load(Bytes.fromHexString("0x01") as Bytes); + if (stats != null) { + stats.outstandingStake = stake.outstandingStake(); + stats.save(); + } } -export function handlePositionRemoved(event: PositionRemovedEvent): void { +export function handlePositionRemoved(event: PositionRemovedEvent, subgraphConfig: SubgraphConfig = getSubgraphConfig()): void { let position = Position.load(Bytes.fromI32(event.params.positionId.toI32())); if (position != null) { position.status = "Closed"; - let harb = Harb.bind(event.address); + let harb = Harb.bind(subgraphConfig.harbergAddress); position.totalSupplyEnd = harb.totalSupply(); position.payout = position.payout.plus(event.params.harbergPayout); position.save(); } + let stake = Stake.bind(event.address); + let stats = Stats.load(Bytes.fromHexString("0x01") as Bytes); + if (stats != null) { + stats.outstandingStake = stake.outstandingStake(); + stats.save(); + } } export function handlePositionShrunk(event: PositionShrunkEvent): void {