From 1ecd467cf5080c2bdad0e6dc3627393aae94d354 Mon Sep 17 00:00:00 2001 From: Harman-singh-waraich Date: Tue, 19 Dec 2023 17:46:40 +0530 Subject: [PATCH 1/2] chore: add-sortition-module-as-dataSource --- subgraph/core/src/KlerosCore.ts | 32 ++---- subgraph/core/src/SortitionModule.ts | 48 +++++++++ .../core/src/entities/JurorTokensPerCourt.ts | 18 +++- subgraph/core/subgraph.yaml | 33 +++++- subgraph/core/tests/sortition-module-utils.ts | 101 ++++++++++++++++++ subgraph/core/tests/sortition-module.test.ts | 39 +++++++ 6 files changed, 238 insertions(+), 33 deletions(-) create mode 100644 subgraph/core/src/SortitionModule.ts create mode 100644 subgraph/core/tests/sortition-module-utils.ts create mode 100644 subgraph/core/tests/sortition-module.test.ts diff --git a/subgraph/core/src/KlerosCore.ts b/subgraph/core/src/KlerosCore.ts index cfb2b57b4..a8dee3fdc 100644 --- a/subgraph/core/src/KlerosCore.ts +++ b/subgraph/core/src/KlerosCore.ts @@ -20,7 +20,7 @@ import { createDisputeFromEvent } from "./entities/Dispute"; import { createRoundFromRoundInfo } from "./entities/Round"; import { updateCases, updateCasesAppealing, updateCasesRuled, updateCasesVoting } from "./datapoint"; import { addUserActiveDispute, ensureUser } from "./entities/User"; -import { updateJurorDelayedStake, updateJurorStake } from "./entities/JurorTokensPerCourt"; +import { updateJurorStake } from "./entities/JurorTokensPerCourt"; import { createDrawFromEvent } from "./entities/Draw"; import { updateTokenAndEthShiftFromEvent } from "./entities/TokenAndEthShift"; import { updateArbitrableCases } from "./entities/Arbitrable"; @@ -29,6 +29,7 @@ import { BigInt } from "@graphprotocol/graph-ts"; import { updatePenalty } from "./entities/Penalty"; import { ensureFeeToken } from "./entities/FeeToken"; import { getAndIncrementPeriodCounter } from "./entities/PeriodIndexCounter"; +import { SortitionModule } from "../generated/SortitionModule/SortitionModule"; function getPeriodName(index: i32): string { const periodArray = ["evidence", "commit", "vote", "appeal", "execution"]; @@ -177,31 +178,14 @@ export function handleDraw(event: DrawEvent): void { const disputeID = event.params._disputeID.toString(); const dispute = Dispute.load(disputeID); if (!dispute) return; - const contract = KlerosCore.bind(event.address); + const klerosCore = KlerosCore.bind(event.address); + const sortitionModule = SortitionModule.bind(klerosCore.sortitionModule()); + const jurorAddress = event.params._address.toHexString(); - updateJurorStake(jurorAddress, dispute.court, contract, event.block.timestamp); + updateJurorStake(jurorAddress, dispute.court, sortitionModule, event.block.timestamp); addUserActiveDispute(jurorAddress, disputeID); } -// TODO: index the sortition module and handle these events there -// export function handleStakeSet(event: StakeSet): void { -// const jurorAddress = event.params._address.toHexString(); -// ensureUser(jurorAddress); -// 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)); -// } -// } - -// TODO: index the sortition module and handle these events there -// export function handleStakeDelayedNotTransferred(event: StakeDelayedNotTransferred): void { -// updateJurorDelayedStake(event.params._address.toHexString(), event.params._courtID.toString(), event.params._amount); -// } - export function handleTokenAndETHShift(event: TokenAndETHShiftEvent): void { updatePenalty(event); updateTokenAndEthShiftFromEvent(event); @@ -211,7 +195,9 @@ export function handleTokenAndETHShift(event: TokenAndETHShiftEvent): void { if (!dispute) return; const court = Court.load(dispute.court); if (!court) return; - updateJurorStake(jurorAddress, court.id, KlerosCore.bind(event.address), event.block.timestamp); + const klerosCore = KlerosCore.bind(event.address); + const sortitionModule = SortitionModule.bind(klerosCore.sortitionModule()); + updateJurorStake(jurorAddress, court.id, sortitionModule, event.block.timestamp); } export function handleAcceptedFeeToken(event: AcceptedFeeToken): void { diff --git a/subgraph/core/src/SortitionModule.ts b/subgraph/core/src/SortitionModule.ts new file mode 100644 index 000000000..12756967e --- /dev/null +++ b/subgraph/core/src/SortitionModule.ts @@ -0,0 +1,48 @@ +import { + SortitionModule, + StakeDelayedAlreadyTransferred, + StakeDelayedAlreadyTransferredWithdrawn, + StakeDelayedNotTransferred, + StakeLocked, + StakeSet, +} from "../generated/SortitionModule/SortitionModule"; + +import { updateJurorDelayedStake, updateJurorStake } from "./entities/JurorTokensPerCourt"; +import { ensureUser } from "./entities/User"; +import { ZERO } from "./utils"; + +export function handleStakeDelayedAlreadyTransferred(event: StakeDelayedAlreadyTransferred): void { + const jurorAddress = event.params._address.toHexString(); + ensureUser(jurorAddress); + const courtID = event.params._courtID.toString(); + + updateJurorStake(jurorAddress, courtID.toString(), SortitionModule.bind(event.address), event.block.timestamp); + + //stake is updated instantly so no delayed amount, set delay amount to zero + updateJurorDelayedStake(jurorAddress, courtID, ZERO); +} + +export function handleStakeDelayedAlreadyTransferredWithdrawn(event: StakeDelayedAlreadyTransferredWithdrawn): void { + const jurorAddress = event.params._address.toHexString(); + ensureUser(jurorAddress); + const courtID = event.params._courtID.toString(); + + updateJurorStake(jurorAddress, courtID.toString(), SortitionModule.bind(event.address), event.block.timestamp); + + updateJurorDelayedStake(jurorAddress, courtID, ZERO); +} + +export function handleStakeDelayedNotTransferred(event: StakeDelayedNotTransferred): void { + updateJurorDelayedStake(event.params._address.toHexString(), event.params._courtID.toString(), event.params._amount); +} + +export function handleStakeSet(event: StakeSet): void { + const jurorAddress = event.params._address.toHexString(); + ensureUser(jurorAddress); + const courtID = event.params._courtID.toString(); + + updateJurorStake(jurorAddress, courtID.toString(), SortitionModule.bind(event.address), event.block.timestamp); + //stake is updated instantly so no delayed amount, set delay amount to zero + updateJurorDelayedStake(jurorAddress, courtID, ZERO); +} +export function handleStakeLocked(event: StakeLocked): void {} diff --git a/subgraph/core/src/entities/JurorTokensPerCourt.ts b/subgraph/core/src/entities/JurorTokensPerCourt.ts index 6365c972c..db8568729 100644 --- a/subgraph/core/src/entities/JurorTokensPerCourt.ts +++ b/subgraph/core/src/entities/JurorTokensPerCourt.ts @@ -1,9 +1,9 @@ import { BigInt, Address } from "@graphprotocol/graph-ts"; -import { KlerosCore } from "../../generated/KlerosCore/KlerosCore"; import { Court, JurorTokensPerCourt } from "../../generated/schema"; import { updateActiveJurors, getDelta, updateStakedPNK } from "../datapoint"; import { ensureUser } from "./User"; import { ONE, ZERO } from "../utils"; +import { SortitionModule } from "../../generated/SortitionModule/SortitionModule"; export function ensureJurorTokensPerCourt(jurorAddress: string, courtID: string): JurorTokensPerCourt { const id = `${jurorAddress}-${courtID}`; @@ -30,7 +30,12 @@ export function createJurorTokensPerCourt(jurorAddress: string, courtID: string) return jurorTokens; } -export function updateJurorStake(jurorAddress: string, courtID: string, contract: KlerosCore, timestamp: BigInt): void { +export function updateJurorStake( + jurorAddress: string, + courtID: string, + contract: SortitionModule, + timestamp: BigInt +): void { const juror = ensureUser(jurorAddress); const court = Court.load(courtID); if (!court) return; @@ -61,9 +66,12 @@ export function updateJurorDelayedStake(jurorAddress: string, courtID: string, a 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); + let lastDelayedAmount = jurorTokens.delayed; + + jurorTokens.delayed = amount; + //since we need to track only the latest delay amount now, subtract the previous amount and add the new amount + juror.totalDelayed = juror.totalDelayed.plus(amount).minus(lastDelayedAmount); + court.delayedStake = court.stake.plus(amount).minus(lastDelayedAmount); jurorTokens.save(); juror.save(); court.save(); diff --git a/subgraph/core/subgraph.yaml b/subgraph/core/subgraph.yaml index 5464349fe..40612313b 100644 --- a/subgraph/core/subgraph.yaml +++ b/subgraph/core/subgraph.yaml @@ -46,11 +46,6 @@ dataSources: handler: handleDisputeKitCreated - event: DisputeKitEnabled(indexed uint96,indexed uint256,indexed bool) handler: handleDisputeKitEnabled - # TODO: index the sortition module and handle these events there - # - event: StakeSet(indexed address,uint256,uint256) - # handler: handleStakeSet - # - event: StakeDelayedNotTransferred(indexed address,uint256,uint256) - # handler: handleStakeDelayedNotTransferred - event: TokenAndETHShift(indexed address,indexed uint256,indexed uint256,uint256,int256,int256,address) handler: handleTokenAndETHShift - event: Ruling(indexed address,indexed uint256,uint256) @@ -136,3 +131,31 @@ dataSources: - event: Evidence(indexed uint256,indexed address,string) handler: handleEvidenceEvent file: ./src/EvidenceModule.ts + - kind: ethereum + name: SortitionModule + network: mainnet + source: + address: "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c" + abi: SortitionModule + startBlock: 20 + mapping: + kind: ethereum/events + apiVersion: 0.0.6 + language: wasm/assemblyscript + entities: + - JurorTokensPerCourt + abis: + - name: SortitionModule + file: ../contracts/deployments/localhost/SortitionModule.json + eventHandlers: + - 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) + handler: handleStakeSet + file: ./src/SortitionModule.ts diff --git a/subgraph/core/tests/sortition-module-utils.ts b/subgraph/core/tests/sortition-module-utils.ts new file mode 100644 index 000000000..2f999a75d --- /dev/null +++ b/subgraph/core/tests/sortition-module-utils.ts @@ -0,0 +1,101 @@ +import { newMockEvent } from "matchstick-as"; +import { ethereum, BigInt, Address } from "@graphprotocol/graph-ts"; +import { + StakeDelayedAlreadyTransferred, + StakeDelayedAlreadyTransferredWithdrawn, + StakeDelayedNotTransferred, + StakeLocked, + StakeSet, +} from "../generated/SortitionModule/SortitionModule"; + +export function createStakeDelayedAlreadyTransferredEvent( + _address: Address, + _courtID: BigInt, + _amount: BigInt +): StakeDelayedAlreadyTransferred { + let stakeDelayedAlreadyTransferredEvent: StakeDelayedAlreadyTransferred = newMockEvent(); + + stakeDelayedAlreadyTransferredEvent.parameters = new Array(); + + stakeDelayedAlreadyTransferredEvent.parameters.push( + new ethereum.EventParam("_address", ethereum.Value.fromAddress(_address)) + ); + stakeDelayedAlreadyTransferredEvent.parameters.push( + new ethereum.EventParam("_courtID", ethereum.Value.fromUnsignedBigInt(_courtID)) + ); + stakeDelayedAlreadyTransferredEvent.parameters.push( + new ethereum.EventParam("_amount", ethereum.Value.fromUnsignedBigInt(_amount)) + ); + + return stakeDelayedAlreadyTransferredEvent; +} + +export function createStakeDelayedAlreadyTransferredWithdrawnEvent( + _address: Address, + _courtID: BigInt, + _amount: BigInt +): StakeDelayedAlreadyTransferredWithdrawn { + let stakeDelayedAlreadyTransferredWithdrawnEvent = newMockEvent(); + + stakeDelayedAlreadyTransferredWithdrawnEvent.parameters = new Array(); + + stakeDelayedAlreadyTransferredWithdrawnEvent.parameters.push( + new ethereum.EventParam("_address", ethereum.Value.fromAddress(_address)) + ); + stakeDelayedAlreadyTransferredWithdrawnEvent.parameters.push( + new ethereum.EventParam("_courtID", ethereum.Value.fromUnsignedBigInt(_courtID)) + ); + stakeDelayedAlreadyTransferredWithdrawnEvent.parameters.push( + new ethereum.EventParam("_amount", ethereum.Value.fromUnsignedBigInt(_amount)) + ); + + return stakeDelayedAlreadyTransferredWithdrawnEvent; +} + +export function createStakeDelayedNotTransferredEvent( + _address: Address, + _courtID: BigInt, + _amount: BigInt +): StakeDelayedNotTransferred { + let stakeDelayedNotTransferredEvent = newMockEvent(); + + stakeDelayedNotTransferredEvent.parameters = new Array(); + + stakeDelayedNotTransferredEvent.parameters.push( + new ethereum.EventParam("_address", ethereum.Value.fromAddress(_address)) + ); + stakeDelayedNotTransferredEvent.parameters.push( + new ethereum.EventParam("_courtID", ethereum.Value.fromUnsignedBigInt(_courtID)) + ); + stakeDelayedNotTransferredEvent.parameters.push( + new ethereum.EventParam("_amount", ethereum.Value.fromUnsignedBigInt(_amount)) + ); + + return stakeDelayedNotTransferredEvent; +} + +export function createStakeLockedEvent(_address: Address, _relativeAmount: BigInt, _unlock: boolean): StakeLocked { + let stakeLockedEvent = newMockEvent(); + + stakeLockedEvent.parameters = new Array(); + + stakeLockedEvent.parameters.push(new ethereum.EventParam("_address", ethereum.Value.fromAddress(_address))); + stakeLockedEvent.parameters.push( + new ethereum.EventParam("_relativeAmount", ethereum.Value.fromUnsignedBigInt(_relativeAmount)) + ); + stakeLockedEvent.parameters.push(new ethereum.EventParam("_unlock", ethereum.Value.fromBoolean(_unlock))); + + return stakeLockedEvent; +} + +export function createStakeSetEvent(_address: Address, _courtID: BigInt, _amount: BigInt): StakeSet { + let stakeSetEvent = newMockEvent(); + + stakeSetEvent.parameters = new Array(); + + stakeSetEvent.parameters.push(new ethereum.EventParam("_address", ethereum.Value.fromAddress(_address))); + stakeSetEvent.parameters.push(new ethereum.EventParam("_courtID", ethereum.Value.fromUnsignedBigInt(_courtID))); + stakeSetEvent.parameters.push(new ethereum.EventParam("_amount", ethereum.Value.fromUnsignedBigInt(_amount))); + + return stakeSetEvent; +} diff --git a/subgraph/core/tests/sortition-module.test.ts b/subgraph/core/tests/sortition-module.test.ts new file mode 100644 index 000000000..8533bd894 --- /dev/null +++ b/subgraph/core/tests/sortition-module.test.ts @@ -0,0 +1,39 @@ +import { assert, describe, test, clearStore, beforeAll, afterAll } from "matchstick-as/assembly/index"; +import { BigInt, Address } from "@graphprotocol/graph-ts"; +import { handleStakeSet } from "../src/SortitionModule"; +import { createStakeSetEvent } from "./sortition-module-utils"; + +// Tests structure (matchstick-as >=0.5.0) +// https://thegraph.com/docs/en/developer/matchstick/#tests-structure-0-5-0 + +describe("Describe event", () => { + beforeAll(() => { + let courtId = BigInt.fromI32(1); + let amount = BigInt.fromI32(1000); + let jurorAddress = Address.fromString("0x922911F4f80a569a4425fa083456239838F7F003"); + let newStakeSetEvent = createStakeSetEvent(jurorAddress, courtId, amount); + handleStakeSet(newStakeSetEvent); + }); + + afterAll(() => { + clearStore(); + }); + + // For more test scenarios, see: + // https://thegraph.com/docs/en/developer/matchstick/#write-a-unit-test + + test("Initialized created and stored", () => { + assert.entityCount("Initialized", 1); + + // 0xa16081f360e3847006db660bae1c6d1b2e17ec2a is the default address used in newMockEvent() function + // assert.fieldEquals( + // "Initialized", + // "0xa16081f360e3847006db660bae1c6d1b2e17ec2a-1", + // "version", + // "234" + // ) + + // More assert options: + // https://thegraph.com/docs/en/developer/matchstick/#asserts + }); +}); From 0ff60461461cc77db7fd774c1defce2254f5ce33 Mon Sep 17 00:00:00 2001 From: jaybuidl Date: Wed, 20 Dec 2023 19:33:15 +0000 Subject: [PATCH 2/2] chore: subgraph values for devnet --- subgraph/core/subgraph.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/subgraph/core/subgraph.yaml b/subgraph/core/subgraph.yaml index 40612313b..f05d7f20e 100644 --- a/subgraph/core/subgraph.yaml +++ b/subgraph/core/subgraph.yaml @@ -133,11 +133,11 @@ dataSources: file: ./src/EvidenceModule.ts - kind: ethereum name: SortitionModule - network: mainnet + network: arbitrum-sepolia source: - address: "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c" + address: "0xf327200420F21BAafce8F1C03B1EEdF926074B95" abi: SortitionModule - startBlock: 20 + startBlock: 3084593 mapping: kind: ethereum/events apiVersion: 0.0.6 @@ -146,7 +146,7 @@ dataSources: - JurorTokensPerCourt abis: - name: SortitionModule - file: ../contracts/deployments/localhost/SortitionModule.json + file: ../../contracts/deployments/arbitrumSepoliaDevnet/SortitionModule.json eventHandlers: - event: StakeDelayedAlreadyTransferred(indexed address,uint256,uint256) handler: handleStakeDelayedAlreadyTransferred