Skip to content
Draft
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
787 changes: 787 additions & 0 deletions apps/indexer/abis/ens-governor.json

Large diffs are not rendered by default.

840 changes: 840 additions & 0 deletions apps/indexer/abis/ens-token.json

Large diffs are not rendered by default.

37 changes: 37 additions & 0 deletions apps/indexer/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: anticapture-indexer
description: Anticapture DAO governance indexer
field_selection:
transaction_fields:
- hash
- to
- from

contracts:
- name: ENSToken
abi_file_path: abis/ens-token.json
handler: src/eventHandlers/ENSToken.ts
events:
- event: "Transfer(address indexed from, address indexed to, uint256 value)"
- event: "DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate)"
- event: "DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance)"
- name: ENSGovernor
abi_file_path: abis/ens-governor.json
handler: src/eventHandlers/ENSGovernor.ts
events:
- event: "ProposalCreated(uint256 proposalId, address proposer, address[] targets, uint256[] values, string[] signatures, bytes[] calldatas, uint256 startBlock, uint256 endBlock, string description)"
- event: "VoteCast(address indexed voter, uint256 proposalId, uint8 support, uint256 weight, string reason)"
- event: "ProposalCanceled(uint256 proposalId)"
- event: "ProposalExecuted(uint256 proposalId)"
- event: "ProposalQueued(uint256 proposalId, uint256 eta)"

