@@ -121,12 +121,16 @@ contract DisputeManager is
121
121
}
122
122
123
123
/// @inheritdoc IDisputeManager
124
- function createIndexingDispute (address allocationId , bytes32 poi ) external override returns (bytes32 ) {
124
+ function createIndexingDispute (
125
+ address allocationId ,
126
+ bytes32 poi ,
127
+ uint256 blockNumber
128
+ ) external override returns (bytes32 ) {
125
129
// Get funds from fisherman
126
130
_graphToken ().pullTokens (msg .sender , disputeDeposit);
127
131
128
132
// Create a dispute
129
- return _createIndexingDisputeWithAllocation (msg .sender , disputeDeposit, allocationId, poi);
133
+ return _createIndexingDisputeWithAllocation (msg .sender , disputeDeposit, allocationId, poi, blockNumber );
130
134
}
131
135
132
136
/// @inheritdoc IDisputeManager
@@ -341,11 +345,7 @@ contract DisputeManager is
341
345
342
346
/// @inheritdoc IDisputeManager
343
347
function getStakeSnapshot (address indexer ) external view override returns (uint256 ) {
344
- IHorizonStaking.Provision memory provision = _graphStaking ().getProvision (
345
- indexer,
346
- address (_getSubgraphService ())
347
- );
348
- return _getStakeSnapshot (indexer, provision.tokens);
348
+ return _getStakeSnapshot (indexer);
349
349
}
350
350
351
351
/// @inheritdoc IDisputeManager
@@ -395,13 +395,6 @@ contract DisputeManager is
395
395
// Get the indexer that signed the attestation
396
396
address indexer = getAttestationIndexer (_attestation);
397
397
398
- // The indexer is disputable
399
- IHorizonStaking.Provision memory provision = _graphStaking ().getProvision (
400
- indexer,
401
- address (_getSubgraphService ())
402
- );
403
- require (provision.tokens != 0 , DisputeManagerZeroTokens ());
404
-
405
398
// Create a disputeId
406
399
bytes32 disputeId = keccak256 (
407
400
abi.encodePacked (
@@ -416,8 +409,11 @@ contract DisputeManager is
416
409
// Only one dispute at a time
417
410
require (! isDisputeCreated (disputeId), DisputeManagerDisputeAlreadyCreated (disputeId));
418
411
412
+ // The indexer is disputable
413
+ uint256 stakeSnapshot = _getStakeSnapshot (indexer);
414
+ require (stakeSnapshot != 0 , DisputeManagerZeroTokens ());
415
+
419
416
// Store dispute
420
- uint256 stakeSnapshot = _getStakeSnapshot (indexer, provision.tokens);
421
417
uint256 cancellableAt = block .timestamp + disputePeriod;
422
418
disputes[disputeId] = Dispute (
423
419
indexer,
@@ -451,16 +447,18 @@ contract DisputeManager is
451
447
* @param _deposit Amount of tokens staked as deposit
452
448
* @param _allocationId Allocation disputed
453
449
* @param _poi The POI being disputed
450
+ * @param _blockNumber The block number for which the POI was calculated
454
451
* @return The dispute id
455
452
*/
456
453
function _createIndexingDisputeWithAllocation (
457
454
address _fisherman ,
458
455
uint256 _deposit ,
459
456
address _allocationId ,
460
- bytes32 _poi
457
+ bytes32 _poi ,
458
+ uint256 _blockNumber
461
459
) private returns (bytes32 ) {
462
460
// Create a disputeId
463
- bytes32 disputeId = keccak256 (abi.encodePacked (_allocationId, _poi));
461
+ bytes32 disputeId = keccak256 (abi.encodePacked (_allocationId, _poi, _blockNumber ));
464
462
465
463
// Only one dispute for an allocationId at a time
466
464
require (! isDisputeCreated (disputeId), DisputeManagerDisputeAlreadyCreated (disputeId));
@@ -472,11 +470,10 @@ contract DisputeManager is
472
470
require (indexer != address (0 ), DisputeManagerIndexerNotFound (_allocationId));
473
471
474
472
// The indexer must be disputable
475
- IHorizonStaking.Provision memory provision = _graphStaking (). getProvision ( indexer, address (subgraphService_) );
476
- require (provision.tokens != 0 , DisputeManagerZeroTokens ());
473
+ uint256 stakeSnapshot = _getStakeSnapshot ( indexer);
474
+ require (stakeSnapshot != 0 , DisputeManagerZeroTokens ());
477
475
478
476
// Store dispute
479
- uint256 stakeSnapshot = _getStakeSnapshot (indexer, provision.tokens);
480
477
uint256 cancellableAt = block .timestamp + disputePeriod;
481
478
disputes[disputeId] = Dispute (
482
479
alloc.indexer,
@@ -497,6 +494,7 @@ contract DisputeManager is
497
494
_deposit,
498
495
_allocationId,
499
496
_poi,
497
+ _blockNumber,
500
498
stakeSnapshot,
501
499
cancellableAt
502
500
);
@@ -685,18 +683,19 @@ contract DisputeManager is
685
683
* @dev A few considerations:
686
684
* - We include both indexer and delegators stake.
687
685
* - Thawing stake is not excluded from the snapshot.
688
- * - Delegators stake is capped at the delegation ratio to prevent delegators from inflating the snapshot
689
- * to increase the indexer slash amount.
690
686
*
691
687
* Note that the snapshot can be inflated by delegators front-running the dispute creation with a delegation
692
688
* to the indexer. Given the snapshot is a cap, the dispute outcome is uncertain and considering the cost of capital
693
689
* and slashing risk, this is not a concern.
694
690
* @param _indexer Indexer address
695
- * @param _indexerStake Indexer's stake
696
691
* @return Total stake snapshot
697
692
*/
698
- function _getStakeSnapshot (address _indexer , uint256 _indexerStake ) private view returns (uint256 ) {
699
- uint256 delegatorsStake = _graphStaking ().getDelegationPool (_indexer, address (_getSubgraphService ())).tokens;
700
- return _indexerStake + delegatorsStake;
693
+ function _getStakeSnapshot (address _indexer ) private view returns (uint256 ) {
694
+ address subgraphService = address (_getSubgraphService ());
695
+
696
+ IHorizonStaking.Provision memory provision = _graphStaking ().getProvision (_indexer, subgraphService);
697
+ uint256 delegatorsStake = _graphStaking ().getDelegationPool (_indexer, subgraphService).tokens;
698
+
699
+ return provision.tokens + delegatorsStake;
701
700
}
702
701
}
0 commit comments