diff --git a/root/.gitignore b/root/.gitignore index 74a16f9..4049558 100644 --- a/root/.gitignore +++ b/root/.gitignore @@ -1 +1,2 @@ subgraph.yaml +src/network.json diff --git a/root/package.json b/root/package.json index e0c4a54..69c729b 100644 --- a/root/package.json +++ b/root/package.json @@ -7,8 +7,8 @@ "graph": "graph", "codegen": "graph codegen", "build": "graph build", - "prepare:mainnet": "mustache config/mainnet.json subgraph.template.yaml > subgraph.yaml", - "prepare:goerli": "mustache config/goerli.json subgraph.template.yaml > subgraph.yaml", + "prepare:mainnet": "mustache config/mainnet.json subgraph.template.yaml > subgraph.yaml && cp config/mainnet.json src/network.json", + "prepare:goerli": "mustache config/goerli.json subgraph.template.yaml > subgraph.yaml && cp config/goerli.json src/network.json", "deploy": "graph deploy --node https://api.thegraph.com/deploy/ --ipfs https://api.thegraph.com/ipfs/ maticnetwork/mumbai-root-subgraphs", "create-local": "graph create --node http://localhost:8020/ maticnetwork/mumbai-root-subgraphs", "remove-local": "graph remove --node http://localhost:8020/ maticnetwork/mumbai-root-subgraphs", diff --git a/root/schema.graphql b/root/schema.graphql index 5f27f23..762a40c 100644 --- a/root/schema.graphql +++ b/root/schema.graphql @@ -7,6 +7,8 @@ type Checkpoint @entity { start: BigInt! end: BigInt! root: Bytes! + transactionHash: Bytes! + timestamp: BigInt! } type StateSync @entity { @@ -72,16 +74,27 @@ type TokenMapping @entity { type Validator @entity { id: ID! validatorId: BigInt! + owner: Bytes! signer: Bytes! signerPubKey: Bytes! liquidatedRewards: BigInt! activationEpoch: BigInt! deactivationEpoch: BigInt! totalStaked: BigInt! + selfStake: BigInt! + delegatedStake: BigInt! commissionRate: BigInt! nonce: BigInt! - unstaked: Boolean! + # Meaning of status codes + # + # 0 : Staked + # 1 : Unstaked + # 2 : Jailed + # 3 : Unjailed + status: Int! jailEndEpoch: BigInt! + auctionAmount: BigInt! + isInAuction: Bool! } type Delegator @entity { diff --git a/root/src/mappings/checkpoint.ts b/root/src/mappings/checkpoint.ts index 0c4f6fe..566f065 100644 --- a/root/src/mappings/checkpoint.ts +++ b/root/src/mappings/checkpoint.ts @@ -17,6 +17,8 @@ export function handleNewHeaderBlock(event: NewHeaderBlock): void { entity.start = event.params.start entity.end = event.params.end entity.root = event.params.root + entity.transactionHash = event.transaction.hash + entity.timestamp = event.block.timestamp // save entity entity.save() diff --git a/root/src/mappings/staking-info.ts b/root/src/mappings/staking-info.ts index 54bcd89..c68584a 100644 --- a/root/src/mappings/staking-info.ts +++ b/root/src/mappings/staking-info.ts @@ -1,9 +1,9 @@ import { Address, BigInt } from '@graphprotocol/graph-ts' -import { - Delegator, - Validator, - Topup, - StakingParams, +import { + Delegator, + Validator, + Topup, + StakingParams, } from '../../generated/schema' import { ClaimFee, @@ -26,8 +26,18 @@ import { UnstakeInit, Unstaked, UpdateCommissionRate, + StartAuction, + ConfirmAuction, } from '../../generated/StakingInfo/StakingInfo' +// using network address from config file +// to be passed to client when creating instance +// of contract, StakingNft, for calling `ownerOf` function +import NetworkConfig from '../network.json' + +// This is the contract we're going to interact with when `Staked` event is emitted +import {StakingNft} from '../../generated/StakingNft/StakingNft' + const STAKING_PARAMS_ID = 'staking:params' @@ -42,12 +52,16 @@ function loadValidator(validatorId: BigInt): Validator { entity = new Validator(id) entity.validatorId = validatorId entity.totalStaked = BigInt.fromI32(0) + entity.selfStake = BigInt.fromI32(0) + entity.delegatedStake = BigInt.fromI32(0) entity.nonce = BigInt.fromI32(0) entity.deactivationEpoch = BigInt.fromI32(0) entity.jailEndEpoch = BigInt.fromI32(0) entity.liquidatedRewards = BigInt.fromI32(0) - entity.unstaked = false + entity.status = 0 entity.commissionRate = BigInt.fromI32(0) + entity.auctionAmount = BigInt.fromI32(0) + entity.isInAuction = false } return entity as Validator @@ -58,9 +72,18 @@ export function handleStaked(event: Staked): void { validator.signer = event.params.signer validator.activationEpoch = event.params.activationEpoch + + // Keeping NFT owner address, to be helpful while responding + // client queries in staking API + let nft = StakingNft.bind(Address.fromString(NetworkConfig.contracts.stakingNft.address)) + validator.owner = nft.ownerOf(event.params.validatorId) + validator.totalStaked = event.params.total + validator.selfStake = event.params.amount + validator.signerPubKey = event.params.signerPubkey validator.nonce = event.params.nonce + validator.status = 0 // save entity validator.save() @@ -70,7 +93,8 @@ export function handleUnstaked(event: Unstaked): void { let validator = loadValidator(event.params.validatorId) // update unstaked status - validator.unstaked = true + validator.status = 1 + validator.selfStake = 0 validator.save() } @@ -105,6 +129,7 @@ export function handleJailed(event: Jailed): void { // save entity with jail end epoch validator.jailEndEpoch = event.params.exitEpoch + validator.status = 2 validator.save() } @@ -113,6 +138,7 @@ export function handleUnJailed(event: UnJailed): void { // save entity with jail end epoch validator.jailEndEpoch = BigInt.fromI32(0) + validator.status = 3 validator.save() } @@ -122,6 +148,14 @@ export function handleStakeUpdate(event: StakeUpdate): void { // update total staked and nonce validator.totalStaked = event.params.newAmount validator.nonce = event.params.nonce + + // Updating validator's self stake + // + // We only get `totalStake` emitted from contract + // which is why we're subtracting delegated stake + // from totalStaked + validator.selfStake = validator.totalStaked.minus(validator.delegatedStake) + validator.save() } @@ -179,6 +213,14 @@ export function handleShareMinted(event: ShareMinted): void { // save entity delegator.save() + + // -- Also updating delegated stake for validator + let validator = loadValidator(event.params.validatorId) + + validator.delegatedStake = validator.delegatedStake.plus(event.params.amount) + + validator.save() + // -- Saving updation } export function handleShareBurned(event: ShareBurned): void { @@ -193,6 +235,14 @@ export function handleShareBurned(event: ShareBurned): void { // save entity delegator.save() + + // -- Also updating delegated stake for validator + let validator = loadValidator(event.params.validatorId) + + validator.delegatedStake = validator.delegatedStake.minus(event.params.amount) + + validator.save() + // -- Saving updation } export function handleDelegatorUnstaked(event: DelegatorUnstaked): void { @@ -296,3 +346,25 @@ export function handleThresholdChange(event: ThresholdChange): void { stakingParams.validatorThreshold = event.params.newThreshold stakingParams.save() } + +export function handleStartAuction(event: StartAuction): void { + + let validator = loadValidator(event.params.validatorId) + + validator.auctionAmount = event.params.auctionAmount + validator.isInAuction = true + + validator.save() + +} + +export function handleConfirmAuction(event: ConfirmAuction): void { + + let validator = loadValidator(event.params.oldValidatorId) + + validator.auctionAmount = BigInt.fromI32(0) + validator.isInAuction = false + + validator.save() + +} diff --git a/root/subgraph.template.yaml b/root/subgraph.template.yaml index 3ec3f65..043fb9a 100644 --- a/root/subgraph.template.yaml +++ b/root/subgraph.template.yaml @@ -126,8 +126,6 @@ dataSources: handler: handleClaimFee - event: ClaimRewards(indexed uint256,indexed uint256,indexed uint256) handler: handleClaimRewards - # - event: ConfirmAuction(indexed uint256,indexed uint256,indexed uint256) - # handler: handleConfirmAuction - event: DelegatorClaimedRewards(indexed uint256,indexed address,indexed uint256) handler: handleDelegatorClaimedRewards # - event: DelegatorRestaked(indexed uint256,indexed address,indexed uint256) @@ -156,7 +154,6 @@ dataSources: handler: handleStakeUpdate - event: Staked(indexed address,indexed uint256,uint256,indexed uint256,uint256,uint256,bytes) handler: handleStaked - # - event: StartAuction(indexed uint256,indexed uint256,indexed uint256) - event: ThresholdChange(uint256,uint256) handler: handleThresholdChange - event: TopUpFee(indexed address,indexed uint256) @@ -169,6 +166,10 @@ dataSources: handler: handleUnstaked - event: UpdateCommissionRate(indexed uint256,indexed uint256,indexed uint256) handler: handleUpdateCommissionRate + - event: StartAuction(indexed uint256,indexed uint256,indexed uint256) + handler: handleStartAuction + - event: ConfirmAuction(indexed uint256,indexed uint256,indexed uint256) + handler: handleConfirmAuction file: ./src/mappings/staking-info.ts - kind: ethereum/contract