Skip to content

Commit

Permalink
feat: fetch token from whitelist in PoolCreated handler
Browse files Browse the repository at this point in the history
  • Loading branch information
0xnigir1 committed Oct 21, 2024
1 parent 63637c6 commit 2073ef8
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 19 deletions.
24 changes: 9 additions & 15 deletions packages/processors/src/allo/handlers/poolCreated.handler.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Address, getAddress, parseUnits, zeroAddress } from "viem";
import { getAddress, parseUnits, zeroAddress } from "viem";

import type { Changeset, NewRound, PendingRoundRole } from "@grants-stack-indexer/repository";
import type { ChainId, ProtocolEvent } from "@grants-stack-indexer/shared";
import type { ChainId, ProtocolEvent, Token } from "@grants-stack-indexer/shared";
import { isAlloNativeToken } from "@grants-stack-indexer/shared";
import { getToken } from "@grants-stack-indexer/shared/dist/src/internal.js";

import type { IEventHandler, ProcessorDependencies, StrategyTimings } from "../../internal.js";
import { getRoundRoles } from "../../helpers/roles.js";
Expand All @@ -17,7 +18,7 @@ type Dependencies = Pick<
>;

// sometimes coingecko returns no prices for 1 hour range, 2 hours works better
const TIMESTAMP_DELTA_RANGE = 2 * 60 * 60 * 1000;
export const TIMESTAMP_DELTA_RANGE = 2 * 60 * 60 * 1000;

/**
/**
Expand Down Expand Up @@ -62,13 +63,7 @@ export class PoolCreatedHandler implements IEventHandler<"Allo", "PoolCreated">

const strategy = extractStrategyFromId(strategyId);

// TODO: get token for the chain
const token = {
address: matchTokenAddress,
decimals: 18, //TODO: get decimals from token
symbol: "USDC", //TODO: get symbol from token
name: "USDC", //TODO: get name from token
};
const token = getToken(this.chainId, matchTokenAddress);

let strategyTimings: StrategyTimings = {
applicationsStartTime: null,
Expand All @@ -87,7 +82,7 @@ export class PoolCreatedHandler implements IEventHandler<"Allo", "PoolCreated">
if (
strategy.name === "allov2.DonationVotingMerkleDistributionDirectTransferStrategy" &&
parsedRoundMetadata.success &&
token !== null
token
) {
matchAmount = parseUnits(
parsedRoundMetadata.data.quadraticFundingConfig.matchingFundsAvailable.toString(),
Expand All @@ -104,7 +99,7 @@ export class PoolCreatedHandler implements IEventHandler<"Allo", "PoolCreated">

let fundedAmountInUsd = "0";

if (token !== null && fundedAmount > 0n) {
if (token && fundedAmount > 0n) {
fundedAmountInUsd = await this.getTokenAmountInUsd(
token,
fundedAmount,
Expand Down Expand Up @@ -206,14 +201,13 @@ export class PoolCreatedHandler implements IEventHandler<"Allo", "PoolCreated">
}

private async getTokenAmountInUsd(
token: { address: Address; decimals: number },
token: Token,
amount: bigint,
timestamp: number,
): Promise<string> {
const { pricingProvider } = this.dependencies;
const tokenPrice = await pricingProvider.getTokenPrice(
this.chainId,
token.address,
token.priceSourceCode,
timestamp,
timestamp + TIMESTAMP_DELTA_RANGE,
);
Expand Down
84 changes: 80 additions & 4 deletions packages/processors/test/allo/handlers/poolCreated.handler.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ import type { EvmProvider } from "@grants-stack-indexer/chain-providers";
import type { IMetadataProvider } from "@grants-stack-indexer/metadata";
import type { IPricingProvider } from "@grants-stack-indexer/pricing";
import type { IRoundReadRepository, Round } from "@grants-stack-indexer/repository";
import type { ChainId, DeepPartial, ProtocolEvent } from "@grants-stack-indexer/shared";
import type { ChainId, DeepPartial, ProtocolEvent, TokenCode } from "@grants-stack-indexer/shared";
import { mergeDeep } from "@grants-stack-indexer/shared";

import { PoolCreatedHandler } from "../../../src/allo/handlers/poolCreated.handler.js";
import {
PoolCreatedHandler,
TIMESTAMP_DELTA_RANGE,
} from "../../../src/allo/handlers/poolCreated.handler.js";

// Function to create a mock event with optional overrides
function createMockEvent(
Expand Down Expand Up @@ -419,6 +422,79 @@ describe("PoolCreatedHandler", () => {
);
});

it.skip("handles a native token");
it.skip("handles an unknown token");
it("handles a native token", async () => {
const mockEvent = createMockEvent({
params: { token: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" },
});

vi.spyOn(mockMetadataProvider, "getMetadata").mockResolvedValue({
round: {
name: "Test Round",
roundType: "private",
quadraticFundingConfig: {
matchingFundsAvailable: 1,
},
},
application: {
version: "1.0.0",
},
});
vi.spyOn(mockPricingProvider, "getTokenPrice").mockResolvedValue({
priceUsd: 2500,
timestampMs: 1708369911,
});
vi.spyOn(mockEvmProvider, "multicall").mockResolvedValue([
1609459200n,
1609459200n,
1609459200n,
1609459200n,
]);

vi.spyOn(mockRoundRepository, "getPendingRoundRoles").mockResolvedValue([]);

const handler = new PoolCreatedHandler(mockEvent, 10 as ChainId, {
evmProvider: mockEvmProvider,
pricingProvider: mockPricingProvider,
metadataProvider: mockMetadataProvider,
roundRepository: mockRoundRepository,
});

await handler.handle();

expect(mockPricingProvider.getTokenPrice).toHaveBeenCalledWith(
"ETH" as TokenCode,
1708369911,
1708369911 + TIMESTAMP_DELTA_RANGE,
);
});

it("handles an unknown token", async () => {
const fundedAmount = parseUnits("10", 18);
const mockEvent = createMockEvent({
params: {
amount: fundedAmount,
token: "0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE",
strategyId: "0xunknown",
},
});

vi.spyOn(mockRoundRepository, "getPendingRoundRoles").mockResolvedValue([]);

const handler = new PoolCreatedHandler(mockEvent, 10 as ChainId, {
evmProvider: mockEvmProvider,
pricingProvider: mockPricingProvider,
metadataProvider: mockMetadataProvider,
roundRepository: mockRoundRepository,
});

const result = await handler.handle();

const changeset = result[0] as { type: "InsertRound"; args: { round: Round } };
expect(changeset.type).toBe("InsertRound");
expect(changeset.args.round).toMatchObject({
fundedAmount: fundedAmount,
fundedAmountInUsd: "0", //since it's an unknown token
});
expect(mockPricingProvider.getTokenPrice).not.toHaveBeenCalled();
});
});
4 changes: 4 additions & 0 deletions packages/shared/src/tokens/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -602,3 +602,7 @@ export const TOKENS: {
},
},
} as const;

export const getToken = (chainId: number, tokenAddress: Address): Token | undefined => {
return TOKENS[chainId]?.[tokenAddress];
};

0 comments on commit 2073ef8

Please sign in to comment.