diff --git a/schema.graphql b/schema.graphql index 6ab70b4..48a36f5 100644 --- a/schema.graphql +++ b/schema.graphql @@ -639,6 +639,12 @@ type UserIDOInvestment @entity(immutable: false) { blockTimestamp: BigInt! } +type UserTotalSpent @entity(immutable: false) { + id: ID! # user address + user: Bytes! # address + totalSpent: BigInt! # uint256 - total amount invested across all IDOs +} + type TotalInvested @entity(immutable: false) { id: ID! poolId: BigInt! # uint256 diff --git a/src/extendedEntities/investProvider.ts b/src/extendedEntities/investProvider.ts index 1f8ebe1..3e65261 100644 --- a/src/extendedEntities/investProvider.ts +++ b/src/extendedEntities/investProvider.ts @@ -1,5 +1,5 @@ import { BigInt, Bytes, log } from "@graphprotocol/graph-ts" -import { PoolData, TotalInvested, UserIDOInvestment } from "../../generated/schema" +import { PoolData, TotalInvested, UserIDOInvestment, UserTotalSpent } from "../../generated/schema" export function updateTotalInvested(poolId: BigInt, amount: BigInt): void { let totalInvested = TotalInvested.load(poolId.toHexString()) // id is string @@ -46,3 +46,17 @@ export function updateInvestProviderPoolParams(poolId: BigInt, amount: BigInt): poolData.save() } } + +export function updateUserTotalSpent(user: Bytes, amount: BigInt): void { + let userTotalSpent = UserTotalSpent.load(user.toHex()) + + if (userTotalSpent == null) { + userTotalSpent = new UserTotalSpent(user.toHex()) + userTotalSpent.user = user + userTotalSpent.totalSpent = amount + } else { + userTotalSpent.totalSpent = userTotalSpent.totalSpent.plus(amount) + } + + userTotalSpent.save() +} diff --git a/src/invest-provider.ts b/src/invest-provider.ts index e7ad019..79144d2 100644 --- a/src/invest-provider.ts +++ b/src/invest-provider.ts @@ -14,7 +14,7 @@ import { InvestNewPoolCreated, UpdateParams, } from "../generated/schema" -import { updateTotalInvested, createTotalInvested, updateUserIDOInvestment, updateInvestProviderPoolParams } from "./extendedEntities/investProvider" +import { updateTotalInvested, createTotalInvested, updateUserIDOInvestment, updateInvestProviderPoolParams, updateUserTotalSpent } from "./extendedEntities/investProvider" import { updatePoolParams } from "./extendedEntities/poolData" export function handleEIP712DomainChanged( @@ -76,6 +76,7 @@ export function handleInvested(event: InvestedEvent): void { updateUserIDOInvestment(event.params.poolId, event.params.user, event.params.amount, event.block.timestamp) updateTotalInvested(event.params.poolId, event.params.amount) updateInvestProviderPoolParams(event.params.poolId, event.params.amount) + updateUserTotalSpent(event.params.user, event.params.amount) } export function handleNewPoolCreated(event: NewPoolCreatedEvent): void { diff --git a/tests/invest-provider.test.ts b/tests/invest-provider.test.ts index 516cec1..edef6e1 100644 --- a/tests/invest-provider.test.ts +++ b/tests/invest-provider.test.ts @@ -128,6 +128,16 @@ describe("Describe entity assertions", () => { "0x0000000000000000000000000000000000000002", ) assert.fieldEquals("UserIDOInvestment", userId, "amount", "100") + + // Test UserTotalSpent entity + assert.entityCount("UserTotalSpent", 1) + assert.fieldEquals( + "UserTotalSpent", + userHex, + "user", + "0x0000000000000000000000000000000000000002" + ) + assert.fieldEquals("UserTotalSpent", userHex, "totalSpent", "100") }) }) @@ -174,5 +184,77 @@ describe("UserIDOInvestment timestamp updates", () => { assert.entityCount("UserIDOInvestment", 1) assert.fieldEquals("UserIDOInvestment", id, "amount", "150") assert.fieldEquals("UserIDOInvestment", id, "blockTimestamp", "2000") + + // Test UserTotalSpent accumulation across multiple investments + let userHex = "0x0000000000000000000000000000000000000002" + assert.entityCount("UserTotalSpent", 1) + assert.fieldEquals("UserTotalSpent", userHex, "totalSpent", "150") // 100 + 50 = 150 + }) +}) + +describe("UserTotalSpent cross-IDO accumulation", () => { + beforeAll(() => { + // Create multiple pools and multiple users + let poolId1 = BigInt.fromI32(10) + let poolId2 = BigInt.fromI32(20) + let owner = Address.fromString("0x0000000000000000000000000000000000000001") + let poolAmount = BigInt.fromI32(1000) + + // Create first pool + let newPoolCreatedEvent1 = createNewPoolCreatedEvent(poolId1, owner, poolAmount) + handleNewPoolCreated(newPoolCreatedEvent1) + + // Create second pool + let newPoolCreatedEvent2 = createNewPoolCreatedEvent(poolId2, owner, poolAmount) + handleNewPoolCreated(newPoolCreatedEvent2) + + // User A invests in both pools + let userA = Address.fromString("0x0000000000000000000000000000000000000003") + let amountA1 = BigInt.fromI32(100) // invest 100 in pool 10 + let amountA2 = BigInt.fromI32(200) // invest 200 in pool 20 + + let investedEventA1 = createInvestedEvent(poolId1, userA, amountA1, BigInt.fromI32(1)) + handleInvested(investedEventA1) + + let investedEventA2 = createInvestedEvent(poolId2, userA, amountA2, BigInt.fromI32(2)) + handleInvested(investedEventA2) + + // User B invests only in pool 10 + let userB = Address.fromString("0x0000000000000000000000000000000000000004") + let amountB1 = BigInt.fromI32(50) // invest 50 in pool 10 + + let investedEventB1 = createInvestedEvent(poolId1, userB, amountB1, BigInt.fromI32(3)) + handleInvested(investedEventB1) + }) + + afterAll(() => { + clearStore() + }) + + test("UserTotalSpent accumulates correctly across multiple IDOs", () => { + let userAHex = "0x0000000000000000000000000000000000000003" + let userBHex = "0x0000000000000000000000000000000000000004" + + // Should have 2 UserTotalSpent entities (userA and userB) + assert.entityCount("UserTotalSpent", 2) + + // User A should have total spent = 100 + 200 = 300 + assert.fieldEquals("UserTotalSpent", userAHex, "totalSpent", "300") + assert.fieldEquals("UserTotalSpent", userAHex, "user", userAHex) + + // User B should have total spent = 50 + assert.fieldEquals("UserTotalSpent", userBHex, "totalSpent", "50") + assert.fieldEquals("UserTotalSpent", userBHex, "user", userBHex) + + // Check that UserIDOInvestment entities are created correctly + assert.entityCount("UserIDOInvestment", 3) // userA-pool10, userA-pool20, userB-pool10 + + let userAPool10Id = "0xa" + "-" + userAHex + let userAPool20Id = "0x14" + "-" + userAHex + let userBPool10Id = "0xa" + "-" + userBHex + + assert.fieldEquals("UserIDOInvestment", userAPool10Id, "amount", "100") + assert.fieldEquals("UserIDOInvestment", userAPool20Id, "amount", "200") + assert.fieldEquals("UserIDOInvestment", userBPool10Id, "amount", "50") }) })