diff --git a/src/indexer/abis/allo-v2/v1/EasyRetroFundingStrategy.ts b/src/indexer/abis/allo-v2/v1/EasyRetroFundingStrategy.ts new file mode 100644 index 00000000..d7f0d864 --- /dev/null +++ b/src/indexer/abis/allo-v2/v1/EasyRetroFundingStrategy.ts @@ -0,0 +1,695 @@ +export default [ + { + type: "constructor", + inputs: [ + { name: "_allo", type: "address", internalType: "address" }, + { name: "_name", type: "string", internalType: "string" }, + ], + stateMutability: "nonpayable", + }, + { type: "receive", stateMutability: "payable" }, + { + type: "function", + name: "NATIVE", + inputs: [], + outputs: [{ name: "", type: "address", internalType: "address" }], + stateMutability: "view", + }, + { + type: "function", + name: "allocate", + inputs: [ + { name: "_data", type: "bytes", internalType: "bytes" }, + { name: "_sender", type: "address", internalType: "address" }, + ], + outputs: [], + stateMutability: "payable", + }, + { + type: "function", + name: "distribute", + inputs: [ + { + name: "_recipientIds", + type: "address[]", + internalType: "address[]", + }, + { name: "_data", type: "bytes", internalType: "bytes" }, + { name: "_sender", type: "address", internalType: "address" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "distributionMetadata", + inputs: [], + outputs: [ + { name: "protocol", type: "uint256", internalType: "uint256" }, + { name: "pointer", type: "string", internalType: "string" }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "distributionStarted", + inputs: [], + outputs: [{ name: "", type: "bool", internalType: "bool" }], + stateMutability: "view", + }, + { + type: "function", + name: "getAllo", + inputs: [], + outputs: [{ name: "", type: "address", internalType: "contract IAllo" }], + stateMutability: "view", + }, + { + type: "function", + name: "getPayouts", + inputs: [ + { + name: "_recipientIds", + type: "address[]", + internalType: "address[]", + }, + { name: "_data", type: "bytes[]", internalType: "bytes[]" }, + ], + outputs: [ + { + name: "", + type: "tuple[]", + internalType: "struct IStrategy.PayoutSummary[]", + components: [ + { + name: "recipientAddress", + type: "address", + internalType: "address", + }, + { name: "amount", type: "uint256", internalType: "uint256" }, + ], + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "getPoolAmount", + inputs: [], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "function", + name: "getPoolId", + inputs: [], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "function", + name: "getRecipient", + inputs: [ + { name: "_recipientId", type: "address", internalType: "address" }, + ], + outputs: [ + { + name: "recipient", + type: "tuple", + internalType: "struct EasyRetroFundingStrategy.Recipient", + components: [ + { + name: "useRegistryAnchor", + type: "bool", + internalType: "bool", + }, + { + name: "recipientAddress", + type: "address", + internalType: "address", + }, + { + name: "metadata", + type: "tuple", + internalType: "struct Metadata", + components: [ + { + name: "protocol", + type: "uint256", + internalType: "uint256", + }, + { + name: "pointer", + type: "string", + internalType: "string", + }, + ], + }, + ], + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "getRecipientStatus", + inputs: [ + { name: "_recipientId", type: "address", internalType: "address" }, + ], + outputs: [ + { name: "", type: "uint8", internalType: "enum IStrategy.Status" }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "getStrategyId", + inputs: [], + outputs: [{ name: "", type: "bytes32", internalType: "bytes32" }], + stateMutability: "view", + }, + { + type: "function", + name: "hasBeenDistributed", + inputs: [{ name: "_index", type: "uint256", internalType: "uint256" }], + outputs: [{ name: "", type: "bool", internalType: "bool" }], + stateMutability: "view", + }, + { + type: "function", + name: "increasePoolAmount", + inputs: [{ name: "_amount", type: "uint256", internalType: "uint256" }], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "initialize", + inputs: [ + { name: "_poolId", type: "uint256", internalType: "uint256" }, + { name: "_data", type: "bytes", internalType: "bytes" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "isDistributionSet", + inputs: [], + outputs: [{ name: "", type: "bool", internalType: "bool" }], + stateMutability: "view", + }, + { + type: "function", + name: "isPoolActive", + inputs: [], + outputs: [{ name: "", type: "bool", internalType: "bool" }], + stateMutability: "view", + }, + { + type: "function", + name: "isValidAllocator", + inputs: [{ name: "_allocator", type: "address", internalType: "address" }], + outputs: [{ name: "", type: "bool", internalType: "bool" }], + stateMutability: "view", + }, + { + type: "function", + name: "metadataRequired", + inputs: [], + outputs: [{ name: "", type: "bool", internalType: "bool" }], + stateMutability: "view", + }, + { + type: "function", + name: "multicall", + inputs: [{ name: "data", type: "bytes[]", internalType: "bytes[]" }], + outputs: [{ name: "results", type: "bytes[]", internalType: "bytes[]" }], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "poolEndTime", + inputs: [], + outputs: [{ name: "", type: "uint64", internalType: "uint64" }], + stateMutability: "view", + }, + { + type: "function", + name: "poolStartTime", + inputs: [], + outputs: [{ name: "", type: "uint64", internalType: "uint64" }], + stateMutability: "view", + }, + { + type: "function", + name: "recipientToStatusIndexes", + inputs: [{ name: "", type: "address", internalType: "address" }], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "function", + name: "recipientsCounter", + inputs: [], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "function", + name: "registerRecipient", + inputs: [ + { name: "_data", type: "bytes", internalType: "bytes" }, + { name: "_sender", type: "address", internalType: "address" }, + ], + outputs: [ + { name: "recipientId", type: "address", internalType: "address" }, + ], + stateMutability: "payable", + }, + { + type: "function", + name: "registrationEndTime", + inputs: [], + outputs: [{ name: "", type: "uint64", internalType: "uint64" }], + stateMutability: "view", + }, + { + type: "function", + name: "registrationStartTime", + inputs: [], + outputs: [{ name: "", type: "uint64", internalType: "uint64" }], + stateMutability: "view", + }, + { + type: "function", + name: "reviewRecipients", + inputs: [ + { + name: "statuses", + type: "tuple[]", + internalType: "struct EasyRetroFundingStrategy.ApplicationStatus[]", + components: [ + { name: "index", type: "uint256", internalType: "uint256" }, + { + name: "statusRow", + type: "uint256", + internalType: "uint256", + }, + ], + }, + { + name: "refRecipientsCounter", + type: "uint256", + internalType: "uint256", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "statusesBitMap", + inputs: [{ name: "", type: "uint256", internalType: "uint256" }], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "function", + name: "totalPayoutAmount", + inputs: [], + outputs: [{ name: "", type: "uint256", internalType: "uint256" }], + stateMutability: "view", + }, + { + type: "function", + name: "updateDistribution", + inputs: [ + { + name: "_distributionMetadata", + type: "tuple", + internalType: "struct Metadata", + components: [ + { + name: "protocol", + type: "uint256", + internalType: "uint256", + }, + { name: "pointer", type: "string", internalType: "string" }, + ], + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "updatePoolTimestamps", + inputs: [ + { + name: "_registrationStartTime", + type: "uint64", + internalType: "uint64", + }, + { + name: "_registrationEndTime", + type: "uint64", + internalType: "uint64", + }, + { + name: "_poolStartTime", + type: "uint64", + internalType: "uint64", + }, + { name: "_poolEndTime", type: "uint64", internalType: "uint64" }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "useRegistryAnchor", + inputs: [], + outputs: [{ name: "", type: "bool", internalType: "bool" }], + stateMutability: "view", + }, + { + type: "function", + name: "withdraw", + inputs: [{ name: "_token", type: "address", internalType: "address" }], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "event", + name: "Allocated", + inputs: [ + { + name: "recipientId", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "amount", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + { + name: "token", + type: "address", + indexed: false, + internalType: "address", + }, + { + name: "sender", + type: "address", + indexed: false, + internalType: "address", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "BatchPayoutSuccessful", + inputs: [ + { + name: "sender", + type: "address", + indexed: true, + internalType: "address", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "Distributed", + inputs: [ + { + name: "recipientId", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "recipientAddress", + type: "address", + indexed: false, + internalType: "address", + }, + { + name: "amount", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + { + name: "sender", + type: "address", + indexed: false, + internalType: "address", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "DistributionUpdated", + inputs: [ + { + name: "metadata", + type: "tuple", + indexed: false, + internalType: "struct Metadata", + components: [ + { + name: "protocol", + type: "uint256", + internalType: "uint256", + }, + { name: "pointer", type: "string", internalType: "string" }, + ], + }, + ], + anonymous: false, + }, + { + type: "event", + name: "FundsDistributed", + inputs: [ + { + name: "amount", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + { + name: "grantee", + type: "address", + indexed: false, + internalType: "address", + }, + { + name: "token", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "recipientId", + type: "address", + indexed: true, + internalType: "address", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "Initialized", + inputs: [ + { + name: "poolId", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + { + name: "data", + type: "bytes", + indexed: false, + internalType: "bytes", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "PoolActive", + inputs: [ + { + name: "active", + type: "bool", + indexed: false, + internalType: "bool", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "RecipientStatusUpdated", + inputs: [ + { + name: "rowIndex", + type: "uint256", + indexed: true, + internalType: "uint256", + }, + { + name: "fullRow", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + { + name: "sender", + type: "address", + indexed: false, + internalType: "address", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "Registered", + inputs: [ + { + name: "recipientId", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "data", + type: "bytes", + indexed: false, + internalType: "bytes", + }, + { + name: "sender", + type: "address", + indexed: false, + internalType: "address", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "TimestampsUpdated", + inputs: [ + { + name: "registrationStartTime", + type: "uint64", + indexed: false, + internalType: "uint64", + }, + { + name: "registrationEndTime", + type: "uint64", + indexed: false, + internalType: "uint64", + }, + { + name: "poolStartTime", + type: "uint64", + indexed: false, + internalType: "uint64", + }, + { + name: "poolEndTime", + type: "uint64", + indexed: false, + internalType: "uint64", + }, + { + name: "sender", + type: "address", + indexed: false, + internalType: "address", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "UpdatedRegistration", + inputs: [ + { + name: "recipientId", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "data", + type: "bytes", + indexed: false, + internalType: "bytes", + }, + { + name: "sender", + type: "address", + indexed: false, + internalType: "address", + }, + { + name: "status", + type: "uint8", + indexed: false, + internalType: "uint8", + }, + ], + anonymous: false, + }, + { type: "error", name: "ALLOCATION_ACTIVE", inputs: [] }, + { type: "error", name: "ALLOCATION_NOT_ACTIVE", inputs: [] }, + { type: "error", name: "ALLOCATION_NOT_ENDED", inputs: [] }, + { type: "error", name: "ALREADY_INITIALIZED", inputs: [] }, + { type: "error", name: "AMOUNT_MISMATCH", inputs: [] }, + { type: "error", name: "ANCHOR_ERROR", inputs: [] }, + { type: "error", name: "ARRAY_MISMATCH", inputs: [] }, + { type: "error", name: "INVALID", inputs: [] }, + { type: "error", name: "INVALID_ADDRESS", inputs: [] }, + { type: "error", name: "INVALID_FEE", inputs: [] }, + { type: "error", name: "INVALID_METADATA", inputs: [] }, + { type: "error", name: "INVALID_REGISTRATION", inputs: [] }, + { type: "error", name: "IS_APPROVED_STRATEGY", inputs: [] }, + { type: "error", name: "MISMATCH", inputs: [] }, + { type: "error", name: "NONCE_NOT_AVAILABLE", inputs: [] }, + { type: "error", name: "NON_ZERO_VALUE", inputs: [] }, + { type: "error", name: "NOT_APPROVED_STRATEGY", inputs: [] }, + { type: "error", name: "NOT_ENOUGH_FUNDS", inputs: [] }, + { type: "error", name: "NOT_IMPLEMENTED", inputs: [] }, + { type: "error", name: "NOT_INITIALIZED", inputs: [] }, + { type: "error", name: "NOT_PENDING_OWNER", inputs: [] }, + { type: "error", name: "POOL_ACTIVE", inputs: [] }, + { type: "error", name: "POOL_INACTIVE", inputs: [] }, + { type: "error", name: "POOL_NOT_ENDED", inputs: [] }, + { type: "error", name: "RECIPIENT_ALREADY_ACCEPTED", inputs: [] }, + { + type: "error", + name: "RECIPIENT_ERROR", + inputs: [{ name: "recipientId", type: "address", internalType: "address" }], + }, + { type: "error", name: "RECIPIENT_NOT_ACCEPTED", inputs: [] }, + { type: "error", name: "REGISTRATION_ACTIVE", inputs: [] }, + { type: "error", name: "REGISTRATION_NOT_ACTIVE", inputs: [] }, + { type: "error", name: "UNAUTHORIZED", inputs: [] }, + { type: "error", name: "ZERO_ADDRESS", inputs: [] }, +] as const; diff --git a/src/indexer/abis/index.ts b/src/indexer/abis/index.ts index 730840d8..f39b04b1 100644 --- a/src/indexer/abis/index.ts +++ b/src/indexer/abis/index.ts @@ -28,6 +28,7 @@ import AlloV1ToV2ProfileMigration from "./allo-v2/AlloV1ToV2ProfileMigration.js" import AlloV2DirectGrantsLiteStrategy from "./allo-v2/v1/DirectGrantsLiteStrategy.js"; import AlloV2EasyRPGFStrategy from "./allo-v2/v1/EasyRPGFStrategy.js"; import AlloV2DirectAllocationStrategy from "./allo-v2/v1/DirectAllocationStrategy.js"; +import AlloV2EasyRetroFundingStrategy from "./allo-v2/v1/EasyRetroFundingStrategy.js"; // Gitcoin Attestation Network import GitcoinAttestationNetwork from "./gitcoin-attestation-network/GitcoinGrantsResolver.js"; @@ -72,7 +73,7 @@ const abis = { "AlloV2/DirectGrantsLiteStrategy/V1": AlloV2DirectGrantsLiteStrategy, "AlloV2/EasyRPGFStrategy/V1": AlloV2EasyRPGFStrategy, "AlloV2/DirectAllocationStrategy/V1": AlloV2DirectAllocationStrategy, - + "AlloV2/EasyRetroFundingStrategy/V1": AlloV2EasyRetroFundingStrategy, // Gitcoin Attestation Network "GitcoinAttestationNetwork/GitcoinGrantsResolver": GitcoinAttestationNetwork, } as const; diff --git a/src/indexer/allo/v2/handleEvent.ts b/src/indexer/allo/v2/handleEvent.ts index 7db6631f..03170691 100644 --- a/src/indexer/allo/v2/handleEvent.ts +++ b/src/indexer/allo/v2/handleEvent.ts @@ -26,6 +26,7 @@ import { DVMDApplicationData, DVMDExtendedApplicationData, DVMDTimeStampUpdatedData, + EasyRetroFundingTimeStampUpdatedData, } from "../../types.js"; import { fetchPoolMetadata } from "./poolMetadata.js"; import roleGranted from "./roleGranted.js"; @@ -332,6 +333,12 @@ export async function handleEvent( address: strategyAddress, }); break; + case "allov2.EasyRetroFundingStrategy": + subscribeToContract({ + contract: "AlloV2/EasyRetroFundingStrategy/V1", + address: strategyAddress, + }); + break; } let applicationsStartTime: Date | null = null; @@ -422,6 +429,61 @@ export async function handleEvent( registrationStartTimeResolved ); applicationsEndTime = getDateFromTimestamp(registrationEndTimeResolved); + } else if ( + strategy !== null && + strategy.name === "allov2.EasyRetroFundingStrategy" + ) { + const contract = "AlloV2/EasyRetroFundingStrategy/V1"; + const [ + registrationStartTimeResolved, + registrationEndTimeResolved, + poolStartTimeResolved, + poolEndTimeResolved, + ] = await Promise.all([ + await readContract({ + contract, + address: strategyAddress, + functionName: "registrationStartTime", + }), + await readContract({ + contract, + address: strategyAddress, + functionName: "registrationEndTime", + }), + await readContract({ + contract, + address: strategyAddress, + functionName: "poolStartTime", + }), + await readContract({ + contract, + address: strategyAddress, + functionName: "poolEndTime", + }), + ]); + + applicationsStartTime = getDateFromTimestamp( + registrationStartTimeResolved + ); + applicationsEndTime = getDateFromTimestamp(registrationEndTimeResolved); + donationsStartTime = getDateFromTimestamp(poolStartTimeResolved); + donationsEndTime = getDateFromTimestamp(poolEndTimeResolved); + + if (parsedMetadata.success && token !== null) { + matchAmount = parseUnits( + parsedMetadata.data.quadraticFundingConfig.matchingFundsAvailable.toString(), + token.decimals + ); + matchAmountInUsd = ( + await convertToUSD( + priceProvider, + chainId, + matchTokenAddress, + matchAmount, + event.blockNumber + ) + ).amount; + } } const fundedAmount = event.params.amount; @@ -808,6 +870,7 @@ export async function handleEvent( case "allov2.DonationVotingMerkleDistributionDirectTransferStrategy": case "allov2.DirectGrantsLiteStrategy": + case "allov2.EasyRetroFundingStrategy": values = decodeDVMDExtendedApplicationData(encodedData); id = (Number(values.recipientsCounter) - 1).toString(); break; @@ -882,6 +945,7 @@ export async function handleEvent( case "allov2.DirectGrantsLiteStrategy": case "allov2.DonationVotingMerkleDistributionDirectTransferStrategy": + case "allov2.EasyRetroFundingStrategy": values = decodeDVMDApplicationData(encodedData); break; @@ -973,6 +1037,19 @@ export async function handleEvent( break; + case "allov2.EasyRetroFundingStrategy": + params = event.params as EasyRetroFundingTimeStampUpdatedData; + + applicationsStartTime = getDateFromTimestamp( + params.registrationStartTime + ); + applicationsEndTime = getDateFromTimestamp( + params.registrationEndTime + ); + donationsStartTime = getDateFromTimestamp(params.poolStartTime); + donationsEndTime = getDateFromTimestamp(params.poolEndTime); + break; + default: throw new Error("Invalid strategy name"); } diff --git a/src/indexer/allo/v2/strategy.ts b/src/indexer/allo/v2/strategy.ts index 23f0b961..34d20ee9 100644 --- a/src/indexer/allo/v2/strategy.ts +++ b/src/indexer/allo/v2/strategy.ts @@ -123,6 +123,14 @@ export function extractStrategyFromId(_id: string): Strategy | null { name: "allov2.DirectAllocationStrategy", groups: ["allov2.DirectAllocationStrategy"], }; + + // EasyRetroFundingStrategyv1.0 + case "0x060ffd6c79f918819a622248c6823443412aedea610cc19c89d28dadcdef7fba": + return { + id: id, + name: "allov2.EasyRetroFundingStrategy", + groups: ["allov2.EasyRetroFundingStrategy"], + }; } return null; diff --git a/src/indexer/types.ts b/src/indexer/types.ts index f3b9b7cb..e3541cfd 100644 --- a/src/indexer/types.ts +++ b/src/indexer/types.ts @@ -28,6 +28,13 @@ export type DVMDTimeStampUpdatedData = { allocationEndTime: bigint; }; +export type EasyRetroFundingTimeStampUpdatedData = { + registrationStartTime: bigint; + registrationEndTime: bigint; + poolStartTime: bigint; + poolEndTime: bigint; +}; + export type DGTimeStampUpdatedData = { registrationStartTime: bigint; registrationEndTime: bigint;