diff --git a/subgraph/schema.graphql b/subgraph/schema.graphql index 13fedcf1b..a0b86a914 100644 --- a/subgraph/schema.graphql +++ b/subgraph/schema.graphql @@ -61,6 +61,7 @@ type User @entity { id: ID! # address tokens: [JurorTokensPerCourt!]! @derivedFrom(field: "juror") totalStake: BigInt! + totalDelayed: BigInt! shifts: [TokenAndETHShift!]! @derivedFrom(field: "juror") draws: [Draw!]! @derivedFrom(field: "juror") activeDisputes: BigInt! @@ -104,6 +105,7 @@ type JurorTokensPerCourt @entity { court: Court! staked: BigInt! locked: BigInt! + delayed: BigInt! } type Court @entity { @@ -124,6 +126,7 @@ type Court @entity { stakedJurors: [JurorTokensPerCourt!]! @derivedFrom(field: "court") numberStakedJurors: BigInt! stake: BigInt! + delayedStake: BigInt! paidETH: BigInt! paidPNK: BigInt! } diff --git a/subgraph/src/KlerosCore.ts b/subgraph/src/KlerosCore.ts index fe4bc689d..aa48e0281 100644 --- a/subgraph/src/KlerosCore.ts +++ b/subgraph/src/KlerosCore.ts @@ -18,17 +18,9 @@ import { createCourtFromEvent, getFeeForJuror } from "./entities/Court"; import { createDisputeKitFromEvent, filterSupportedDisputeKits } from "./entities/DisputeKit"; import { createDisputeFromEvent } from "./entities/Dispute"; import { createRoundFromRoundInfo } from "./entities/Round"; -import { - updateCases, - updatePaidETH, - updateStakedPNK, - updateRedistributedPNK, - updateCasesRuled, - updateCasesVoting, - getDelta, -} from "./datapoint"; +import { updateCases, updatePaidETH, updateRedistributedPNK, updateCasesRuled, updateCasesVoting } from "./datapoint"; import { addUserActiveDispute, ensureUser, resolveUserDispute } from "./entities/User"; -import { ensureJurorTokensPerCourt, updateJurorStake } from "./entities/JurorTokensPerCourt"; +import { updateJurorDelayedStake, updateJurorStake } from "./entities/JurorTokensPerCourt"; import { createDrawFromEvent } from "./entities/Draw"; import { createTokenAndEthShiftFromEvent } from "./entities/TokenAndEthShift"; import { updateArbitrableCases } from "./entities/Arbitrable"; @@ -144,17 +136,18 @@ export function handleDraw(event: DrawEvent): void { export function handleStakeSet(event: StakeSet): void { const jurorAddress = event.params._address.toHexString(); ensureUser(jurorAddress); - const courtID = event.params._courtID; + const courtID = event.params._courtID.toString(); updateJurorStake(jurorAddress, courtID.toString(), KlerosCore.bind(event.address), event.block.timestamp); + + // Check if the transaction the event comes from is executeDelayedStakes + if (event.transaction.input.toHexString().substring(0, 10) === "0x35975f4a") { + updateJurorDelayedStake(jurorAddress, courtID, ZERO.minus(event.params._amount)); + } } export function handleStakeDelayed(event: StakeDelayed): void { - const jurorAddress = event.params._address.toHexString(); - ensureUser(jurorAddress); - const courtID = event.params._courtID; - - // TODO: Update stake delayed + updateJurorDelayedStake(event.params._address.toString(), event.params._courtID.toString(), event.params._amount); } export function handleTokenAndETHShift(event: TokenAndETHShiftEvent): void { diff --git a/subgraph/src/entities/Court.ts b/subgraph/src/entities/Court.ts index 618eed5b6..520f9b2c7 100644 --- a/subgraph/src/entities/Court.ts +++ b/subgraph/src/entities/Court.ts @@ -12,12 +12,11 @@ export function createCourtFromEvent(event: CourtCreated): void { court.feeForJuror = event.params._feeForJuror; court.jurorsForCourtJump = event.params._jurorsForCourtJump; court.timesPerPeriod = event.params._timesPerPeriod; - court.supportedDisputeKits = event.params._supportedDisputeKits.map( - (value) => value.toString() - ); + court.supportedDisputeKits = event.params._supportedDisputeKits.map((value) => value.toString()); court.numberDisputes = ZERO; court.numberStakedJurors = ZERO; court.stake = ZERO; + court.delayedStake = ZERO; court.paidETH = ZERO; court.paidPNK = ZERO; court.save(); diff --git a/subgraph/src/entities/JurorTokensPerCourt.ts b/subgraph/src/entities/JurorTokensPerCourt.ts index 786516d9f..cccf06d7b 100644 --- a/subgraph/src/entities/JurorTokensPerCourt.ts +++ b/subgraph/src/entities/JurorTokensPerCourt.ts @@ -5,31 +5,18 @@ import { updateActiveJurors, getDelta, updateStakedPNK } from "../datapoint"; import { ensureUser } from "./User"; import { ONE, ZERO } from "../utils"; -export function ensureJurorTokensPerCourt( - jurorAddress: string, - courtID: string -): JurorTokensPerCourt { +export function ensureJurorTokensPerCourt(jurorAddress: string, courtID: string): JurorTokensPerCourt { const id = `${jurorAddress}-${courtID}`; - let jurorTokens = JurorTokensPerCourt.load(id); + const jurorTokens = JurorTokensPerCourt.load(id); if (jurorTokens) { return jurorTokens; } - jurorTokens = new JurorTokensPerCourt(id); - jurorTokens.juror = jurorAddress; - jurorTokens.court = courtID; - jurorTokens.staked = ZERO; - jurorTokens.locked = ZERO; - jurorTokens.save(); - - return jurorTokens; + return createJurorTokensPerCourt(jurorAddress, courtID); } -export function createJurorTokensPerCourt( - jurorAddress: string, - courtID: string -): JurorTokensPerCourt { +export function createJurorTokensPerCourt(jurorAddress: string, courtID: string): JurorTokensPerCourt { const id = `${jurorAddress}-${courtID}`; const jurorTokens = new JurorTokensPerCourt(id); @@ -37,25 +24,18 @@ export function createJurorTokensPerCourt( jurorTokens.court = courtID; jurorTokens.staked = ZERO; jurorTokens.locked = ZERO; + jurorTokens.delayed = ZERO; jurorTokens.save(); return jurorTokens; } -export function updateJurorStake( - jurorAddress: string, - courtID: string, - contract: KlerosCore, - timestamp: BigInt -): void { +export function updateJurorStake(jurorAddress: string, courtID: string, contract: KlerosCore, timestamp: BigInt): void { const juror = ensureUser(jurorAddress); const court = Court.load(courtID); if (!court) return; const jurorTokens = ensureJurorTokensPerCourt(jurorAddress, courtID); - const jurorBalance = contract.getJurorBalance( - Address.fromString(jurorAddress), - BigInt.fromString(courtID) - ); + const jurorBalance = contract.getJurorBalance(Address.fromString(jurorAddress), BigInt.fromString(courtID)); const previousStake = jurorTokens.staked; const previousTotalStake = juror.totalStake; jurorTokens.staked = jurorBalance.value0; @@ -67,16 +47,26 @@ export function updateJurorStake( court.stake = court.stake.plus(stakeDelta); updateStakedPNK(stakeDelta, timestamp); const activeJurorsDelta = getActivityDelta(previousTotalStake, newTotalStake); - const stakedJurorsDelta = getActivityDelta( - previousStake, - jurorBalance.value0 - ); + const stakedJurorsDelta = getActivityDelta(previousStake, jurorBalance.value0); court.numberStakedJurors = court.numberStakedJurors.plus(stakedJurorsDelta); updateActiveJurors(activeJurorsDelta, timestamp); juror.save(); court.save(); } +export function updateJurorDelayedStake(jurorAddress: string, courtID: string, amount: BigInt): void { + const juror = ensureUser(jurorAddress); + const court = Court.load(courtID); + if (!court) return; + const jurorTokens = ensureJurorTokensPerCourt(jurorAddress, courtID); + jurorTokens.delayed = jurorTokens.delayed.plus(amount); + juror.totalDelayed = juror.totalDelayed.plus(amount); + court.delayedStake = court.stake.plus(amount); + jurorTokens.save(); + juror.save(); + court.save(); +} + function getActivityDelta(previousStake: BigInt, newStake: BigInt): BigInt { if (previousStake.gt(ZERO)) { return newStake.gt(ZERO) ? ZERO : BigInt.fromI32(-1); diff --git a/subgraph/src/entities/User.ts b/subgraph/src/entities/User.ts index 333ae517a..3e8367517 100644 --- a/subgraph/src/entities/User.ts +++ b/subgraph/src/entities/User.ts @@ -15,6 +15,7 @@ export function ensureUser(id: string): User { export function createUserFromAddress(id: string): User { const user = new User(id); user.totalStake = ZERO; + user.totalDelayed = ZERO; user.activeDisputes = ZERO; user.disputes = []; user.resolvedDisputes = []; @@ -36,11 +37,7 @@ export function addUserActiveDispute(id: string, disputeID: string): void { user.save(); } -export function resolveUserDispute( - id: string, - tokenAmount: BigInt, - disputeID: string -): void { +export function resolveUserDispute(id: string, tokenAmount: BigInt, disputeID: string): void { const user = ensureUser(id); if (user.resolvedDisputes.includes(disputeID)) { return;