diff --git a/abis/HorizonStaking.json b/abis/HorizonStaking.json index 67eb616b..1b2a72f6 100644 --- a/abis/HorizonStaking.json +++ b/abis/HorizonStaking.json @@ -254,6 +254,11 @@ "name": "HorizonStakingInvalidZeroTokens", "type": "error" }, + { + "inputs": [], + "name": "HorizonStakingLegacySlashFailed", + "type": "error" + }, { "inputs": [ { @@ -280,6 +285,11 @@ "name": "HorizonStakingNothingThawing", "type": "error" }, + { + "inputs": [], + "name": "HorizonStakingNothingToWithdraw", + "type": "error" + }, { "inputs": [], "name": "HorizonStakingProvisionAlreadyExists", @@ -1159,6 +1169,12 @@ "internalType": "uint256", "name": "tokens", "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shares", + "type": "uint256" } ], "name": "TokensUndelegated", @@ -1517,7 +1533,7 @@ "outputs": [ { "internalType": "uint256", - "name": "tokens", + "name": "", "type": "uint256" } ], @@ -1682,6 +1698,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "getStakingExtension", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -2423,9 +2452,5 @@ ], "stateMutability": "nonpayable", "type": "function" - }, - { - "stateMutability": "payable", - "type": "receive" } ] \ No newline at end of file diff --git a/schema.graphql b/schema.graphql index c12b4561..fdf94006 100644 --- a/schema.graphql +++ b/schema.graphql @@ -246,6 +246,9 @@ type DataService @entity { "Total GRT currently in allocations for this DataService" totalTokensAllocated: BigInt! + "Ratio of max staked delegation tokens to indexers stake that earns rewards" + delegationRatio: Int + provisions: [Provision!]! @derivedFrom(field: "dataService") } @@ -867,6 +870,10 @@ type Provision @entity { tokensAllocated: BigInt! + tokensSlashedServiceProvider: BigInt! + + tokensSlashedDelegationPool: BigInt! + totalAllocationCount: BigInt! allocationCount: Int! @@ -893,12 +900,22 @@ type Provision @entity { thawingPeriodPending: BigInt! # Cuts for subgraph service. Percentage of rewards that the delegation pool receives + "Raw query fee cut. In Horizon this is amount of query fees that the delegation pool receives in PPM" queryFeeCut: BigInt! + "Raw indexing fee cut. In Horizon this is amount of indexing fees that the delegation pool receives in PPM" indexingFeeCut: BigInt! + "Raw indexing rewards cut. In Horizon this is amount of indexing rewards that the delegation pool receives in PPM" indexingRewardsCut: BigInt! + "The percent of indexing rewards generated by the delegated stake that the Indexer keeps for itself" + indexingRewardEffectiveCut: BigDecimal! + "The percent of query fees generated by the delegated stake that the Indexer keeps for itself" + queryFeeEffectiveCut: BigDecimal! + "The percent of reward dilution delegators experience because of overdelegation. Overdelegated stake can't be used to generate rewards but still gets accounted while distributing the generated rewards. This causes dilution of the rewards for the rest of the pool." + overDelegationDilution: BigDecimal! + # Might want to add polymorphic handling of different fee cuts through a generic hashmap in the future # Indexing rewards. Keeping the same naming from Indexer entity to make it easier to understand @@ -924,6 +941,12 @@ type Provision @entity { delegatorShares: BigInt! "Exchange rate of of tokens received for each share" delegationExchangeRate: BigDecimal! + "Ratio between the amount of the indexers own stake over the total usable stake (capped by the delegationRatio)." + ownStakeRatio: BigDecimal! + "Ratio between the amount of delegated stake over the total usable stake (capped by the delegationRatio)." + delegatedStakeRatio: BigDecimal! + "Percentage of indexers' own rewards received in relation to its own stake. 1 (100%) means that the indexer is receiving the exact amount that is generated by his own stake, the value can be over 100% or below depending on the amount of delegation and cuts set" + indexerRewardsOwnGenerationRatio: BigDecimal! "Service registry URL for the indexer" url: String @@ -1111,8 +1134,12 @@ Delegator stake for a single Indexer type DelegatedStake @entity { "Concatenation of Delegator address and Indexer address" id: ID! - "Index the stake is delegated to" + "Indexer the stake is delegated to" indexer: Indexer! + "DataService the stake is delegated to. Only for Horizon delegations" + dataService: DataService + "Provision the stake is delegated to. Only for Horizon delegations" + provision: Provision "Delegator" delegator: Delegator! "CUMULATIVE tokens delegated" diff --git a/src/mappings/helpers/helpers.ts b/src/mappings/helpers/helpers.ts index a70eef19..1787efbe 100644 --- a/src/mappings/helpers/helpers.ts +++ b/src/mappings/helpers/helpers.ts @@ -202,6 +202,8 @@ export function createOrLoadProvision(indexerAddress: Bytes, verifierAddress: By provision.dataService = verifierAddress.toHexString() provision.tokensProvisioned = BigInt.fromI32(0) provision.tokensAllocated = BigInt.fromI32(0) + provision.tokensSlashedServiceProvider = BigInt.fromI32(0) + provision.tokensSlashedDelegationPool = BigInt.fromI32(0) provision.totalAllocationCount = BigInt.fromI32(0) provision.allocationCount = 0 provision.tokensThawing = BigInt.fromI32(0) @@ -216,6 +218,11 @@ export function createOrLoadProvision(indexerAddress: Bytes, verifierAddress: By provision.delegatedTokens = BigInt.fromI32(0) provision.delegatorShares = BigInt.fromI32(0) provision.delegationExchangeRate = BigInt.fromI32(0).toBigDecimal() + provision.indexingRewardEffectiveCut = BigInt.fromI32(0).toBigDecimal() + provision.queryFeeEffectiveCut = BigInt.fromI32(0).toBigDecimal() + provision.ownStakeRatio = BigInt.fromI32(0).toBigDecimal() + provision.delegatedStakeRatio = BigInt.fromI32(0).toBigDecimal() + provision.indexerRewardsOwnGenerationRatio = BigInt.fromI32(0).toBigDecimal() provision.save() } @@ -348,6 +355,46 @@ export function createOrLoadDelegatedStake( } return delegatedStake as DelegatedStake } + +export function createOrLoadDelegatedStakeForProvision( + delegator: string, + indexer: string, + dataService: string, + timestamp: i32, +): DelegatedStake { + let provisionId = joinID([indexer, dataService]) + let id = joinID([delegator, provisionId]) + let delegatedStake = DelegatedStake.load(id) + if (delegatedStake == null) { + delegatedStake = new DelegatedStake(id) + delegatedStake.indexer = indexer + delegatedStake.dataService = dataService + delegatedStake.provision = provisionId + delegatedStake.delegator = delegator + delegatedStake.stakedTokens = BigInt.fromI32(0) + delegatedStake.transferredToL2 = false + delegatedStake.stakedTokensTransferredToL2 = BigInt.fromI32(0) + delegatedStake.unstakedTokens = BigInt.fromI32(0) + delegatedStake.lockedTokens = BigInt.fromI32(0) + delegatedStake.lockedUntil = 0 + delegatedStake.shareAmount = BigInt.fromI32(0) + delegatedStake.personalExchangeRate = BigDecimal.fromString('1') + delegatedStake.realizedRewards = BigDecimal.fromString('0') + delegatedStake.createdAt = timestamp + + delegatedStake.save() + + let delegatorEntity = Delegator.load(delegator)! + delegatorEntity.stakesCount = delegatorEntity.stakesCount + 1 + delegatorEntity.save() + + let graphNetwork = GraphNetwork.load('1')! + graphNetwork.delegationCount = graphNetwork.delegationCount + 1 + graphNetwork.save() + } + return delegatedStake as DelegatedStake +} + export function createOrLoadCurator(curatorAddress: Bytes, timestamp: BigInt): Curator { let id = curatorAddress.toHexString() let curator = Curator.load(id) @@ -916,6 +963,71 @@ export function updateAdvancedIndexerMetrics(indexer: Indexer): Indexer { return indexer as Indexer } +export function calculateOwnStakeRatioForProvision(provision: Provision): BigDecimal { + let totalTokens = provision.tokensProvisioned.plus(provision.delegatedTokens) + return totalTokens == BigInt.fromI32(0) + ? BigDecimal.fromString('0') + : provision.tokensProvisioned.toBigDecimal().div(totalTokens.toBigDecimal()) +} + +export function calculateDelegatedStakeRatioForProvision(provision: Provision): BigDecimal { + let totalTokens = provision.tokensProvisioned.plus(provision.delegatedTokens) + return totalTokens == BigInt.fromI32(0) + ? BigDecimal.fromString('0') + : provision.delegatedTokens.toBigDecimal().div(totalTokens.toBigDecimal()) +} + +export function calculateIndexingRewardEffectiveCutForProvision(provision: Provision): BigDecimal { + let delegatorCut = + provision.indexingRewardsCut.toBigDecimal() / + BigDecimal.fromString('1000000') + return provision.delegatedStakeRatio == BigDecimal.fromString('0') + ? BigDecimal.fromString('0') + : BigDecimal.fromString('1') - delegatorCut / provision.delegatedStakeRatio +} + +export function calculateQueryFeeEffectiveCutForProvision(provision: Provision): BigDecimal { + let delegatorCut = + provision.queryFeeCut.toBigDecimal() / BigDecimal.fromString('1000000') + return provision.delegatedStakeRatio == BigDecimal.fromString('0') + ? BigDecimal.fromString('0') + : BigDecimal.fromString('1') - delegatorCut / provision.delegatedStakeRatio +} + +export function calculateIndexerRewardOwnGenerationRatioForProvision(provision: Provision): BigDecimal { + let delegatorCut = + provision.indexingRewardsCut.toBigDecimal() / BigDecimal.fromString('1000000') + return provision.ownStakeRatio == BigDecimal.fromString('0') + ? BigDecimal.fromString('0') + : (BigDecimal.fromString('1') - delegatorCut) / provision.ownStakeRatio +} + +export function calculateOverdelegationDilutionForProvision(provision: Provision): BigDecimal { + let provisionedTokensBD = provision.tokensProvisioned.toBigDecimal() + let delegatedTokensBD = provision.delegatedTokens.toBigDecimal() + let dataService = DataService.load(provision.dataService)! + if (dataService.delegationRatio == null) { + return BigDecimal.fromString('0') + } + let delegationRatioBD = BigInt.fromI32(dataService.delegationRatio).toBigDecimal() + let maxDelegatedStake = provisionedTokensBD * delegationRatioBD + return provisionedTokensBD == BigDecimal.fromString('0') + ? BigDecimal.fromString('0') + : BigDecimal.fromString('1') - maxDelegatedStake / max(maxDelegatedStake, delegatedTokensBD) +} + +export function updateAdvancedProvisionMetrics(provision: Provision): Provision { + provision.ownStakeRatio = calculateOwnStakeRatioForProvision(provision as Provision) + provision.delegatedStakeRatio = calculateDelegatedStakeRatioForProvision(provision as Provision) + provision.indexingRewardEffectiveCut = calculateIndexingRewardEffectiveCutForProvision(provision as Provision) + provision.queryFeeEffectiveCut = calculateQueryFeeEffectiveCutForProvision(provision as Provision) + provision.indexerRewardsOwnGenerationRatio = calculateIndexerRewardOwnGenerationRatioForProvision( + provision as Provision, + ) + provision.overDelegationDilution = calculateOverdelegationDilutionForProvision(provision as Provision) + return provision as Provision +} + export function updateDelegationExchangeRate(indexer: Indexer): Indexer { indexer.delegationExchangeRate = indexer.delegatedTokens .toBigDecimal() @@ -924,6 +1036,14 @@ export function updateDelegationExchangeRate(indexer: Indexer): Indexer { return indexer as Indexer } +export function updateDelegationExchangeRateForProvision(provision: Provision): Provision { + provision.delegationExchangeRate = provision.delegatedTokens + .toBigDecimal() + .div(provision.delegatorShares.toBigDecimal()) + .truncate(18) + return provision as Provision +} + // TODO - this is broken if we change the delegatio ratio // Need to remove, or find a fix export function calculateCapacities(indexer: Indexer): Indexer { @@ -957,10 +1077,10 @@ export function calculatePricePerShare(deployment: SubgraphDeployment): BigDecim deployment.signalAmount == BigInt.fromI32(0) ? BigDecimal.fromString('0') : deployment.signalledTokens - .toBigDecimal() - .div(deployment.signalAmount.toBigDecimal()) - .times(BigInt.fromI32(reserveRatioMultiplier).toBigDecimal()) - .truncate(18) + .toBigDecimal() + .div(deployment.signalAmount.toBigDecimal()) + .times(BigInt.fromI32(reserveRatioMultiplier).toBigDecimal()) + .truncate(18) return pricePerShare } diff --git a/src/mappings/horizonStaking.ts b/src/mappings/horizonStaking.ts index 3253cea6..3407d6a2 100644 --- a/src/mappings/horizonStaking.ts +++ b/src/mappings/horizonStaking.ts @@ -1,8 +1,8 @@ import { BigInt } from '@graphprotocol/graph-ts' import { addresses } from '../../config/addresses' -import { DelegationFeeCutSet, HorizonStakeDeposited, HorizonStakeLocked, HorizonStakeWithdrawn, OperatorSet, TokensDeprovisioned, TokensToDelegationPoolAdded } from '../types/HorizonStaking/HorizonStaking' -import { Indexer, ThawRequest } from '../types/schema' -import { createOrLoadDataService, createOrLoadEpoch, createOrLoadGraphAccount, createOrLoadGraphNetwork, createOrLoadIndexer, createOrLoadOperator, createOrLoadProvision, updateDelegationExchangeRate } from './helpers/helpers' +import { DelegatedTokensWithdrawn, DelegationFeeCutSet, DelegationSlashed, HorizonStakeDeposited, HorizonStakeLocked, HorizonStakeWithdrawn, OperatorSet, StakeDelegatedWithdrawn, TokensDelegated, TokensDeprovisioned, TokensToDelegationPoolAdded, TokensUndelegated } from '../types/HorizonStaking/HorizonStaking' +import { DelegatedStake, Delegator, Indexer, Provision, ThawRequest } from '../types/schema' +import { calculateCapacities, createOrLoadDataService, createOrLoadDelegatedStake, createOrLoadDelegatedStakeForProvision, createOrLoadDelegator, createOrLoadEpoch, createOrLoadGraphAccount, createOrLoadGraphNetwork, createOrLoadIndexer, createOrLoadOperator, createOrLoadProvision, joinID, updateAdvancedIndexerMetrics, updateAdvancedProvisionMetrics, updateDelegationExchangeRate, updateDelegationExchangeRateForProvision } from './helpers/helpers' import { ProvisionCreated, ProvisionIncreased, @@ -230,15 +230,16 @@ export function handleProvisionSlashed(event: ProvisionSlashed): void { indexer.provisionedTokens = indexer.provisionedTokens.minus(event.params.tokens) indexer.stakedTokens = indexer.stakedTokens.minus(event.params.tokens) indexer.save() - + dataService.totalTokensProvisioned = dataService.totalTokensProvisioned.minus(event.params.tokens) dataService.save() - + graphNetwork.totalTokensProvisioned = graphNetwork.totalTokensProvisioned.minus(event.params.tokens) graphNetwork.totalTokensStaked = graphNetwork.totalTokensStaked.minus(event.params.tokens) graphNetwork.save() - + provision.tokensProvisioned = provision.tokensProvisioned.minus(event.params.tokens) + provision.tokensSlashedServiceProvider = provision.tokensSlashedServiceProvider.plus(event.params.tokens) provision.save() } @@ -279,4 +280,185 @@ export function handleTokensToDelegationPoolAdded(event: TokensToDelegationPoolA graphNetwork.totalDelegatedTokens = graphNetwork.totalDelegatedTokens.plus(event.params.tokens) graphNetwork.save() +} + +// Delegation + +export function handleTokensDelegated(event: TokensDelegated): void { + let zeroShares = event.params.shares.equals(BigInt.fromI32(0)) + + let dataService = createOrLoadDataService(event.params.verifier) + // Might want to track some stuff here in the future + dataService.save() + + let provision = createOrLoadProvision(event.params.serviceProvider, event.params.verifier, event.block.timestamp) + provision.delegatedTokens = provision.delegatedTokens.plus(event.params.tokens) + provision.delegatorShares = provision.delegatorShares.plus(event.params.shares) + if (provision.delegatorShares != BigInt.fromI32(0)) { + provision = updateDelegationExchangeRateForProvision(provision as Provision) + } + provision = updateAdvancedProvisionMetrics(provision as Provision) + provision.save() + + // update indexer + let indexer = createOrLoadIndexer(event.params.serviceProvider, event.block.timestamp) + indexer.delegatedTokens = indexer.delegatedTokens.plus(event.params.tokens) + indexer.delegatorShares = indexer.delegatorShares.plus(event.params.shares) + indexer.save() + + // update delegator + let delegatorID = event.params.delegator.toHexString() + let delegator = createOrLoadDelegator(event.params.delegator, event.block.timestamp) + delegator.totalStakedTokens = delegator.totalStakedTokens.plus(event.params.tokens) + delegator.save() + + // update delegated stake + let delegatedStake = createOrLoadDelegatedStakeForProvision( + delegatorID, + indexer.id, + dataService.id, + event.block.timestamp.toI32(), + ) + + if (!zeroShares) { + let previousExchangeRate = delegatedStake.personalExchangeRate + let previousShares = delegatedStake.shareAmount + let averageCostBasisTokens = previousExchangeRate + .times(previousShares.toBigDecimal()) + .plus(event.params.tokens.toBigDecimal()) + let averageCostBasisShares = previousShares.plus(event.params.shares) + if (averageCostBasisShares.gt(BigInt.fromI32(0))) { + delegatedStake.personalExchangeRate = averageCostBasisTokens + .div(averageCostBasisShares.toBigDecimal()) + .truncate(18) + } + } + + let isStakeBecomingActive = delegatedStake.shareAmount.isZero() && !event.params.shares.isZero() + + delegatedStake.stakedTokens = delegatedStake.stakedTokens.plus(event.params.tokens) + delegatedStake.shareAmount = delegatedStake.shareAmount.plus(event.params.shares) + delegatedStake.lastDelegatedAt = event.block.timestamp.toI32() + delegatedStake.save() + + // reload delegator to avoid edge case where we can overwrite stakesCount if stake is new + delegator = Delegator.load(delegatorID) as Delegator + + // upgrade graph network + let graphNetwork = createOrLoadGraphNetwork(event.block.number, event.address) + graphNetwork.totalDelegatedTokens = graphNetwork.totalDelegatedTokens.plus(event.params.tokens) + + if (isStakeBecomingActive) { + graphNetwork.activeDelegationCount = graphNetwork.activeDelegationCount + 1 + delegator.activeStakesCount = delegator.activeStakesCount + 1 + // Is delegator becoming active because of the stake becoming active? + if (delegator.activeStakesCount == 1) { + graphNetwork.activeDelegatorCount = graphNetwork.activeDelegatorCount + 1 + } + } + + graphNetwork.save() + delegator.save() +} + +export function handleDelegationSlashed(event: DelegationSlashed): void { + // This is a delegation pool wide change, no particular delegation or delegator can be updated here. + + // update provision + let provision = createOrLoadProvision(event.params.serviceProvider, event.params.verifier, event.block.timestamp) + provision.delegatedTokens = provision.delegatedTokens.minus(event.params.tokens) + provision.tokensSlashedDelegationPool = provision.tokensSlashedDelegationPool.plus(event.params.tokens) + if (provision.delegatorShares != BigInt.fromI32(0)) { + provision = updateDelegationExchangeRateForProvision(provision as Provision) + } + provision = updateAdvancedProvisionMetrics(provision as Provision) + provision.save() + + // update indexer + let indexerID = event.params.serviceProvider.toHexString() + let indexer = Indexer.load(indexerID)! + indexer.delegatedTokens = indexer.delegatedTokens.minus(event.params.tokens) + indexer.save() + + // upgrade graph network + let graphNetwork = createOrLoadGraphNetwork(event.block.number, event.address) + graphNetwork.totalDelegatedTokens = graphNetwork.totalDelegatedTokens.minus(event.params.tokens) + graphNetwork.save() +} + +export function handleTokensUndelegated(event: TokensUndelegated): void { + // update provision + let provision = createOrLoadProvision(event.params.serviceProvider, event.params.verifier, event.block.timestamp) + + let beforeUpdateDelegationExchangeRate = provision.delegationExchangeRate + + provision.delegatedTokens = provision.delegatedTokens.minus(event.params.tokens) + provision.delegatorShares = provision.delegatorShares.minus(event.params.shares) + if (provision.delegatorShares != BigInt.fromI32(0)) { + provision = updateDelegationExchangeRateForProvision(provision as Provision) + } + provision = updateAdvancedProvisionMetrics(provision as Provision) + provision.save() + + // update indexer + let indexerID = event.params.serviceProvider.toHexString() + let indexer = Indexer.load(indexerID)! + indexer.delegatedTokens = indexer.delegatedTokens.minus(event.params.tokens) + indexer.delegatorShares = indexer.delegatorShares.minus(event.params.shares) + indexer.save() + + // update delegated stake + let delegatorID = event.params.delegator.toHexString() + let id = joinID([delegatorID, provision.id]) + let delegatedStake = DelegatedStake.load(id)! + + let isStakeBecomingInactive = + !delegatedStake.shareAmount.isZero() && delegatedStake.shareAmount == event.params.shares + + delegatedStake.unstakedTokens = delegatedStake.unstakedTokens.plus(event.params.tokens) + delegatedStake.shareAmount = delegatedStake.shareAmount.minus(event.params.shares) + delegatedStake.lockedTokens = delegatedStake.lockedTokens.plus(event.params.tokens) + //delegatedStake.lockedUntil = event.params.until.toI32() // until always updates and overwrites the past lockedUntil time + delegatedStake.lastUndelegatedAt = event.block.timestamp.toI32() + + let currentBalance = event.params.shares.toBigDecimal().times(beforeUpdateDelegationExchangeRate) + let oldBalance = event.params.shares.toBigDecimal().times(delegatedStake.personalExchangeRate) + let realizedRewards = currentBalance.minus(oldBalance) + + delegatedStake.realizedRewards = delegatedStake.realizedRewards.plus(realizedRewards) + delegatedStake.save() + + // update delegator + let delegator = Delegator.load(delegatorID)! + delegator.totalUnstakedTokens = delegator.totalUnstakedTokens.plus(event.params.tokens) + delegator.totalRealizedRewards = delegator.totalRealizedRewards.plus(realizedRewards) + + // upgrade graph network + let graphNetwork = createOrLoadGraphNetwork(event.block.number, event.address) + graphNetwork.totalDelegatedTokens = graphNetwork.totalDelegatedTokens.minus(event.params.tokens) + + if (isStakeBecomingInactive) { + graphNetwork.activeDelegationCount = graphNetwork.activeDelegationCount - 1 + delegator.activeStakesCount = delegator.activeStakesCount - 1 + // Is delegator becoming inactive because of the stake becoming inactive? + if (delegator.activeStakesCount == 0) { + graphNetwork.activeDelegatorCount = graphNetwork.activeDelegatorCount - 1 + } + } + + graphNetwork.save() + delegator.save() +} + +export function handleDelegatedTokensWithdrawn(event: DelegatedTokensWithdrawn): void { + let provision = createOrLoadProvision(event.params.serviceProvider, event.params.verifier, event.block.timestamp) + // might want to track locked/thawing tokens in provision too + provision.save() + + // update delegated stake + let delegatorID = event.params.delegator.toHexString() + let id = joinID([delegatorID, provision.id]) + let delegatedStake = DelegatedStake.load(id)! + delegatedStake.lockedTokens = delegatedStake.lockedTokens.minus(event.params.tokens) + delegatedStake.save() } \ No newline at end of file diff --git a/src/mappings/subgraphService.ts b/src/mappings/subgraphService.ts index dd27b7e0..fe686087 100644 --- a/src/mappings/subgraphService.ts +++ b/src/mappings/subgraphService.ts @@ -1,6 +1,6 @@ import { BigDecimal, BigInt, ethereum, log } from "@graphprotocol/graph-ts" -import { AllocationClosed, AllocationCreated, AllocationResized, IndexingRewardsCollected, QueryFeesCollected, RewardsDestinationSet, ServiceProviderRegistered } from "../types/SubgraphService/SubgraphService" -import { batchUpdateSubgraphSignalledTokens, calculatePricePerShare, createOrLoadEpoch, createOrLoadGraphNetwork, createOrLoadIndexerQueryFeePaymentAggregation, createOrLoadPaymentSource, createOrLoadProvision, createOrLoadSubgraphDeployment, joinID, updateDelegationExchangeRate } from "./helpers/helpers" +import { AllocationClosed, AllocationCreated, AllocationResized, DelegationRatioSet, IndexingRewardsCollected, QueryFeesCollected, RewardsDestinationSet, ServiceProviderRegistered } from "../types/SubgraphService/SubgraphService" +import { batchUpdateSubgraphSignalledTokens, calculatePricePerShare, createOrLoadDataService, createOrLoadEpoch, createOrLoadGraphNetwork, createOrLoadIndexerQueryFeePaymentAggregation, createOrLoadPaymentSource, createOrLoadProvision, createOrLoadSubgraphDeployment, joinID, updateDelegationExchangeRate } from "./helpers/helpers" import { Allocation, GraphAccount, Indexer, PoiSubmission, SubgraphDeployment } from "../types/schema" import { addresses } from "../../config/addresses" @@ -23,6 +23,12 @@ export function handleRewardsDestinationSet(event: RewardsDestinationSet): void provision.save() } +export function handleDelegationRatioSet(event: DelegationRatioSet): void { + let dataService = createOrLoadDataService(event.address) + dataService.delegationRatio = event.params.ratio + dataService.save() +} + export function handleAllocationCreated(event: AllocationCreated): void { let graphNetwork = createOrLoadGraphNetwork(event.block.number, event.address) let subgraphDeploymentID = event.params.subgraphDeploymentId.toHexString() diff --git a/subgraph.template.yaml b/subgraph.template.yaml index 7b3bb3f3..156c77a2 100644 --- a/subgraph.template.yaml +++ b/subgraph.template.yaml @@ -429,6 +429,14 @@ dataSources: handler: handleDelegationFeeCutSet - event: TokensToDelegationPoolAdded(indexed address,indexed address,uint256) handler: handleTokensToDelegationPoolAdded + - event: TokensDelegated(indexed address,indexed address,indexed address,uint256,uint256) + handler: handleTokensDelegated + - event: DelegationSlashed(indexed address,indexed address,uint256) + handler: handleDelegationSlashed + - event: TokensUndelegated(indexed address,indexed address,indexed address,uint256,uint256) + handler: handleTokensUndelegated + - event: DelegatedTokensWithdrawn(indexed address,indexed address,indexed address,uint256) + handler: handleDelegatedTokensWithdrawn - kind: ethereum/contract name: SubgraphService network: {{network}} @@ -465,6 +473,8 @@ dataSources: handler: handleIndexingRewardsCollected - event: QueryFeesCollected(indexed address,indexed address,indexed address,bytes32,uint256,uint256) handler: handleQueryFeesCollected + - event: DelegationRatioSet(uint32) + handler: handleDelegationRatioSet - kind: ethereum/contract name: GraphPayments network: {{network}}