From 3b694ce35dfd6cc2195857f6d8a65cba2f505d0d Mon Sep 17 00:00:00 2001 From: 0xdavinchee <0xdavinchee@gmail.com> Date: Thu, 29 Feb 2024 13:14:10 +0200 Subject: [PATCH 1/3] fix resolver entry --- packages/subgraph/src/mappingHelpers.ts | 25 ------------ packages/subgraph/src/mappings/resolver.ts | 47 +++++++++++++--------- 2 files changed, 29 insertions(+), 43 deletions(-) diff --git a/packages/subgraph/src/mappingHelpers.ts b/packages/subgraph/src/mappingHelpers.ts index 9c4a53a624..0eaabc909a 100644 --- a/packages/subgraph/src/mappingHelpers.ts +++ b/packages/subgraph/src/mappingHelpers.ts @@ -10,7 +10,6 @@ import { Pool, PoolDistributor, PoolMember, - ResolverEntry, Stream, StreamRevision, Token, @@ -462,30 +461,6 @@ export function getOrInitSubscription( return subscription as IndexSubscription; } -export function getOrInitResolverEntry( - id: string, - target: Address, - block: ethereum.Block -): ResolverEntry { - let resolverEntry = ResolverEntry.load(id); - - if (resolverEntry == null) { - resolverEntry = new ResolverEntry(id); - resolverEntry.createdAtBlockNumber = block.number; - resolverEntry.createdAtTimestamp = block.timestamp; - resolverEntry.targetAddress = target; - - const superToken = Token.load(target.toHex()); - resolverEntry.isToken = superToken != null; - } - resolverEntry.updatedAtBlockNumber = block.number; - resolverEntry.updatedAtTimestamp = block.timestamp; - resolverEntry.isListed = target.notEqual(ZERO_ADDRESS); - - resolverEntry.save(); - return resolverEntry as ResolverEntry; -} - export function getOrInitPool(event: ethereum.Event, poolId: string): Pool { // get existing pool let pool = Pool.load(poolId); diff --git a/packages/subgraph/src/mappings/resolver.ts b/packages/subgraph/src/mappings/resolver.ts index 69a0d3dc26..f23a47b049 100644 --- a/packages/subgraph/src/mappings/resolver.ts +++ b/packages/subgraph/src/mappings/resolver.ts @@ -1,18 +1,13 @@ -import { Bytes, ethereum } from "@graphprotocol/graph-ts"; -import { - RoleAdminChanged, - RoleGranted, - RoleRevoked, - Set, -} from "../../generated/ResolverV1/Resolver"; +import { Address, Bytes, ethereum } from "@graphprotocol/graph-ts"; +import { RoleAdminChanged, RoleGranted, RoleRevoked, Set } from "../../generated/ResolverV1/Resolver"; import { + ResolverEntry, RoleAdminChangedEvent, RoleGrantedEvent, RoleRevokedEvent, SetEvent, Token, } from "../../generated/schema"; -import { getOrInitResolverEntry } from "../mappingHelpers"; import { createEventID, initializeEventEntity, ZERO_ADDRESS } from "../utils"; export function handleRoleAdminChanged(event: RoleAdminChanged): void { @@ -47,14 +42,34 @@ export function handleRoleRevoked(event: RoleRevoked): void { ev.save(); } +function getOrInitResolverEntry(id: string, target: Address, block: ethereum.Block): ResolverEntry { + let resolverEntry = ResolverEntry.load(id); + + if (resolverEntry == null) { + resolverEntry = new ResolverEntry(id); + resolverEntry.createdAtBlockNumber = block.number; + resolverEntry.createdAtTimestamp = block.timestamp; + resolverEntry.targetAddress = target; + } + const isListed = target.notEqual(ZERO_ADDRESS); + + // we only update this if the target is not equal to the zero address + if (isListed) { + resolverEntry.isToken = Token.load(target.toHex()) != null; + } + resolverEntry.updatedAtBlockNumber = block.number; + resolverEntry.updatedAtTimestamp = block.timestamp; + resolverEntry.isListed = isListed; + + resolverEntry.save(); + + return resolverEntry as ResolverEntry; +} + export function handleSet(event: Set): void { _createSetEvent(event, event.params.target, event.params.name); - const resolverEntry = getOrInitResolverEntry( - event.params.name.toHex(), - event.params.target, - event.block - ); + const resolverEntry = getOrInitResolverEntry(event.params.name.toHex(), event.params.target, event.block); // upon initial setting, we will know if this address belongs to a token contract if (resolverEntry.isToken) { @@ -80,11 +95,7 @@ export function handleSet(event: Set): void { resolverEntry.save(); } -function _createSetEvent( - event: ethereum.Event, - target: Bytes, - name: Bytes -): void { +function _createSetEvent(event: ethereum.Event, target: Bytes, name: Bytes): void { const eventId = createEventID("Set", event); const ev = new SetEvent(eventId); initializeEventEntity(ev, event, [target]); From 21b5b1ee6053abb90e166aad6f0c20e205978771 Mon Sep 17 00:00:00 2001 From: 0xdavinchee <0xdavinchee@gmail.com> Date: Mon, 25 Mar 2024 14:30:49 +0200 Subject: [PATCH 2/3] do resolver rpc call on token initialization and remove handleTokenRPCCalls in subsequent token calls --- packages/subgraph/src/addresses.template.ts | 4 ++++ packages/subgraph/src/mappingHelpers.ts | 13 ++++-------- packages/subgraph/src/utils.ts | 23 +++++++++++++++++---- packages/subgraph/tests/mockedFunctions.ts | 4 ++-- 4 files changed, 29 insertions(+), 15 deletions(-) diff --git a/packages/subgraph/src/addresses.template.ts b/packages/subgraph/src/addresses.template.ts index ad6559454c..4edf31d65b 100644 --- a/packages/subgraph/src/addresses.template.ts +++ b/packages/subgraph/src/addresses.template.ts @@ -15,3 +15,7 @@ export function getResolverAddress(): Address { export function getNativeAssetSuperTokenAddress(): Address { return Address.fromString("{{nativeAssetSuperTokenAddress}}"); } + +export function getIsLocalIntegrationTesting(): boolean { + return "{{testNetwork}}".length > 0; +} \ No newline at end of file diff --git a/packages/subgraph/src/mappingHelpers.ts b/packages/subgraph/src/mappingHelpers.ts index 75f4f5bfa5..1453bf3c93 100644 --- a/packages/subgraph/src/mappingHelpers.ts +++ b/packages/subgraph/src/mappingHelpers.ts @@ -36,6 +36,7 @@ import { getActiveStreamsDelta, getClosedStreamsDelta, MAX_UINT256, + getIsTokenListed, } from "./utils"; import { SuperToken as SuperTokenTemplate } from "../generated/templates"; import { ISuperToken as SuperToken } from "../generated/templates/SuperToken/ISuperToken"; @@ -117,8 +118,8 @@ export function getOrInitSuperToken( nativeAssetSuperTokenAddress ); - token = handleTokenRPCCalls(token, resolverAddress); - token.isListed = false; + token = handleTokenRPCCalls(token); + token.isListed = getIsTokenListed(token, resolverAddress); const underlyingAddress = token.underlyingAddress; token.underlyingToken = underlyingAddress.toHexString(); @@ -147,12 +148,6 @@ export function getOrInitSuperToken( return token as Token; } - // @note - this is currently being called every single time to handle list/unlist of tokens - // because we don't have the Resolver Set event on some networks - // We can remove this once we have migrated data to a new resolver which emits this event on - // all networks. - token = handleTokenRPCCalls(token, resolverAddress); - token.save(); return token as Token; @@ -233,7 +228,7 @@ export function getOrInitToken( token.isNativeAssetSuperToken = false; token.isListed = false; - token = handleTokenRPCCalls(token, resolverAddress); + token = handleTokenRPCCalls(token); token.save(); } diff --git a/packages/subgraph/src/utils.ts b/packages/subgraph/src/utils.ts index a182123f3c..3d50ee4839 100644 --- a/packages/subgraph/src/utils.ts +++ b/packages/subgraph/src/utils.ts @@ -8,12 +8,14 @@ import { log, Value, } from "@graphprotocol/graph-ts"; -import { ISuperToken as SuperToken } from "../generated/templates/SuperToken/ISuperToken"; import { IndexSubscription, - Token, PoolMember, + Token, } from "../generated/schema"; +import { ISuperToken as SuperToken } from "../generated/templates/SuperToken/ISuperToken"; +import { Resolver } from "../generated/templates/SuperToken/Resolver"; +import { getIsLocalIntegrationTesting } from "./addresses"; /************************************************************************** * Constants @@ -108,8 +110,7 @@ export function initializeEventEntity( *************************************************************************/ export function handleTokenRPCCalls( - token: Token, - resolverAddress: Address + token: Token ): Token { // we must handle the case when the native token hasn't been initialized // there is no name/symbol, but this may occur later @@ -119,6 +120,20 @@ export function handleTokenRPCCalls( return token; } +export function getIsTokenListed( + token: Token, + resolverAddress: Address +): boolean { + const resolverContract = Resolver.bind(resolverAddress); + const isLocalIntegrationTesting = getIsLocalIntegrationTesting(); + const version = isLocalIntegrationTesting ? "test" : "v1"; + const result = resolverContract.try_get( + "supertokens." + version + "." + token.symbol + ); + const superTokenAddress = result.reverted ? ZERO_ADDRESS : result.value; + return token.id == superTokenAddress.toHex(); +} + export function getTokenInfoAndReturn(token: Token): Token { const tokenAddress = Address.fromString(token.id); const tokenContract = SuperToken.bind(tokenAddress); diff --git a/packages/subgraph/tests/mockedFunctions.ts b/packages/subgraph/tests/mockedFunctions.ts index 88629bdc57..3b658a4a0b 100644 --- a/packages/subgraph/tests/mockedFunctions.ts +++ b/packages/subgraph/tests/mockedFunctions.ts @@ -95,7 +95,7 @@ export function mockedHandleFlowUpdatedRPCCalls( // getOrInitStream(event) => getOrInitAccount(receiver) => host.try_getAppManifest(receiver) mockedGetAppManifest(receiver, false, false, BIG_INT_ZERO); - // [START] getOrInitStream(event) => getOrInitSuperToken(token, block) => handleTokenRPCCalls(token, resolverAddress) + // [START] getOrInitStream(event) => getOrInitSuperToken(token, block) => handleTokenRPCCalls(token) mockedHandleSuperTokenInitRPCCalls( superToken, decimals, @@ -103,7 +103,7 @@ export function mockedHandleFlowUpdatedRPCCalls( tokenName, tokenSymbol ); - // [END] getOrInitStream(event) => getOrInitSuperToken(token, block) => handleTokenRPCCalls(token, resolverAddress) + // [END] getOrInitStream(event) => getOrInitSuperToken(token, block) => handleTokenRPCCalls(token) // updateATSStreamedAndBalanceUntilUpdatedAt => updateATSBalanceAndUpdatedAt => try_realtimeBalanceOf(sender) mockedRealtimeBalanceOf( From d51ea5a8a28e1631385e7ddf430041589835b12c Mon Sep 17 00:00:00 2001 From: 0xdavinchee <0xdavinchee@gmail.com> Date: Mon, 25 Mar 2024 16:05:04 +0200 Subject: [PATCH 3/3] fix broken tests --- .../tests/bugs/2024-02-29-aleph-total-supply.test.ts | 4 +++- packages/subgraph/tests/constants.ts | 2 +- packages/subgraph/tests/idav1/event/idav1.event.test.ts | 6 ++++-- packages/subgraph/tests/mockedFunctions.ts | 7 ++++++- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/subgraph/tests/bugs/2024-02-29-aleph-total-supply.test.ts b/packages/subgraph/tests/bugs/2024-02-29-aleph-total-supply.test.ts index bfb7412813..2862a3c879 100644 --- a/packages/subgraph/tests/bugs/2024-02-29-aleph-total-supply.test.ts +++ b/packages/subgraph/tests/bugs/2024-02-29-aleph-total-supply.test.ts @@ -3,7 +3,7 @@ import { assert, describe, test } from "matchstick-as"; import { handleMinted } from "../../src/mappings/superToken"; import { handleCustomSuperTokenCreated } from "../../src/mappings/superTokenFactory"; import { ZERO_ADDRESS } from "../../src/utils"; -import { bob, alice } from "../constants"; +import { bob, alice, resolverAddress } from "../constants"; import { stringToBytes } from "../converters"; import { mockedGetHost, @@ -12,6 +12,7 @@ import { mockedTokenSymbol, mockedTokenDecimals, mockedTokenTotalSupply, + mockedResolverGet, } from "../mockedFunctions"; import { createMintedEvent } from "../superToken/superToken.helper"; import { createCustomSuperTokenCreatedEvent } from "../superTokenFactory/superTokenFactory.helper"; @@ -30,6 +31,7 @@ describe("ALEPH Total Supply Bug", () => { mockedTokenName(superToken, "tokenName"); mockedTokenSymbol(superToken, "tokenSymbol"); mockedTokenDecimals(superToken, 18); + mockedResolverGet(resolverAddress, "supertokens.v1.tokenSymbol", ZERO_ADDRESS.toHexString()); // unused mocked function call after change in this commit (removing total supply RPC call in getOrInitSuperToken) mockedTokenTotalSupply(superToken, totalSupply); diff --git a/packages/subgraph/tests/constants.ts b/packages/subgraph/tests/constants.ts index 1c15feacfc..11358dc9e9 100644 --- a/packages/subgraph/tests/constants.ts +++ b/packages/subgraph/tests/constants.ts @@ -26,7 +26,7 @@ export const cfaV1Address = "0x6eee6060f715257b970700bc2656de21dedf074c"; export const idaV1Address = "0xb0aabba4b2783a72c52956cdef62d438eca2d7a1"; export const superTokenFactoryAddress = "0x2c90719f25b10fc5646c82da3240c76fa5bccf34"; export const superTokenLogicAddress = "0x1349b5f1006ef0366a7b6ae41fa9155c6cd91e4b"; -export const resolverAddress = "0xe0cc76334405ee8b39213e620587d815967af39c"; +export const resolverAddress = "0x8bDCb5613153f41B2856F71Bd7A7e0432F6dbe58"; // this is not the actual TOGA export const togaAddress = "0x6aeaee5fd4d05a741723d752d30ee4d72690a8f7"; export const maticXAddress = "0x3ad736904e9e65189c3000c7dd2c8ac8bb7cd4e3"; diff --git a/packages/subgraph/tests/idav1/event/idav1.event.test.ts b/packages/subgraph/tests/idav1/event/idav1.event.test.ts index 7bc6e08288..c343d17049 100644 --- a/packages/subgraph/tests/idav1/event/idav1.event.test.ts +++ b/packages/subgraph/tests/idav1/event/idav1.event.test.ts @@ -14,9 +14,9 @@ import { } from "../../../src/mappings/idav1"; import { BIG_INT_ZERO, getIndexID, ZERO_ADDRESS } from "../../../src/utils"; import { assertIDAEventBaseProperties, assertIDAIndexEventBaseProperties } from "../../assertionHelpers"; -import { alice, bob, DEFAULT_DECIMALS, FAKE_INITIAL_BALANCE, maticXAddress, maticXName, maticXSymbol } from "../../constants"; +import { alice, bob, DEFAULT_DECIMALS, FAKE_INITIAL_BALANCE, maticXAddress, maticXName, maticXSymbol, resolverAddress } from "../../constants"; import { stringToBytes } from "../../converters"; -import { mockedGetAppManifest, mockedGetHost, mockedHandleSuperTokenInitRPCCalls, mockedRealtimeBalanceOf } from "../../mockedFunctions"; +import { mockedGetAppManifest, mockedGetHost, mockedHandleSuperTokenInitRPCCalls, mockedRealtimeBalanceOf, mockedResolverGet } from "../../mockedFunctions"; import { createIndexCreatedEvent, createIndexDistributionClaimedEvent, @@ -267,6 +267,8 @@ describe("InstantDistributionV1 Event Entity Unit Tests", () => { userData ); + mockedResolverGet(resolverAddress, "supertokens.v1.MATICx", ZERO_ADDRESS.toHexString()); + mockedRealtimeBalanceOf( superToken, subscriber, diff --git a/packages/subgraph/tests/mockedFunctions.ts b/packages/subgraph/tests/mockedFunctions.ts index 3b658a4a0b..b7ef7a8426 100644 --- a/packages/subgraph/tests/mockedFunctions.ts +++ b/packages/subgraph/tests/mockedFunctions.ts @@ -1,11 +1,12 @@ import { Address, BigInt, ethereum } from "@graphprotocol/graph-ts"; import { createMockedFunction } from "matchstick-as/assembly/index"; import { FlowUpdated } from "../generated/ConstantFlowAgreementV1/IConstantFlowAgreementV1"; -import { BIG_INT_ZERO } from "../src/utils"; +import { BIG_INT_ZERO, ZERO_ADDRESS } from "../src/utils"; import { FAKE_INITIAL_BALANCE, FAKE_SUPER_TOKEN_TOTAL_SUPPLY, hostAddress, + resolverAddress, } from "./constants"; import { getETHAddress, @@ -46,6 +47,8 @@ export function mockedHandleSuperTokenInitRPCCalls( mockedTokenDecimals(superToken, decimals); // [END] getTokenInfoAndReturn + mockedResolverGet(resolverAddress, "supertokens.v1." + tokenSymbol, ZERO_ADDRESS.toHexString()); + // updateTotalSupplyForNativeSuperToken(token, tokenStatistic, tokenAddress) mockedTokenTotalSupply(superToken, FAKE_SUPER_TOKEN_TOTAL_SUPPLY); } @@ -105,6 +108,8 @@ export function mockedHandleFlowUpdatedRPCCalls( ); // [END] getOrInitStream(event) => getOrInitSuperToken(token, block) => handleTokenRPCCalls(token) + mockedResolverGet(resolverAddress, "supertokens.v1." + tokenSymbol, ZERO_ADDRESS.toHexString()); + // updateATSStreamedAndBalanceUntilUpdatedAt => updateATSBalanceAndUpdatedAt => try_realtimeBalanceOf(sender) mockedRealtimeBalanceOf( superToken,