Skip to content

Commit

Permalink
[SUBGRAPH] fix resolver entry (#1843)
Browse files Browse the repository at this point in the history
* fix resolver entry

* do resolver rpc call on token initialization and remove handleTokenRPCCalls in subsequent token calls

* fix broken tests
  • Loading branch information
0xdavinchee authored Mar 25, 2024
1 parent c3e41bb commit 6a9e78b
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 79 deletions.
4 changes: 4 additions & 0 deletions packages/subgraph/src/addresses.template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,7 @@ export function getResolverAddress(): Address {
export function getNativeAssetSuperTokenAddress(): Address {
return Address.fromString("{{nativeAssetSuperTokenAddress}}");
}

export function getIsLocalIntegrationTesting(): boolean {
return "{{testNetwork}}".length > 0;
}
68 changes: 19 additions & 49 deletions packages/subgraph/src/mappingHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Address, BigInt, ethereum } from "@graphprotocol/graph-ts";
import { FlowUpdated } from "../generated/ConstantFlowAgreementV1/IConstantFlowAgreementV1";
import { ISuperfluid as Superfluid } from "../generated/Host/ISuperfluid";
import {
Account,
Expand All @@ -10,41 +11,40 @@ import {
Pool,
PoolDistributor,
PoolMember,
ResolverEntry,
Stream,
StreamRevision,
Token,
TokenGovernanceConfig,
TokenStatistic,
TokenStatisticLog,
} from "../generated/schema";
import { SuperToken as SuperTokenTemplate } from "../generated/templates";
import { ISuperToken as SuperToken } from "../generated/templates/SuperToken/ISuperToken";
import {
getHostAddress,
getNativeAssetSuperTokenAddress,
getResolverAddress,
} from "./addresses";
import {
BIG_INT_ZERO,
createLogID,
ZERO_ADDRESS,
calculateMaybeCriticalAtTimestamp,
createLogID,
getAccountTokenSnapshotID,
getActiveStreamsDelta,
getAmountStreamedSinceLastUpdatedAt,
getClosedStreamsDelta,
getFlowOperatorID,
getIndexID,
getIsTokenListed,
getOrder,
getPoolDistributorID,
getPoolMemberID,
getStreamID,
getStreamRevisionID,
getSubscriptionID,
ZERO_ADDRESS,
handleTokenRPCCalls,
getPoolMemberID,
getPoolDistributorID,
getActiveStreamsDelta,
getClosedStreamsDelta,
handleTokenRPCCalls
} from "./utils";
import { SuperToken as SuperTokenTemplate } from "../generated/templates";
import { ISuperToken as SuperToken } from "../generated/templates/SuperToken/ISuperToken";
import {
getHostAddress,
getNativeAssetSuperTokenAddress,
getResolverAddress,
} from "./addresses";
import { FlowUpdated } from "../generated/ConstantFlowAgreementV1/IConstantFlowAgreementV1";

/**************************************************************************
* HOL initializer functions
Expand Down Expand Up @@ -117,8 +117,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();
token.governanceConfig = ZERO_ADDRESS.toHexString();
Expand Down Expand Up @@ -148,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;
Expand Down Expand Up @@ -240,7 +234,7 @@ export function getOrInitToken(
token.isNativeAssetSuperToken = false;
token.isListed = false;

token = handleTokenRPCCalls(token, resolverAddress);
token = handleTokenRPCCalls(token);
token.save();
}

Expand Down Expand Up @@ -463,30 +457,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);
Expand Down
47 changes: 29 additions & 18 deletions packages/subgraph/src/mappings/resolver.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -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) {
Expand All @@ -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]);
Expand Down
23 changes: 19 additions & 4 deletions packages/subgraph/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -12,6 +12,7 @@ import {
mockedTokenSymbol,
mockedTokenDecimals,
mockedTokenTotalSupply,
mockedResolverGet,
} from "../mockedFunctions";
import { createMintedEvent } from "../superToken/superToken.helper";
import { createCustomSuperTokenCreatedEvent } from "../superTokenFactory/superTokenFactory.helper";
Expand All @@ -30,7 +31,8 @@ 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);

Expand Down
2 changes: 1 addition & 1 deletion packages/subgraph/tests/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
6 changes: 4 additions & 2 deletions packages/subgraph/tests/idav1/event/idav1.event.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -267,6 +267,8 @@ describe("InstantDistributionV1 Event Entity Unit Tests", () => {
userData
);

mockedResolverGet(resolverAddress, "supertokens.v1.MATICx", ZERO_ADDRESS.toHexString());

mockedRealtimeBalanceOf(
superToken,
subscriber,
Expand Down
11 changes: 8 additions & 3 deletions packages/subgraph/tests/mockedFunctions.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -95,15 +98,17 @@ 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,
underlyingAddress,
tokenName,
tokenSymbol
);
// [END] getOrInitStream(event) => getOrInitSuperToken(token, block) => handleTokenRPCCalls(token, resolverAddress)
// [END] getOrInitStream(event) => getOrInitSuperToken(token, block) => handleTokenRPCCalls(token)

mockedResolverGet(resolverAddress, "supertokens.v1." + tokenSymbol, ZERO_ADDRESS.toHexString());

// updateATSStreamedAndBalanceUntilUpdatedAt => updateATSBalanceAndUpdatedAt => try_realtimeBalanceOf(sender)
mockedRealtimeBalanceOf(
Expand Down

0 comments on commit 6a9e78b

Please sign in to comment.