@@ -108,6 +108,46 @@ contract RewardsManager is RewardsManagerV6Storage, GraphUpgradeable, IERC165, I
108108 address indexed newRewardsEligibilityOracle
109109 );
110110
111+ /**
112+ * @notice Emitted when the eligibility reclaim address is set
113+ * @param oldReclaimAddress Previous eligibility reclaim address
114+ * @param newReclaimAddress New eligibility reclaim address
115+ */
116+ event IndexerEligibilityReclaimAddressSet (address indexed oldReclaimAddress , address indexed newReclaimAddress );
117+
118+ /**
119+ * @notice Emitted when the subgraph reclaim address is set
120+ * @param oldReclaimAddress Previous subgraph reclaim address
121+ * @param newReclaimAddress New subgraph reclaim address
122+ */
123+ event SubgraphDeniedReclaimAddressSet (address indexed oldReclaimAddress , address indexed newReclaimAddress );
124+
125+ /**
126+ * @notice Emitted when denied rewards are reclaimed due to eligibility
127+ * @param indexer Address of the indexer whose rewards were denied
128+ * @param allocationID Address of the allocation
129+ * @param amount Amount of rewards reclaimed
130+ */
131+ event RewardsReclaimedDueToIndexerEligibility (
132+ address indexed indexer ,
133+ address indexed allocationID ,
134+ uint256 amount
135+ );
136+
137+ /**
138+ * @notice Emitted when denied rewards are reclaimed due to subgraph denylist
139+ * @param indexer Address of the indexer whose rewards were denied
140+ * @param allocationID Address of the allocation
141+ * @param subgraphDeploymentID Subgraph deployment ID that was denied
142+ * @param amount Amount of rewards reclaimed
143+ */
144+ event RewardsReclaimedDueToSubgraphDenylist (
145+ address indexed indexer ,
146+ address indexed allocationID ,
147+ bytes32 indexed subgraphDeploymentID ,
148+ uint256 amount
149+ );
150+
111151 // -- Modifiers --
112152
113153 /**
@@ -264,6 +304,32 @@ contract RewardsManager is RewardsManagerV6Storage, GraphUpgradeable, IERC165, I
264304 }
265305 }
266306
307+ /**
308+ * @inheritdoc IRewardsManager
309+ * @dev Set to zero address to disable eligibility reclaim functionality
310+ */
311+ function setIndexerEligibilityReclaimAddress (address newReclaimAddress ) external override onlyGovernor {
312+ address oldReclaimAddress = indexerEligibilityReclaimAddress;
313+
314+ if (oldReclaimAddress != newReclaimAddress) {
315+ indexerEligibilityReclaimAddress = newReclaimAddress;
316+ emit IndexerEligibilityReclaimAddressSet (oldReclaimAddress, newReclaimAddress);
317+ }
318+ }
319+
320+ /**
321+ * @inheritdoc IRewardsManager
322+ * @dev Set to zero address to disable subgraph reclaim functionality
323+ */
324+ function setSubgraphDeniedReclaimAddress (address newReclaimAddress ) external override onlyGovernor {
325+ address oldReclaimAddress = subgraphDeniedReclaimAddress;
326+
327+ if (oldReclaimAddress != newReclaimAddress) {
328+ subgraphDeniedReclaimAddress = newReclaimAddress;
329+ emit SubgraphDeniedReclaimAddressSet (oldReclaimAddress, newReclaimAddress);
330+ }
331+ }
332+
267333 // -- Denylist --
268334
269335 /**
@@ -494,6 +560,60 @@ contract RewardsManager is RewardsManagerV6Storage, GraphUpgradeable, IERC165, I
494560 return newAccrued.mul (_tokens).div (FIXED_POINT_SCALING_FACTOR);
495561 }
496562
563+ /**
564+ * @notice Checks for and handles denial and reclaim of rewards due to subgraph deny list
565+ * @dev If denied, emits RewardsDenied event and mints to reclaim address if configured
566+ * @param indexer Address of the indexer
567+ * @param allocationID Address of the allocation
568+ * @param subgraphDeploymentID Subgraph deployment ID
569+ * @param rewards Amount of rewards that would be distributed
570+ * @return True if rewards are denied, false otherwise
571+ */
572+ function _rewardsDeniedDueToSubgraphDenyList (
573+ address indexer ,
574+ address allocationID ,
575+ bytes32 subgraphDeploymentID ,
576+ uint256 rewards
577+ ) private returns (bool ) {
578+ if (isDenied (subgraphDeploymentID)) {
579+ emit RewardsDenied (indexer, allocationID);
580+
581+ // If a reclaim address is set, mint the denied rewards there
582+ if (0 < rewards && subgraphDeniedReclaimAddress != address (0 )) {
583+ graphToken ().mint (subgraphDeniedReclaimAddress, rewards);
584+ emit RewardsReclaimedDueToSubgraphDenylist (indexer, allocationID, subgraphDeploymentID, rewards);
585+ }
586+ return true ;
587+ }
588+ return false ;
589+ }
590+
591+ /**
592+ * @notice Checks for and handles denial and reclaim of rewards due to indexer eligibility
593+ * @dev If denied, emits RewardsDeniedDueToEligibility event and mints to reclaim address if configured
594+ * @param indexer Address of the indexer
595+ * @param allocationID Address of the allocation
596+ * @param rewards Amount of rewards that would be distributed
597+ * @return True if rewards are denied, false otherwise
598+ */
599+ function _rewardsDeniedDueToIndexerEligibility (
600+ address indexer ,
601+ address allocationID ,
602+ uint256 rewards
603+ ) private returns (bool ) {
604+ if (address (rewardsEligibilityOracle) != address (0 ) && ! rewardsEligibilityOracle.isEligible (indexer)) {
605+ emit RewardsDeniedDueToEligibility (indexer, allocationID, rewards);
606+
607+ // If a reclaim address is set, mint the denied rewards there
608+ if (0 < rewards && indexerEligibilityReclaimAddress != address (0 )) {
609+ graphToken ().mint (indexerEligibilityReclaimAddress, rewards);
610+ emit RewardsReclaimedDueToIndexerEligibility (indexer, allocationID, rewards);
611+ }
612+ return true ;
613+ }
614+ return false ;
615+ }
616+
497617 /**
498618 * @inheritdoc IRewardsManager
499619 * @dev This function can only be called by an authorized rewards issuer which are
@@ -518,31 +638,24 @@ contract RewardsManager is RewardsManagerV6Storage, GraphUpgradeable, IERC165, I
518638
519639 uint256 updatedAccRewardsPerAllocatedToken = onSubgraphAllocationUpdate (subgraphDeploymentID);
520640
521- // Do not do rewards on denied subgraph deployments ID
522- if (isDenied (subgraphDeploymentID)) {
523- emit RewardsDenied (indexer, _allocationID);
524- return 0 ;
525- }
526-
527641 uint256 rewards = 0 ;
528642 if (isActive) {
529643 // Calculate rewards accrued by this allocation
530644 rewards = accRewardsPending.add (
531645 _calcRewards (tokens, accRewardsPerAllocatedToken, updatedAccRewardsPerAllocatedToken)
532646 );
647+ }
533648
534- // Do not reward if indexer is not eligible based on rewards eligibility
535- if (address (rewardsEligibilityOracle) != address (0 ) && ! rewardsEligibilityOracle.isEligible (indexer)) {
536- emit RewardsDeniedDueToEligibility (indexer, _allocationID, rewards);
537- return 0 ;
538- }
649+ if (_rewardsDeniedDueToSubgraphDenyList (indexer, _allocationID, subgraphDeploymentID, rewards)) return 0 ;
539650
540- if (rewards > 0 ) {
541- // Mint directly to rewards issuer for the reward amount
542- // The rewards issuer contract will do bookkeeping of the reward and
543- // assign in proportion to each stakeholder incentive
544- graphToken ().mint (rewardsIssuer, rewards);
545- }
651+ if (_rewardsDeniedDueToIndexerEligibility (indexer, _allocationID, rewards)) return 0 ;
652+
653+ // Mint rewards to the rewards issuer
654+ if (rewards > 0 ) {
655+ // Mint directly to rewards issuer for the reward amount
656+ // The rewards issuer contract will do bookkeeping of the reward and
657+ // assign in proportion to each stakeholder incentive
658+ graphToken ().mint (rewardsIssuer, rewards);
546659 }
547660
548661 emit HorizonRewardsAssigned (indexer, _allocationID, rewards);
0 commit comments