networks:
- id: 1
hypersync_config:
url: https://eth.hypersync.xyz
start_block: 9380410
contracts:
- name: ENSToken
address: "0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72"
- name: ENSGovernor
address: "0x323a76393544d5ecca80cd6ef2a560c6a395b7e3"
start_block: 13533772
2 changes: 2 additions & 0 deletions apps/indexer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"private": true,
"scripts": {
"dev": "ponder dev",
"envio": "envio dev",
"start": "ponder start --views-schema=anticapture --schema=$RAILWAY_DEPLOYMENT_ID",
"db:list": "ponder db list",
"db:prune": "ponder db prune",
Expand All @@ -24,6 +25,7 @@
"@types/node": "^20.16.5",
"@types/pg": "^8.15.6",
"dotenv": "^16.5.0",
"envio": "^2.32.12",
"eslint": "^9",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.1",
Expand Down
202 changes: 202 additions & 0 deletions apps/indexer/schema.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
enum MetricType {
total
delegated
cex
dex
lending
circulating
treasury
non_circulating
}

enum EventType {
VOTE
PROPOSAL
PROPOSAL_EXTENDED
DELEGATION
DELEGATION_VOTES_CHANGED
TRANSFER
}

type Token {
id: ID!
name: String
decimals: Int!
totalSupply: BigInt!
delegatedSupply: BigInt!
cexSupply: BigInt!
dexSupply: BigInt!
lendingSupply: BigInt!
circulatingSupply: BigInt!
treasury: BigInt!
nonCirculatingSupply: BigInt!
}

type Account {
id: ID!
}

# Composite PK: "{accountId}-{tokenId}"
type AccountBalance {
id: ID!
accountId: String! @index
tokenId: String! @index
balance: BigInt!
delegate: String!
}

# Composite PK: "{accountId}"
type AccountPower {
id: ID!
accountId: String! @index
daoId: String!
votingPower: BigInt!
votesCount: Int!
proposalsCount: Int!
delegationsCount: Int!
lastVoteTimestamp: BigInt!
}

# Composite PK: "{txHash}-{accountId}-{logIndex}"
type VotingPowerHistory {
id: ID!
transactionHash: String! @index
daoId: String!
accountId: String! @index
votingPower: BigInt!
delta: BigInt!
deltaMod: BigInt!
timestamp: BigInt!
logIndex: Int!
}

# Composite PK: "{txHash}-{accountId}-{logIndex}"
type BalanceHistory {
id: ID!
transactionHash: String! @index
daoId: String!
accountId: String! @index
balance: BigInt!
delta: BigInt!
deltaMod: BigInt!
timestamp: BigInt!
logIndex: Int!
}

# Composite PK: "{txHash}-{delegatorId}-{delegateId}"
type Delegation {
id: ID!
transactionHash: String! @index
daoId: String!
delegateAccountId: String! @index
delegatorAccountId: String! @index
delegatedValue: BigInt!
previousDelegate: String
timestamp: BigInt! @index
logIndex: Int!
isCex: Boolean!
isDex: Boolean!
isLending: Boolean!
isTotal: Boolean!
delegationType: Int
}

# Composite PK: "{txHash}-{fromId}-{toId}"
type Transfer {
id: ID!
transactionHash: String! @index
daoId: String!
tokenId: String! @index
amount: BigInt! @index
fromAccountId: String! @index
toAccountId: String! @index
timestamp: BigInt! @index
logIndex: Int!
isCex: Boolean!
isDex: Boolean!
isLending: Boolean!
isTotal: Boolean!
}

# Composite PK: "{voterId}-{proposalId}"
type VoteOnchain {
id: ID!
txHash: String!
daoId: String!
voterAccountId: String! @index
proposalId: String! @index
support: String!
votingPower: BigInt!
reason: String
timestamp: BigInt!
}

type ProposalOnchain {
id: ID!
txHash: String!
daoId: String!
proposerAccountId: String! @index
targets: Json!
values: Json!
signatures: Json!
calldatas: Json!
startBlock: Int!
endBlock: Int!
title: String!
description: String!
timestamp: BigInt!
logIndex: Int!
endTimestamp: BigInt!
status: String!
forVotes: BigInt!
againstVotes: BigInt!
abstainVotes: BigInt!
proposalType: Int
}

# Composite PK: "{date}-{tokenId}-{metricType}"
type DaoMetricsDayBucket {
id: ID!
date: BigInt!
daoId: String!
tokenId: String! @index
metricType: MetricType!
openValue: BigInt!
closeValue: BigInt!
low: BigInt!
high: BigInt!
average: BigInt!
volume: BigInt!
count: Int!
lastUpdate: BigInt!
}

type Transaction {
id: ID!
transactionHash: String!
fromAddress: String
toAddress: String
isCex: Boolean!
isDex: Boolean!
isLending: Boolean!
isTotal: Boolean!
timestamp: BigInt!
}


type TokenPrice {
id: ID!
price: BigInt!
timestamp: BigInt!
}

# Composite PK: "{txHash}-{logIndex}"
type FeedEvent {
id: ID!
txHash: String! @index
logIndex: Int!
eventType: EventType!
value: BigInt! @index
timestamp: BigInt! @index
metadata: Json
}
65 changes: 65 additions & 0 deletions apps/indexer/src/eventHandlers/ENSGovernor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { ENSGovernor } from "../../generated/index.js";
import type { Hex, Address } from "viem";

import { ProposalStatus, CONTRACT_ADDRESSES } from "../lib/constants.ts";
import { DaoIdEnum } from "../lib/enums.ts";

import { proposalCreated, updateProposalStatus, voteCast } from "./voting.ts";

const DAO_ID = DaoIdEnum.ENS;
const BLOCK_TIME = CONTRACT_ADDRESSES[DAO_ID].blockTime;

ENSGovernor.VoteCast.handler(async ({ event, context }) => {
await voteCast(context, DAO_ID, {
proposalId: event.params.proposalId.toString(),
voter: event.params.voter as Address,
reason: event.params.reason,
support: Number(event.params.support),
timestamp: BigInt(event.block.timestamp),
txHash: event.transaction.hash as Hex,
votingPower: event.params.weight,
logIndex: event.logIndex,
});
});

ENSGovernor.ProposalCreated.handler(async ({ event, context }) => {
await proposalCreated(context, DAO_ID, BLOCK_TIME, {
proposalId: event.params.proposalId.toString(),
txHash: event.transaction.hash as Hex,
proposer: event.params.proposer as Address,
targets: [...event.params.targets] as Address[],
values: [...event.params.values],
signatures: [...event.params.signatures],
calldatas: [...event.params.calldatas] as Hex[],
startBlock: event.params.startBlock.toString(),
endBlock: event.params.endBlock.toString(),
description: event.params.description,
timestamp: BigInt(event.block.timestamp),
blockNumber: BigInt(event.block.number as number),
logIndex: event.logIndex,
});
});

ENSGovernor.ProposalCanceled.handler(async ({ event, context }) => {
await updateProposalStatus(
context,
event.params.proposalId.toString(),
ProposalStatus.CANCELED,
);
});

ENSGovernor.ProposalExecuted.handler(async ({ event, context }) => {
await updateProposalStatus(
context,
event.params.proposalId.toString(),
ProposalStatus.EXECUTED,
);
});

ENSGovernor.ProposalQueued.handler(async ({ event, context }) => {
await updateProposalStatus(
context,
event.params.proposalId.toString(),
ProposalStatus.QUEUED,
);
});
Loading
Loading