diff --git a/subgraph/core-neo/subgraph.template.yaml b/subgraph/core-neo/subgraph.template.yaml new file mode 100644 index 000000000..d2be35a78 --- /dev/null +++ b/subgraph/core-neo/subgraph.template.yaml @@ -0,0 +1,202 @@ +specVersion: 0.0.5 +schema: + file: ./schema.graphql +features: + - fullTextSearch +dataSources: + - kind: ethereum + name: KlerosCore + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: KlerosCore + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - User + - Arbitrable + - TokenAndETHShift + - JurorTokensPerCourt + - Court + - Dispute + - Round + - Draw + - DisputeKit + - Counter + abis: + - name: SortitionModule + file: ../../contracts/deployments/_PLACEHOLDER_/SortitionModuleNeo.json + - name: DisputeKitClassic + file: ../../contracts/deployments/_PLACEHOLDER_/DisputeKitClassicNeo.json + - name: KlerosCore + file: ../../contracts/deployments/_PLACEHOLDER_/KlerosCoreNeo.json + eventHandlers: + - event: AppealDecision(indexed uint256,indexed address) + handler: handleAppealDecision + - event: DisputeCreation(indexed uint256,indexed address) + handler: handleDisputeCreation + receipt: true + - event: Draw(indexed address,indexed uint256,uint256,uint256) + handler: handleDraw + - event: NewPeriod(indexed uint256,uint8) + handler: handleNewPeriod + - event: CourtCreated(indexed uint256,indexed uint96,bool,uint256,uint256,uint256,uint256,uint256[4],uint256[]) + handler: handleCourtCreated + - event: CourtModified(indexed uint96,bool,uint256,uint256,uint256,uint256,uint256[4]) + handler: handleCourtModified + - event: DisputeKitCreated(indexed uint256,indexed address) + handler: handleDisputeKitCreated + - event: DisputeKitEnabled(indexed uint96,indexed uint256,indexed bool) + handler: handleDisputeKitEnabled + - event: TokenAndETHShift(indexed address,indexed uint256,indexed uint256,uint256,int256,int256,address) + handler: handleTokenAndETHShift + - event: Ruling(indexed address,indexed uint256,uint256) + handler: handleRuling + - event: AcceptedFeeToken(indexed address,indexed bool) + handler: handleAcceptedFeeToken + - event: CourtJump(indexed uint256,indexed uint256,indexed uint96,uint96) + handler: handleCourtJump + file: ./src/KlerosCore.ts + - kind: ethereum + name: PolicyRegistry + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: PolicyRegistry + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - Court + abis: + - name: PolicyRegistry + file: ../../contracts/deployments/_PLACEHOLDER_/PolicyRegistry.json + eventHandlers: + - event: PolicyUpdate(indexed uint256,string,string) + handler: handlePolicyUpdate + file: ./src/PolicyRegistry.ts + - kind: ethereum + name: DisputeKitClassic + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: DisputeKitClassic + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - ClassicDispute + - ClassicRound + - ClassicVote + - ClassicContribution + abis: + - name: DisputeKitClassic + file: ../../contracts/deployments/_PLACEHOLDER_/DisputeKitClassicNeo.json + - name: KlerosCore + file: ../../contracts/deployments/_PLACEHOLDER_/KlerosCoreNeo.json + eventHandlers: + - event: DisputeCreation(indexed uint256,uint256,bytes) + 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: ChoiceFunded(indexed uint256,indexed uint256,indexed uint256) + handler: handleChoiceFunded + - event: VoteCast(indexed uint256,indexed address,uint256[],indexed uint256,string) + handler: handleVoteCast + - event: CommitCast(indexed uint256,indexed address,uint256[],bytes32) + handler: handleCommitCast + file: ./src/DisputeKitClassic.ts + - kind: ethereum + name: DisputeKitShutter + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: DisputeKitShutter + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - ClassicDispute + - ClassicRound + - ClassicVote + - ClassicContribution + abis: + - name: DisputeKitShutter + file: ../../contracts/deployments/_PLACEHOLDER_/DisputeKitShutter.json + - name: KlerosCore + # FIX: temporarily point to abi with event addition + file: ./abi-migrations/KlerosCore.json + eventHandlers: + - event: DisputeCreation(indexed uint256,uint256,bytes) + 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: ChoiceFunded(indexed uint256,indexed uint256,indexed uint256) + handler: handleChoiceFunded + - event: VoteCast(indexed uint256,indexed address,uint256[],indexed uint256,string) + handler: handleVoteCast + - event: CommitCast(indexed uint256,indexed address,uint256[],bytes32) + handler: handleCommitCast + file: ./src/DisputeKitClassic.ts + - kind: ethereum + name: EvidenceModule + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: EvidenceModule + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - ClassicEvidenceGroup + - ClassicEvidence + abis: + - name: EvidenceModule + file: ../../contracts/deployments/_PLACEHOLDER_/EvidenceModule.json + eventHandlers: + - event: Evidence(indexed uint256,indexed address,string) + handler: handleEvidenceEvent + file: ./src/EvidenceModule.ts + - kind: ethereum + name: SortitionModule + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: SortitionModule + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - JurorTokensPerCourt + abis: + - name: SortitionModule + file: ../../contracts/deployments/_PLACEHOLDER_/SortitionModuleNeo.json + eventHandlers: + - event: StakeDelayedAlreadyTransferredDeposited(indexed address,uint256,uint256) + handler: handleStakeDelayedAlreadyTransferredDeposited + - event: StakeDelayedAlreadyTransferredWithdrawn(indexed address,indexed uint96,uint256) + handler: handleStakeDelayedAlreadyTransferredWithdrawn + - event: StakeDelayedNotTransferred(indexed address,uint256,uint256) + handler: handleStakeDelayedNotTransferred + - event: StakeLocked(indexed address,uint256,bool) + handler: handleStakeLocked + - event: StakeSet(indexed address,uint256,uint256,uint256) + handler: handleStakeSet + file: ./src/SortitionModule.ts diff --git a/subgraph/core-neo/subgraph.yaml b/subgraph/core-neo/subgraph.yaml index ff00a883f..ae70065e2 100644 --- a/subgraph/core-neo/subgraph.yaml +++ b/subgraph/core-neo/subgraph.yaml @@ -1,3 +1,4 @@ +# THIS FILE IS AUTO-GENERATED BY update.sh FROM subgraph.template.yaml, ANY CHANGES WILL BE LOST. specVersion: 0.0.5 schema: file: ./schema.graphql diff --git a/subgraph/core-university/subgraph.template.yaml b/subgraph/core-university/subgraph.template.yaml new file mode 100644 index 000000000..06dc82e46 --- /dev/null +++ b/subgraph/core-university/subgraph.template.yaml @@ -0,0 +1,160 @@ +specVersion: 0.0.5 +schema: + file: ./schema.graphql +features: + - fullTextSearch +dataSources: + - kind: ethereum + name: KlerosCore + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: KlerosCore + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - User + - Arbitrable + - TokenAndETHShift + - JurorTokensPerCourt + - Court + - Dispute + - Round + - Draw + - DisputeKit + - Counter + abis: + - name: SortitionModule + file: ../../contracts/deployments/_PLACEHOLDER_/SortitionModuleUniversity.json + - name: DisputeKitClassic + file: ../../contracts/deployments/_PLACEHOLDER_/DisputeKitClassicUniversity.json + - name: KlerosCore + file: ../../contracts/deployments/_PLACEHOLDER_/KlerosCoreUniversity.json + eventHandlers: + - event: AppealDecision(indexed uint256,indexed address) + handler: handleAppealDecision + - event: DisputeCreation(indexed uint256,indexed address) + handler: handleDisputeCreation + receipt: true + - event: Draw(indexed address,indexed uint256,uint256,uint256) + handler: handleDraw + - event: NewPeriod(indexed uint256,uint8) + handler: handleNewPeriod + - event: CourtCreated(indexed uint256,indexed uint96,bool,uint256,uint256,uint256,uint256,uint256[4],uint256[]) + handler: handleCourtCreated + - event: CourtModified(indexed uint96,bool,uint256,uint256,uint256,uint256,uint256[4]) + handler: handleCourtModified + - event: DisputeKitCreated(indexed uint256,indexed address) + handler: handleDisputeKitCreated + - event: DisputeKitEnabled(indexed uint96,indexed uint256,indexed bool) + handler: handleDisputeKitEnabled + - event: TokenAndETHShift(indexed address,indexed uint256,indexed uint256,uint256,int256,int256,address) + handler: handleTokenAndETHShift + - event: Ruling(indexed address,indexed uint256,uint256) + handler: handleRuling + - event: AcceptedFeeToken(indexed address,indexed bool) + handler: handleAcceptedFeeToken + - event: CourtJump(indexed uint256,indexed uint256,indexed uint96,uint96) + handler: handleCourtJump + file: ./src/KlerosCore.ts + - kind: ethereum + name: PolicyRegistry + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: PolicyRegistry + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - Court + abis: + - name: PolicyRegistry + file: ../../contracts/deployments/_PLACEHOLDER_/PolicyRegistry.json + eventHandlers: + - event: PolicyUpdate(indexed uint256,string,string) + handler: handlePolicyUpdate + file: ./src/PolicyRegistry.ts + - kind: ethereum + name: DisputeKitClassic + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: DisputeKitClassic + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - ClassicDispute + - ClassicRound + - ClassicVote + - ClassicContribution + abis: + - name: DisputeKitClassic + file: ../../contracts/deployments/_PLACEHOLDER_/DisputeKitClassicUniversity.json + - name: KlerosCore + file: ../../contracts/deployments/_PLACEHOLDER_/KlerosCoreUniversity.json + eventHandlers: + - event: DisputeCreation(indexed uint256,uint256,bytes) + 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: ChoiceFunded(indexed uint256,indexed uint256,indexed uint256) + handler: handleChoiceFunded + - event: VoteCast(indexed uint256,indexed address,uint256[],indexed uint256,string) + handler: handleVoteCast + - event: CommitCast(indexed uint256,indexed address,uint256[],bytes32) + handler: handleCommitCast + file: ./src/DisputeKitClassic.ts + - kind: ethereum + name: EvidenceModule + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: EvidenceModule + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - ClassicEvidenceGroup + - ClassicEvidence + abis: + - name: EvidenceModule + file: ../../contracts/deployments/_PLACEHOLDER_/EvidenceModule.json + eventHandlers: + - event: Evidence(indexed uint256,indexed address,string) + handler: handleEvidenceEvent + file: ./src/EvidenceModule.ts + - kind: ethereum + name: SortitionModule + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: SortitionModule + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - JurorTokensPerCourt + abis: + - name: SortitionModule + file: ../../contracts/deployments/_PLACEHOLDER_/SortitionModuleUniversity.json + eventHandlers: + - event: StakeLocked(indexed address,uint256,bool) + handler: handleStakeLocked + - event: StakeSet(indexed address,uint256,uint256,uint256) + handler: handleStakeSet + file: ./src/SortitionModule.ts diff --git a/subgraph/core-university/subgraph.yaml b/subgraph/core-university/subgraph.yaml index a0398c2f8..d820954c8 100644 --- a/subgraph/core-university/subgraph.yaml +++ b/subgraph/core-university/subgraph.yaml @@ -1,3 +1,4 @@ +# THIS FILE IS AUTO-GENERATED BY update.sh FROM subgraph.template.yaml, ANY CHANGES WILL BE LOST. specVersion: 0.0.5 schema: file: ./schema.graphql @@ -64,9 +65,9 @@ dataSources: name: PolicyRegistry network: arbitrum-sepolia source: - address: "0x2AC2EdFD336732bc6963f1AD03ED98B22dB949da" + address: "0x31d067405184d7FaA64b0834511cBcFAF32CdC4b" abi: PolicyRegistry - startBlock: 3084568 + startBlock: 141215158 mapping: kind: ethereum/events apiVersion: 0.0.7 @@ -119,9 +120,9 @@ dataSources: name: EvidenceModule network: arbitrum-sepolia source: - address: "0x57fd453FB0d16f8ca174E7386102D7170E17Be09" + address: "0x990f44d19a5F46889801B31bf58e0536fBECf27C" abi: EvidenceModule - startBlock: 3638735 + startBlock: 141215177 mapping: kind: ethereum/events apiVersion: 0.0.7 diff --git a/subgraph/core/src/DisputeKitClassic.ts b/subgraph/core/src/DisputeKitClassic.ts index c58147bf1..894ab9827 100644 --- a/subgraph/core/src/DisputeKitClassic.ts +++ b/subgraph/core/src/DisputeKitClassic.ts @@ -9,7 +9,7 @@ import { CommitCast, } from "../generated/DisputeKitClassic/DisputeKitClassic"; import { KlerosCore } from "../generated/KlerosCore/KlerosCore"; -import { ClassicDispute, ClassicJustification, ClassicRound, ClassicVote, Dispute } from "../generated/schema"; +import { ClassicDispute, ClassicJustification, ClassicRound, ClassicVote, Dispute, Round } from "../generated/schema"; import { ensureClassicContributionFromEvent } from "./entities/ClassicContribution"; import { createClassicDisputeFromEvent } from "./entities/ClassicDispute"; import { @@ -19,23 +19,36 @@ import { updateCountsAndGetCurrentRuling, } from "./entities/ClassicRound"; import { ensureClassicVote } from "./entities/ClassicVote"; -import { ONE, ZERO } from "./utils"; - -export const DISPUTEKIT_ID = "1"; +import { ONE, extractDisputeKitIDFromExtraData } from "./utils"; export function handleDisputeCreation(event: DisputeCreation): void { const disputeID = event.params._coreDisputeID.toString(); - createClassicDisputeFromEvent(event); - const numberOfChoices = event.params._numberOfChoices; - createClassicRound(disputeID, numberOfChoices, ZERO); + const disputeKitID = extractDisputeKitIDFromExtraData(event.params._extraData); + + const disputeKitClassic = DisputeKitClassic.bind(event.address); + const klerosCore = KlerosCore.bind(disputeKitClassic.core()); + const totalRounds = klerosCore.getNumberOfRounds(event.params._coreDisputeID); + const newRoundIndex = totalRounds.minus(ONE); + + createClassicDisputeFromEvent(event, disputeKitID, newRoundIndex); + createClassicRound(disputeID, event.params._numberOfChoices, newRoundIndex, disputeKitID); } export function handleCommitCast(event: CommitCast): void { - const coreDisputeID = event.params._coreDisputeID; - const coreDispute = Dispute.load(coreDisputeID.toString()); - const classicDisputeID = `${DISPUTEKIT_ID}-${coreDisputeID}`; + const coreDisputeID = event.params._coreDisputeID.toString(); + const coreDispute = Dispute.load(coreDisputeID); + if (!coreDispute) return; + + const coreCurrentRound = Round.load(coreDispute.currentRound); + if (!coreCurrentRound) return; + + const disputeKitID = coreCurrentRound.disputeKit; + + const classicDisputeID = `${disputeKitID}-${coreDisputeID}`; + const classicDispute = ClassicDispute.load(classicDisputeID); - if (!classicDispute || !coreDispute) return; + if (!classicDispute) return; + const currentLocalRoundID = classicDispute.id + "-" + classicDispute.currentLocalRoundIndex.toString(); const voteIDs = event.params._voteIDs; for (let i = 0; i < voteIDs.length; i++) { @@ -55,9 +68,18 @@ export function handleVoteCast(event: VoteCast): void { const juror = event.params._juror.toHexString(); const coreDisputeID = event.params._coreDisputeID.toString(); const coreDispute = Dispute.load(coreDisputeID); - const classicDisputeID = `${DISPUTEKIT_ID}-${coreDisputeID}`; + if (!coreDispute) return; + + const coreCurrentRound = Round.load(coreDispute.currentRound); + if (!coreCurrentRound) return; + + const disputeKitID = coreCurrentRound.disputeKit; + + const classicDisputeID = `${disputeKitID}-${coreDisputeID}`; + const classicDispute = ClassicDispute.load(classicDisputeID); - if (!classicDispute || !coreDispute) return; + if (!classicDispute) return; + const choice = event.params._choice; const currentLocalRoundID = classicDispute.id + "-" + classicDispute.currentLocalRoundIndex.toString(); const voteIDs = event.params._voteIDs; @@ -70,6 +92,7 @@ export function handleVoteCast(event: VoteCast): void { justification.transactionHash = event.transaction.hash.toHexString(); justification.timestamp = event.block.timestamp; justification.save(); + const currentRulingInfo = updateCountsAndGetCurrentRuling( currentLocalRoundID, choice, @@ -78,6 +101,7 @@ export function handleVoteCast(event: VoteCast): void { coreDispute.currentRuling = currentRulingInfo.ruling; coreDispute.tied = currentRulingInfo.tied; coreDispute.save(); + let classicVote: ClassicVote; for (let i = 0; i < voteIDs.length; i++) { classicVote = ensureClassicVote(currentLocalRoundID, juror, voteIDs[i], coreDispute); @@ -97,7 +121,16 @@ export function handleChoiceFunded(event: ChoiceFunded): void { const coreDisputeID = event.params._coreDisputeID.toString(); const coreRoundIndex = event.params._coreRoundID.toString(); const choice = event.params._choice; - const roundID = `${DISPUTEKIT_ID}-${coreDisputeID}-${coreRoundIndex}`; + + const coreDispute = Dispute.load(coreDisputeID); + if (!coreDispute) return; + + const roundId = `${coreDisputeID}-${coreRoundIndex}`; + const coreRound = Round.load(roundId); + if (!coreRound) return; + const disputeKitID = coreRound.disputeKit; + + const roundID = `${disputeKitID}-${coreDisputeID}-${coreRoundIndex}`; const localRound = ClassicRound.load(roundID); if (!localRound) return; @@ -123,13 +156,18 @@ export function handleChoiceFunded(event: ChoiceFunded): void { localRound.feeRewards = localRound.feeRewards.minus(appealCost); - const localDispute = ClassicDispute.load(`${DISPUTEKIT_ID}-${coreDisputeID}`); + const newDisputeKitID = roundInfo.disputeKitID; + + const localDispute = ClassicDispute.load(`${disputeKitID}-${coreDisputeID}`); if (!localDispute) return; - const newRoundIndex = localDispute.currentLocalRoundIndex.plus(ONE); - const numberOfChoices = localDispute.numberOfChoices; - localDispute.currentLocalRoundIndex = newRoundIndex; - localDispute.save(); - createClassicRound(coreDisputeID, numberOfChoices, newRoundIndex); + + if (BigInt.fromString(disputeKitID) === newDisputeKitID) { + const newRoundIndex = localDispute.currentLocalRoundIndex.plus(ONE); + const numberOfChoices = localDispute.numberOfChoices; + localDispute.currentLocalRoundIndex = newRoundIndex; + localDispute.save(); + createClassicRound(coreDisputeID, numberOfChoices, newRoundIndex, disputeKitID); + } } localRound.save(); @@ -144,7 +182,16 @@ export function handleWithdrawal(event: Withdrawal): void { // check if all appeal fees have been withdrawn const coreDisputeID = event.params._coreDisputeID.toString(); const coreRoundIndex = event.params._coreRoundID.toString(); - const roundID = `${DISPUTEKIT_ID}-${coreDisputeID}-${coreRoundIndex}`; + + const coreDispute = Dispute.load(coreDisputeID); + if (!coreDispute) return; + + const roundId = `${coreDisputeID}-${coreRoundIndex}`; + const coreRound = Round.load(roundId); + if (!coreRound) return; + const disputeKitID = coreRound.disputeKit; + + const roundID = `${disputeKitID}-${coreDisputeID}-${coreRoundIndex}`; const localRound = ClassicRound.load(roundID); if (!localRound) return; diff --git a/subgraph/core/src/KlerosCore.ts b/subgraph/core/src/KlerosCore.ts index 42a54644f..18e9cb45e 100644 --- a/subgraph/core/src/KlerosCore.ts +++ b/subgraph/core/src/KlerosCore.ts @@ -156,7 +156,7 @@ export function handleNewPeriod(event: NewPeriod): void { updateTotalLeaderboardJurors(ONE, event.block.timestamp); } - // Since this is a ClassicVote entity, this will only work for the Classic DisputeKit (which has ID "1"). + // Since this is a ClassicVote entity, this will only work for the ClassicDisputeKit and ShutterDisputeKit. const vote = ClassicVote.load(`${round.disputeKit}-${draw.id}`); if (!vote) { diff --git a/subgraph/core/src/entities/ClassicContribution.ts b/subgraph/core/src/entities/ClassicContribution.ts index c9d11211f..0473d0f39 100644 --- a/subgraph/core/src/entities/ClassicContribution.ts +++ b/subgraph/core/src/entities/ClassicContribution.ts @@ -1,13 +1,23 @@ -import { ClassicContribution } from "../../generated/schema"; +import { ClassicContribution, Dispute, DisputeKit, Round } from "../../generated/schema"; import { Contribution as ContributionEvent, Withdrawal } from "../../generated/DisputeKitClassic/DisputeKitClassic"; -import { DISPUTEKIT_ID } from "../DisputeKitClassic"; import { ensureUser } from "./User"; export function ensureClassicContributionFromEvent(event: T): ClassicContribution | null { if (!(event instanceof ContributionEvent) && !(event instanceof Withdrawal)) return null; const coreDisputeID = event.params._coreDisputeID.toString(); const coreRoundIndex = event.params._coreRoundID.toString(); - const roundID = `${DISPUTEKIT_ID}-${coreDisputeID}-${coreRoundIndex}`; + + const coreDispute = Dispute.load(coreDisputeID); + if (!coreDispute) return null; + + const roundId = `${coreDisputeID}-${coreRoundIndex}`; + const coreRound = Round.load(roundId); + if (!coreRound) return null; + + const disputeKitID = coreRound.disputeKit; + + const roundID = `${disputeKitID}-${coreDisputeID}-${coreRoundIndex}`; + ensureUser(event.params._contributor.toHexString()); const contributor = event.params._contributor.toHexString(); const choice = event.params._choice; diff --git a/subgraph/core/src/entities/ClassicDispute.ts b/subgraph/core/src/entities/ClassicDispute.ts index bc0604517..dfdd24532 100644 --- a/subgraph/core/src/entities/ClassicDispute.ts +++ b/subgraph/core/src/entities/ClassicDispute.ts @@ -1,12 +1,12 @@ +import { BigInt } from "@graphprotocol/graph-ts"; import { DisputeCreation } from "../../generated/DisputeKitClassic/DisputeKitClassic"; import { ClassicDispute } from "../../generated/schema"; -import { ZERO } from "../utils"; -export function createClassicDisputeFromEvent(event: DisputeCreation): void { +export function createClassicDisputeFromEvent(event: DisputeCreation, disputeKitID: string, roundIndex: BigInt): void { const coreDisputeID = event.params._coreDisputeID.toString(); - const classicDispute = new ClassicDispute(`1-${coreDisputeID}`); + const classicDispute = new ClassicDispute(`${disputeKitID}-${coreDisputeID}`); classicDispute.coreDispute = coreDisputeID; - classicDispute.currentLocalRoundIndex = ZERO; + classicDispute.currentLocalRoundIndex = roundIndex; classicDispute.numberOfChoices = event.params._numberOfChoices; classicDispute.extraData = event.params._extraData; classicDispute.timestamp = event.block.timestamp; diff --git a/subgraph/core/src/entities/ClassicRound.ts b/subgraph/core/src/entities/ClassicRound.ts index 86dc57491..57862a347 100644 --- a/subgraph/core/src/entities/ClassicRound.ts +++ b/subgraph/core/src/entities/ClassicRound.ts @@ -1,10 +1,15 @@ import { BigInt } from "@graphprotocol/graph-ts"; import { Contribution } from "../../generated/DisputeKitClassic/DisputeKitClassic"; -import { Answer, ClassicRound } from "../../generated/schema"; +import { Answer, ClassicRound, Dispute, Round } from "../../generated/schema"; import { ZERO } from "../utils"; -export function createClassicRound(disputeID: string, numberOfChoices: BigInt, roundIndex: BigInt): void { - const localDisputeID = `1-${disputeID}`; +export function createClassicRound( + disputeID: string, + numberOfChoices: BigInt, + roundIndex: BigInt, + disputeKitID: string +): void { + const localDisputeID = `${disputeKitID}-${disputeID}`; const id = `${localDisputeID}-${roundIndex.toString()}`; const classicRound = new ClassicRound(id); classicRound.localDispute = localDisputeID; @@ -67,9 +72,16 @@ export function updateCountsAndGetCurrentRuling(id: string, choice: BigInt, delt } export function updateChoiceFundingFromContributionEvent(event: Contribution): void { - const disputeKitID = "1"; const coreDisputeID = event.params._coreDisputeID.toString(); const coreRoundIndex = event.params._coreRoundID.toString(); + const coreDispute = Dispute.load(coreDisputeID); + if (!coreDispute) return; + + const roundId = `${coreDisputeID}-${coreRoundIndex}`; + const coreRound = Round.load(roundId); + if (!coreRound) return; + const disputeKitID = coreRound.disputeKit; + const roundID = `${disputeKitID}-${coreDisputeID}-${coreRoundIndex}`; const classicRound = ClassicRound.load(roundID); diff --git a/subgraph/core/src/utils.ts b/subgraph/core/src/utils.ts index 73b2f99dc..78d2abaa4 100644 --- a/subgraph/core/src/utils.ts +++ b/subgraph/core/src/utils.ts @@ -1,4 +1,10 @@ -import { BigInt } from "@graphprotocol/graph-ts"; +import { BigInt, Bytes } from "@graphprotocol/graph-ts"; export const ZERO = BigInt.fromI32(0); export const ONE = BigInt.fromI32(1); + +export function extractDisputeKitIDFromExtraData(extraData: Bytes): string { + const start = extraData.length - 32; + const littleEndian = extraData.subarray(start, extraData.length).reverse(); + return BigInt.fromUnsignedBytes(Bytes.fromUint8Array(littleEndian)).toString(); +} diff --git a/subgraph/core/subgraph.template.yaml b/subgraph/core/subgraph.template.yaml new file mode 100644 index 000000000..19bd8d49d --- /dev/null +++ b/subgraph/core/subgraph.template.yaml @@ -0,0 +1,216 @@ +specVersion: 0.0.5 +schema: + file: ./schema.graphql +features: + - fullTextSearch +dataSources: + - kind: ethereum + name: KlerosCore + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: KlerosCore + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - User + - Arbitrable + - TokenAndETHShift + - JurorTokensPerCourt + - Court + - Dispute + - Round + - Draw + - DisputeKit + - Counter + abis: + - name: SortitionModule + file: ../../contracts/deployments/_PLACEHOLDER_/SortitionModule.json + - name: DisputeKitClassic + file: ../../contracts/deployments/_PLACEHOLDER_/DisputeKitClassic.json + - name: KlerosCore + # FIX: temporarily point to the abi with event addition. + file: ./abi-migrations/KlerosCore.json + eventHandlers: + - event: AppealDecision(indexed uint256,indexed address) + handler: handleAppealDecision + - event: DisputeCreation(indexed uint256,indexed address) + handler: handleDisputeCreation + receipt: true + - event: Draw(indexed address,indexed uint256,uint256,uint256) + handler: handleDraw + - event: NewPeriod(indexed uint256,uint8) + handler: handleNewPeriod + - event: CourtCreated(indexed uint96,indexed uint96,bool,uint256,uint256,uint256,uint256,uint256[4],uint256[]) + handler: handleCourtCreated + # FIX: This is support for old signature + - event: CourtCreated(indexed uint256,indexed uint96,bool,uint256,uint256,uint256,uint256,uint256[4],uint256[]) + handler: handleCourtCreated + - event: CourtModified(indexed uint96,bool,uint256,uint256,uint256,uint256,uint256[4]) + handler: handleCourtModified + - event: DisputeKitCreated(indexed uint256,indexed address) + handler: handleDisputeKitCreated + - event: DisputeKitEnabled(indexed uint96,indexed uint256,indexed bool) + handler: handleDisputeKitEnabled + - event: TokenAndETHShift(indexed address,indexed uint256,indexed uint256,uint256,int256,int256,address) + handler: handleTokenAndETHShift + - event: Ruling(indexed address,indexed uint256,uint256) + handler: handleRuling + - event: AcceptedFeeToken(indexed address,indexed bool) + handler: handleAcceptedFeeToken + - event: CourtJump(indexed uint256,indexed uint256,indexed uint96,uint96) + handler: handleCourtJump + file: ./src/KlerosCore.ts + - kind: ethereum + name: PolicyRegistry + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: PolicyRegistry + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - Court + abis: + - name: PolicyRegistry + file: ../../contracts/deployments/_PLACEHOLDER_/PolicyRegistry.json + eventHandlers: + - event: PolicyUpdate(indexed uint256,string,string) + handler: handlePolicyUpdate + file: ./src/PolicyRegistry.ts + - kind: ethereum + name: DisputeKitClassic + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: DisputeKitClassic + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - ClassicDispute + - ClassicRound + - ClassicVote + - ClassicContribution + abis: + - name: DisputeKitClassic + file: ../../contracts/deployments/_PLACEHOLDER_/DisputeKitClassic.json + - name: KlerosCore + # FIX: temporarily point to abi with event addition + file: ./abi-migrations/KlerosCore.json + eventHandlers: + - event: DisputeCreation(indexed uint256,uint256,bytes) + 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: ChoiceFunded(indexed uint256,indexed uint256,indexed uint256) + handler: handleChoiceFunded + - event: VoteCast(indexed uint256,indexed address,uint256[],indexed uint256,string) + handler: handleVoteCast + - event: CommitCast(indexed uint256,indexed address,uint256[],bytes32) + handler: handleCommitCast + file: ./src/DisputeKitClassic.ts + - kind: ethereum + name: DisputeKitShutter + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: DisputeKitShutter + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - ClassicDispute + - ClassicRound + - ClassicVote + - ClassicContribution + abis: + - name: DisputeKitShutter + file: ../../contracts/deployments/_PLACEHOLDER_/DisputeKitShutter.json + - name: DisputeKitClassic # Required on Alchemy + file: ../../contracts/deployments/_PLACEHOLDER_/DisputeKitClassic.json + - name: KlerosCore + # FIX: temporarily point to abi with event addition + file: ./abi-migrations/KlerosCore.json + eventHandlers: + - event: DisputeCreation(indexed uint256,uint256,bytes) + 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: ChoiceFunded(indexed uint256,indexed uint256,indexed uint256) + handler: handleChoiceFunded + - event: VoteCast(indexed uint256,indexed address,uint256[],indexed uint256,string) + handler: handleVoteCast + - event: CommitCast(indexed uint256,indexed address,uint256[],bytes32) + handler: handleCommitCast + file: ./src/DisputeKitClassic.ts + - kind: ethereum + name: EvidenceModule + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: EvidenceModule + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - ClassicEvidenceGroup + - ClassicEvidence + abis: + - name: EvidenceModule + file: ../../contracts/deployments/_PLACEHOLDER_/EvidenceModule.json + eventHandlers: + - event: Evidence(indexed uint256,indexed address,string) + handler: handleEvidenceEvent + file: ./src/EvidenceModule.ts + - kind: ethereum + name: SortitionModule + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: SortitionModule + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - JurorTokensPerCourt + abis: + - name: SortitionModule + # FIX: temporarily point to abi with event addition + file: ./abi-migrations/SortitionModule.json + eventHandlers: + - event: StakeDelayedAlreadyTransferredDeposited(indexed address,uint256,uint256) + handler: handleStakeDelayedAlreadyTransferredDeposited + # FIX: temporarily indexing old event name + - event: StakeDelayedAlreadyTransferred(indexed address,uint256,uint256) + handler: handleStakeDelayedAlreadyTransferred + - event: StakeDelayedAlreadyTransferredWithdrawn(indexed address,indexed uint96,uint256) + handler: handleStakeDelayedAlreadyTransferredWithdrawn + - event: StakeDelayedNotTransferred(indexed address,uint256,uint256) + handler: handleStakeDelayedNotTransferred + - event: StakeLocked(indexed address,uint256,bool) + handler: handleStakeLocked + - event: StakeSet(indexed address,uint256,uint256,uint256) + handler: handleStakeSet + # FIX: old stake set signature + - event: StakeSet(indexed address,uint256,uint256) + handler: handleStakeSet + file: ./src/SortitionModule.ts diff --git a/subgraph/core/subgraph.yaml b/subgraph/core/subgraph.yaml index d3aff9873..41d8eb000 100644 --- a/subgraph/core/subgraph.yaml +++ b/subgraph/core/subgraph.yaml @@ -1,3 +1,4 @@ +# THIS FILE IS AUTO-GENERATED BY update.sh FROM subgraph.template.yaml, ANY CHANGES WILL BE LOST. specVersion: 0.0.5 schema: file: ./schema.graphql @@ -120,6 +121,44 @@ dataSources: - event: CommitCast(indexed uint256,indexed address,uint256[],bytes32) handler: handleCommitCast file: ./src/DisputeKitClassic.ts + - kind: ethereum + name: DisputeKitShutter + network: arbitrum-sepolia + source: + address: "0x09F3d00B995186D76Af9AA8627D06351d0d9f950" + abi: DisputeKitShutter + startBlock: 148194178 + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - ClassicDispute + - ClassicRound + - ClassicVote + - ClassicContribution + abis: + - name: DisputeKitShutter + file: ../../contracts/deployments/arbitrumSepoliaDevnet/DisputeKitShutter.json + - name: DisputeKitClassic # Testing for Alchemy + file: ../../contracts/deployments/arbitrumSepoliaDevnet/DisputeKitClassic.json + - name: KlerosCore + # FIX: temporarily point to abi with event addition + file: ./abi-migrations/KlerosCore.json + eventHandlers: + - event: DisputeCreation(indexed uint256,uint256,bytes) + 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: ChoiceFunded(indexed uint256,indexed uint256,indexed uint256) + handler: handleChoiceFunded + - event: VoteCast(indexed uint256,indexed address,uint256[],indexed uint256,string) + handler: handleVoteCast + - event: CommitCast(indexed uint256,indexed address,uint256[],bytes32) + handler: handleCommitCast + file: ./src/DisputeKitClassic.ts - kind: ethereum name: EvidenceModule network: arbitrum-sepolia diff --git a/subgraph/dispute-template-registry/subgraph.template.yaml b/subgraph/dispute-template-registry/subgraph.template.yaml new file mode 100644 index 000000000..36f784c12 --- /dev/null +++ b/subgraph/dispute-template-registry/subgraph.template.yaml @@ -0,0 +1,24 @@ +specVersion: 0.0.5 +schema: + file: schema.graphql +dataSources: + - kind: ethereum + name: DisputeTemplateRegistry + network: _PLACEHOLDER_ + source: + address: "_PLACEHOLDER_" + abi: DisputeTemplateRegistry + startBlock: _PLACEHOLDER_ + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - DisputeTemplate + abis: + - name: DisputeTemplateRegistry + file: ../../contracts/deployments/_PLACEHOLDER_/DisputeTemplateRegistry.json + eventHandlers: + - event: DisputeTemplate(indexed uint256,indexed string,string,string) + handler: handleDisputeTemplate + file: src/DisputeTemplateRegistry.ts diff --git a/subgraph/dispute-template-registry/subgraph.yaml b/subgraph/dispute-template-registry/subgraph.yaml index 1fdfc46b6..0e57a2280 100644 --- a/subgraph/dispute-template-registry/subgraph.yaml +++ b/subgraph/dispute-template-registry/subgraph.yaml @@ -1,3 +1,4 @@ +# THIS FILE IS AUTO-GENERATED BY update.sh FROM subgraph.template.yaml, ANY CHANGES WILL BE LOST. specVersion: 0.0.5 schema: file: schema.graphql diff --git a/subgraph/package.json b/subgraph/package.json index 0a125ee5e..b2599e3e8 100644 --- a/subgraph/package.json +++ b/subgraph/package.json @@ -1,6 +1,6 @@ { "name": "@kleros/kleros-v2-subgraph", - "version": "0.15.2", + "version": "0.16.1", "drtVersion": "0.12.0", "license": "MIT", "scripts": { diff --git a/subgraph/scripts/all.sh b/subgraph/scripts/all.sh index 0902ec6f4..3c2b5269b 100755 --- a/subgraph/scripts/all.sh +++ b/subgraph/scripts/all.sh @@ -10,7 +10,7 @@ then exit 1 fi -for subgraph in core drt +for subgraph in core core-neo core-university drt do echo "Running for ${cmdPrefix}:${subgraph}${cmdPostfix:+:}${cmdPostfix}" yarn "${cmdPrefix}:${subgraph}${cmdPostfix:+:}${cmdPostfix}" diff --git a/subgraph/scripts/update.sh b/subgraph/scripts/update.sh index d1223e3ff..3459d30d9 100755 --- a/subgraph/scripts/update.sh +++ b/subgraph/scripts/update.sh @@ -1,9 +1,26 @@ #!/usr/bin/env bash -SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" -function update() #hardhatNetwork #graphNetwork #subgraphConfig #dataSourceIndex #contract -{ +function isContractDeployed() { #hardhatNetwork #graphNetwork #subgraphConfig #dataSourceIndex #contract + local hardhatNetwork="$1" + local graphNetwork="$2" + local subgraphConfig="$3" + local dataSourceIndex="$4" + local dataSourceName="$5" + + # Get the deployment artifact + local contractName=$(basename $(yq '.dataSources['$dataSourceIndex'].mapping.abis[] | select(.name == "'$dataSourceName'") | .file' "$subgraphConfig") .json) + local artifact="$SCRIPT_DIR/../../contracts/deployments/$hardhatNetwork/$contractName.json" + + if [ -f "$artifact" ]; then + return 0 # success in bash + else + return 1 # failure in bash + fi +} + +function update() { #hardhatNetwork #graphNetwork #subgraphConfig #dataSourceIndex #contract local hardhatNetwork="$1" local graphNetwork="$2" local subgraphConfig="$3" @@ -25,15 +42,14 @@ function update() #hardhatNetwork #graphNetwork #subgraphConfig #dataSourceIndex yq -i ".dataSources[$dataSourceIndex].source.startBlock=$blockNumber" "$subgraphConfig" # Set the Graph network - graphNetwork=$graphNetwork yq -i ".dataSources[$dataSourceIndex].network=env(graphNetwork)" "$subgraphConfig" + graphNetwork=$graphNetwork yq -i ".dataSources[$dataSourceIndex].network=env(graphNetwork)" "$subgraphConfig" # Set the ABIs path for this Hardhat network local abiIndex=0 - for f in $(yq e .dataSources[$dataSourceIndex].mapping.abis[].file "$subgraphConfig" -o json -I 0 | jq -sr '.[]') - do + for f in $(yq e .dataSources[$dataSourceIndex].mapping.abis[].file "$subgraphConfig" -o json -I 0 | jq -sr '.[]'); do f2=$(echo $f | sed "s|\(.*\/deployments\/\).*\/|\1$hardhatNetwork\/|") yq -i ".dataSources[$dataSourceIndex].mapping.abis[$abiIndex].file=\"$f2\"" "$subgraphConfig" - (( ++abiIndex )) + ((++abiIndex)) done } @@ -49,9 +65,31 @@ echo "Updating $subgraphConfig" # backup cp "$subgraphConfig" "$subgraphConfig.bak.$(date +%s)" +# initialize from template +template="${subgraphConfig%.yaml}.template.yaml" +echo '# THIS FILE IS AUTO-GENERATED BY update.sh FROM subgraph.template.yaml, ANY CHANGES WILL BE LOST.' > "$subgraphConfig" +cat "$template" >>"$subgraphConfig" + +# find contracts that are not deployed +notDeployedSourceIndices=() +i=0 +for contract in $(yq .dataSources[].name "$subgraphConfig"); do + if ! isContractDeployed $hardhatNetwork $graphNetwork "$subgraphConfig" $i $contract; then + echo -e "\e[1;31mContract $contract is not deployed\e[0m" + notDeployedSourceIndices+=($i) + fi + ((++i)) +done + +# delete the data sources for the contracts that are not deployed +for i in "${notDeployedSourceIndices[@]}"; do + echo -e "\e[1;31mDeleting data source $i\e[0m" + yq -i 'del(.dataSources['$i'])' "$subgraphConfig" +done + +# update the data sources i=0 -for contract in $(yq .dataSources[].name "$subgraphConfig") -do +for contract in $(yq .dataSources[].name "$subgraphConfig"); do update $hardhatNetwork $graphNetwork "$subgraphConfig" $i $contract - (( ++i )) + ((++i)) done