Skip to content

Commit ba7d51e

Browse files
committed
fix: prevent GraphTallyCollector from accepting non QueryFee payments
Signed-off-by: Tomás Migone <tomas@edgeandnode.com>
1 parent c3d96e4 commit ba7d51e

File tree

5 files changed

+92
-0
lines changed

5 files changed

+92
-0
lines changed

packages/horizon/contracts/interfaces/IGraphTallyCollector.sol

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,12 @@ interface IGraphTallyCollector is IPaymentsCollector {
9999
*/
100100
error GraphTallyCollectorInvalidTokensToCollectAmount(uint256 tokensToCollect, uint256 maxTokensToCollect);
101101

102+
/**
103+
* @notice Thrown when the payment type is invalid
104+
* @param paymentType The payment type
105+
*/
106+
error GraphTallyCollectorInvalidPaymentType(IGraphPayments.PaymentTypes paymentType);
107+
102108
/**
103109
* @notice See {IPaymentsCollector.collect}
104110
* This variant adds the ability to partially collect a RAV by specifying the amount of tokens to collect.

packages/horizon/contracts/payments/collectors/GraphTallyCollector.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ contract GraphTallyCollector is EIP712, GraphDirectory, Authorizable, IGraphTall
102102
bytes calldata _data,
103103
uint256 _tokensToCollect
104104
) private returns (uint256) {
105+
require(_paymentType == IGraphPayments.PaymentTypes.QueryFee, GraphTallyCollectorInvalidPaymentType(_paymentType));
106+
105107
(SignedRAV memory signedRAV, uint256 dataServiceCut, address receiverDestination) = abi.decode(
106108
_data,
107109
(SignedRAV, uint256, address)

packages/horizon/test/unit/payments/graph-tally-collector/collect/collect.t.sol

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,4 +483,31 @@ contract GraphTallyCollectTest is GraphTallyTest {
483483
bytes memory allocation0Data = _getQueryFeeEncodedData(signerPrivateKey, collectTestParams[0]);
484484
_collect(IGraphPayments.PaymentTypes.QueryFee, allocation0Data);
485485
}
486+
487+
function testGraphTally_Collect_RevertWhen_IncorrectPaymentType(
488+
uint256 tokens
489+
) public useIndexer useProvisionDataService(users.verifier, 100, 0, 0) useGateway useSigner {
490+
tokens = bound(tokens, 1, type(uint128).max);
491+
492+
_depositTokens(address(graphTallyCollector), users.indexer, tokens);
493+
494+
CollectTestParams memory params = CollectTestParams({
495+
tokens: tokens,
496+
allocationId: _allocationId,
497+
payer: users.gateway,
498+
indexer: users.indexer,
499+
collector: users.verifier
500+
});
501+
502+
bytes memory data = _getQueryFeeEncodedData(signerPrivateKey, params);
503+
504+
resetPrank(users.verifier);
505+
vm.expectRevert(
506+
abi.encodeWithSelector(
507+
IGraphTallyCollector.GraphTallyCollectorInvalidPaymentType.selector,
508+
IGraphPayments.PaymentTypes.IndexingRewards
509+
)
510+
);
511+
graphTallyCollector.collect(IGraphPayments.PaymentTypes.IndexingRewards, data);
512+
}
486513
}

packages/subgraph-service/test/unit/subgraphService/collect/indexing/indexing.t.sol

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,4 +171,14 @@ contract SubgraphServiceCollectIndexingTest is SubgraphServiceTest {
171171
);
172172
subgraphService.collect(newIndexer, paymentType, data);
173173
}
174+
175+
function test_SubgraphService_Collect_Indexing_RevertWhen_IncorrectPaymentType(uint256 tokens) public useIndexer useAllocation(tokens) {
176+
bytes memory data = abi.encode(allocationID, bytes32("POI"), _getHardcodedPOIMetadata());
177+
178+
// skip time to ensure allocation gets rewards
179+
vm.roll(block.number + EPOCH_LENGTH);
180+
181+
vm.expectRevert();
182+
subgraphService.collect(users.indexer, IGraphPayments.PaymentTypes.QueryFee, data);
183+
}
174184
}

packages/subgraph-service/test/unit/subgraphService/collect/query/query.t.sol

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { MessageHashUtils } from "@openzeppelin/contracts/utils/cryptography/Mes
1111

1212
import { ISubgraphService } from "../../../../../contracts/interfaces/ISubgraphService.sol";
1313
import { SubgraphServiceTest } from "../../SubgraphService.t.sol";
14+
import { Allocation } from "../../../../../contracts/libraries/Allocation.sol";
1415

1516
contract SubgraphServiceRegisterTest is SubgraphServiceTest {
1617
using PPMMath for uint128;
@@ -279,4 +280,50 @@ contract SubgraphServiceRegisterTest is SubgraphServiceTest {
279280
);
280281
assertEq(afterTokensCollected, intermediateTokensCollected + tokensToCollect + (oddTokensPayment ? 1 : 0));
281282
}
283+
284+
function testCollect_QueryFees_ClosedAllocation(
285+
uint256 tokensAllocated,
286+
uint256 tokensPayment
287+
) public useIndexer useAllocation(tokensAllocated) {
288+
vm.assume(tokensAllocated > minimumProvisionTokens * stakeToFeesRatio);
289+
uint256 maxTokensPayment = tokensAllocated / stakeToFeesRatio > type(uint128).max
290+
? type(uint128).max
291+
: tokensAllocated / stakeToFeesRatio;
292+
tokensPayment = bound(tokensPayment, minimumProvisionTokens, maxTokensPayment);
293+
294+
resetPrank(users.gateway);
295+
_deposit(tokensPayment);
296+
_authorizeSigner();
297+
298+
// Close the allocation
299+
resetPrank(users.indexer);
300+
bytes memory closeAlloData = abi.encode(allocationID);
301+
_stopService(users.indexer, closeAlloData);
302+
303+
// Collect the RAV
304+
resetPrank(users.indexer);
305+
bytes memory data = _getQueryFeeEncodedData(users.indexer, uint128(tokensPayment), 0);
306+
_collect(users.indexer, IGraphPayments.PaymentTypes.QueryFee, data);
307+
}
308+
309+
function testCollect_QueryFees_RevertWhen_IncorrectPaymentType(
310+
uint256 tokensAllocated,
311+
uint256 tokensPayment
312+
) public useIndexer useAllocation(tokensAllocated) {
313+
vm.assume(tokensAllocated > minimumProvisionTokens * stakeToFeesRatio);
314+
uint256 maxTokensPayment = tokensAllocated / stakeToFeesRatio > type(uint128).max
315+
? type(uint128).max
316+
: tokensAllocated / stakeToFeesRatio;
317+
tokensPayment = bound(tokensPayment, minimumProvisionTokens, maxTokensPayment);
318+
319+
resetPrank(users.gateway);
320+
_deposit(tokensPayment);
321+
_authorizeSigner();
322+
323+
resetPrank(users.indexer);
324+
bytes memory data = _getQueryFeeEncodedData(users.indexer, uint128(tokensPayment), 0);
325+
326+
vm.expectRevert();
327+
subgraphService.collect(users.indexer, IGraphPayments.PaymentTypes.IndexingRewards, data);
328+
}
282329
}

0 commit comments

Comments
 (0)