From 797fb8c3bc4c3e36b88a4f647d645866a3a5ce8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 5 Nov 2025 17:25:07 -0300 Subject: [PATCH 1/9] feat: track thawing delegation tokens MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- schema.graphql | 4 ++++ src/mappings/helpers/helpers.ts | 2 ++ src/mappings/horizonStaking.ts | 9 +++++++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/schema.graphql b/schema.graphql index c597fadb..2405d382 100644 --- a/schema.graphql +++ b/schema.graphql @@ -815,6 +815,8 @@ type Indexer @entity(immutable: false) { delegators: [DelegatedStake!]! @derivedFrom(field: "indexer") "CURRENT tokens delegated to the indexer" delegatedTokens: BigInt! + "Tokens delegated that are thawing from the provision" + delegatedThawingTokens: BigInt! "Ratio between the amount of the indexers own stake over the total usable stake." ownStakeRatio: BigDecimal! "Ratio between the amount of delegated stake over the total usable stake." @@ -998,6 +1000,8 @@ type Provision @entity(immutable: false) { # Delegation "Tokens delegated to the provision" delegatedTokens: BigInt! + "Tokens delegated that are thawing from the provision" + delegatedThawingTokens: BigInt! "Total shares of the delegator pool" delegatorShares: BigInt! "Exchange rate of tokens received for each share" diff --git a/src/mappings/helpers/helpers.ts b/src/mappings/helpers/helpers.ts index 0d4d65bc..016537b2 100644 --- a/src/mappings/helpers/helpers.ts +++ b/src/mappings/helpers/helpers.ts @@ -163,6 +163,7 @@ export function createOrLoadIndexer(indexerAddress: Bytes, timestamp: BigInt ): indexer.availableStake = BigInt.fromI32(0) indexer.delegatedTokens = BigInt.fromI32(0) + indexer.delegatedThawingTokens = BigInt.fromI32(0) indexer.ownStakeRatio = BigDecimal.fromString('0') indexer.delegatedStakeRatio = BigDecimal.fromString('0') indexer.delegatorShares = BigInt.fromI32(0) @@ -244,6 +245,7 @@ export function createOrLoadProvision(indexerAddress: Bytes, verifierAddress: By provision.indexerQueryFees = BigInt.fromI32(0) provision.delegatorQueryFees = BigInt.fromI32(0) provision.delegatedTokens = BigInt.fromI32(0) + provision.delegatedThawingTokens = BigInt.fromI32(0) provision.delegatorShares = BigInt.fromI32(0) provision.delegationExchangeRate = BigInt.fromI32(0).toBigDecimal() provision.thawingUntil = BigInt.fromI32(0) diff --git a/src/mappings/horizonStaking.ts b/src/mappings/horizonStaking.ts index ee001aba..c4f246f3 100644 --- a/src/mappings/horizonStaking.ts +++ b/src/mappings/horizonStaking.ts @@ -466,7 +466,6 @@ export function handleTokensUndelegated(event: TokensUndelegated): void { 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) @@ -477,7 +476,6 @@ export function handleTokensUndelegated(event: TokensUndelegated): void { // 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) if (indexer.delegatorShares != BigInt.fromI32(0)) { indexer = updateDelegationExchangeRate(indexer as Indexer) @@ -534,8 +532,15 @@ export function handleTokensUndelegated(event: TokensUndelegated): void { 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.delegatedTokens = provision.delegatedTokens.minus(event.params.tokens) provision.save() + let indexerID = event.params.serviceProvider.toHexString() + let indexer = Indexer.load(indexerID)! + + indexer.delegatedTokens = indexer.delegatedTokens.minus(event.params.tokens) + indexer.save() + // update delegated stake let delegatorID = event.params.delegator.toHexString() let id = joinID([delegatorID, provision.id]) From af5494cdf9f8f2593fd498ff26026ebd9d40f188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Wed, 5 Nov 2025 17:48:49 -0300 Subject: [PATCH 2/9] fix: capacity calculations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- src/mappings/helpers/helpers.ts | 10 ++++++---- src/mappings/horizonStaking.ts | 4 +++- src/mappings/subgraphService.ts | 5 ++++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/mappings/helpers/helpers.ts b/src/mappings/helpers/helpers.ts index 016537b2..ac8518a5 100644 --- a/src/mappings/helpers/helpers.ts +++ b/src/mappings/helpers/helpers.ts @@ -1155,16 +1155,18 @@ export function updateDelegationExchangeRateForProvision(provision: Provision): // Need to remove, or find a fix export function calculateCapacities(indexer: Indexer): Indexer { let graphNetwork = GraphNetwork.load('1')! - let tokensDelegatedMax = indexer.stakedTokens.times(BigInt.fromI32(graphNetwork.delegationRatio)) + let tokensDelegatedMax = indexer.provisionedTokens.times(BigInt.fromI32(graphNetwork.delegationRatio)) // Eligible to add to the capacity + let delegatedTokens = indexer.delegatedTokens.minus(indexer.delegatedThawingTokens) indexer.delegatedCapacity = - indexer.delegatedTokens < tokensDelegatedMax ? indexer.delegatedTokens : tokensDelegatedMax + delegatedTokens < tokensDelegatedMax ? delegatedTokens : tokensDelegatedMax - indexer.tokenCapacity = indexer.stakedTokens.plus(indexer.delegatedCapacity) + indexer.tokenCapacity = indexer.provisionedTokens + .minus(indexer.thawingTokens) + .plus(indexer.delegatedCapacity) indexer.availableStake = indexer.tokenCapacity .minus(indexer.allocatedTokens) - .minus(indexer.lockedTokens) return indexer } diff --git a/src/mappings/horizonStaking.ts b/src/mappings/horizonStaking.ts index c4f246f3..66c4f507 100644 --- a/src/mappings/horizonStaking.ts +++ b/src/mappings/horizonStaking.ts @@ -2,7 +2,7 @@ import { BigInt } from '@graphprotocol/graph-ts' import { addresses } from '../../config/addresses' import { AllowedLockedVerifierSet, DelegatedTokensWithdrawn, DelegationFeeCutSet, DelegationSlashed, DelegationSlashingEnabled, HorizonStakeDeposited, HorizonStakeLocked, HorizonStakeWithdrawn, MaxThawingPeriodSet, OperatorSet, StakeDelegatedWithdrawn, ThawingPeriodCleared, TokensDelegated, TokensDeprovisioned, TokensToDelegationPoolAdded, TokensUndelegated } from '../types/HorizonStaking/HorizonStaking' import { DelegatedStake, Delegator, Indexer, Provision, ThawRequest } from '../types/schema' -import { createOrLoadDataService, createOrLoadDelegatedStakeForProvision, createOrLoadDelegator, createOrLoadEpoch, createOrLoadGraphAccount, createOrLoadGraphNetwork, createOrLoadHorizonOperator, createOrLoadIndexer, createOrLoadProvision, joinID, updateAdvancedIndexerMetrics, updateAdvancedProvisionMetrics, updateDelegationExchangeRate, updateDelegationExchangeRateForProvision } from './helpers/helpers' +import { calculateCapacities, createOrLoadDataService, createOrLoadDelegatedStakeForProvision, createOrLoadDelegator, createOrLoadEpoch, createOrLoadGraphAccount, createOrLoadGraphNetwork, createOrLoadHorizonOperator, createOrLoadIndexer, createOrLoadProvision, joinID, updateAdvancedIndexerMetrics, updateAdvancedProvisionMetrics, updateDelegationExchangeRate, updateDelegationExchangeRateForProvision } from './helpers/helpers' import { ProvisionCreated, ProvisionIncreased, @@ -126,6 +126,7 @@ export function handleProvisionThawed(event: ProvisionThawed): void { let provision = createOrLoadProvision(event.params.serviceProvider, event.params.verifier, event.block.timestamp) indexer.thawingTokens = indexer.thawingTokens.plus(event.params.tokens) + indexer = calculateCapacities(indexer as Indexer) indexer.save() dataService.totalTokensThawing = dataService.totalTokensThawing.plus(event.params.tokens) @@ -146,6 +147,7 @@ export function handleTokensDeprovisioned(event: TokensDeprovisioned): void { indexer.provisionedTokens = indexer.provisionedTokens.minus(event.params.tokens) indexer.thawingTokens = indexer.thawingTokens.minus(event.params.tokens) + indexer = calculateCapacities(indexer as Indexer) indexer.save() dataService.totalTokensProvisioned = dataService.totalTokensProvisioned.minus(event.params.tokens) diff --git a/src/mappings/subgraphService.ts b/src/mappings/subgraphService.ts index 1ec947f2..a8fa6132 100644 --- a/src/mappings/subgraphService.ts +++ b/src/mappings/subgraphService.ts @@ -1,6 +1,6 @@ import { BigDecimal, BigInt, Bytes, ethereum, log } from "@graphprotocol/graph-ts" import { AllocationClosed, AllocationCreated, AllocationResized, CurationCutSet, DelegationRatioSet, IndexingRewardsCollected, MaxPOIStalenessSet, ProvisionTokensRangeSet, QueryFeesCollected, RewardsDestinationSet, ServiceProviderRegistered, StakeToFeesRatioSet, ThawingPeriodRangeSet, VerifierCutRangeSet } from "../types/SubgraphService/SubgraphService" -import { batchUpdateSubgraphSignalledTokens, calculatePricePerShare, createOrLoadDataService, createOrLoadGraphNetwork, createOrLoadEpoch,createOrLoadIndexerQueryFeePaymentAggregation, createOrLoadPaymentSource, createOrLoadProvision, createOrLoadSubgraphDeployment, joinID, updateDelegationExchangeRate } from "./helpers/helpers" +import { batchUpdateSubgraphSignalledTokens, calculatePricePerShare, createOrLoadDataService, createOrLoadGraphNetwork, createOrLoadEpoch,createOrLoadIndexerQueryFeePaymentAggregation, createOrLoadPaymentSource, createOrLoadProvision, createOrLoadSubgraphDeployment, joinID, updateDelegationExchangeRate, calculateCapacities } from "./helpers/helpers" import { Allocation, Indexer, PoiSubmission, SubgraphDeployment } from "../types/schema" import { addresses } from "../../config/addresses" import { tuplePrefixBytes } from "./helpers/decoder" @@ -64,6 +64,7 @@ export function handleAllocationCreated(event: AllocationCreated): void { indexer.allocatedTokens = indexer.allocatedTokens.plus(event.params.tokens) indexer.totalAllocationCount = indexer.totalAllocationCount.plus(BigInt.fromI32(1)) indexer.allocationCount = indexer.allocationCount + 1 + indexer = calculateCapacities(indexer as Indexer) indexer.save() // update provision @@ -140,6 +141,7 @@ export function handleAllocationClosed(event: AllocationClosed): void { indexer.allocatedTokens = indexer.allocatedTokens.minus(event.params.tokens) indexer.allocationCount = indexer.allocationCount - 1 + indexer = calculateCapacities(indexer as Indexer) indexer.save() // update provision @@ -189,6 +191,7 @@ export function handleAllocationResized(event: AllocationResized): void { // update indexer let indexer = Indexer.load(indexerID)! indexer.allocatedTokens = indexer.allocatedTokens.plus(diffTokens) + indexer = calculateCapacities(indexer as Indexer) indexer.save() // update provision From cf79828fdc3eff994f1483dbd19fdd1b9b5622ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 6 Nov 2025 09:48:37 -0300 Subject: [PATCH 3/9] fix: support calculate capacity pre horizon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- src/mappings/helpers/helpers.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/mappings/helpers/helpers.ts b/src/mappings/helpers/helpers.ts index ac8518a5..1e5d450d 100644 --- a/src/mappings/helpers/helpers.ts +++ b/src/mappings/helpers/helpers.ts @@ -1154,6 +1154,14 @@ export function updateDelegationExchangeRateForProvision(provision: Provision): // TODO - this is broken if we change the delegatio ratio // Need to remove, or find a fix export function calculateCapacities(indexer: Indexer): Indexer { + if (indexer.provisionedTokens.gt(BigInt.fromI32(0))) { + return calculateCapacitiesHorizon(indexer) + } else { + return calculateCapacitiesLegacy(indexer) + } +} + +export function calculateCapacitiesHorizon(indexer: Indexer): Indexer { let graphNetwork = GraphNetwork.load('1')! let tokensDelegatedMax = indexer.provisionedTokens.times(BigInt.fromI32(graphNetwork.delegationRatio)) @@ -1170,6 +1178,21 @@ export function calculateCapacities(indexer: Indexer): Indexer { return indexer } +export function calculateCapacitiesLegacy(indexer: Indexer): Indexer { + let graphNetwork = GraphNetwork.load('1')! + let tokensDelegatedMax = indexer.stakedTokens.times(BigInt.fromI32(graphNetwork.delegationRatio)) + + // Eligible to add to the capacity + indexer.delegatedCapacity = + indexer.delegatedTokens < tokensDelegatedMax ? indexer.delegatedTokens : tokensDelegatedMax + + indexer.tokenCapacity = indexer.stakedTokens.plus(indexer.delegatedCapacity) + indexer.availableStake = indexer.tokenCapacity + .minus(indexer.allocatedTokens) + .minus(indexer.lockedTokens) + return indexer +} + export function calculatePricePerShare(deployment: SubgraphDeployment): BigDecimal { // TODO check why there's a deviation from the values of the bancor formula // Ideally this would be a 1 to 1 recreation of the share sell formula, but due to From 786ddea199f4d4db5faf2781b7b77f5f73943886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 6 Nov 2025 11:45:10 -0300 Subject: [PATCH 4/9] fix: improve capacity calculation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- src/mappings/helpers/helpers.ts | 3 ++- src/mappings/horizonStaking.ts | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/mappings/helpers/helpers.ts b/src/mappings/helpers/helpers.ts index 1e5d450d..95118422 100644 --- a/src/mappings/helpers/helpers.ts +++ b/src/mappings/helpers/helpers.ts @@ -1154,7 +1154,8 @@ export function updateDelegationExchangeRateForProvision(provision: Provision): // TODO - this is broken if we change the delegatio ratio // Need to remove, or find a fix export function calculateCapacities(indexer: Indexer): Indexer { - if (indexer.provisionedTokens.gt(BigInt.fromI32(0))) { + let graphNetwork = GraphNetwork.load('1')! + if (graphNetwork.maxThawingPeriod.gt(BigInt.fromI32(0))) { return calculateCapacitiesHorizon(indexer) } else { return calculateCapacitiesLegacy(indexer) diff --git a/src/mappings/horizonStaking.ts b/src/mappings/horizonStaking.ts index 66c4f507..e1b8be85 100644 --- a/src/mappings/horizonStaking.ts +++ b/src/mappings/horizonStaking.ts @@ -84,6 +84,7 @@ export function handleProvisionCreated(event: ProvisionCreated): void { let provision = createOrLoadProvision(event.params.serviceProvider, event.params.verifier, event.block.timestamp) indexer.provisionedTokens = indexer.provisionedTokens.plus(event.params.tokens) + indexer = calculateCapacities(indexer as Indexer) indexer.save() dataService.totalTokensProvisioned = dataService.totalTokensProvisioned.plus(event.params.tokens) @@ -107,6 +108,7 @@ export function handleProvisionIncreased(event: ProvisionIncreased): void { let provision = createOrLoadProvision(event.params.serviceProvider, event.params.verifier, event.block.timestamp) indexer.provisionedTokens = indexer.provisionedTokens.plus(event.params.tokens) + indexer = calculateCapacities(indexer as Indexer) indexer.save() dataService.totalTokensProvisioned = dataService.totalTokensProvisioned.plus(event.params.tokens) @@ -247,6 +249,7 @@ export function handleProvisionSlashed(event: ProvisionSlashed): void { // Due to thawing tokens potentially getting cancelled, we will need to figure the thawing situation indexer.provisionedTokens = indexer.provisionedTokens.minus(event.params.tokens) indexer.stakedTokens = indexer.stakedTokens.minus(event.params.tokens) + indexer = calculateCapacities(indexer as Indexer) indexer.save() dataService.totalTokensProvisioned = dataService.totalTokensProvisioned.minus(event.params.tokens) @@ -302,6 +305,7 @@ export function handleThawRequestCreated(event: ThawRequestCreated): void { event.params.thawingUntil > indexer.thawingUntil ? event.params.thawingUntil : indexer.thawingUntil + indexer = calculateCapacities(indexer as Indexer) indexer.save() } else { // update delegated stake for delegation thaw request @@ -347,6 +351,7 @@ export function handleTokensToDelegationPoolAdded(event: TokensToDelegationPoolA indexer = updateDelegationExchangeRate(indexer as Indexer) } indexer = updateAdvancedIndexerMetrics(indexer as Indexer) + indexer = calculateCapacities(indexer as Indexer) indexer.save() let dataService = createOrLoadDataService(event.params.verifier) @@ -380,6 +385,7 @@ export function handleTokensDelegated(event: TokensDelegated): void { indexer = updateDelegationExchangeRate(indexer as Indexer) } indexer = updateAdvancedIndexerMetrics(indexer as Indexer) + indexer = calculateCapacities(indexer as Indexer) indexer.save() // update delegator @@ -454,6 +460,7 @@ export function handleDelegationSlashed(event: DelegationSlashed): void { let indexerID = event.params.serviceProvider.toHexString() let indexer = Indexer.load(indexerID)! indexer.delegatedTokens = indexer.delegatedTokens.minus(event.params.tokens) + indexer = calculateCapacities(indexer as Indexer) indexer.save() // upgrade graph network @@ -483,6 +490,7 @@ export function handleTokensUndelegated(event: TokensUndelegated): void { indexer = updateDelegationExchangeRate(indexer as Indexer) } indexer = updateAdvancedIndexerMetrics(indexer as Indexer) + indexer = calculateCapacities(indexer as Indexer) indexer.save() // update delegated stake @@ -541,6 +549,7 @@ export function handleDelegatedTokensWithdrawn(event: DelegatedTokensWithdrawn): let indexer = Indexer.load(indexerID)! indexer.delegatedTokens = indexer.delegatedTokens.minus(event.params.tokens) + indexer = calculateCapacities(indexer as Indexer) indexer.save() // update delegated stake From a31c9b78ecaa74f37e4a9316ffa90aa43e36a6b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 6 Nov 2025 12:03:21 -0300 Subject: [PATCH 5/9] fix: disputemanager bad signature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- abis/HorizonDisputeManager.json | 2409 +++++++++++++------------------ subgraph.template.yaml | 2 +- 2 files changed, 1007 insertions(+), 1404 deletions(-) diff --git a/abis/HorizonDisputeManager.json b/abis/HorizonDisputeManager.json index 4b541a90..bd78a48e 100644 --- a/abis/HorizonDisputeManager.json +++ b/abis/HorizonDisputeManager.json @@ -1,1548 +1,1151 @@ [ { - "inputs": [ - { - "internalType": "address", - "name": "controller", - "type": "address" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "length", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expectedLength", - "type": "uint256" - } - ], - "name": "AttestationInvalidBytesLength", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "disputeId", - "type": "bytes32" - } - ], - "name": "DisputeManagerDisputeAlreadyCreated", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "disputeId", - "type": "bytes32" - } - ], - "name": "DisputeManagerDisputeInConflict", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "disputeId", - "type": "bytes32" - } - ], - "name": "DisputeManagerDisputeNotInConflict", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "enum IDisputeManager.DisputeStatus", - "name": "status", - "type": "uint8" - } - ], - "name": "DisputeManagerDisputeNotPending", - "type": "error" - }, - { - "inputs": [], - "name": "DisputeManagerDisputePeriodNotFinished", - "type": "error" - }, - { - "inputs": [], - "name": "DisputeManagerDisputePeriodZero", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "allocationId", - "type": "address" - } - ], - "name": "DisputeManagerIndexerNotFound", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "disputeId", - "type": "bytes32" - } - ], - "name": "DisputeManagerInvalidDispute", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "disputeDeposit", - "type": "uint256" - } - ], - "name": "DisputeManagerInvalidDisputeDeposit", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint32", - "name": "cut", - "type": "uint32" - } - ], - "name": "DisputeManagerInvalidFishermanReward", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint32", - "name": "maxSlashingCut", - "type": "uint32" - } - ], - "name": "DisputeManagerInvalidMaxSlashingCut", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokensSlash", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "maxTokensSlash", - "type": "uint256" - } - ], - "name": "DisputeManagerInvalidTokensSlash", - "type": "error" - }, - { - "inputs": [], - "name": "DisputeManagerInvalidZeroAddress", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "disputeId", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "relatedDisputeId", - "type": "bytes32" - } - ], - "name": "DisputeManagerMustAcceptRelatedDispute", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "requestCID1", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "responseCID1", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "subgraphDeploymentId1", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "requestCID2", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "responseCID2", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "subgraphDeploymentId2", - "type": "bytes32" - } - ], - "name": "DisputeManagerNonConflictingAttestations", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "subgraphDeploymentId1", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "subgraphDeploymentId2", - "type": "bytes32" - } - ], - "name": "DisputeManagerNonMatchingSubgraphDeployment", - "type": "error" - }, - { - "inputs": [], - "name": "DisputeManagerNotArbitrator", - "type": "error" - }, - { - "inputs": [], - "name": "DisputeManagerNotFisherman", - "type": "error" - }, - { - "inputs": [], - "name": "DisputeManagerSubgraphServiceNotSet", - "type": "error" - }, - { - "inputs": [], - "name": "DisputeManagerZeroTokens", - "type": "error" + "type": "function", + "name": "acceptDispute", + "inputs": [ + { + "name": "disputeId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "tokensSlash", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" }, { - "inputs": [], - "name": "ECDSAInvalidSignature", - "type": "error" + "type": "function", + "name": "acceptDisputeConflict", + "inputs": [ + { + "name": "disputeId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "tokensSlash", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "acceptDisputeInConflict", + "type": "bool", + "internalType": "bool" + }, + { + "name": "tokensSlashRelated", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "length", - "type": "uint256" - } - ], - "name": "ECDSAInvalidSignatureLength", - "type": "error" + "type": "function", + "name": "areConflictingAttestations", + "inputs": [ + { + "name": "attestation1", + "type": "tuple", + "internalType": "struct IAttestation.State", + "components": [ + { + "name": "requestCID", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "responseCID", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "subgraphDeploymentId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "r", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "s", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "v", + "type": "uint8", + "internalType": "uint8" + } + ] + }, + { + "name": "attestation2", + "type": "tuple", + "internalType": "struct IAttestation.State", + "components": [ + { + "name": "requestCID", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "responseCID", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "subgraphDeploymentId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "r", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "s", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "v", + "type": "uint8", + "internalType": "uint8" + } + ] + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "pure" }, { - "inputs": [ - { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" - } - ], - "name": "ECDSAInvalidSignatureS", - "type": "error" + "type": "function", + "name": "cancelDispute", + "inputs": [ + { + "name": "disputeId", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [], + "stateMutability": "nonpayable" }, { - "inputs": [ - { - "internalType": "bytes", - "name": "contractName", - "type": "bytes" - } - ], - "name": "GraphDirectoryInvalidZeroAddress", - "type": "error" + "type": "function", + "name": "createAndAcceptLegacyDispute", + "inputs": [ + { + "name": "allocationId", + "type": "address", + "internalType": "address" + }, + { + "name": "fisherman", + "type": "address", + "internalType": "address" + }, + { + "name": "tokensSlash", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "tokensRewards", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "nonpayable" }, { - "inputs": [], - "name": "InvalidInitialization", - "type": "error" + "type": "function", + "name": "createIndexingDispute", + "inputs": [ + { + "name": "allocationId", + "type": "address", + "internalType": "address" + }, + { + "name": "poi", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "blockNumber", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "nonpayable" }, { - "inputs": [], - "name": "NotInitializing", - "type": "error" + "type": "function", + "name": "createQueryDispute", + "inputs": [ + { + "name": "attestationData", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "nonpayable" }, { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "OwnableInvalidOwner", - "type": "error" + "type": "function", + "name": "createQueryDisputeConflict", + "inputs": [ + { + "name": "attestationData1", + "type": "bytes", + "internalType": "bytes" + }, + { + "name": "attestationData2", + "type": "bytes", + "internalType": "bytes" + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "nonpayable" }, { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "OwnableUnauthorizedAccount", - "type": "error" + "type": "function", + "name": "drawDispute", + "inputs": [ + { + "name": "disputeId", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [], + "stateMutability": "nonpayable" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "a", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "b", - "type": "uint256" - } - ], - "name": "PPMMathInvalidMulPPM", - "type": "error" + "type": "function", + "name": "encodeReceipt", + "inputs": [ + { + "name": "receipt", + "type": "tuple", + "internalType": "struct IAttestation.Receipt", + "components": [ + { + "name": "requestCID", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "responseCID", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "subgraphDeploymentId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + } + ], + "outputs": [ + { + "name": "", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "stateMutability": "view" }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "arbitrator", - "type": "address" - } - ], - "name": "ArbitratorSet", - "type": "event" + "type": "function", + "name": "getAttestationIndexer", + "inputs": [ + { + "name": "attestation", + "type": "tuple", + "internalType": "struct IAttestation.State", + "components": [ + { + "name": "requestCID", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "responseCID", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "subgraphDeploymentId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "r", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "s", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "v", + "type": "uint8", + "internalType": "uint8" + } + ] + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "disputeId", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "indexer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "fisherman", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "tokens", - "type": "uint256" - } - ], - "name": "DisputeAccepted", - "type": "event" + "type": "function", + "name": "getDisputePeriod", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint64", + "internalType": "uint64" + } + ], + "stateMutability": "view" }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "disputeId", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "indexer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "fisherman", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "tokens", - "type": "uint256" - } - ], - "name": "DisputeCancelled", - "type": "event" + "type": "function", + "name": "getFishermanRewardCut", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "uint32", + "internalType": "uint32" + } + ], + "stateMutability": "view" }, { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint256", - "name": "disputeDeposit", - "type": "uint256" - } - ], - "name": "DisputeDepositSet", - "type": "event" + "type": "function", + "name": "getStakeSnapshot", + "inputs": [ + { + "name": "indexer", + "type": "address", + "internalType": "address" + } + ], + "outputs": [ + { + "name": "", + "type": "uint256", + "internalType": "uint256" + } + ], + "stateMutability": "view" }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "disputeId", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "indexer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "fisherman", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "tokens", - "type": "uint256" - } - ], - "name": "DisputeDrawn", - "type": "event" + "type": "function", + "name": "initialize", + "inputs": [ + { + "name": "owner", + "type": "address", + "internalType": "address" + }, + { + "name": "arbitrator", + "type": "address", + "internalType": "address" + }, + { + "name": "disputePeriod", + "type": "uint64", + "internalType": "uint64" + }, + { + "name": "disputeDeposit", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "fishermanRewardCut_", + "type": "uint32", + "internalType": "uint32" + }, + { + "name": "maxSlashingCut_", + "type": "uint32", + "internalType": "uint32" + } + ], + "outputs": [], + "stateMutability": "nonpayable" }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "disputeId1", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "disputeId2", - "type": "bytes32" - } - ], - "name": "DisputeLinked", - "type": "event" + "type": "function", + "name": "isDisputeCreated", + "inputs": [ + { + "name": "disputeId", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "", + "type": "bool", + "internalType": "bool" + } + ], + "stateMutability": "view" }, { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint64", - "name": "disputePeriod", - "type": "uint64" - } - ], - "name": "DisputePeriodSet", - "type": "event" + "type": "function", + "name": "rejectDispute", + "inputs": [ + { + "name": "disputeId", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [], + "stateMutability": "nonpayable" }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "disputeId", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "indexer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "fisherman", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "tokens", - "type": "uint256" - } - ], - "name": "DisputeRejected", - "type": "event" + "type": "function", + "name": "setArbitrator", + "inputs": [ + { + "name": "arbitrator", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" }, { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint32", - "name": "fishermanRewardCut", - "type": "uint32" - } - ], - "name": "FishermanRewardCutSet", - "type": "event" + "type": "function", + "name": "setDisputeDeposit", + "inputs": [ + { + "name": "disputeDeposit", + "type": "uint256", + "internalType": "uint256" + } + ], + "outputs": [], + "stateMutability": "nonpayable" }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "graphToken", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "graphStaking", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "graphPayments", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "graphEscrow", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "graphController", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "graphEpochManager", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "graphRewardsManager", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "graphTokenGateway", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "graphProxyAdmin", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "graphCuration", - "type": "address" - } - ], - "name": "GraphDirectoryInitialized", - "type": "event" + "type": "function", + "name": "setDisputePeriod", + "inputs": [ + { + "name": "disputePeriod", + "type": "uint64", + "internalType": "uint64" + } + ], + "outputs": [], + "stateMutability": "nonpayable" }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "disputeId", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "indexer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "fisherman", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "tokens", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "address", - "name": "allocationId", - "type": "address" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "poi", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "stakeSnapshot", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "cancellableAt", - "type": "uint256" - } - ], - "name": "IndexingDisputeCreated", - "type": "event" + "type": "function", + "name": "setFishermanRewardCut", + "inputs": [ + { + "name": "fishermanRewardCut_", + "type": "uint32", + "internalType": "uint32" + } + ], + "outputs": [], + "stateMutability": "nonpayable" }, { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint64", - "name": "version", - "type": "uint64" - } - ], - "name": "Initialized", - "type": "event" + "type": "function", + "name": "setMaxSlashingCut", + "inputs": [ + { + "name": "maxSlashingCut_", + "type": "uint32", + "internalType": "uint32" + } + ], + "outputs": [], + "stateMutability": "nonpayable" }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "disputeId", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "indexer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "fisherman", - "type": "address" - }, - { - "indexed": false, - "internalType": "address", - "name": "allocationId", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "tokensSlash", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "tokensRewards", - "type": "uint256" - } - ], - "name": "LegacyDisputeCreated", - "type": "event" + "type": "function", + "name": "setSubgraphService", + "inputs": [ + { + "name": "subgraphService", + "type": "address", + "internalType": "address" + } + ], + "outputs": [], + "stateMutability": "nonpayable" }, { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint32", - "name": "maxSlashingCut", - "type": "uint32" - } - ], - "name": "MaxSlashingCutSet", - "type": "event" + "type": "event", + "name": "ArbitratorSet", + "inputs": [ + { + "name": "arbitrator", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "previousOwner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "OwnershipTransferred", - "type": "event" + "type": "event", + "name": "DisputeAccepted", + "inputs": [ + { + "name": "disputeId", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "indexer", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "fisherman", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "tokens", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "bytes32", - "name": "disputeId", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "indexer", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "fisherman", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "tokens", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "subgraphDeploymentId", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "attestation", - "type": "bytes" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "stakeSnapshot", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "cancellableAt", - "type": "uint256" - } - ], - "name": "QueryDisputeCreated", - "type": "event" + "type": "event", + "name": "DisputeCancelled", + "inputs": [ + { + "name": "disputeId", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "indexer", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "fisherman", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "tokens", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false }, { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "subgraphService", - "type": "address" - } - ], - "name": "SubgraphServiceSet", - "type": "event" + "type": "event", + "name": "DisputeDepositSet", + "inputs": [ + { + "name": "disputeDeposit", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false }, { - "inputs": [], - "name": "MAX_FISHERMAN_REWARD_CUT", - "outputs": [ - { - "internalType": "uint32", - "name": "", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" + "type": "event", + "name": "DisputeDrawn", + "inputs": [ + { + "name": "disputeId", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "indexer", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "fisherman", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "tokens", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false }, { - "inputs": [], - "name": "MIN_DISPUTE_DEPOSIT", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" + "type": "event", + "name": "DisputeLinked", + "inputs": [ + { + "name": "disputeId1", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "disputeId2", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + } + ], + "anonymous": false }, { - "inputs": [ - { - "internalType": "bytes32", - "name": "disputeId", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "tokensSlash", - "type": "uint256" - } - ], - "name": "acceptDispute", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "type": "event", + "name": "DisputePeriodSet", + "inputs": [ + { + "name": "disputePeriod", + "type": "uint64", + "indexed": false, + "internalType": "uint64" + } + ], + "anonymous": false }, { - "inputs": [ - { - "internalType": "bytes32", - "name": "disputeId", - "type": "bytes32" - }, - { - "internalType": "uint256", - "name": "tokensSlash", - "type": "uint256" - }, - { - "internalType": "bool", - "name": "acceptDisputeInConflict", - "type": "bool" - }, - { - "internalType": "uint256", - "name": "tokensSlashRelated", - "type": "uint256" - } - ], - "name": "acceptDisputeConflict", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "type": "event", + "name": "DisputeRejected", + "inputs": [ + { + "name": "disputeId", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, + { + "name": "indexer", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "fisherman", + "type": "address", + "indexed": true, + "internalType": "address" + }, + { + "name": "tokens", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false }, { - "inputs": [], - "name": "arbitrator", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" + "type": "event", + "name": "FishermanRewardCutSet", + "inputs": [ + { + "name": "fishermanRewardCut", + "type": "uint32", + "indexed": false, + "internalType": "uint32" + } + ], + "anonymous": false }, { - "inputs": [ - { - "components": [ + "type": "event", + "name": "IndexingDisputeCreated", + "inputs": [ { - "internalType": "bytes32", - "name": "requestCID", - "type": "bytes32" + "name": "disputeId", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" }, { - "internalType": "bytes32", - "name": "responseCID", - "type": "bytes32" + "name": "indexer", + "type": "address", + "indexed": true, + "internalType": "address" }, { - "internalType": "bytes32", - "name": "subgraphDeploymentId", - "type": "bytes32" + "name": "fisherman", + "type": "address", + "indexed": true, + "internalType": "address" }, { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" + "name": "tokens", + "type": "uint256", + "indexed": false, + "internalType": "uint256" }, { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" + "name": "allocationId", + "type": "address", + "indexed": false, + "internalType": "address" }, { - "internalType": "uint8", - "name": "v", - "type": "uint8" - } - ], - "internalType": "struct Attestation.State", - "name": "attestation1", - "type": "tuple" - }, - { - "components": [ - { - "internalType": "bytes32", - "name": "requestCID", - "type": "bytes32" + "name": "poi", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" }, { - "internalType": "bytes32", - "name": "responseCID", - "type": "bytes32" + "name": "blockNumber", + "type": "uint256", + "indexed": false, + "internalType": "uint256" }, { - "internalType": "bytes32", - "name": "subgraphDeploymentId", - "type": "bytes32" + "name": "stakeSnapshot", + "type": "uint256", + "indexed": false, + "internalType": "uint256" }, { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" + "name": "cancellableAt", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + } + ], + "anonymous": false + }, + { + "type": "event", + "name": "LegacyDisputeCreated", + "inputs": [ + { + "name": "disputeId", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" }, { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" + "name": "indexer", + "type": "address", + "indexed": true, + "internalType": "address" }, { - "internalType": "uint8", - "name": "v", - "type": "uint8" - } - ], - "internalType": "struct Attestation.State", - "name": "attestation2", - "type": "tuple" - } - ], - "name": "areConflictingAttestations", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "pure", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "disputeId", - "type": "bytes32" - } - ], - "name": "cancelDispute", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "allocationId", - "type": "address" - }, - { - "internalType": "address", - "name": "fisherman", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokensSlash", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "tokensRewards", - "type": "uint256" - } - ], - "name": "createAndAcceptLegacyDispute", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "allocationId", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "poi", - "type": "bytes32" - } - ], - "name": "createIndexingDispute", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "attestationData", - "type": "bytes" - } - ], - "name": "createQueryDispute", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "attestationData1", - "type": "bytes" - }, - { - "internalType": "bytes", - "name": "attestationData2", - "type": "bytes" - } - ], - "name": "createQueryDisputeConflict", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - }, - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "disputeDeposit", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "disputePeriod", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "disputeId", - "type": "bytes32" - } - ], - "name": "disputes", - "outputs": [ - { - "internalType": "address", - "name": "indexer", - "type": "address" - }, - { - "internalType": "address", - "name": "fisherman", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deposit", - "type": "uint256" - }, - { - "internalType": "bytes32", - "name": "relatedDisputeId", - "type": "bytes32" - }, - { - "internalType": "enum IDisputeManager.DisputeType", - "name": "disputeType", - "type": "uint8" - }, - { - "internalType": "enum IDisputeManager.DisputeStatus", - "name": "status", - "type": "uint8" - }, - { - "internalType": "uint256", - "name": "createdAt", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "cancellableAt", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "stakeSnapshot", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "disputeId", - "type": "bytes32" - } - ], - "name": "drawDispute", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ + "name": "fisherman", + "type": "address", + "indexed": true, + "internalType": "address" + }, { - "internalType": "bytes32", - "name": "requestCID", - "type": "bytes32" + "name": "allocationId", + "type": "address", + "indexed": false, + "internalType": "address" }, { - "internalType": "bytes32", - "name": "responseCID", - "type": "bytes32" + "name": "tokensSlash", + "type": "uint256", + "indexed": false, + "internalType": "uint256" }, { - "internalType": "bytes32", - "name": "subgraphDeploymentId", - "type": "bytes32" + "name": "tokensRewards", + "type": "uint256", + "indexed": false, + "internalType": "uint256" } - ], - "internalType": "struct Attestation.Receipt", - "name": "receipt", - "type": "tuple" - } - ], - "name": "encodeReceipt", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" + ], + "anonymous": false }, { - "inputs": [], - "name": "fishermanRewardCut", - "outputs": [ - { - "internalType": "uint32", - "name": "", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" + "type": "event", + "name": "MaxSlashingCutSet", + "inputs": [ + { + "name": "maxSlashingCut", + "type": "uint32", + "indexed": false, + "internalType": "uint32" + } + ], + "anonymous": false }, { - "inputs": [ - { - "components": [ + "type": "event", + "name": "QueryDisputeCreated", + "inputs": [ + { + "name": "disputeId", + "type": "bytes32", + "indexed": true, + "internalType": "bytes32" + }, { - "internalType": "bytes32", - "name": "requestCID", - "type": "bytes32" + "name": "indexer", + "type": "address", + "indexed": true, + "internalType": "address" }, { - "internalType": "bytes32", - "name": "responseCID", - "type": "bytes32" + "name": "fisherman", + "type": "address", + "indexed": true, + "internalType": "address" }, { - "internalType": "bytes32", - "name": "subgraphDeploymentId", - "type": "bytes32" + "name": "tokens", + "type": "uint256", + "indexed": false, + "internalType": "uint256" }, { - "internalType": "bytes32", - "name": "r", - "type": "bytes32" + "name": "subgraphDeploymentId", + "type": "bytes32", + "indexed": false, + "internalType": "bytes32" }, { - "internalType": "bytes32", - "name": "s", - "type": "bytes32" + "name": "attestation", + "type": "bytes", + "indexed": false, + "internalType": "bytes" }, { - "internalType": "uint8", - "name": "v", - "type": "uint8" + "name": "stakeSnapshot", + "type": "uint256", + "indexed": false, + "internalType": "uint256" + }, + { + "name": "cancellableAt", + "type": "uint256", + "indexed": false, + "internalType": "uint256" } - ], - "internalType": "struct Attestation.State", - "name": "attestation", - "type": "tuple" - } - ], - "name": "getAttestationIndexer", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" + ], + "anonymous": false }, { - "inputs": [], - "name": "getDisputePeriod", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" + "type": "event", + "name": "SubgraphServiceSet", + "inputs": [ + { + "name": "subgraphService", + "type": "address", + "indexed": true, + "internalType": "address" + } + ], + "anonymous": false }, { - "inputs": [], - "name": "getFishermanRewardCut", - "outputs": [ - { - "internalType": "uint32", - "name": "", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" + "type": "error", + "name": "DisputeManagerDisputeAlreadyCreated", + "inputs": [ + { + "name": "disputeId", + "type": "bytes32", + "internalType": "bytes32" + } + ] }, { - "inputs": [ - { - "internalType": "address", - "name": "indexer", - "type": "address" - } - ], - "name": "getStakeSnapshot", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" + "type": "error", + "name": "DisputeManagerDisputeInConflict", + "inputs": [ + { + "name": "disputeId", + "type": "bytes32", + "internalType": "bytes32" + } + ] }, { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "arbitrator_", - "type": "address" - }, - { - "internalType": "uint64", - "name": "disputePeriod_", - "type": "uint64" - }, - { - "internalType": "uint256", - "name": "disputeDeposit_", - "type": "uint256" - }, - { - "internalType": "uint32", - "name": "fishermanRewardCut_", - "type": "uint32" - }, - { - "internalType": "uint32", - "name": "maxSlashingCut_", - "type": "uint32" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "type": "error", + "name": "DisputeManagerDisputeNotInConflict", + "inputs": [ + { + "name": "disputeId", + "type": "bytes32", + "internalType": "bytes32" + } + ] }, { - "inputs": [ - { - "internalType": "bytes32", - "name": "disputeId", - "type": "bytes32" - } - ], - "name": "isDisputeCreated", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" + "type": "error", + "name": "DisputeManagerDisputeNotPending", + "inputs": [ + { + "name": "status", + "type": "uint8", + "internalType": "enum IDisputeManager.DisputeStatus" + } + ] }, { - "inputs": [], - "name": "maxSlashingCut", - "outputs": [ - { - "internalType": "uint32", - "name": "", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" + "type": "error", + "name": "DisputeManagerDisputePeriodNotFinished", + "inputs": [] }, { - "inputs": [], - "name": "owner", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" + "type": "error", + "name": "DisputeManagerDisputePeriodZero", + "inputs": [] }, { - "inputs": [ - { - "internalType": "bytes32", - "name": "disputeId", - "type": "bytes32" - } - ], - "name": "rejectDispute", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "type": "error", + "name": "DisputeManagerIndexerNotFound", + "inputs": [ + { + "name": "allocationId", + "type": "address", + "internalType": "address" + } + ] }, { - "inputs": [], - "name": "renounceOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "type": "error", + "name": "DisputeManagerInvalidDispute", + "inputs": [ + { + "name": "disputeId", + "type": "bytes32", + "internalType": "bytes32" + } + ] }, { - "inputs": [ - { - "internalType": "address", - "name": "arbitrator", - "type": "address" - } - ], - "name": "setArbitrator", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "type": "error", + "name": "DisputeManagerInvalidDisputeDeposit", + "inputs": [ + { + "name": "disputeDeposit", + "type": "uint256", + "internalType": "uint256" + } + ] }, { - "inputs": [ - { - "internalType": "uint256", - "name": "disputeDeposit", - "type": "uint256" - } - ], - "name": "setDisputeDeposit", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "type": "error", + "name": "DisputeManagerInvalidFishermanReward", + "inputs": [ + { + "name": "cut", + "type": "uint32", + "internalType": "uint32" + } + ] }, { - "inputs": [ - { - "internalType": "uint64", - "name": "disputePeriod", - "type": "uint64" - } - ], - "name": "setDisputePeriod", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "type": "error", + "name": "DisputeManagerInvalidMaxSlashingCut", + "inputs": [ + { + "name": "maxSlashingCut", + "type": "uint32", + "internalType": "uint32" + } + ] + }, + { + "type": "error", + "name": "DisputeManagerInvalidTokensSlash", + "inputs": [ + { + "name": "tokensSlash", + "type": "uint256", + "internalType": "uint256" + }, + { + "name": "maxTokensSlash", + "type": "uint256", + "internalType": "uint256" + } + ] + }, + { + "type": "error", + "name": "DisputeManagerInvalidZeroAddress", + "inputs": [] }, { - "inputs": [ - { - "internalType": "uint32", - "name": "fishermanRewardCut_", - "type": "uint32" - } - ], - "name": "setFishermanRewardCut", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "type": "error", + "name": "DisputeManagerMustAcceptRelatedDispute", + "inputs": [ + { + "name": "disputeId", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "relatedDisputeId", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "DisputeManagerNonConflictingAttestations", + "inputs": [ + { + "name": "requestCID1", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "responseCID1", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "subgraphDeploymentId1", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "requestCID2", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "responseCID2", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "subgraphDeploymentId2", + "type": "bytes32", + "internalType": "bytes32" + } + ] + }, + { + "type": "error", + "name": "DisputeManagerNonMatchingSubgraphDeployment", + "inputs": [ + { + "name": "subgraphDeploymentId1", + "type": "bytes32", + "internalType": "bytes32" + }, + { + "name": "subgraphDeploymentId2", + "type": "bytes32", + "internalType": "bytes32" + } + ] }, { - "inputs": [ - { - "internalType": "uint32", - "name": "maxSlashingCut_", - "type": "uint32" - } - ], - "name": "setMaxSlashingCut", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "type": "error", + "name": "DisputeManagerNotArbitrator", + "inputs": [] }, { - "inputs": [ - { - "internalType": "address", - "name": "subgraphService_", - "type": "address" - } - ], - "name": "setSubgraphService", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "type": "error", + "name": "DisputeManagerNotFisherman", + "inputs": [] }, { - "inputs": [], - "name": "subgraphService", - "outputs": [ - { - "internalType": "contract ISubgraphService", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" + "type": "error", + "name": "DisputeManagerSubgraphServiceNotSet", + "inputs": [] }, { - "inputs": [ - { - "internalType": "address", - "name": "newOwner", - "type": "address" - } - ], - "name": "transferOwnership", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" + "type": "error", + "name": "DisputeManagerZeroTokens", + "inputs": [] } ] \ No newline at end of file diff --git a/subgraph.template.yaml b/subgraph.template.yaml index c3fbb158..2913aca2 100644 --- a/subgraph.template.yaml +++ b/subgraph.template.yaml @@ -604,7 +604,7 @@ dataSources: eventHandlers: - event: QueryDisputeCreated(indexed bytes32,indexed address,indexed address,uint256,bytes32,bytes,uint256,uint256) handler: handleQueryDisputeCreated - - event: IndexingDisputeCreated(indexed bytes32,indexed address,indexed address,uint256,address,bytes32,uint256,uint256) + - event: IndexingDisputeCreated(indexed bytes32,indexed address,indexed address,uint256,address,bytes32,uint256,uint256,uint256) handler: handleIndexingDisputeCreated - event: LegacyDisputeCreated(indexed bytes32,indexed address,indexed address,address,uint256,uint256) handler: handleLegacyDisputeCreated From cbd06f97f73c33497ca8f4205ba4b5b3db6c23e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 6 Nov 2025 13:06:24 -0300 Subject: [PATCH 6/9] fix: capacity fix for horizon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- src/mappings/helpers/helpers.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mappings/helpers/helpers.ts b/src/mappings/helpers/helpers.ts index 95118422..09bf6aa1 100644 --- a/src/mappings/helpers/helpers.ts +++ b/src/mappings/helpers/helpers.ts @@ -1175,7 +1175,8 @@ export function calculateCapacitiesHorizon(indexer: Indexer): Indexer { .minus(indexer.thawingTokens) .plus(indexer.delegatedCapacity) indexer.availableStake = indexer.tokenCapacity - .minus(indexer.allocatedTokens) + .minus(indexer.allocatedTokens) // this includes both legacy and horizon allos + .plus(indexer.legacyAllocatedTokens) // so we add the legacy tokens back return indexer } From 824def7ba32e8dbb9d100c45b26f5ea656e906f7 Mon Sep 17 00:00:00 2001 From: Juan Manuel Rodriguez Defago Date: Thu, 6 Nov 2025 23:22:26 -0300 Subject: [PATCH 7/9] fix: missing Cancelled status for Disputes --- schema.graphql | 1 + 1 file changed, 1 insertion(+) diff --git a/schema.graphql b/schema.graphql index 2405d382..0b077c61 100644 --- a/schema.graphql +++ b/schema.graphql @@ -1523,6 +1523,7 @@ enum DisputeStatus { Accepted Rejected Draw + Cancelled } """ From 3214ac6a71156bf4715c5522f6389444b96a185a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Mon, 10 Nov 2025 14:23:22 -0300 Subject: [PATCH 8/9] fix: track delegation thawing tokens MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- src/mappings/horizonStaking.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mappings/horizonStaking.ts b/src/mappings/horizonStaking.ts index e1b8be85..c6a202ac 100644 --- a/src/mappings/horizonStaking.ts +++ b/src/mappings/horizonStaking.ts @@ -479,6 +479,7 @@ export function handleTokensUndelegated(event: TokensUndelegated): void { if (provision.delegatorShares != BigInt.fromI32(0)) { provision = updateDelegationExchangeRateForProvision(provision as Provision) } + provision.delegatedThawingTokens = provision.delegatedThawingTokens.plus(event.params.tokens) provision = updateAdvancedProvisionMetrics(provision as Provision) provision.save() @@ -486,6 +487,7 @@ export function handleTokensUndelegated(event: TokensUndelegated): void { let indexerID = event.params.serviceProvider.toHexString() let indexer = Indexer.load(indexerID)! indexer.delegatorShares = indexer.delegatorShares.minus(event.params.shares) + indexer.delegatedThawingTokens = indexer.delegatedThawingTokens.plus(event.params.tokens) if (indexer.delegatorShares != BigInt.fromI32(0)) { indexer = updateDelegationExchangeRate(indexer as Indexer) } @@ -543,12 +545,14 @@ export function handleDelegatedTokensWithdrawn(event: DelegatedTokensWithdrawn): let provision = createOrLoadProvision(event.params.serviceProvider, event.params.verifier, event.block.timestamp) // might want to track locked/thawing tokens in provision too provision.delegatedTokens = provision.delegatedTokens.minus(event.params.tokens) + provision.delegatedThawingTokens = provision.delegatedThawingTokens.minus(event.params.tokens) provision.save() let indexerID = event.params.serviceProvider.toHexString() let indexer = Indexer.load(indexerID)! indexer.delegatedTokens = indexer.delegatedTokens.minus(event.params.tokens) + indexer.delegatedThawingTokens = indexer.delegatedThawingTokens.minus(event.params.tokens) indexer = calculateCapacities(indexer as Indexer) indexer.save() From c71247d0a1bea912e9f15bdadbe55b2b4e996a16 Mon Sep 17 00:00:00 2001 From: Juan Manuel Rodriguez Defago Date: Wed, 12 Nov 2025 01:29:17 -0300 Subject: [PATCH 9/9] fix: entity overwrite cases --- src/mappings/curation.ts | 13 ++++----- src/mappings/gns.ts | 40 ++++++++++++++++++---------- src/mappings/helpers/helpers.ts | 47 ++++++++++++++++++--------------- src/mappings/horizonStaking.ts | 13 +++++---- src/mappings/l1staking.ts | 4 +-- src/mappings/l2gns.ts | 6 +++++ src/mappings/rewardsManager.ts | 1 + src/mappings/serviceRegistry.ts | 5 ++-- src/mappings/staking.ts | 18 +++++++------ src/mappings/subgraphService.ts | 17 +++++++----- tests/staking.test.ts | 6 ++--- 11 files changed, 101 insertions(+), 69 deletions(-) diff --git a/src/mappings/curation.ts b/src/mappings/curation.ts index cb4a6c6c..71cf7abf 100644 --- a/src/mappings/curation.ts +++ b/src/mappings/curation.ts @@ -16,6 +16,7 @@ import { joinID, calculatePricePerShare, batchUpdateSubgraphSignalledTokens, + loadGraphNetwork, } from './helpers/helpers' import { zeroBD } from './utils' import { addresses } from '../../config/addresses' @@ -27,11 +28,11 @@ import { addresses } from '../../config/addresses' * - updates subgraph deployment, creates if needed */ export function handleSignalled(event: Signalled): void { - let graphNetwork = GraphNetwork.load('1')! + let graphNetwork = loadGraphNetwork() // Create curator and update most of the parameters let id = event.params.curator.toHexString() let gnsID = graphNetwork.gns.toHexString() - let curator = createOrLoadCurator(event.params.curator, event.block.timestamp) + let curator = createOrLoadCurator(event.params.curator, event.block.timestamp, graphNetwork) curator.totalSignalledTokens = curator.totalSignalledTokens.plus( event.params.tokens.minus(event.params.curationTax), ) @@ -98,7 +99,7 @@ export function handleSignalled(event: Signalled): void { curator.save() // Update subgraph deployment - let deployment = createOrLoadSubgraphDeployment(subgraphDeploymentID, event.block.timestamp) + let deployment = createOrLoadSubgraphDeployment(subgraphDeploymentID, event.block.timestamp, graphNetwork) let oldSignalAmount = deployment.signalAmount let oldSignalledTokens = deployment.signalledTokens deployment.signalledTokens = deployment.signalledTokens.plus( @@ -165,7 +166,7 @@ export function handleSignalled(event: Signalled): void { * - updates subgraph */ export function handleBurned(event: Burned): void { - let graphNetwork = GraphNetwork.load('1')! + let graphNetwork = loadGraphNetwork() let id = event.params.curator.toHexString() let gnsID = graphNetwork.gns.toHexString() // Update signal @@ -215,7 +216,7 @@ export function handleBurned(event: Burned): void { // Assuming curator is created since it's a burn can't be done, as signals can be transferred and // we currently can't track transfers, thus this might be the first curation interaction of this // account - let curator = createOrLoadCurator(event.params.curator, event.block.timestamp) + let curator = createOrLoadCurator(event.params.curator, event.block.timestamp, graphNetwork) curator.totalUnsignalledTokens = curator.totalUnsignalledTokens.plus(event.params.tokens) curator.totalSignal = curator.totalSignal.minus(event.params.signal.toBigDecimal()) curator.totalSignalAverageCostBasis = curator.totalSignalAverageCostBasis.minus(diffACB) @@ -298,7 +299,7 @@ export function handleBurned(event: Burned): void { */ export function handleParameterUpdated(event: ParameterUpdated): void { let parameter = event.params.param - let graphNetwork = GraphNetwork.load('1')! + let graphNetwork = loadGraphNetwork() let curation = Curation.bind(event.address) if (parameter == 'defaultReserveRatio') { diff --git a/src/mappings/gns.ts b/src/mappings/gns.ts index 21c5c757..e60829a4 100644 --- a/src/mappings/gns.ts +++ b/src/mappings/gns.ts @@ -56,7 +56,8 @@ import { updateCurrentDeploymentLinks, getSubgraphID, convertBigIntSubgraphIDToBase58, - createOrLoadGraphNetwork + createOrLoadGraphNetwork, + loadGraphNetwork, } from './helpers/helpers' import { addresses } from '../../config/addresses' @@ -172,10 +173,11 @@ function addDefaultNameTokenLockWallets(graphAccount: GraphAccount): void { } export function handleSubgraphMetadataUpdated(event: SubgraphMetadataUpdated): void { + let graphNetwork = loadGraphNetwork() let subgraphID = getSubgraphID(event.params.graphAccount, event.params.subgraphNumber) // Create subgraph - let subgraph = createOrLoadSubgraph(subgraphID, event.params.graphAccount, event.block.timestamp) + let subgraph = createOrLoadSubgraph(subgraphID, event.params.graphAccount, event.block.timestamp, graphNetwork) let hexHash = changetype(addQm(event.params.subgraphMetadata)) let base58Hash = hexHash.toBase58() @@ -200,12 +202,13 @@ export function handleSubgraphMetadataUpdated(event: SubgraphMetadataUpdated): v * - creates graph account, if needed */ export function handleSubgraphPublished(event: SubgraphPublished): void { + let graphNetwork = GraphNetwork.load('1')! let subgraphID = getSubgraphID(event.params.graphAccount, event.params.subgraphNumber) let versionNumber: BigInt // Update subgraph // Create subgraph - let subgraph = createOrLoadSubgraph(subgraphID, event.params.graphAccount, event.block.timestamp) + let subgraph = createOrLoadSubgraph(subgraphID, event.params.graphAccount, event.block.timestamp, graphNetwork) let oldVersionID = subgraph.currentVersion versionNumber = subgraph.versionCount @@ -227,7 +230,7 @@ export function handleSubgraphPublished(event: SubgraphPublished): void { // Create subgraph deployment, if needed. Can happen if the deployment has never been staked on let subgraphDeploymentID = event.params.subgraphDeploymentID.toHexString() - let deployment = createOrLoadSubgraphDeployment(subgraphDeploymentID, event.block.timestamp) + let deployment = createOrLoadSubgraphDeployment(subgraphDeploymentID, event.block.timestamp, graphNetwork) // Create subgraph version let subgraphVersion = new SubgraphVersion(versionID) @@ -306,7 +309,7 @@ export function handleNSignalMinted(event: NSignalMinted): void { subgraph.save() // Update the curator - let curator = createOrLoadCurator(event.params.nameCurator, event.block.timestamp) + let curator = createOrLoadCurator(event.params.nameCurator, event.block.timestamp, graphNetwork) // nSignal curator.totalNameSignalledTokens = curator.totalNameSignalledTokens.plus( event.params.tokensDeposited, @@ -339,7 +342,7 @@ export function handleNSignalMinted(event: NSignalMinted): void { } curator.save() - let nameSignal = createOrLoadNameSignal(event.params.nameCurator, subgraphID, event.block.timestamp) + let nameSignal = createOrLoadNameSignal(event.params.nameCurator, subgraphID, event.block.timestamp, graphNetwork) let isNameSignalBecomingActive = nameSignal.nameSignal.isZero() && !event.params.nSignalCreated.isZero() @@ -421,6 +424,7 @@ export function handleNSignalBurned(event: NSignalBurned): void { event.params.nameCurator, subgraphID, event.block.timestamp, + graphNetwork, ) let isNameSignalBecomingInactive = @@ -446,7 +450,7 @@ export function handleNSignalBurned(event: NSignalBurned): void { } // update curator - let curator = createOrLoadCurator(event.params.nameCurator, event.block.timestamp) + let curator = createOrLoadCurator(event.params.nameCurator, event.block.timestamp, graphNetwork) curator.totalNameUnsignalledTokens = curator.totalNameUnsignalledTokens.plus( event.params.tokensReceived, ) @@ -586,6 +590,7 @@ export function handleNameSignalDisabled(event: NameSignalDisabled): void { } export function handleGRTWithdrawn(event: GRTWithdrawn): void { + let graphNetwork = loadGraphNetwork() let bigIntID = getSubgraphID(event.params.graphAccount, event.params.subgraphNumber) let subgraphID = convertBigIntSubgraphIDToBase58(bigIntID) let subgraph = Subgraph.load(subgraphID)! @@ -598,6 +603,7 @@ export function handleGRTWithdrawn(event: GRTWithdrawn): void { event.params.nameCurator, subgraphID, event.block.timestamp, + graphNetwork, ) nameSignal.withdrawnTokens = event.params.withdrawnGRT nameSignal.nameSignal = nameSignal.nameSignal.minus(event.params.nSignalBurnt) @@ -614,7 +620,7 @@ export function handleGRTWithdrawn(event: GRTWithdrawn): void { nameSignal.signalAverageCostBasisPerSignal = BigDecimal.fromString('0') nameSignal.save() - let curator = createOrLoadCurator(event.params.nameCurator, event.block.timestamp) + let curator = createOrLoadCurator(event.params.nameCurator, event.block.timestamp, graphNetwork) curator.totalWithdrawnTokens = curator.totalWithdrawnTokens.plus(event.params.withdrawnGRT) curator.save() } @@ -639,6 +645,7 @@ export function handleParameterUpdated(event: ParameterUpdated): void { // handler: handleSubgraphPublishedV2 export function handleSubgraphPublishedV2(event: SubgraphPublished1): void { + let graphNetwork = loadGraphNetwork() let bigIntID = event.params.subgraphID let subgraphID = convertBigIntSubgraphIDToBase58(bigIntID) let versionID: string @@ -649,6 +656,7 @@ export function handleSubgraphPublishedV2(event: SubgraphPublished1): void { event.params.subgraphID, event.transaction.from, event.block.timestamp, + graphNetwork, ) let oldVersionID = subgraph.currentVersion @@ -665,7 +673,7 @@ export function handleSubgraphPublishedV2(event: SubgraphPublished1): void { // Create subgraph deployment, if needed. Can happen if the deployment has never been staked on let subgraphDeploymentID = event.params.subgraphDeploymentID.toHexString() - let deployment = createOrLoadSubgraphDeployment(subgraphDeploymentID, event.block.timestamp) + let deployment = createOrLoadSubgraphDeployment(subgraphDeploymentID, event.block.timestamp, graphNetwork) // Create subgraph version let subgraphVersion = new SubgraphVersion(versionID) @@ -751,7 +759,7 @@ export function handleNSignalMintedV2(event: SignalMinted): void { subgraph.save() // Update the curator - let curator = createOrLoadCurator(event.params.curator, event.block.timestamp) + let curator = createOrLoadCurator(event.params.curator, event.block.timestamp, graphNetwork) // nSignal curator.totalNameSignalledTokens = curator.totalNameSignalledTokens.plus( event.params.tokensDeposited, @@ -784,7 +792,7 @@ export function handleNSignalMintedV2(event: SignalMinted): void { } curator.save() - let nameSignal = createOrLoadNameSignal(event.params.curator, subgraphID, event.block.timestamp) + let nameSignal = createOrLoadNameSignal(event.params.curator, subgraphID, event.block.timestamp, graphNetwork) let isNameSignalBecomingActive = nameSignal.nameSignal.isZero() && !event.params.nSignalCreated.isZero() @@ -868,6 +876,7 @@ export function handleNSignalBurnedV2(event: SignalBurned): void { event.params.curator, subgraphID, event.block.timestamp, + graphNetwork, ) let isNameSignalBecomingInactive = @@ -893,7 +902,7 @@ export function handleNSignalBurnedV2(event: SignalBurned): void { } // update curator - let curator = createOrLoadCurator(event.params.curator, event.block.timestamp) + let curator = createOrLoadCurator(event.params.curator, event.block.timestamp, graphNetwork) curator.totalNameUnsignalledTokens = curator.totalNameUnsignalledTokens.plus( event.params.tokensReceived, ) @@ -1111,7 +1120,7 @@ export function handleSubgraphVersionUpdated(event: SubgraphVersionUpdated): voi // Create subgraph deployment, if needed. Can happen if the deployment has never been staked on let subgraphDeploymentID = event.params.subgraphDeploymentID.toHexString() - let deployment = createOrLoadSubgraphDeployment(subgraphDeploymentID, event.block.timestamp) + let deployment = createOrLoadSubgraphDeployment(subgraphDeploymentID, event.block.timestamp, graphNetwork) // Create subgraph version let subgraphVersion = new SubgraphVersion(versionID) @@ -1146,10 +1155,11 @@ export function handleSubgraphVersionUpdated(event: SubgraphVersionUpdated): voi // handler: handleLegacySubgraphClaimed export function handleLegacySubgraphClaimed(event: LegacySubgraphClaimed): void { + let graphNetwork = loadGraphNetwork() let subgraphID = getSubgraphID(event.params.graphAccount, event.params.subgraphNumber) // Update subgraph v2 - let subgraph = createOrLoadSubgraph(subgraphID, event.params.graphAccount, event.block.timestamp) + let subgraph = createOrLoadSubgraph(subgraphID, event.params.graphAccount, event.block.timestamp, graphNetwork) subgraph.migrated = true subgraph.save() } @@ -1160,11 +1170,13 @@ export function handleLegacySubgraphClaimed(event: LegacySubgraphClaimed): void export function handleTransfer(event: Transfer): void { let newOwner = createOrLoadGraphAccount(event.params.to, event.block.timestamp) + let graphNetwork = loadGraphNetwork() // Update subgraph v2 let subgraph = createOrLoadSubgraph( event.params.tokenId, event.transaction.from, event.block.timestamp, + graphNetwork, ) subgraph.updatedAt = event.block.timestamp.toI32() subgraph.owner = newOwner.id diff --git a/src/mappings/helpers/helpers.ts b/src/mappings/helpers/helpers.ts index 09bf6aa1..1f8a8819 100644 --- a/src/mappings/helpers/helpers.ts +++ b/src/mappings/helpers/helpers.ts @@ -43,6 +43,7 @@ export function createOrLoadSubgraph( bigIntID: BigInt, owner: Address, timestamp: BigInt, + graphNetwork: GraphNetwork, ): Subgraph { let subgraphID = convertBigIntSubgraphIDToBase58(bigIntID) let subgraph = Subgraph.load(subgraphID) @@ -76,7 +77,6 @@ export function createOrLoadSubgraph( subgraph.save() - let graphNetwork = GraphNetwork.load('1')! graphNetwork.subgraphCount = graphNetwork.subgraphCount + 1 graphNetwork.activeSubgraphCount = graphNetwork.activeSubgraphCount + 1 graphNetwork.save() @@ -87,10 +87,10 @@ export function createOrLoadSubgraph( export function createOrLoadSubgraphDeployment( subgraphID: string, timestamp: BigInt, + graphNetwork: GraphNetwork, ): SubgraphDeployment { let deployment = SubgraphDeployment.load(subgraphID) if (deployment == null) { - let graphNetwork = GraphNetwork.load('1')! let prefix = '1220' deployment = new SubgraphDeployment(subgraphID) deployment.ipfsHash = Bytes.fromHexString(prefix.concat(subgraphID.slice(2))).toBase58() @@ -129,7 +129,7 @@ export function createOrLoadSubgraphDeployment( return deployment as SubgraphDeployment } -export function createOrLoadIndexer(indexerAddress: Bytes, timestamp: BigInt ): Indexer { +export function createOrLoadIndexer(indexerAddress: Bytes, timestamp: BigInt, graphNetwork: GraphNetwork): Indexer { let id = indexerAddress.toHexString() let indexer = Indexer.load(id) if (indexer == null) { @@ -197,7 +197,6 @@ export function createOrLoadIndexer(indexerAddress: Bytes, timestamp: BigInt ): indexer.defaultDisplayName = graphAccount.defaultDisplayName - let graphNetwork = GraphNetwork.load('1')! graphNetwork.indexerCount = graphNetwork.indexerCount + 1 graphNetwork.save() @@ -206,8 +205,8 @@ export function createOrLoadIndexer(indexerAddress: Bytes, timestamp: BigInt ): return indexer as Indexer } -export function createOrLoadLegacyIndexer(indexerAddress: Bytes, timestamp: BigInt): Indexer { - let indexer = createOrLoadIndexer(indexerAddress, timestamp) +export function createOrLoadLegacyIndexer(indexerAddress: Bytes, timestamp: BigInt, graphNetwork: GraphNetwork): Indexer { + let indexer = createOrLoadIndexer(indexerAddress, timestamp, graphNetwork) indexer.isLegacy = true indexer.save() return indexer @@ -339,7 +338,7 @@ export function createOrLoadIndexerQueryFeePaymentAggregation(paymentAddress: By } -export function createOrLoadDelegator(delegatorAddress: Bytes, timestamp: BigInt): Delegator { +export function createOrLoadDelegator(delegatorAddress: Bytes, timestamp: BigInt, graphNetwork: GraphNetwork): Delegator { let id = delegatorAddress.toHexString() let delegator = Delegator.load(id) if (delegator == null) { @@ -357,7 +356,6 @@ export function createOrLoadDelegator(delegatorAddress: Bytes, timestamp: BigInt graphAccount.delegator = id graphAccount.save() - let graphNetwork = GraphNetwork.load('1')! graphNetwork.delegatorCount = graphNetwork.delegatorCount + 1 graphNetwork.save() } @@ -368,6 +366,7 @@ export function createOrLoadDelegatedStake( delegator: string, indexer: string, timestamp: i32, + graphNetwork: GraphNetwork, ): DelegatedStake { let id = joinID([delegator, indexer]) let delegatedStake = DelegatedStake.load(id) @@ -394,7 +393,6 @@ export function createOrLoadDelegatedStake( delegatorEntity.stakesCount = delegatorEntity.stakesCount + 1 delegatorEntity.save() - let graphNetwork = GraphNetwork.load('1')! graphNetwork.delegationCount = graphNetwork.delegationCount + 1 graphNetwork.save() } @@ -406,6 +404,7 @@ export function createOrLoadDelegatedStakeForProvision( indexer: string, dataService: string, timestamp: i32, + graphNetwork: GraphNetwork, ): DelegatedStake { let provisionId = joinID([indexer, dataService]) let id = joinID([delegator, provisionId]) @@ -435,14 +434,13 @@ export function createOrLoadDelegatedStakeForProvision( 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 { +export function createOrLoadCurator(curatorAddress: Bytes, timestamp: BigInt, graphNetwork: GraphNetwork): Curator { let id = curatorAddress.toHexString() let curator = Curator.load(id) if (curator == null) { @@ -479,7 +477,6 @@ export function createOrLoadCurator(curatorAddress: Bytes, timestamp: BigInt): C graphAccount.curator = id graphAccount.save() - let graphNetwork = GraphNetwork.load('1')! graphNetwork.curatorCount = graphNetwork.curatorCount + 1 graphNetwork.save() } @@ -523,12 +520,13 @@ export function createOrLoadNameSignal( curatorAddress: Bytes, subgraphID: string, timestamp: BigInt, + graphNetwork: GraphNetwork, ): NameSignal { let nameSignalID = joinID([curatorAddress.toHexString(), subgraphID]) let nameSignal = NameSignal.load(nameSignalID) if (nameSignal == null) { nameSignal = new NameSignal(nameSignalID) - let underlyingCurator = createOrLoadCurator(curatorAddress, timestamp) + let underlyingCurator = createOrLoadCurator(curatorAddress, timestamp, graphNetwork) nameSignal.entityVersion = 2 nameSignal.curator = underlyingCurator.id nameSignal.subgraph = subgraphID @@ -550,10 +548,9 @@ export function createOrLoadNameSignal( nameSignal.signalAverageCostBasisPerSignal = BigDecimal.fromString('0') nameSignal.save() - let curatorEntity = Curator.load(curatorAddress.toHexString())! - curatorEntity.nameSignalCount = curatorEntity.nameSignalCount + 1 - curatorEntity.combinedSignalCount = curatorEntity.combinedSignalCount + 1 - curatorEntity.save() + underlyingCurator.nameSignalCount = underlyingCurator.nameSignalCount + 1 + underlyingCurator.combinedSignalCount = underlyingCurator.combinedSignalCount + 1 + underlyingCurator.save() let subgraphEntity = Subgraph.load(subgraphID)! let relation = new NameSignalSubgraphRelation( @@ -649,6 +646,12 @@ export function createEpoch(startBlock: i32, epochLength: i32, epochNumber: i32) return epoch } +export function loadGraphNetwork(): GraphNetwork { + // Should only be called whenever we are sure a GraphNetwork entity exists. + // This is only made to centralize the load statements that are everywhere + return GraphNetwork.load('1')! +} + export function createOrLoadGraphNetwork( blockNumber: BigInt, controllerAddress: Bytes, @@ -969,7 +972,7 @@ function max(a: BigDecimal, b: BigDecimal): BigDecimal { export function calculateOwnStakeRatio(indexer: Indexer): BigDecimal { let stakedTokensBD = indexer.stakedTokens.minus(indexer.lockedTokens).toBigDecimal() let delegatedTokensBD = indexer.delegatedTokens.toBigDecimal() - let graphNetwork = GraphNetwork.load('1')! + let graphNetwork = loadGraphNetwork() let delegationRatioBD = BigInt.fromI32(graphNetwork.delegationRatio).toBigDecimal() let maxPossibleTotalUsable = stakedTokensBD + stakedTokensBD * delegationRatioBD let currentTotalStake = stakedTokensBD + delegatedTokensBD @@ -1035,7 +1038,7 @@ export function calculateLegacyIndexerRewardOwnGenerationRatio(indexer: Indexer) export function calculateOverdelegationDilution(indexer: Indexer): BigDecimal { let stakedTokensBD = indexer.stakedTokens.toBigDecimal() let delegatedTokensBD = indexer.delegatedTokens.toBigDecimal() - let graphNetwork = GraphNetwork.load('1')! + let graphNetwork = loadGraphNetwork() let delegationRatioBD = BigInt.fromI32(graphNetwork.delegationRatio).toBigDecimal() let maxDelegatedStake = stakedTokensBD * delegationRatioBD let maxDelegatedStakeBD = max(maxDelegatedStake, delegatedTokensBD) @@ -1154,7 +1157,7 @@ export function updateDelegationExchangeRateForProvision(provision: Provision): // TODO - this is broken if we change the delegatio ratio // Need to remove, or find a fix export function calculateCapacities(indexer: Indexer): Indexer { - let graphNetwork = GraphNetwork.load('1')! + let graphNetwork = loadGraphNetwork() if (graphNetwork.maxThawingPeriod.gt(BigInt.fromI32(0))) { return calculateCapacitiesHorizon(indexer) } else { @@ -1163,7 +1166,7 @@ export function calculateCapacities(indexer: Indexer): Indexer { } export function calculateCapacitiesHorizon(indexer: Indexer): Indexer { - let graphNetwork = GraphNetwork.load('1')! + let graphNetwork = loadGraphNetwork() let tokensDelegatedMax = indexer.provisionedTokens.times(BigInt.fromI32(graphNetwork.delegationRatio)) // Eligible to add to the capacity @@ -1181,7 +1184,7 @@ export function calculateCapacitiesHorizon(indexer: Indexer): Indexer { } export function calculateCapacitiesLegacy(indexer: Indexer): Indexer { - let graphNetwork = GraphNetwork.load('1')! + let graphNetwork = loadGraphNetwork() let tokensDelegatedMax = indexer.stakedTokens.times(BigInt.fromI32(graphNetwork.delegationRatio)) // Eligible to add to the capacity diff --git a/src/mappings/horizonStaking.ts b/src/mappings/horizonStaking.ts index c6a202ac..9a898cf5 100644 --- a/src/mappings/horizonStaking.ts +++ b/src/mappings/horizonStaking.ts @@ -2,7 +2,7 @@ import { BigInt } from '@graphprotocol/graph-ts' import { addresses } from '../../config/addresses' import { AllowedLockedVerifierSet, DelegatedTokensWithdrawn, DelegationFeeCutSet, DelegationSlashed, DelegationSlashingEnabled, HorizonStakeDeposited, HorizonStakeLocked, HorizonStakeWithdrawn, MaxThawingPeriodSet, OperatorSet, StakeDelegatedWithdrawn, ThawingPeriodCleared, TokensDelegated, TokensDeprovisioned, TokensToDelegationPoolAdded, TokensUndelegated } from '../types/HorizonStaking/HorizonStaking' import { DelegatedStake, Delegator, Indexer, Provision, ThawRequest } from '../types/schema' -import { calculateCapacities, createOrLoadDataService, createOrLoadDelegatedStakeForProvision, createOrLoadDelegator, createOrLoadEpoch, createOrLoadGraphAccount, createOrLoadGraphNetwork, createOrLoadHorizonOperator, createOrLoadIndexer, createOrLoadProvision, joinID, updateAdvancedIndexerMetrics, updateAdvancedProvisionMetrics, updateDelegationExchangeRate, updateDelegationExchangeRateForProvision } from './helpers/helpers' +import { calculateCapacities, createOrLoadDataService, createOrLoadDelegatedStakeForProvision, createOrLoadDelegator, createOrLoadEpoch, createOrLoadGraphAccount, createOrLoadGraphNetwork, createOrLoadHorizonOperator, createOrLoadIndexer, createOrLoadProvision, joinID, loadGraphNetwork, updateAdvancedIndexerMetrics, updateAdvancedProvisionMetrics, updateDelegationExchangeRate, updateDelegationExchangeRateForProvision } from './helpers/helpers' import { ProvisionCreated, ProvisionIncreased, @@ -17,7 +17,7 @@ import { export function handleHorizonStakeDeposited(event: HorizonStakeDeposited): void { let graphNetwork = createOrLoadGraphNetwork(event.block.number, event.address) // update indexer - let indexer = createOrLoadIndexer(event.params.serviceProvider, event.block.timestamp) + let indexer = createOrLoadIndexer(event.params.serviceProvider, event.block.timestamp, graphNetwork) let previousStake = indexer.stakedTokens indexer.stakedTokens = indexer.stakedTokens.plus(event.params.tokens) indexer.save() @@ -266,6 +266,7 @@ export function handleProvisionSlashed(event: ProvisionSlashed): void { } export function handleThawRequestCreated(event: ThawRequestCreated): void { + let graphNetwork = loadGraphNetwork() let dataService = createOrLoadDataService(event.params.verifier) let indexer = Indexer.load(event.params.serviceProvider.toHexString())! let owner = createOrLoadGraphAccount(event.params.owner, event.block.timestamp) @@ -314,6 +315,7 @@ export function handleThawRequestCreated(event: ThawRequestCreated): void { indexer.id, dataService.id, event.block.timestamp.toI32(), + graphNetwork, ) delegatedStake.lockedUntil = @@ -362,6 +364,7 @@ export function handleTokensToDelegationPoolAdded(event: TokensToDelegationPoolA // Delegation export function handleTokensDelegated(event: TokensDelegated): void { + let graphNetwork = loadGraphNetwork() let zeroShares = event.params.shares.equals(BigInt.fromI32(0)) let dataService = createOrLoadDataService(event.params.verifier) @@ -378,7 +381,7 @@ export function handleTokensDelegated(event: TokensDelegated): void { provision.save() // update indexer - let indexer = createOrLoadIndexer(event.params.serviceProvider, event.block.timestamp) + let indexer = createOrLoadIndexer(event.params.serviceProvider, event.block.timestamp, graphNetwork) indexer.delegatedTokens = indexer.delegatedTokens.plus(event.params.tokens) indexer.delegatorShares = indexer.delegatorShares.plus(event.params.shares) if (indexer.delegatorShares != BigInt.fromI32(0)) { @@ -390,7 +393,7 @@ export function handleTokensDelegated(event: TokensDelegated): void { // update delegator let delegatorID = event.params.delegator.toHexString() - let delegator = createOrLoadDelegator(event.params.delegator, event.block.timestamp) + let delegator = createOrLoadDelegator(event.params.delegator, event.block.timestamp, graphNetwork) delegator.totalStakedTokens = delegator.totalStakedTokens.plus(event.params.tokens) delegator.save() @@ -400,6 +403,7 @@ export function handleTokensDelegated(event: TokensDelegated): void { indexer.id, dataService.id, event.block.timestamp.toI32(), + graphNetwork, ) if (!zeroShares) { @@ -427,7 +431,6 @@ export function handleTokensDelegated(event: TokensDelegated): void { 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) { diff --git a/src/mappings/l1staking.ts b/src/mappings/l1staking.ts index 5ff7716a..3fab7c28 100644 --- a/src/mappings/l1staking.ts +++ b/src/mappings/l1staking.ts @@ -6,7 +6,7 @@ import { } from '../types/L1Staking/L1Staking' import { Indexer, DelegatedStake, GraphNetwork } from '../types/schema' -import { calculateCapacities, createOrLoadGraphNetwork, joinID, updateLegacyAdvancedIndexerMetrics, updateDelegationExchangeRate } from './helpers/helpers' +import { calculateCapacities, createOrLoadGraphNetwork, joinID, updateLegacyAdvancedIndexerMetrics, updateDelegationExchangeRate, loadGraphNetwork } from './helpers/helpers' /* /// @dev Emitted when an indexer transfers their stake to L2. @@ -103,7 +103,7 @@ export function handleDelegationTransferredToL2(event: DelegationTransferredToL2 export function handleStakeDelegatedUnlockedDueToL2Transfer( event: StakeDelegatedUnlockedDueToL2Transfer, ): void { - let graphNetwork = GraphNetwork.load('1')! + let graphNetwork = loadGraphNetwork() let delegationID = joinID([ event.params.delegator.toHexString(), event.params.indexer.toHexString(), diff --git a/src/mappings/l2gns.ts b/src/mappings/l2gns.ts index 86a7f7d8..ee861059 100644 --- a/src/mappings/l2gns.ts +++ b/src/mappings/l2gns.ts @@ -12,6 +12,7 @@ import { createOrLoadNameSignal, createOrLoadGraphAccount, convertBigIntSubgraphIDToBase58, + loadGraphNetwork, } from './helpers/helpers' /* @@ -25,12 +26,14 @@ import { export function handleSubgraphReceivedFromL1(event: SubgraphReceivedFromL1): void { let bigIntID = event.params._l2SubgraphID let subgraphID = convertBigIntSubgraphIDToBase58(bigIntID) + let graphNetwork = loadGraphNetwork() // Create subgraph if needed let subgraph = createOrLoadSubgraph( event.params._l2SubgraphID, event.params._owner, event.block.timestamp, + graphNetwork, ) subgraph.startedTransferToL2 = true subgraph.startedTransferToL2At = event.block.timestamp @@ -47,6 +50,7 @@ export function handleSubgraphReceivedFromL1(event: SubgraphReceivedFromL1): voi event.params._owner, subgraphID, event.block.timestamp, + graphNetwork, ) nameSignal.transferredToL2 = true nameSignal.transferredToL2At = event.block.timestamp @@ -88,11 +92,13 @@ export function handleSubgraphL2TransferFinalized(event: SubgraphL2TransferFinal export function handleCuratorBalanceReceived(event: CuratorBalanceReceived): void { let bigIntID = event.params._l2SubgraphID let subgraphID = convertBigIntSubgraphIDToBase58(bigIntID) + let graphNetwork = loadGraphNetwork() let nameSignal = createOrLoadNameSignal( event.params._l2Curator, subgraphID, event.block.timestamp, + graphNetwork, ) nameSignal.transferredToL2 = true nameSignal.transferredToL2At = event.block.timestamp diff --git a/src/mappings/rewardsManager.ts b/src/mappings/rewardsManager.ts index 6157d014..e492b2b8 100644 --- a/src/mappings/rewardsManager.ts +++ b/src/mappings/rewardsManager.ts @@ -65,6 +65,7 @@ export function handleRewardsAssigned(event: RewardsAssigned): void { let subgraphDeployment = createOrLoadSubgraphDeployment( subgraphDeploymentID, event.block.timestamp, + graphNetwork, ) subgraphDeployment.indexingRewardAmount = subgraphDeployment.indexingRewardAmount.plus( event.params.amount, diff --git a/src/mappings/serviceRegistry.ts b/src/mappings/serviceRegistry.ts index 69c92074..cfdaded9 100644 --- a/src/mappings/serviceRegistry.ts +++ b/src/mappings/serviceRegistry.ts @@ -1,17 +1,18 @@ import { ServiceRegistered, ServiceUnregistered } from '../types/ServiceRegistry/ServiceRegistry' import { Indexer } from '../types/schema' -import { createOrLoadLegacyIndexer, createOrLoadGraphAccount } from './helpers/helpers' +import { createOrLoadLegacyIndexer, createOrLoadGraphAccount, loadGraphNetwork } from './helpers/helpers' /** * @dev handleServiceRegistered * - updates indexer, creates if needed */ export function handleServiceRegistered(event: ServiceRegistered): void { + let graphNetwork = loadGraphNetwork() // Creates Graph Account, if needed createOrLoadGraphAccount(event.params.indexer, event.block.timestamp) - let indexer = createOrLoadLegacyIndexer(event.params.indexer, event.block.timestamp) + let indexer = createOrLoadLegacyIndexer(event.params.indexer, event.block.timestamp, graphNetwork) indexer.url = event.params.url indexer.geoHash = event.params.geohash indexer.save() diff --git a/src/mappings/staking.ts b/src/mappings/staking.ts index 6272a622..3ded4118 100644 --- a/src/mappings/staking.ts +++ b/src/mappings/staking.ts @@ -48,12 +48,13 @@ import { calculateCapacities, createOrLoadIndexerQueryFeePaymentAggregation, createOrLoadPaymentSource, + loadGraphNetwork, } from './helpers/helpers' import { addresses } from '../../config/addresses' export function handleDelegationParametersUpdated(event: DelegationParametersUpdated): void { let graphNetwork = createOrLoadGraphNetwork(event.block.number, event.address) - let indexer = createOrLoadLegacyIndexer(event.params.indexer, event.block.timestamp) + let indexer = createOrLoadLegacyIndexer(event.params.indexer, event.block.timestamp, graphNetwork) indexer.legacyIndexingRewardCut = event.params.indexingRewardCut.toI32() indexer.legacyQueryFeeCut = event.params.queryFeeCut.toI32() indexer.delegatorParameterCooldown = event.params.cooldownBlocks.toI32() @@ -73,7 +74,7 @@ export function handleDelegationParametersUpdated(event: DelegationParametersUpd export function handleStakeDeposited(event: StakeDeposited): void { let graphNetwork = createOrLoadGraphNetwork(event.block.number, event.address) // update indexer - let indexer = createOrLoadLegacyIndexer(event.params.indexer, event.block.timestamp) + let indexer = createOrLoadLegacyIndexer(event.params.indexer, event.block.timestamp, graphNetwork) let previousStake = indexer.stakedTokens indexer.stakedTokens = indexer.stakedTokens.plus(event.params.tokens) indexer = updateLegacyAdvancedIndexerMetrics(indexer as Indexer) @@ -203,10 +204,11 @@ export function handleStakeSlashed(event: StakeSlashed): void { } export function handleStakeDelegated(event: StakeDelegated): void { + let graphNetwork = loadGraphNetwork() let zeroShares = event.params.shares.equals(BigInt.fromI32(0)) // update indexer - let indexer = createOrLoadLegacyIndexer(event.params.indexer, event.block.timestamp) + let indexer = createOrLoadLegacyIndexer(event.params.indexer, event.block.timestamp, graphNetwork) indexer.delegatedTokens = indexer.delegatedTokens.plus(event.params.tokens) indexer.delegatorShares = indexer.delegatorShares.plus(event.params.shares) @@ -219,7 +221,7 @@ export function handleStakeDelegated(event: StakeDelegated): void { // update delegator let delegatorID = event.params.delegator.toHexString() - let delegator = createOrLoadDelegator(event.params.delegator, event.block.timestamp) + let delegator = createOrLoadDelegator(event.params.delegator, event.block.timestamp, graphNetwork) delegator.totalStakedTokens = delegator.totalStakedTokens.plus(event.params.tokens) delegator.save() @@ -228,6 +230,7 @@ export function handleStakeDelegated(event: StakeDelegated): void { delegatorID, event.params.indexer.toHexString(), event.block.timestamp.toI32(), + graphNetwork, ) if (!zeroShares) { let previousExchangeRate = delegatedStake.personalExchangeRate @@ -254,7 +257,6 @@ export function handleStakeDelegated(event: StakeDelegated): void { 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) { @@ -375,7 +377,7 @@ export function handleAllocationCreated(event: AllocationCreated): void { graphNetwork.save() // update subgraph deployment - let deployment = createOrLoadSubgraphDeployment(subgraphDeploymentID, event.block.timestamp) + let deployment = createOrLoadSubgraphDeployment(subgraphDeploymentID, event.block.timestamp, graphNetwork) deployment.stakedTokens = deployment.stakedTokens.plus(event.params.tokens) deployment.save() @@ -567,7 +569,7 @@ export function handleAllocationClosed(event: AllocationClosed): void { // update subgraph deployment. Pretty sure this should be done here, if not // it would be done in handleRebateClaimed let subgraphDeploymentID = event.params.subgraphDeploymentID.toHexString() - let deployment = createOrLoadSubgraphDeployment(subgraphDeploymentID, event.block.timestamp) + let deployment = createOrLoadSubgraphDeployment(subgraphDeploymentID, event.block.timestamp, graphNetwork) deployment.stakedTokens = deployment.stakedTokens.minus(event.params.tokens) deployment.save() @@ -644,7 +646,7 @@ export function handleAllocationClosedCobbDouglas(event: AllocationClosed1): voi // update subgraph deployment. Pretty sure this should be done here, if not // it would be done in handleRebateClaimed let subgraphDeploymentID = event.params.subgraphDeploymentID.toHexString() - let deployment = createOrLoadSubgraphDeployment(subgraphDeploymentID, event.block.timestamp) + let deployment = createOrLoadSubgraphDeployment(subgraphDeploymentID, event.block.timestamp, graphNetwork) deployment.stakedTokens = deployment.stakedTokens.minus(event.params.tokens) deployment.save() diff --git a/src/mappings/subgraphService.ts b/src/mappings/subgraphService.ts index a8fa6132..09172afd 100644 --- a/src/mappings/subgraphService.ts +++ b/src/mappings/subgraphService.ts @@ -1,12 +1,13 @@ import { BigDecimal, BigInt, Bytes, ethereum, log } from "@graphprotocol/graph-ts" import { AllocationClosed, AllocationCreated, AllocationResized, CurationCutSet, DelegationRatioSet, IndexingRewardsCollected, MaxPOIStalenessSet, ProvisionTokensRangeSet, QueryFeesCollected, RewardsDestinationSet, ServiceProviderRegistered, StakeToFeesRatioSet, ThawingPeriodRangeSet, VerifierCutRangeSet } from "../types/SubgraphService/SubgraphService" -import { batchUpdateSubgraphSignalledTokens, calculatePricePerShare, createOrLoadDataService, createOrLoadGraphNetwork, createOrLoadEpoch,createOrLoadIndexerQueryFeePaymentAggregation, createOrLoadPaymentSource, createOrLoadProvision, createOrLoadSubgraphDeployment, joinID, updateDelegationExchangeRate, calculateCapacities } from "./helpers/helpers" +import { batchUpdateSubgraphSignalledTokens, calculatePricePerShare, createOrLoadDataService, createOrLoadGraphNetwork, createOrLoadEpoch,createOrLoadIndexerQueryFeePaymentAggregation, createOrLoadPaymentSource, createOrLoadProvision, createOrLoadSubgraphDeployment, joinID, updateDelegationExchangeRate, calculateCapacities, loadGraphNetwork } from "./helpers/helpers" import { Allocation, Indexer, PoiSubmission, SubgraphDeployment } from "../types/schema" import { addresses } from "../../config/addresses" import { tuplePrefixBytes } from "./helpers/decoder" import { createOrLoadIndexer } from "./helpers/helpers" export function handleServiceProviderRegistered(event: ServiceProviderRegistered): void { + let graphNetwork = loadGraphNetwork() let decodedCalldata = ethereum.decode('(string,string,address)', tuplePrefixBytes(event.params.data)) if (decodedCalldata != null && decodedCalldata.kind == ethereum.ValueKind.TUPLE) { let tupleData = decodedCalldata.toTuple() @@ -22,7 +23,7 @@ export function handleServiceProviderRegistered(event: ServiceProviderRegistered provision.save() // Update indexer - let indexer = createOrLoadIndexer(event.params.serviceProvider, event.block.timestamp) + let indexer = createOrLoadIndexer(event.params.serviceProvider, event.block.timestamp, graphNetwork) indexer.url = url indexer.geoHash = geoHash indexer.rewardsDestination = rewardsDestination @@ -36,13 +37,14 @@ export function handleServiceProviderRegistered(event: ServiceProviderRegistered } export function handleRewardsDestinationSet(event: RewardsDestinationSet): void { + let graphNetwork = loadGraphNetwork() // Update provision let provision = createOrLoadProvision(event.params.indexer, event.address, event.block.timestamp) provision.rewardsDestination = event.params.rewardsDestination provision.save() // Update indexer - let indexer = createOrLoadIndexer(event.params.indexer, event.block.timestamp) + let indexer = createOrLoadIndexer(event.params.indexer, event.block.timestamp, graphNetwork) indexer.rewardsDestination = event.params.rewardsDestination indexer.save() } @@ -86,7 +88,7 @@ export function handleAllocationCreated(event: AllocationCreated): void { dataService.save() // update subgraph deployment - let deployment = createOrLoadSubgraphDeployment(subgraphDeploymentID, event.block.timestamp) + let deployment = createOrLoadSubgraphDeployment(subgraphDeploymentID, event.block.timestamp, graphNetwork) deployment.stakedTokens = deployment.stakedTokens.plus(event.params.tokens) deployment.save() @@ -168,7 +170,7 @@ export function handleAllocationClosed(event: AllocationClosed): void { allocation.save() let subgraphDeploymentID = event.params.subgraphDeploymentId.toHexString() - let deployment = createOrLoadSubgraphDeployment(subgraphDeploymentID, event.block.timestamp) + let deployment = createOrLoadSubgraphDeployment(subgraphDeploymentID, event.block.timestamp, graphNetwork) deployment.stakedTokens = deployment.stakedTokens.minus(event.params.tokens) deployment.save() @@ -184,6 +186,7 @@ export function handleAllocationClosed(event: AllocationClosed): void { } export function handleAllocationResized(event: AllocationResized): void { + let graphNetwork = loadGraphNetwork() let allocationID = event.params.allocationId.toHexString() let indexerID = event.params.indexer.toHexString() let diffTokens = event.params.newTokens.minus(event.params.oldTokens) @@ -211,12 +214,11 @@ export function handleAllocationResized(event: AllocationResized): void { // update subgraph deployment let subgraphDeploymentID = allocation.subgraphDeployment - let deployment = createOrLoadSubgraphDeployment(subgraphDeploymentID, event.block.timestamp) + let deployment = createOrLoadSubgraphDeployment(subgraphDeploymentID, event.block.timestamp, graphNetwork) deployment.stakedTokens = deployment.stakedTokens.plus(diffTokens) deployment.save() // update graph network - let graphNetwork = createOrLoadGraphNetwork(event.block.number, event.address) graphNetwork.totalTokensAllocated = graphNetwork.totalTokensAllocated.plus(diffTokens) graphNetwork.save() } @@ -302,6 +304,7 @@ export function handleIndexingRewardsCollected(event: IndexingRewardsCollected): let subgraphDeployment = createOrLoadSubgraphDeployment( subgraphDeploymentID, event.block.timestamp, + graphNetwork, ) subgraphDeployment.indexingRewardAmount = subgraphDeployment.indexingRewardAmount.plus( event.params.tokensRewards, diff --git a/tests/staking.test.ts b/tests/staking.test.ts index ff3942e6..a3a77688 100644 --- a/tests/staking.test.ts +++ b/tests/staking.test.ts @@ -41,7 +41,7 @@ import { mockSlasherUpdate, mockAssetHolderUpdate, } from './factories/staking' -import { createOrLoadGraphNetwork } from '../src/mappings/helpers/helpers' +import { createOrLoadGraphNetwork, loadGraphNetwork } from '../src/mappings/helpers/helpers' import { mockTransfer } from './factories/graphToken' import { GraphNetwork, GraphAccount } from '../src/types/schema' @@ -919,7 +919,7 @@ describe('NETWORK SETS AND UPDATES', () => { let slasher = mockSlasherUpdate(indexerAddress, slasherAddress, true) handleSlasherUpdate(slasher) - let graphNetwork = GraphNetwork.load('1')! + let graphNetwork = loadGraphNetwork() let slashers = graphNetwork.slashers if (slashers !== null) { @@ -943,7 +943,7 @@ describe('NETWORK SETS AND UPDATES', () => { let assetHolder = mockAssetHolderUpdate(indexerAddress, assetHolderAddress, true) handleAssetHolderUpdate(assetHolder) - let graphNetwork = GraphNetwork.load('1')! + let graphNetwork = loadGraphNetwork() let assetHolders = graphNetwork.assetHolders if (assetHolders !== null) {