@@ -108,6 +108,48 @@ 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 oldEligibilityReclaimAddress Previous eligibility reclaim address
114+ * @param newEligibilityReclaimAddress New eligibility reclaim address
115+ */
116+ event EligibilityReclaimAddressSet (
117+ address indexed oldEligibilityReclaimAddress ,
118+ address indexed newEligibilityReclaimAddress
119+ );
120+
121+ /**
122+ * @notice Emitted when the subgraph reclaim address is set
123+ * @param oldSubgraphReclaimAddress Previous subgraph reclaim address
124+ * @param newSubgraphReclaimAddress New subgraph reclaim address
125+ */
126+ event SubgraphReclaimAddressSet (
127+ address indexed oldSubgraphReclaimAddress ,
128+ address indexed newSubgraphReclaimAddress
129+ );
130+
131+ /**
132+ * @notice Emitted when denied rewards are reclaimed due to eligibility
133+ * @param indexer Address of the indexer whose rewards were denied
134+ * @param allocationID Address of the allocation
135+ * @param amount Amount of rewards reclaimed
136+ */
137+ event RewardsReclaimedDueToEligibility (address indexed indexer , address indexed allocationID , uint256 amount );
138+
139+ /**
140+ * @notice Emitted when denied rewards are reclaimed due to subgraph denylist
141+ * @param indexer Address of the indexer whose rewards were denied
142+ * @param allocationID Address of the allocation
143+ * @param subgraphDeploymentID Subgraph deployment ID that was denied
144+ * @param amount Amount of rewards reclaimed
145+ */
146+ event RewardsReclaimedDueToSubgraphDenylist (
147+ address indexed indexer ,
148+ address indexed allocationID ,
149+ bytes32 indexed subgraphDeploymentID ,
150+ uint256 amount
151+ );
152+
111153 // -- Modifiers --
112154
113155 /**
@@ -264,6 +306,30 @@ contract RewardsManager is RewardsManagerV6Storage, GraphUpgradeable, IERC165, I
264306 }
265307 }
266308
309+ /**
310+ * @inheritdoc IRewardsManager
311+ * @dev Set to zero address to disable eligibility reclaim functionality
312+ */
313+ function setIndexerEligibilityReclaimAddress (address newEligibilityReclaimAddress ) external override onlyGovernor {
314+ if (indexerEligibilityReclaimAddress != newEligibilityReclaimAddress) {
315+ address oldEligibilityReclaimAddress = indexerEligibilityReclaimAddress;
316+ indexerEligibilityReclaimAddress = newEligibilityReclaimAddress;
317+ emit EligibilityReclaimAddressSet (oldEligibilityReclaimAddress, newEligibilityReclaimAddress);
318+ }
319+ }
320+
321+ /**
322+ * @inheritdoc IRewardsManager
323+ * @dev Set to zero address to disable subgraph reclaim functionality
324+ */
325+ function setSubgraphDeniedReclaimAddress (address newSubgraphReclaimAddress ) external override onlyGovernor {
326+ if (subgraphDeniedReclaimAddress != newSubgraphReclaimAddress) {
327+ address oldSubgraphReclaimAddress = subgraphDeniedReclaimAddress;
328+ subgraphDeniedReclaimAddress = newSubgraphReclaimAddress;
329+ emit SubgraphReclaimAddressSet (oldSubgraphReclaimAddress, newSubgraphReclaimAddress);
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 RewardsReclaimedDueToEligibility (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