From b66db5f8d28f0a835c3d57974ca5d3a69831d6d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Migone?= Date: Fri, 7 Feb 2025 16:54:53 -0300 Subject: [PATCH] feat: add getter for provision tracker free tokens MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Tomás Migone --- .../libraries/ProvisionTracker.sol | 17 ++++++++++++++ .../contracts/SubgraphService.sol | 14 +++++++++++ .../contracts/interfaces/ISubgraphService.sol | 23 +++++++++++++++++++ .../contracts/utilities/AllocationManager.sol | 10 ++++++++ 4 files changed, 64 insertions(+) diff --git a/packages/horizon/contracts/data-service/libraries/ProvisionTracker.sol b/packages/horizon/contracts/data-service/libraries/ProvisionTracker.sol index 25449909b..60f8c9d5f 100644 --- a/packages/horizon/contracts/data-service/libraries/ProvisionTracker.sol +++ b/packages/horizon/contracts/data-service/libraries/ProvisionTracker.sol @@ -72,4 +72,21 @@ library ProvisionTracker { uint256 tokensAvailable = graphStaking.getTokensAvailable(serviceProvider, address(this), delegationRatio); return self[serviceProvider] <= tokensAvailable; } + + /** + * @notice Returns the number of free tokens for a service provider. Free tokens are those currently available to lock. + * @param self The provision tracker mapping + * @param graphStaking The HorizonStaking contract + * @param serviceProvider The service provider address + * @param delegationRatio A delegation ratio to limit the amount of delegation that's usable + */ + function getTokensFree( + mapping(address => uint256) storage self, + IHorizonStaking graphStaking, + address serviceProvider, + uint32 delegationRatio + ) internal view returns (uint256) { + uint256 tokensAvailable = graphStaking.getTokensAvailable(serviceProvider, address(this), delegationRatio); + return tokensAvailable > self[serviceProvider] ? tokensAvailable - self[serviceProvider] : 0; + } } diff --git a/packages/subgraph-service/contracts/SubgraphService.sol b/packages/subgraph-service/contracts/SubgraphService.sol index 1e7adae5a..1e9f020f8 100644 --- a/packages/subgraph-service/contracts/SubgraphService.sol +++ b/packages/subgraph-service/contracts/SubgraphService.sol @@ -21,6 +21,7 @@ import { TokenUtils } from "@graphprotocol/contracts/contracts/utils/TokenUtils. import { PPMMath } from "@graphprotocol/horizon/contracts/libraries/PPMMath.sol"; import { Allocation } from "./libraries/Allocation.sol"; import { LegacyAllocation } from "./libraries/LegacyAllocation.sol"; +import { ProvisionTracker } from "@graphprotocol/horizon/contracts/data-service/libraries/ProvisionTracker.sol"; /** * @title SubgraphService contract @@ -40,6 +41,7 @@ contract SubgraphService is IRewardsIssuer, ISubgraphService { + using ProvisionTracker for mapping(address => uint256); using PPMMath for uint256; using Allocation for mapping(address => Allocation.State); using Allocation for Allocation.State; @@ -489,6 +491,14 @@ contract SubgraphService is return _isOverAllocated(indexer, delegationRatio); } + function getAllocationTokensFree(address indexer) external view override returns (uint256) { + return _getAllocationTokensFree(indexer, delegationRatio); + } + + function getFeesTokensFree(address indexer) external view override returns (uint256) { + return feesProvisionTracker.getTokensFree(_graphStaking(), indexer, delegationRatio); + } + // -- Data service parameter getters -- /** * @notice Getter for the accepted thawing period range for provisions @@ -579,6 +589,10 @@ contract SubgraphService is return tokensCollected; } + /** + * @notice Set the stake to fees ratio + * @param _stakeToFeesRatio The new stake to fees ratio + */ function _setStakeToFeesRatio(uint256 _stakeToFeesRatio) private { require(_stakeToFeesRatio != 0, SubgraphServiceInvalidZeroStakeToFeesRatio()); stakeToFeesRatio = _stakeToFeesRatio; diff --git a/packages/subgraph-service/contracts/interfaces/ISubgraphService.sol b/packages/subgraph-service/contracts/interfaces/ISubgraphService.sol index 7278a4a4f..b76468887 100644 --- a/packages/subgraph-service/contracts/interfaces/ISubgraphService.sol +++ b/packages/subgraph-service/contracts/interfaces/ISubgraphService.sol @@ -228,6 +228,29 @@ interface ISubgraphService is IDataServiceFees { */ function getLegacyAllocation(address allocationId) external view returns (LegacyAllocation.State memory); + /** + * @notice Returns the number of free tokens for an indexer. + * Free tokens are those that can be immediately used to lock as economic security. + * @param indexer The address of the indexer + * @param paymentType The type of payment to consider + * @return The number of free tokens + */ + // function getTokensFree(address indexer, IGraphPayments.PaymentTypes paymentType) external view returns (uint256); + + /** + * @notice Returns the number of free tokens for an indexer for indexing rewards + * @param indexer The address of the indexer + * @return The number of free tokens + */ + function getAllocationTokensFree(address indexer) external view returns (uint256); + + /** + * @notice Returns the number of free tokens for an indexer for query fees + * @param indexer The address of the indexer + * @return The number of free tokens + */ + function getFeesTokensFree(address indexer) external view returns (uint256); + /** * @notice Encodes the allocation proof for EIP712 signing * @param indexer The address of the indexer diff --git a/packages/subgraph-service/contracts/utilities/AllocationManager.sol b/packages/subgraph-service/contracts/utilities/AllocationManager.sol index 008a65eef..4a452ef39 100644 --- a/packages/subgraph-service/contracts/utilities/AllocationManager.sol +++ b/packages/subgraph-service/contracts/utilities/AllocationManager.sol @@ -476,6 +476,16 @@ abstract contract AllocationManager is EIP712Upgradeable, GraphDirectory, Alloca return !allocationProvisionTracker.check(_graphStaking(), _indexer, _delegationRatio); } + /** + * @notice Returns the number of free tokens for an indexer + * @param _indexer The address of the indexer + * @param _delegationRatio The delegation ratio to consider when locking tokens + * @return The number of free tokens + */ + function _getAllocationTokensFree(address _indexer, uint32 _delegationRatio) internal view returns (uint256) { + return allocationProvisionTracker.getTokensFree(_graphStaking(), _indexer, _delegationRatio); + } + /** * @notice Verifies ownership of an allocation id by verifying an EIP712 allocation proof * @dev Requirements: