diff --git a/package.json b/package.json index 120774bf..7cb10e59 100644 --- a/package.json +++ b/package.json @@ -13,10 +13,10 @@ "prepublishOnly": "yarn & yarn build:ipfs", "build": "graph build", "build:ipfs:mainnet": "yarn && yarn prepare:mainnet && graph build --ipfs https://ipfs.network.thegraph.com", - "deploy-mainnet": "yarn && yarn prepare:mainnet && graph deploy --studio graph-network-ethereum", - "deploy-arbitrum": "yarn && yarn prepare:arbitrum && graph deploy --studio graph-network-arbitrum", - "deploy-sepolia": "yarn && yarn prepare:sepolia && graph deploy --studio graph-network-sepolia", - "deploy-arbitrum-sepolia": "yarn && yarn prepare:arbitrum-sepolia && graph deploy --studio graph-network-arbitrum-sepolia", + "deploy-mainnet": "yarn && yarn prepare:mainnet && graph deploy graph-network-ethereum", + "deploy-arbitrum": "yarn && yarn prepare:arbitrum && graph deploy graph-network-arbitrum", + "deploy-sepolia": "yarn && yarn prepare:sepolia && graph deploy graph-network-sepolia", + "deploy-arbitrum-sepolia": "yarn && yarn prepare:arbitrum-sepolia && graph deploy graph-network-arbitrum-sepolia", "deploy-arbitrum-sepolia-test": "yarn && yarn prepare:arbitrum-sepolia && graph deploy horizon-testing-arb-sepolia -l test-old", "deploy-studio": "yarn deploy-mainnet && yarn deploy-arbitrum && yarn deploy-sepolia && yarn deploy-arbitrum-sepolia", "prep:addresses:sepolia": "ts-node config/sepoliaAddressScript.ts && mustache ./config/generatedAddresses.json ./config/addresses.template.ts > ./config/addresses.ts", diff --git a/schema.graphql b/schema.graphql index df842a63..c597fadb 100644 --- a/schema.graphql +++ b/schema.graphql @@ -745,8 +745,10 @@ type Indexer @entity(immutable: false) { provisionedTokens: BigInt! "CURRENT tokens thawing from provisions to data services in the protocol. Only for Horizon" thawingTokens: BigInt! - "CURRENT tokens allocated on all subgraphs" + "CURRENT tokens allocated on all subgraphs - including legacy and horizon allocations" allocatedTokens: BigInt! + "[Legacy only] CURRENT tokens allocated on all subgraphs ONLY for legacy allocations" + legacyAllocatedTokens: BigInt! "NOT IMPLEMENTED - Tokens that have been unstaked and withdrawn" unstakedTokens: BigInt! # will be used for return % calcs "CURRENT tokens locked" @@ -1509,6 +1511,7 @@ enum DisputeType { SingleQuery Conflicting Indexing + Legacy } enum DisputeStatus { diff --git a/src/mappings/helpers/helpers.ts b/src/mappings/helpers/helpers.ts index c2a590cd..0d4d65bc 100644 --- a/src/mappings/helpers/helpers.ts +++ b/src/mappings/helpers/helpers.ts @@ -146,6 +146,7 @@ export function createOrLoadIndexer(indexerAddress: Bytes, timestamp: BigInt ): indexer.provisionedTokens = BigInt.fromI32(0) indexer.thawingTokens = BigInt.fromI32(0) indexer.allocatedTokens = BigInt.fromI32(0) + indexer.legacyAllocatedTokens = BigInt.fromI32(0) indexer.lockedTokens = BigInt.fromI32(0) indexer.legacyLockedTokens = BigInt.fromI32(0) indexer.unstakedTokens = BigInt.fromI32(0) diff --git a/src/mappings/staking.ts b/src/mappings/staking.ts index 50126eb6..6272a622 100644 --- a/src/mappings/staking.ts +++ b/src/mappings/staking.ts @@ -98,6 +98,7 @@ export function handleStakeDeposited(event: StakeDeposited): void { /** * @dev handleStakeLocked + * Handler for legacy stake locking * - updated the Indexers stake * - note - the contracts work by not changing the tokensStaked amount, so here, capacity does not * get changed @@ -127,6 +128,7 @@ export function handleStakeLocked(event: StakeLocked): void { /** * @dev handleStakeWithdrawn + * Handler for legacy stake withdrawal * - updated the Indexers stake * - updates the GraphNetwork total stake */ @@ -161,21 +163,42 @@ export function handleStakeSlashed(event: StakeSlashed): void { let id = event.params.indexer.toHexString() let indexer = Indexer.load(id)! - indexer.stakedTokens = indexer.stakedTokens.minus(event.params.tokens) + let slashedTokens = event.params.tokens + + // When tokens are slashed, locked tokens might need to be unlocked if indexer overallocated + if (slashedTokens.gt(BigInt.fromI32(0))) { + let tokensUsed = indexer.legacyAllocatedTokens.plus(indexer.legacyLockedTokens) + let tokensAvailable = tokensUsed.gt(indexer.stakedTokens) + ? BigInt.fromI32(0) + : indexer.stakedTokens.minus(tokensUsed) + + if (slashedTokens.gt(tokensAvailable) && indexer.legacyLockedTokens.gt(BigInt.fromI32(0))) { + let tokensOverAllocated = slashedTokens.minus(tokensAvailable) + // Calculate min(tokensOverAllocated, lockedTokens) + let tokensToUnlock = tokensOverAllocated.lt(indexer.legacyLockedTokens) + ? tokensOverAllocated + : indexer.legacyLockedTokens + + indexer.legacyLockedTokens = indexer.legacyLockedTokens.minus(tokensToUnlock) + indexer.lockedTokens = indexer.lockedTokens.minus(tokensToUnlock) + + if (indexer.legacyLockedTokens.equals(BigInt.fromI32(0))) { + indexer.legacyTokensLockedUntil = 0 + } + if (indexer.lockedTokens.equals(BigInt.fromI32(0))) { + indexer.tokensLockedUntil = 0 + } + } + } + + indexer.stakedTokens = indexer.stakedTokens.minus(slashedTokens) - // We need to call into stakes mapping, because locked tokens might have been - // decremented, and this is not released in the event - // To fix this we would need to indicate in the event how many locked tokens were released - let staking = Staking.bind(event.address) - let indexerStored = staking.stakes(event.params.indexer) - indexer.lockedTokens = indexerStored.tokensLocked - indexer.legacyLockedTokens = indexerStored.tokensLocked indexer = updateLegacyAdvancedIndexerMetrics(indexer as Indexer) indexer = calculateCapacities(indexer as Indexer) indexer.save() // Update graph network - graphNetwork.totalTokensStaked = graphNetwork.totalTokensStaked.minus(event.params.tokens) + graphNetwork.totalTokensStaked = graphNetwork.totalTokensStaked.minus(slashedTokens) graphNetwork.save() } @@ -337,6 +360,7 @@ export function handleAllocationCreated(event: AllocationCreated): void { // update indexer let indexer = Indexer.load(indexerID)! + indexer.legacyAllocatedTokens = indexer.legacyAllocatedTokens.plus(event.params.tokens) indexer.allocatedTokens = indexer.allocatedTokens.plus(event.params.tokens) indexer.totalAllocationCount = indexer.totalAllocationCount.plus(BigInt.fromI32(1)) indexer.allocationCount = indexer.allocationCount + 1 @@ -517,6 +541,7 @@ export function handleAllocationClosed(event: AllocationClosed): void { allocation.forceClosed = false } indexer.allocatedTokens = indexer.allocatedTokens.minus(event.params.tokens) + indexer.legacyAllocatedTokens = indexer.legacyAllocatedTokens.minus(event.params.tokens) indexer.allocationCount = indexer.allocationCount - 1 indexer = updateLegacyAdvancedIndexerMetrics(indexer as Indexer) indexer = calculateCapacities(indexer as Indexer) @@ -579,6 +604,7 @@ export function handleAllocationClosedCobbDouglas(event: AllocationClosed1): voi } else { allocation.forceClosed = false } + indexer.legacyAllocatedTokens = indexer.legacyAllocatedTokens.minus(event.params.tokens) indexer.allocatedTokens = indexer.allocatedTokens.minus(event.params.tokens) indexer.allocationCount = indexer.allocationCount - 1 indexer = updateLegacyAdvancedIndexerMetrics(indexer as Indexer)