diff --git a/subgraph/schema.graphql b/subgraph/schema.graphql index b6d89b846..2cad533d4 100644 --- a/subgraph/schema.graphql +++ b/subgraph/schema.graphql @@ -156,22 +156,6 @@ type DisputeKit @entity { courts: [Court!]! @derivedFrom(field: "supportedDisputeKits") } -type GatewayDispute @entity { - id: ID! - homeDispute: Dispute! - arbitrator: Bytes! - disputeHash: Bytes! - arbitrationCost: BigInt! - relayer: Bytes! -} - -type OutgoingBatch @entity { - id: ID! # messageHash - size: BigInt! - epoch: BigInt! - batchMerkleRoot: String! -} - type Counter @entity { id: ID! # Will be the timestamp except for the counter which will be 0 stakedPNK: BigInt! diff --git a/subgraph/src/DisputeKitClassic.ts b/subgraph/src/DisputeKitClassic.ts index 96e019f5d..7d3704bea 100644 --- a/subgraph/src/DisputeKitClassic.ts +++ b/subgraph/src/DisputeKitClassic.ts @@ -20,6 +20,7 @@ import { ensureClassicEvidenceGroup } from "./entities/ClassicEvidenceGroup"; import { createClassicRound, updateChoiceFundingFromContributionEvent, + updateCounts, } from "./entities/ClassicRound"; import { createClassicVote } from "./entities/ClassicVote"; import { ONE, ZERO } from "./utils"; @@ -29,7 +30,8 @@ export const DISPUTEKIT_ID = "1"; export function handleDisputeCreation(event: DisputeCreation): void { const disputeID = event.params._coreDisputeID.toString(); createClassicDisputeFromEvent(event); - createClassicRound(disputeID, ZERO); + const numberOfChoices = event.params._numberOfChoices; + createClassicRound(disputeID, numberOfChoices, ZERO); } export function handleEvidenceEvent(event: EvidenceEvent): void { @@ -52,9 +54,9 @@ export function handleJustificationEvent(event: JustificationEvent): void { const classicDisputeID = `${DISPUTEKIT_ID}-${coreDisputeID}`; const classicDispute = ClassicDispute.load(classicDisputeID); if (!classicDispute) return; - const currentLocalRoundID = `${ - classicDispute.id - }-${classicDispute.currentLocalRoundIndex.toString()}`; + const currentLocalRoundID = + classicDispute.id + "-" + classicDispute.currentLocalRoundIndex.toString(); + updateCounts(currentLocalRoundID, event.params._choice); createClassicVote(currentLocalRoundID, event); } @@ -88,7 +90,8 @@ export function handleChoiceFunded(event: ChoiceFunded): void { ); if (!localDispute) return; const newRoundIndex = localDispute.currentLocalRoundIndex.plus(ONE); - createClassicRound(coreDisputeID, newRoundIndex); + const numberOfChoices = localDispute.numberOfChoices; + createClassicRound(coreDisputeID, numberOfChoices, newRoundIndex); } localRound.save(); diff --git a/subgraph/src/KlerosCore.ts b/subgraph/src/KlerosCore.ts index 7a1f8244a..437fa0314 100644 --- a/subgraph/src/KlerosCore.ts +++ b/subgraph/src/KlerosCore.ts @@ -26,7 +26,7 @@ import { updateRedistributedPNK, getDelta, } from "./datapoint"; -import { ensureUser } from "./entities/Juror"; +import { ensureUser } from "./entities/User"; import { ensureJurorTokensPerCourt, updateJurorStake, @@ -169,6 +169,6 @@ export function handleTokenAndETHShift(event: TokenAndETHShiftEvent): void { event.block.timestamp ); court.paidETH = court.paidETH.plus(ethAmount); - court.paidPNK = court.paidETH.plus(tokenAmount); + court.paidPNK = court.paidPNK.plus(tokenAmount); court.save(); } diff --git a/subgraph/src/datapoint.ts b/subgraph/src/datapoint.ts index e08d8a357..63e8db1ee 100644 --- a/subgraph/src/datapoint.ts +++ b/subgraph/src/datapoint.ts @@ -20,19 +20,34 @@ function updateDataPoint( timestamp: BigInt, variable: string ): void { - let counter = store.get("Counter", "0"); - if (!counter) { - counter = new Entity(); - for (let i = 0; i < VARIABLES.length; i++) { - counter.set(VARIABLES[i], Value.fromBigInt(ZERO)); - } + const newCounter = new Entity(); + const counter = store.get("Counter", "0"); + for (let i = 0; i < VARIABLES.length; i++) { + const currentVar = VARIABLES[i]; + newCounter.set( + currentVar, + getNewValue(currentVar, variable, delta, counter) + ); } const dayID = timestamp.toI32() / 86400; const dayStartTimestamp = dayID * 86400; - const newValue = counter.get(variable)!.toBigInt().plus(delta); - counter.set(variable, Value.fromBigInt(newValue)); - store.set("Counter", dayStartTimestamp.toString(), counter); - store.set("Counter", "0", counter); + store.set("Counter", dayStartTimestamp.toString(), newCounter); + store.set("Counter", "0", newCounter); +} + +function getNewValue( + currentVar: string, + targetVar: string, + delta: BigInt, + counter: Entity | null +): Value { + if (currentVar === targetVar) { + return !counter + ? Value.fromBigInt(delta) + : Value.fromBigInt(counter.get(currentVar)!.toBigInt().plus(delta)); + } else { + return !counter ? Value.fromBigInt(ZERO) : counter.get(currentVar)!; + } } export function updateStakedPNK(delta: BigInt, timestamp: BigInt): void { diff --git a/subgraph/src/entities/ClassicRound.ts b/subgraph/src/entities/ClassicRound.ts index 9bfbbbd98..afed8be9e 100644 --- a/subgraph/src/entities/ClassicRound.ts +++ b/subgraph/src/entities/ClassicRound.ts @@ -1,28 +1,50 @@ import { BigInt } from "@graphprotocol/graph-ts"; import { Contribution } from "../../generated/DisputeKitClassic/DisputeKitClassic"; import { ClassicRound } from "../../generated/schema"; -import { ZERO } from "../utils"; +import { ONE, ZERO } from "../utils"; export function createClassicRound( disputeID: string, + numberOfChoices: BigInt, roundIndex: BigInt ): void { + const choicesLength = numberOfChoices.plus(ONE); const localDisputeID = `1-${disputeID}`; const id = `${localDisputeID}-${roundIndex.toString()}`; const classicRound = new ClassicRound(id); classicRound.localDispute = localDisputeID; classicRound.votes = []; classicRound.winningChoice = ZERO; - classicRound.counts = []; + classicRound.counts = new Array(choicesLength.toI32()).fill(ZERO); classicRound.tied = true; classicRound.totalVoted = ZERO; classicRound.totalCommited = ZERO; - classicRound.paidFees = []; + classicRound.paidFees = new Array(choicesLength.toI32()).fill(ZERO); classicRound.feeRewards = ZERO; classicRound.fundedChoices = []; classicRound.save(); } +export function updateCounts(id: string, choice: BigInt): void { + const round = ClassicRound.load(id); + if (!round) return; + const choiceNum = choice.toI32(); + const updatedCount = round.counts[choiceNum].plus(ONE); + round.counts[choiceNum] = updatedCount; + const currentWinningCount = round.counts[round.winningChoice.toI32()]; + if (choice.equals(round.winningChoice)) { + if (round.tied) round.tied = false; + } else { + if (updatedCount.equals(currentWinningCount)) { + if (!round.tied) round.tied = true; + } else if (updatedCount.gt(currentWinningCount)) { + round.winningChoice = choice; + round.tied = false; + } + } + round.save(); +} + export function updateChoiceFundingFromContributionEvent( event: Contribution ): void { diff --git a/subgraph/src/entities/JurorTokensPerCourt.ts b/subgraph/src/entities/JurorTokensPerCourt.ts index be4d755ee..f119a63f0 100644 --- a/subgraph/src/entities/JurorTokensPerCourt.ts +++ b/subgraph/src/entities/JurorTokensPerCourt.ts @@ -2,7 +2,7 @@ import { BigInt, Address } from "@graphprotocol/graph-ts"; import { KlerosCore } from "../../generated/KlerosCore/KlerosCore"; import { Court, JurorTokensPerCourt } from "../../generated/schema"; import { updateActiveJurors, getDelta } from "../datapoint"; -import { ensureUser } from "./Juror"; +import { ensureUser } from "./User"; import { ZERO } from "../utils"; export function ensureJurorTokensPerCourt( @@ -61,7 +61,7 @@ export function updateJurorStake( jurorTokens.staked = jurorBalance.value0; jurorTokens.locked = jurorBalance.value1; jurorTokens.save(); - const stakeDelta = getDelta(jurorTokens.staked, previousStake); + const stakeDelta = getDelta(previousStake, jurorTokens.staked); juror.totalStake = juror.totalStake.plus(stakeDelta); court.stake = court.stake.plus(stakeDelta); let activeJurorsDelta: BigInt; diff --git a/subgraph/src/entities/Juror.ts b/subgraph/src/entities/User.ts similarity index 76% rename from subgraph/src/entities/Juror.ts rename to subgraph/src/entities/User.ts index 8db9d3790..6d49bb895 100644 --- a/subgraph/src/entities/Juror.ts +++ b/subgraph/src/entities/User.ts @@ -1,7 +1,8 @@ import { User } from "../../generated/schema"; +import { ZERO } from "../utils"; export function ensureUser(id: string): User { - let user = User.load(id); + const user = User.load(id); if (user) { return user; @@ -12,6 +13,7 @@ export function ensureUser(id: string): User { export function createUserFromAddress(id: string): User { const user = new User(id); + user.totalStake = ZERO; user.save(); return user; diff --git a/subgraph/subgraph.yaml b/subgraph/subgraph.yaml index ac9752492..064578689 100644 --- a/subgraph/subgraph.yaml +++ b/subgraph/subgraph.yaml @@ -14,19 +14,16 @@ dataSources: apiVersion: 0.0.6 language: wasm/assemblyscript entities: - - Court - - Juror + - User + - Arbitrable - TokenAndETHShift - JurorTokensPerCourt + - Court + - Dispute - Round - Draw - - Dispute - DisputeKit - - PNKStakedDataPoint - - ETHPaidDataPoint - - PNKRedistributedDataPoint - - ActiveJurorsDataPoint - - CasesDataPoint + - Counter abis: - name: KlerosCore file: ../contracts/deployments/arbitrumGoerli/KlerosCore.json @@ -84,8 +81,12 @@ dataSources: apiVersion: 0.0.6 language: wasm/assemblyscript entities: - - EvidenceGroup - - Evidence + - ClassicDispute + - ClassicRound + - ClassicVote + - ClassicEvidenceGroup + - ClassicEvidence + - ClassicContribution abis: - name: DisputeKitClassic file: ../contracts/deployments/arbitrumGoerli/DisputeKitClassic.json @@ -94,8 +95,8 @@ dataSources: handler: handleDisputeCreation - event: Contribution(indexed uint256,indexed uint256,uint256,indexed address,uint256) handler: handleContributionEvent - # - event: Withdrawal(indexed uint256,indexed uint256,uint256,indexed address,uint256) - # handler: handleWithdrawal + - event: Withdrawal(indexed uint256,indexed uint256,uint256,indexed address,uint256) + handler: handleWithdrawal - event: ChoiceFunded(indexed uint256,indexed uint256,indexed uint256) handler: handleChoiceFunded - event: Evidence(indexed address,indexed uint256,indexed address,string)