Skip to content

Commit 9ad1569

Browse files
authored
feat: base strategy processor & dvmd strategy factory (#16)
# 🤖 Linear Closes GIT-60 GIT-61 GIT-62 ## Description - `StrategyHandlerFactory` to create the proper Strategy handler based on strategyId - `BaseStrategyHandler` abstract class w/ default implementation for fetch functions (some strategies require custom logic) - `DVMDDirectTransferStrategy` handler - `Distributed` and `Registered` handlers for DVMD strategy (PR #17) - refactored TODOs from `PoolCreatedHandler` ## Checklist before requesting a review - [x] I have conducted a self-review of my code. - [x] I have conducted a QA. - [x] If it is a core feature, I have included comprehensive tests.
1 parent 28dcae6 commit 9ad1569

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1501
-269
lines changed

.husky/pre-commit

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
pnpm lint-staged && pnpm check-types
1+
pnpm lint-staged && pnpm check-types --force

packages/data-flow/test/unit/eventsFetcher.spec.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ describe("EventsFetcher", () => {
2727
eventName: "PoolCreated",
2828
srcAddress: "0x1234567890123456789012345678901234567890",
2929
logIndex: 0,
30-
params: { contractAddress: "0x1234" },
30+
params: { contractAddress: "0x1234", tokenAddress: "0x1234", amount: 1000 },
3131
transactionFields: { hash: "0x1234", transactionIndex: 0 },
3232
},
3333
{
@@ -38,7 +38,11 @@ describe("EventsFetcher", () => {
3838
eventName: "PoolCreated",
3939
srcAddress: "0x1234567890123456789012345678901234567890",
4040
logIndex: 0,
41-
params: { contractAddress: "0x1234" },
41+
params: {
42+
contractAddress: "0x1234",
43+
tokenAddress: "0x1234",
44+
amount: 1000,
45+
},
4246
transactionFields: { hash: "0x1234", transactionIndex: 1 },
4347
},
4448
];

packages/indexer-client/test/unit/envioIndexerClient.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ describe("EnvioIndexerClient", () => {
5151
eventName: "PoolCreated",
5252
srcAddress: "0x1234567890123456789012345678901234567890",
5353
logIndex: 0,
54-
params: { contractAddress: "0x1234" },
54+
params: { contractAddress: "0x1234", tokenAddress: "0x1234", amount: 1000 },
5555
transactionFields: {
5656
hash: "0x123",
5757
transactionIndex: 1,

packages/processors/src/allo/handlers/poolCreated.handler.ts

Lines changed: 21 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
1-
import { getAddress, parseUnits, zeroAddress } from "viem";
1+
import { getAddress, zeroAddress } from "viem";
22

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

87
import type { IEventHandler, ProcessorDependencies, StrategyTimings } from "../../internal.js";
9-
import { getRoundRoles } from "../../helpers/roles.js";
10-
import { extractStrategyFromId, getStrategyTimings } from "../../helpers/strategy.js";
11-
import { calculateAmountInUsd } from "../../helpers/tokenMath.js";
12-
import { TokenPriceNotFoundError } from "../../internal.js";
8+
import { calculateAmountInUsd, getRoundRoles } from "../../helpers/index.js";
9+
import { StrategyHandlerFactory, TokenPriceNotFoundError } from "../../internal.js";
1310
import { RoundMetadataSchema } from "../../schemas/index.js";
1411

1512
type Dependencies = Pick<
@@ -61,7 +58,11 @@ export class PoolCreatedHandler implements IEventHandler<"Allo", "PoolCreated">
6158
? zeroAddress
6259
: checksummedTokenAddress;
6360

64-
const strategy = extractStrategyFromId(strategyId);
61+
const strategyHandler = StrategyHandlerFactory.createHandler(
62+
this.chainId,
63+
this.dependencies as ProcessorDependencies,
64+
strategyId,
65+
);
6566

6667
const token = getToken(this.chainId, matchTokenAddress);
6768

@@ -72,26 +73,17 @@ export class PoolCreatedHandler implements IEventHandler<"Allo", "PoolCreated">
7273
donationsEndTime: null,
7374
};
7475

75-
let matchAmount = 0n;
76-
let matchAmountInUsd = "0";
77-
78-
if (strategy) {
79-
strategyTimings = await getStrategyTimings(evmProvider, strategy, strategyAddress);
80-
81-
//TODO: when creating strategy handlers, should this be moved there?
82-
if (
83-
strategy.name === "allov2.DonationVotingMerkleDistributionDirectTransferStrategy" &&
84-
parsedRoundMetadata.success &&
85-
token
86-
) {
87-
matchAmount = parseUnits(
88-
parsedRoundMetadata.data.quadraticFundingConfig.matchingFundsAvailable.toString(),
89-
token.decimals,
90-
);
76+
let matchAmountObj = {
77+
matchAmount: 0n,
78+
matchAmountInUsd: "0",
79+
};
9180

92-
matchAmountInUsd = await this.getTokenAmountInUsd(
81+
if (strategyHandler) {
82+
strategyTimings = await strategyHandler.fetchStrategyTimings(strategyAddress);
83+
if (parsedRoundMetadata.success && token) {
84+
matchAmountObj = await strategyHandler.fetchMatchAmount(
85+
Number(parsedRoundMetadata.data.quadraticFundingConfig.matchingFundsAvailable),
9386
token,
94-
matchAmount,
9587
this.event.blockTimestamp,
9688
);
9789
}
@@ -120,8 +112,8 @@ export class PoolCreatedHandler implements IEventHandler<"Allo", "PoolCreated">
120112
totalAmountDonatedInUsd: "0",
121113
uniqueDonorsCount: 0,
122114
matchTokenAddress,
123-
matchAmount,
124-
matchAmountInUsd,
115+
matchAmount: matchAmountObj.matchAmount,
116+
matchAmountInUsd: matchAmountObj.matchAmountInUsd,
125117
fundedAmount,
126118
fundedAmountInUsd,
127119
applicationMetadataCid: metadataPointer,
@@ -132,7 +124,7 @@ export class PoolCreatedHandler implements IEventHandler<"Allo", "PoolCreated">
132124
...roundRoles,
133125
strategyAddress,
134126
strategyId,
135-
strategyName: strategy?.name ?? "",
127+
strategyName: strategyHandler?.name ?? "",
136128
createdByAddress: getAddress(createdBy),
137129
createdAtBlock: BigInt(this.event.blockNumber),
138130
updatedAtBlock: BigInt(this.event.blockNumber),
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
export * from "./tokenPriceNotFound.exception.js";
22
export * from "./unsupportedEvent.exception.js";
33
export * from "./invalidArgument.exception.js";
4+
export * from "./unsupportedStrategy.exception.js";
5+
export * from "./projectNotFound.exception.js";
6+
export * from "./roundNotFound.exception.js";
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { ChainId } from "@grants-stack-indexer/shared";
2+
3+
export class ProjectNotFound extends Error {
4+
constructor(chainId: ChainId, anchorAddress: string) {
5+
super(`Project not found for chainId: ${chainId} and anchorAddress: ${anchorAddress}`);
6+
}
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { ChainId } from "@grants-stack-indexer/shared";
2+
3+
export class RoundNotFound extends Error {
4+
constructor(chainId: ChainId, strategyAddress: string) {
5+
super(`Round not found for chainId: ${chainId} and strategyAddress: ${strategyAddress}`);
6+
}
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { Hex } from "viem";
2+
3+
export class UnsupportedStrategy extends Error {
4+
constructor(strategyId: Hex) {
5+
super(`Strategy ${strategyId} unsupported`);
6+
}
7+
}

packages/processors/src/external.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
// Add your external exports here
22
export { StrategyProcessor, AlloProcessor } from "./internal.js";
33
export type { IProcessor } from "./internal.js";
4+
5+
export { existsHandler } from "./internal.js";
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from "./roles.js";
2+
export * from "./utils.js";
3+
export * from "./tokenMath.js";

0 commit comments

Comments
 (0)