Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions abis/RewardsManagerStitched.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,31 @@
"name": "RewardsAssigned",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "indexer",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "allocationID",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "HorizonRewardsAssigned",
"type": "event"
},
{
"anonymous": false,
"inputs": [
Expand Down
154 changes: 100 additions & 54 deletions src/mappings/rewardsManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Address, BigInt } from '@graphprotocol/graph-ts'
import { Indexer, Allocation, SubgraphDeployment } from '../types/schema'
import {
RewardsAssigned,
HorizonRewardsAssigned,
ParameterUpdated,
RewardsManagerStitched as RewardsManager,
RewardsDenylistUpdated,
Expand All @@ -16,22 +17,109 @@ import {
import { addresses } from '../../config/addresses'

export function handleRewardsAssigned(event: RewardsAssigned): void {
let graphNetwork = createOrLoadGraphNetwork(event.block.number, event.address)
let indexerID = event.params.indexer.toHexString()
processRewardsAssigned(
event.params.indexer,
event.params.allocationID.toHexString(),
event.params.amount,
event.block.number,
event.block.timestamp,
event.address,
)
}

/**
* @dev handleHorizonRewardsAssigned
* - Handles the HorizonRewardsAssigned event emitted after Horizon upgrade
* - Only processes rewards for legacy allocations (created via old Staking contract)
* - New allocations (via SubgraphService) are handled by IndexingRewardsCollected instead
*/
export function handleHorizonRewardsAssigned(event: HorizonRewardsAssigned): void {
let allocationID = event.params.allocationID.toHexString()
let allocation = Allocation.load(allocationID)

// Skip if allocation doesn't exist or is not a legacy allocation
// New allocations have their rewards tracked via IndexingRewardsCollected from SubgraphService
if (allocation == null || !allocation.isLegacy) {
return
}

processRewardsAssigned(
event.params.indexer,
allocationID,
event.params.amount,
event.block.number,
event.block.timestamp,
event.address,
)
}

/**
* @dev handleParameterUpdated
* - handlers updating all parameters
*/
export function handleParameterUpdated(event: ParameterUpdated): void {
let parameter = event.params.param
let graphNetwork = createOrLoadGraphNetwork(event.block.number, event.address)
let rewardsManager = RewardsManager.bind(event.address as Address)

if (parameter == 'issuanceRate') {
graphNetwork.networkGRTIssuance = rewardsManager.issuanceRate()
} else if (parameter == 'issuancePerBlock') {
graphNetwork.networkGRTIssuancePerBlock = rewardsManager.issuancePerBlock()
} else if (parameter == 'subgraphAvailabilityOracle') {
graphNetwork.subgraphAvailabilityOracle = rewardsManager.subgraphAvailabilityOracle()
}
graphNetwork.save()
}

// export function handleImplementationUpdated(event: ImplementationUpdated): void {
// let graphNetwork = GraphNetwork.load('1')
// let implementations = graphNetwork.rewardsManagerImplementations
// implementations.push(event.params.newImplementation)
// graphNetwork.rewardsManagerImplementations = implementations
// graphNetwork.save()
// }

export function handleRewardsDenyListUpdated(event: RewardsDenylistUpdated): void {
let subgraphDeployment = SubgraphDeployment.load(event.params.subgraphDeploymentID.toHexString())
if (subgraphDeployment != null) {
if (event.params.sinceBlock.toI32() == 0) {
subgraphDeployment.deniedAt = 0
} else {
subgraphDeployment.deniedAt = event.params.sinceBlock.toI32()
}
subgraphDeployment.save()
}
// We might need to handle the case where the subgraph deployment doesn't exists later
}

/**
* @dev processRewardsAssigned
* - Common logic for processing rewards assigned events (both legacy RewardsAssigned and HorizonRewardsAssigned)
*/
function processRewardsAssigned(
indexerAddress: Address,
allocationID: string,
amount: BigInt,
blockNumber: BigInt,
blockTimestamp: BigInt,
eventAddress: Address,
): void {
let graphNetwork = createOrLoadGraphNetwork(blockNumber, eventAddress)
let indexerID = indexerAddress.toHexString()

// update indexer
let indexer = Indexer.load(indexerID)!
indexer.rewardsEarned = indexer.rewardsEarned.plus(event.params.amount)
indexer.rewardsEarned = indexer.rewardsEarned.plus(amount)
// If the delegation pool has zero tokens, the contracts don't give away any rewards
let indexerIndexingRewards =
indexer.delegatedTokens == BigInt.fromI32(0)
? event.params.amount
: event.params.amount
? amount
: amount
.times(BigInt.fromI32(indexer.legacyIndexingRewardCut))
.div(BigInt.fromI32(1000000))

let delegatorIndexingRewards = event.params.amount.minus(indexerIndexingRewards)
let delegatorIndexingRewards = amount.minus(indexerIndexingRewards)

indexer.delegatorIndexingRewards = indexer.delegatorIndexingRewards.plus(delegatorIndexingRewards)
indexer.indexerIndexingRewards = indexer.indexerIndexingRewards.plus(indexerIndexingRewards)
Expand All @@ -46,16 +134,16 @@ export function handleRewardsAssigned(event: RewardsAssigned): void {
// update allocation
// no status updated, Claimed happens when RebateClaimed, and it is done
let allocation = Allocation.load(allocationID)!
allocation.indexingRewards = allocation.indexingRewards.plus(event.params.amount)
allocation.indexingRewards = allocation.indexingRewards.plus(amount)
allocation.indexingIndexerRewards = allocation.indexingIndexerRewards.plus(indexerIndexingRewards)
allocation.indexingDelegatorRewards = allocation.indexingDelegatorRewards.plus(
delegatorIndexingRewards,
)
allocation.save()

// Update epoch
let epoch = createOrLoadEpoch(addresses.isL1 ? event.block.number : graphNetwork.currentL1BlockNumber!, graphNetwork)
epoch.totalRewards = epoch.totalRewards.plus(event.params.amount)
let epoch = createOrLoadEpoch(addresses.isL1 ? blockNumber : graphNetwork.currentL1BlockNumber!, graphNetwork)
epoch.totalRewards = epoch.totalRewards.plus(amount)
epoch.totalIndexerRewards = epoch.totalIndexerRewards.plus(indexerIndexingRewards)
epoch.totalDelegatorRewards = epoch.totalDelegatorRewards.plus(delegatorIndexingRewards)
epoch.save()
Expand All @@ -64,12 +152,10 @@ export function handleRewardsAssigned(event: RewardsAssigned): void {
let subgraphDeploymentID = allocation.subgraphDeployment
let subgraphDeployment = createOrLoadSubgraphDeployment(
subgraphDeploymentID,
event.block.timestamp,
blockTimestamp,
graphNetwork,
)
subgraphDeployment.indexingRewardAmount = subgraphDeployment.indexingRewardAmount.plus(
event.params.amount,
)
subgraphDeployment.indexingRewardAmount = subgraphDeployment.indexingRewardAmount.plus(amount)
subgraphDeployment.indexingIndexerRewardAmount = subgraphDeployment.indexingIndexerRewardAmount.plus(
indexerIndexingRewards,
)
Expand All @@ -79,7 +165,7 @@ export function handleRewardsAssigned(event: RewardsAssigned): void {
subgraphDeployment.save()

// update graph network
graphNetwork.totalIndexingRewards = graphNetwork.totalIndexingRewards.plus(event.params.amount)
graphNetwork.totalIndexingRewards = graphNetwork.totalIndexingRewards.plus(amount)
graphNetwork.totalIndexingIndexerRewards = graphNetwork.totalIndexingIndexerRewards.plus(
indexerIndexingRewards,
)
Expand All @@ -89,43 +175,3 @@ export function handleRewardsAssigned(event: RewardsAssigned): void {
graphNetwork.totalDelegatedTokens = graphNetwork.totalDelegatedTokens.plus(delegatorIndexingRewards)
graphNetwork.save()
}

/**
* @dev handleParameterUpdated
* - handlers updating all parameters
*/
export function handleParameterUpdated(event: ParameterUpdated): void {
let parameter = event.params.param
let graphNetwork = createOrLoadGraphNetwork(event.block.number, event.address)
let rewardsManager = RewardsManager.bind(event.address as Address)

if (parameter == 'issuanceRate') {
graphNetwork.networkGRTIssuance = rewardsManager.issuanceRate()
} else if (parameter == 'issuancePerBlock') {
graphNetwork.networkGRTIssuancePerBlock = rewardsManager.issuancePerBlock()
} else if (parameter == 'subgraphAvailabilityOracle') {
graphNetwork.subgraphAvailabilityOracle = rewardsManager.subgraphAvailabilityOracle()
}
graphNetwork.save()
}

// export function handleImplementationUpdated(event: ImplementationUpdated): void {
// let graphNetwork = GraphNetwork.load('1')
// let implementations = graphNetwork.rewardsManagerImplementations
// implementations.push(event.params.newImplementation)
// graphNetwork.rewardsManagerImplementations = implementations
// graphNetwork.save()
// }

export function handleRewardsDenyListUpdated(event: RewardsDenylistUpdated): void {
let subgraphDeployment = SubgraphDeployment.load(event.params.subgraphDeploymentID.toHexString())
if (subgraphDeployment != null) {
if (event.params.sinceBlock.toI32() == 0) {
subgraphDeployment.deniedAt = 0
} else {
subgraphDeployment.deniedAt = event.params.sinceBlock.toI32()
}
subgraphDeployment.save()
}
// We might need to handle the case where the subgraph deployment doesn't exists later
}
2 changes: 2 additions & 0 deletions subgraph.template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,8 @@ dataSources:
eventHandlers:
- event: RewardsAssigned(indexed address,indexed address,uint256,uint256)
handler: handleRewardsAssigned
- event: HorizonRewardsAssigned(indexed address,indexed address,uint256)
handler: handleHorizonRewardsAssigned
- event: RewardsDenylistUpdated(indexed bytes32,uint256)
handler: handleRewardsDenyListUpdated
# - event: ImplementationUpdated(address,address)
Expand Down
Loading