Skip to content
Merged
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
28 changes: 15 additions & 13 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -769,8 +769,10 @@ type Indexer @entity(immutable: false) {
indexerIndexingRewards: BigInt!
"The total amount of indexing rewards given to delegators"
delegatorIndexingRewards: BigInt!
"Percentage of indexers' own rewards received in relation to its own stake. 1 (100%) means that the indexer is receiving the exact amount that is generated by his own stake"
"[Horizon only] Percentage of indexers' own rewards received in relation to its own stake. 1 (100%) means that the indexer is receiving the exact amount that is generated by his own stake"
indexerRewardsOwnGenerationRatio: BigDecimal!
"Percentage of indexers' own rewards received in relation to its own stake. 1 (100%) means that the indexer is receiving the exact amount that is generated by his own stake. This is the indexerRewardsOwnGenerationRatio before Horizon"
legacyIndexerRewardsOwnGenerationRatio: BigDecimal!
"Whether the indexer has been transferred from L1 to L2 partially or fully"
transferredToL2: Boolean!
"Timestamp for the FIRST L1 -> L2 Transfer"
Expand Down Expand Up @@ -813,18 +815,26 @@ type Indexer @entity(immutable: false) {
delegatorShares: BigInt!
"Exchange rate of of tokens received for each share"
delegationExchangeRate: BigDecimal!
"The percent of indexing rewards generated by the total stake that the Indexer keeps for itself. In parts per million"
"[Horizon only] The percent of indexing rewards generated by the total stake that the Indexer keeps for itself. In parts per million"
indexingRewardCut: Int!
"The percent of indexing rewards generated by the delegated stake that the Indexer keeps for itself"
"The percent of indexing rewards generated by the total stake that the Indexer keeps for itself. In parts per million. This is the indexingRewardCut before Horizon"
legacyIndexingRewardCut: Int!
"[Horizon only] The percent of indexing rewards generated by the delegated stake that the Indexer keeps for itself"
indexingRewardEffectiveCut: BigDecimal!
"The percent of indexing rewards generated by the delegated stake that the Indexer keeps for itself. This is the indexingRewardEffectiveCut before Horizon"
legacyIndexingRewardEffectiveCut: BigDecimal!
"The percent of reward dilution delegators experience because of overdelegation. Overdelegated stake can't be used to generate rewards but still gets accounted while distributing the generated rewards. This causes dilution of the rewards for the rest of the pool."
overDelegationDilution: BigDecimal!
"The total amount of query fees given to delegators"
delegatorQueryFees: BigInt!
"The percent of query rebate rewards the Indexer keeps for itself. In parts per million"
"[Horizon only] The percent of query rebate rewards generated by the total stake that the Indexer keeps for itself. In parts per million"
queryFeeCut: Int!
"The percent of query rebate rewards generated by the delegated stake that the Indexer keeps for itself"
"The percent of query rebate rewards generated by the total stake that the Indexer keeps for itself. In parts per million. This is the queryFeeCut before Horizon"
legacyQueryFeeCut: Int!
"[Horizon only] The percent of query rebate rewards generated by the delegated stake that the Indexer keeps for itself"
queryFeeEffectiveCut: BigDecimal!
"The percent of query rebate rewards generated by the delegated stake that the Indexer keeps for itself. This is the queryFeeEffectiveCut before Horizon"
legacyQueryFeeEffectiveCut: BigDecimal!
"Amount of blocks a delegator chooses for the waiting period for changing their params"
delegatorParameterCooldown: Int!
"Block number for the last time the delegator updated their parameters"
Expand All @@ -834,14 +844,6 @@ type Indexer @entity(immutable: false) {

# Provisioning
provisions: [Provision!]! @derivedFrom(field: "indexer")

# Metrics
"NOT IMPLEMENTED - Total return this indexer has earned"
totalReturn: BigDecimal!
"NOT IMPLEMENTED - Annualized rate of return for the indexer"
annualizedReturn: BigDecimal! # You must multiple by 100 to get percentage
"NOT IMPLEMENTED - Staking efficiency of the indexer"
stakingEfficiency: BigDecimal!
}

type PaymentSource @entity(immutable: false) {
Expand Down
72 changes: 53 additions & 19 deletions src/mappings/helpers/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ export function createOrLoadIndexer(indexerAddress: Bytes, timestamp: BigInt ):
indexer.queryFeeRebates = BigInt.fromI32(0)
indexer.rewardsEarned = BigInt.fromI32(0)
indexer.indexerRewardsOwnGenerationRatio = BigDecimal.fromString('0')
indexer.legacyIndexerRewardsOwnGenerationRatio = BigDecimal.fromString('0')

indexer.delegatedCapacity = BigInt.fromI32(0)
indexer.tokenCapacity = BigInt.fromI32(0)
Expand All @@ -163,24 +164,24 @@ export function createOrLoadIndexer(indexerAddress: Bytes, timestamp: BigInt ):
indexer.delegatedStakeRatio = BigDecimal.fromString('0')
indexer.delegatorShares = BigInt.fromI32(0)
indexer.delegationExchangeRate = BigDecimal.fromString('1')
indexer.indexingRewardCut = 0
indexer.indexingRewardCut = 1000000
indexer.indexingRewardEffectiveCut = BigDecimal.fromString('0')
indexer.legacyIndexingRewardCut = 0
indexer.legacyIndexingRewardEffectiveCut = BigDecimal.fromString('0')
indexer.overDelegationDilution = BigDecimal.fromString('0')
indexer.delegatorIndexingRewards = BigInt.fromI32(0)
indexer.indexerIndexingRewards = BigInt.fromI32(0)
indexer.delegatorQueryFees = BigInt.fromI32(0)
indexer.queryFeeCut = 0
indexer.queryFeeCut = 1000000
indexer.queryFeeEffectiveCut = BigDecimal.fromString('0')
indexer.legacyQueryFeeCut = 0
indexer.legacyQueryFeeEffectiveCut = BigDecimal.fromString('0')
indexer.delegatorParameterCooldown = 0
indexer.lastDelegationParameterUpdate = 0
indexer.forcedClosures = 0
indexer.allocationCount = 0
indexer.totalAllocationCount = BigInt.fromI32(0)

indexer.totalReturn = BigDecimal.fromString('0')
indexer.annualizedReturn = BigDecimal.fromString('0')
indexer.stakingEfficiency = BigDecimal.fromString('0')

indexer.url = ''
indexer.geoHash = ''
indexer.rewardsDestination = Address.fromString('0x0000000000000000000000000000000000000000')
Expand Down Expand Up @@ -226,9 +227,9 @@ export function createOrLoadProvision(indexerAddress: Bytes, verifierAddress: By
provision.maxVerifierCutPending = BigInt.fromI32(0)
provision.thawingPeriod = BigInt.fromI32(0)
provision.thawingPeriodPending = BigInt.fromI32(0)
provision.queryFeeCut = BigInt.fromI32(0)
provision.indexingFeeCut = BigInt.fromI32(0)
provision.indexingRewardsCut = BigInt.fromI32(0)
provision.queryFeeCut = BigInt.fromI32(1000000)
provision.indexingFeeCut = BigInt.fromI32(1000000)
provision.indexingRewardsCut = BigInt.fromI32(1000000)
provision.indexingRewardEffectiveCut = BigInt.fromI32(0).toBigDecimal()
provision.queryFeeEffectiveCut = BigInt.fromI32(0).toBigDecimal()
provision.overDelegationDilution = BigInt.fromI32(0).toBigDecimal()
Expand Down Expand Up @@ -956,25 +957,44 @@ export function calculateDelegatedStakeRatio(indexer: Indexer): BigDecimal {
}

export function calculateIndexingRewardEffectiveCut(indexer: Indexer): BigDecimal {
let delegatorCut =
BigInt.fromI32(1000000 - indexer.indexingRewardCut).toBigDecimal() /
BigDecimal.fromString('1000000')
let delegatorCut = BigInt.fromI32(indexer.indexingRewardCut).toBigDecimal() / BigDecimal.fromString('1000000')
return indexer.delegatedStakeRatio == BigDecimal.fromString('0')
? BigDecimal.fromString('0')
: BigDecimal.fromString('1') - delegatorCut / indexer.delegatedStakeRatio
}

export function calculateQueryFeeEffectiveCut(indexer: Indexer): BigDecimal {
let delegatorCut =
BigInt.fromI32(1000000 - indexer.queryFeeCut).toBigDecimal() / BigDecimal.fromString('1000000')
let delegatorCut = BigInt.fromI32(indexer.queryFeeCut).toBigDecimal() / BigDecimal.fromString('1000000')
return indexer.delegatedStakeRatio == BigDecimal.fromString('0')
? BigDecimal.fromString('0')
: BigDecimal.fromString('1') - delegatorCut / indexer.delegatedStakeRatio
}

export function calculateIndexerRewardOwnGenerationRatio(indexer: Indexer): BigDecimal {
let rewardCut =
BigInt.fromI32(indexer.indexingRewardCut).toBigDecimal() / BigDecimal.fromString('1000000')
BigInt.fromI32(1000000 -indexer.indexingRewardCut).toBigDecimal() / BigDecimal.fromString('1000000')
return indexer.ownStakeRatio == BigDecimal.fromString('0')
? BigDecimal.fromString('0')
: rewardCut / indexer.ownStakeRatio
}

export function calculateLegacyIndexingRewardEffectiveCut(indexer: Indexer): BigDecimal {
let delegatorCut = BigInt.fromI32(indexer.legacyIndexingRewardCut).toBigDecimal() / BigDecimal.fromString('1000000')
return indexer.delegatedStakeRatio == BigDecimal.fromString('0')
? BigDecimal.fromString('0')
: BigDecimal.fromString('1') - delegatorCut / indexer.delegatedStakeRatio
}

export function calculateLegacyQueryFeeEffectiveCut(indexer: Indexer): BigDecimal {
let delegatorCut = BigInt.fromI32(indexer.legacyQueryFeeCut).toBigDecimal() / BigDecimal.fromString('1000000')
return indexer.delegatedStakeRatio == BigDecimal.fromString('0')
? BigDecimal.fromString('0')
: BigDecimal.fromString('1') - delegatorCut / indexer.delegatedStakeRatio
}

export function calculateLegacyIndexerRewardOwnGenerationRatio(indexer: Indexer): BigDecimal {
let rewardCut =
BigInt.fromI32(1000000 - indexer.legacyIndexingRewardCut).toBigDecimal() / BigDecimal.fromString('1000000')
return indexer.ownStakeRatio == BigDecimal.fromString('0')
? BigDecimal.fromString('0')
: rewardCut / indexer.ownStakeRatio
Expand Down Expand Up @@ -1004,6 +1024,18 @@ export function updateAdvancedIndexerMetrics(indexer: Indexer): Indexer {
return indexer as Indexer
}

export function updateLegacyAdvancedIndexerMetrics(indexer: Indexer): Indexer {
indexer.ownStakeRatio = calculateOwnStakeRatio(indexer as Indexer)
indexer.delegatedStakeRatio = calculateDelegatedStakeRatio(indexer as Indexer)
indexer.legacyIndexingRewardEffectiveCut = calculateLegacyIndexingRewardEffectiveCut(indexer as Indexer)
indexer.legacyQueryFeeEffectiveCut = calculateLegacyQueryFeeEffectiveCut(indexer as Indexer)
indexer.legacyIndexerRewardsOwnGenerationRatio = calculateLegacyIndexerRewardOwnGenerationRatio(
indexer as Indexer,
)
indexer.overDelegationDilution = calculateOverdelegationDilution(indexer as Indexer)
return indexer as Indexer
}

export function calculateOwnStakeRatioForProvision(provision: Provision): BigDecimal {
let totalTokens = provision.tokensProvisioned.plus(provision.delegatedTokens)
return totalTokens == BigInt.fromI32(0)
Expand All @@ -1020,7 +1052,7 @@ export function calculateDelegatedStakeRatioForProvision(provision: Provision):

export function calculateIndexingRewardEffectiveCutForProvision(provision: Provision): BigDecimal {
let delegatorCut =
provision.indexingRewardsCut.toBigDecimal() /
BigInt.fromI32(1000000).minus(provision.indexingRewardsCut).toBigDecimal() /
BigDecimal.fromString('1000000')
return provision.delegatedStakeRatio == BigDecimal.fromString('0')
? BigDecimal.fromString('0')
Expand All @@ -1029,15 +1061,17 @@ export function calculateIndexingRewardEffectiveCutForProvision(provision: Provi

export function calculateQueryFeeEffectiveCutForProvision(provision: Provision): BigDecimal {
let delegatorCut =
provision.queryFeeCut.toBigDecimal() / BigDecimal.fromString('1000000')
BigInt.fromI32(1000000).minus(provision.queryFeeCut).toBigDecimal() /
BigDecimal.fromString('1000000')
return provision.delegatedStakeRatio == BigDecimal.fromString('0')
? BigDecimal.fromString('0')
: BigDecimal.fromString('1') - delegatorCut / provision.delegatedStakeRatio
}

export function calculateIndexerRewardOwnGenerationRatioForProvision(provision: Provision): BigDecimal {
let delegatorCut =
provision.indexingRewardsCut.toBigDecimal() / BigDecimal.fromString('1000000')
BigInt.fromI32(1000000).minus(provision.indexingRewardsCut).toBigDecimal() /
BigDecimal.fromString('1000000')
return provision.ownStakeRatio == BigDecimal.fromString('0')
? BigDecimal.fromString('0')
: (BigDecimal.fromString('1') - delegatorCut) / provision.ownStakeRatio
Expand Down Expand Up @@ -1215,7 +1249,7 @@ export function batchUpdateSubgraphSignalledTokens(deployment: SubgraphDeploymen
}
}

export function convertBigIntSubgraphIDToBase58(bigIntRepresentation: BigInt): String {
export function convertBigIntSubgraphIDToBase58(bigIntRepresentation: BigInt): string {
// Might need to unpad the BigInt since `fromUnsignedBytes` pads one byte with a zero.
// Although for the events where the uint256 is provided, we probably don't need to unpad.
let hexString = bigIntRepresentation.toHexString()
Expand Down
17 changes: 14 additions & 3 deletions src/mappings/horizonStaking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,21 @@ export function handleOperatorSet(event: OperatorSet): void {

export function handleDelegationFeeCutSet(event: DelegationFeeCutSet): void {
let provision = createOrLoadProvision(event.params.serviceProvider, event.params.verifier, event.block.timestamp)
provision.queryFeeCut = event.params.paymentType == 0 ? event.params.feeCut : provision.queryFeeCut
provision.indexingFeeCut = event.params.paymentType == 1 ? event.params.feeCut : provision.indexingFeeCut
provision.indexingRewardsCut = event.params.paymentType == 2 ? event.params.feeCut : provision.indexingRewardsCut

// Before horizon the cuts represented how much the indexer took home. After horizon they now represent how much the delegators get
// To avoid confusion and more changes on explorer we invert the meaning here to keep it consistent.
let invertedCut = BigInt.fromI32(1_000_000).minus(event.params.feeCut)
provision.queryFeeCut = event.params.paymentType == 0 ? invertedCut : provision.queryFeeCut
provision.indexingFeeCut = event.params.paymentType == 1 ? invertedCut : provision.indexingFeeCut
provision.indexingRewardsCut = event.params.paymentType == 2 ? invertedCut : provision.indexingRewardsCut
provision = updateAdvancedProvisionMetrics(provision as Provision)
provision.save()

let indexer = Indexer.load(event.params.serviceProvider.toHexString())!
indexer.indexingRewardCut = event.params.paymentType == 2 ? invertedCut.toI32() : indexer.indexingRewardCut
indexer.queryFeeCut = event.params.paymentType == 0 ? invertedCut.toI32() : indexer.queryFeeCut
indexer = updateAdvancedIndexerMetrics(indexer as Indexer)
indexer.save()
}

export function handleProvisionSlashed(event: ProvisionSlashed): void {
Expand Down
6 changes: 3 additions & 3 deletions src/mappings/l1staking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
} from '../types/L1Staking/L1Staking'

import { Indexer, DelegatedStake, GraphNetwork } from '../types/schema'
import { calculateCapacities, createOrLoadGraphNetwork, joinID, updateAdvancedIndexerMetrics, updateDelegationExchangeRate } from './helpers/helpers'
import { calculateCapacities, createOrLoadGraphNetwork, joinID, updateLegacyAdvancedIndexerMetrics, updateDelegationExchangeRate } from './helpers/helpers'

/*
/// @dev Emitted when an indexer transfers their stake to L2.
Expand Down Expand Up @@ -34,7 +34,7 @@ export function handleIndexerStakeTransferredToL2(event: IndexerStakeTransferred
indexer.lastTransferredToL2At = event.block.timestamp
indexer.lastTransferredToL2AtBlockNumber = event.block.number
indexer.lastTransferredToL2AtTx = event.transaction.hash.toHexString()
indexer = updateAdvancedIndexerMetrics(indexer as Indexer)
indexer = updateLegacyAdvancedIndexerMetrics(indexer as Indexer)
indexer = calculateCapacities(indexer as Indexer)
indexer.save()

Expand Down Expand Up @@ -84,7 +84,7 @@ export function handleDelegationTransferredToL2(event: DelegationTransferredToL2
if (indexer.delegatorShares != BigInt.fromI32(0)) {
indexer = updateDelegationExchangeRate(indexer as Indexer)
}
indexer = updateAdvancedIndexerMetrics(indexer as Indexer)
indexer = updateLegacyAdvancedIndexerMetrics(indexer as Indexer)
indexer = calculateCapacities(indexer as Indexer)
indexer.save()

Expand Down
6 changes: 3 additions & 3 deletions src/mappings/rewardsManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
import {
createOrLoadSubgraphDeployment,
createOrLoadEpoch,
updateAdvancedIndexerMetrics,
updateLegacyAdvancedIndexerMetrics,
updateDelegationExchangeRate,
createOrLoadGraphNetwork
} from './helpers/helpers'
Expand All @@ -28,7 +28,7 @@ export function handleRewardsAssigned(event: RewardsAssigned): void {
indexer.delegatedTokens == BigInt.fromI32(0)
? event.params.amount
: event.params.amount
.times(BigInt.fromI32(indexer.indexingRewardCut))
.times(BigInt.fromI32(indexer.legacyIndexingRewardCut))
.div(BigInt.fromI32(1000000))

let delegatorIndexingRewards = event.params.amount.minus(indexerIndexingRewards)
Expand All @@ -40,7 +40,7 @@ export function handleRewardsAssigned(event: RewardsAssigned): void {
if (indexer.delegatorShares != BigInt.fromI32(0)) {
indexer = updateDelegationExchangeRate(indexer as Indexer)
}
indexer = updateAdvancedIndexerMetrics(indexer as Indexer)
indexer = updateLegacyAdvancedIndexerMetrics(indexer as Indexer)
indexer.save()

// update allocation
Expand Down
Loading