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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@ All notable changes to the DTF Index Subgraph will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.8.7] - 2026-02-24

### Added
- `RewardClaim` entity to track `RewardsClaimed` events from StakingVault
- New `rewardClaims` derived field on `Account`
- Event handler registered in `StakingToken` template
- `queueAccount`, `executionAccount`, `cancellationAccount` fields on `Proposal` entity
- Tracks which account queued, executed, or cancelled a proposal (via `event.transaction.from`)

## [1.8.6-test1] - 2025-12-18

### Added
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "dtf-index-subgraph",
"license": "UNLICENSED",
"version": "1.8.6",
"version": "1.8.7",
"scripts": {
"codegen": "graph codegen",
"build": "graph build",
Expand Down
21 changes: 21 additions & 0 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -813,6 +813,9 @@ type Account @entity(immutable: false) {
" Locks "
locks: [Lock!]! @derivedFrom(field: "account")

" Reward claims "
rewardClaims: [RewardClaim!]! @derivedFrom(field: "account")

" Token balances snapshot that this account holds "
balancesSnapshot: [AccountBalanceDailySnapshot!]!
@derivedFrom(field: "account")
Expand Down Expand Up @@ -1038,6 +1041,8 @@ type Proposal @entity(immutable: false) {
voteEnd: BigInt!
"Transaction hash of the proposal being queued"
queueTxnHash: String
"Account that queued the proposal"
queueAccount: Account
"Block number proposal was queued in"
queueBlock: BigInt
"Timestamp of block proposal was queued in"
Expand All @@ -1046,12 +1051,16 @@ type Proposal @entity(immutable: false) {
executionETA: BigInt
"Transaction hash of the proposal execution"
executionTxnHash: String
"Account that executed the proposal"
executionAccount: Account
"Block number proposal was executed in"
executionBlock: BigInt
"Timestamp of block proposal was executed in"
executionTime: BigInt
"Transaction hash of the proposal cancellation"
cancellationTxnHash: String
"Account that cancelled the proposal"
cancellationAccount: Account
"Block number proposal was canceled in"
cancellationBlock: BigInt
"Timestamp of block proposal was canceled in"
Expand Down Expand Up @@ -1223,6 +1232,18 @@ type Lock @entity(immutable: false) {
claimedTxnHash: String
}

type RewardClaim @entity(immutable: true) {
" { StakingToken Address }-{ Transaction Hash }-{ Log Index } "
id: ID!
token: StakingToken!
account: Account!
rewardToken: Token!
amount: BigInt!
blockNumber: BigInt!
timestamp: BigInt!
txnHash: String!
}

type Delegate @entity(immutable: false) {
"A Delegate is any address that has been delegated with voting tokens by a token holder, id is {stTokenAddress}-{delegateAddress}"
id: ID!
Expand Down
4 changes: 4 additions & 0 deletions src/governance/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
ProposalState,
VoteChoice,
} from "../utils/constants";
import { getOrCreateAccount } from "../account/mappings";
import { getOrCreateStakingToken } from "../utils/getters";

export const SECONDS_PER_DAY = 60 * 60 * 24;
Expand Down Expand Up @@ -227,6 +228,7 @@ export function _handleProposalCanceled(
const proposal = getProposal(proposalId);
proposal.state = ProposalState.CANCELED;
proposal.cancellationTxnHash = event.transaction.hash.toHexString();
proposal.cancellationAccount = getOrCreateAccount(event.transaction.from).id;
proposal.cancellationBlock = event.block.number;
proposal.cancellationTime = event.block.timestamp;
proposal.save();
Expand All @@ -245,6 +247,7 @@ export function _handleProposalExecuted(
const proposal = getProposal(proposalId);
proposal.state = ProposalState.EXECUTED;
proposal.executionTxnHash = event.transaction.hash.toHexString();
proposal.executionAccount = getOrCreateAccount(event.transaction.from).id;
proposal.executionBlock = event.block.number;
proposal.executionTime = event.block.timestamp;
proposal.save();
Expand Down Expand Up @@ -275,6 +278,7 @@ export function _handleProposalQueued(
const proposal = getProposal(proposalId.toString());
proposal.state = ProposalState.QUEUED;
proposal.queueTxnHash = event.transaction.hash.toHexString();
proposal.queueAccount = getOrCreateAccount(event.transaction.from).id;
proposal.queueBlock = event.block.number;
proposal.queueTime = event.block.timestamp;
proposal.executionETA = eta;
Expand Down
26 changes: 26 additions & 0 deletions src/staking-token/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Address, BigInt, ethereum } from "@graphprotocol/graph-ts";
import {
AccountBalance,
Lock,
RewardClaim,
StakingTokenRewards,
UnstakingManager,
} from "../../generated/schema";
Expand Down Expand Up @@ -95,6 +96,31 @@ export function _handleRewardTokenRemoved(
}
}

export function _handleRewardsClaimed(
stakingTokenAddress: Address,
userAddress: Address,
rewardTokenAddress: Address,
amount: BigInt,
event: ethereum.Event
): void {
let id =
stakingTokenAddress.toHexString() +
"-" +
event.transaction.hash.toHexString() +
"-" +
event.logIndex.toString();

let claim = new RewardClaim(id);
claim.token = getOrCreateStakingToken(stakingTokenAddress).id;
claim.account = getOrCreateAccount(userAddress).id;
claim.rewardToken = getOrCreateToken(rewardTokenAddress, TokenType.ASSET).id;
claim.amount = amount;
claim.blockNumber = event.block.number;
claim.timestamp = event.block.timestamp;
claim.txnHash = event.transaction.hash.toHexString();
claim.save();
}

export function _handleDelegateChanged(
delegator: string,
fromDelegate: string,
Expand Down
12 changes: 12 additions & 0 deletions src/staking-token/mappings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
DelegateChanged,
DelegateVotesChanged,
OwnershipTransferred,
RewardsClaimed,
RewardTokenAdded,
RewardTokenRemoved,
Transfer,
Expand All @@ -19,6 +20,7 @@ import {
_handleLockClaimed,
_handleLockCreated,
_handleOwnershipTransferred,
_handleRewardsClaimed,
_handleRewardTokenAdded,
_handleRewardTokenRemoved,
} from "./handlers";
Expand Down Expand Up @@ -79,6 +81,16 @@ export function handleOwnershipTransferred(event: OwnershipTransferred): void {
);
}

export function handleRewardsClaimed(event: RewardsClaimed): void {
_handleRewardsClaimed(
event.address,
event.params.user,
event.params.rewardToken,
event.params.amount,
event
);
}

export function handleTransfer(event: Transfer): void {
_handleTransfer(
event.params.from,
Expand Down
2 changes: 2 additions & 0 deletions subgraph.yaml.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ templates:
handler: handleTransfer
- event: OwnershipTransferred(indexed address,indexed address)
handler: handleOwnershipTransferred
- event: RewardsClaimed(address,address,uint256)
handler: handleRewardsClaimed
file: ./src/staking-token/mappings.ts
- name: UnstakingManager
kind: ethereum/contract
Expand Down