From 04432d28e080f83d4f4ad2b54acbaf6a96e6b0dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Thu, 23 May 2024 13:40:43 -0300 Subject: [PATCH] fix: take pending rewards for subgraph service MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../contracts/SubgraphService.sol | 7 ++++++- .../contracts/libraries/Allocation.sol | 11 +++++++++++ .../contracts/utilities/AllocationManager.sol | 17 +++++++++++++---- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/packages/subgraph-service/contracts/SubgraphService.sol b/packages/subgraph-service/contracts/SubgraphService.sol index e82e7c7e6..dd4c92d10 100644 --- a/packages/subgraph-service/contracts/SubgraphService.sol +++ b/packages/subgraph-service/contracts/SubgraphService.sol @@ -205,7 +205,12 @@ contract SubgraphService is address allocationId ) external view override returns (address, bytes32, uint256, uint256) { Allocation.State memory allo = allocations[allocationId]; - return (allo.indexer, allo.subgraphDeploymentId, allo.tokens, allo.accRewardsPerAllocatedToken); + return ( + allo.indexer, + allo.subgraphDeploymentId, + allo.tokens, + allo.accRewardsPerAllocatedToken + allo.accRewardsPending + ); } function getLegacyAllocation(address allocationId) external view returns (LegacyAllocation.State memory) { diff --git a/packages/subgraph-service/contracts/libraries/Allocation.sol b/packages/subgraph-service/contracts/libraries/Allocation.sol index f7b5c972a..8543b4f57 100644 --- a/packages/subgraph-service/contracts/libraries/Allocation.sol +++ b/packages/subgraph-service/contracts/libraries/Allocation.sol @@ -69,6 +69,17 @@ library Allocation { return allocation; } + function clearPendingRewards( + mapping(address => State) storage self, + address allocationId + ) internal returns (State memory) { + State storage allocation = _get(self, allocationId); + if (!allocation.isOpen()) revert AllocationClosed(allocationId, allocation.closedAt); + allocation.accRewardsPending = 0; + + return allocation; + } + function close(mapping(address => State) storage self, address allocationId) internal returns (State memory) { State storage allocation = _get(self, allocationId); if (!allocation.isOpen()) revert AllocationClosed(allocationId, allocation.closedAt); diff --git a/packages/subgraph-service/contracts/utilities/AllocationManager.sol b/packages/subgraph-service/contracts/utilities/AllocationManager.sol index 62a70aee4..fa4d0a654 100644 --- a/packages/subgraph-service/contracts/utilities/AllocationManager.sol +++ b/packages/subgraph-service/contracts/utilities/AllocationManager.sol @@ -147,6 +147,9 @@ abstract contract AllocationManager is EIP712, GraphDirectory, AllocationManager ); allocations.presentPOI(allocationId); + // Any pending rewards should have been collected now + allocations.clearPendingRewards(allocationId); + if (tokensRewards == 0) { emit IndexingRewardsCollected( allocation.indexer, @@ -225,12 +228,11 @@ abstract contract AllocationManager is EIP712, GraphDirectory, AllocationManager // Update the allocation allocations[_allocationId].tokens = _tokens; allocations[_allocationId].accRewardsPerAllocatedToken = accRewardsPerAllocatedToken; - allocations[_allocationId].accRewardsPending = allocations[_allocationId].accRewardsPending + accRewardsPending; + allocations[_allocationId].accRewardsPending += accRewardsPending; // Update total allocated tokens for the subgraph deployment - subgraphAllocatedTokens[allocation.subgraphDeploymentId] = - subgraphAllocatedTokens[allocation.subgraphDeploymentId] + - (_tokens - oldTokens); + // underflow: subgraphAllocatedTokens should at least be oldTokens so it can't underflow + subgraphAllocatedTokens[allocation.subgraphDeploymentId] += (_tokens - oldTokens); emit AllocationResized(allocation.indexer, _allocationId, allocation.subgraphDeploymentId, _tokens, oldTokens); return allocations[_allocationId]; @@ -242,6 +244,13 @@ abstract contract AllocationManager is EIP712, GraphDirectory, AllocationManager allocations.close(_allocationId); allocationProvisionTracker.release(allocation.indexer, allocation.tokens); + // Take rewards snapshot to prevent other allos from counting tokens from this allo + allocations.snapshotRewards( + _allocationId, + _graphRewardsManager().onSubgraphAllocationUpdate(allocation.subgraphDeploymentId) + ); + + // Update total allocated tokens for the subgraph deployment subgraphAllocatedTokens[allocation.subgraphDeploymentId] = subgraphAllocatedTokens[allocation.subgraphDeploymentId] - allocation.tokens;