Skip to content

Commit

Permalink
fix: osnap bot on disputed proposals (#4768)
Browse files Browse the repository at this point in the history
Signed-off-by: Reinis Martinsons <[email protected]>
  • Loading branch information
Reinis-FRP authored Jul 17, 2024
1 parent 3711850 commit 30ab4dd
Showing 1 changed file with 44 additions and 32 deletions.
76 changes: 44 additions & 32 deletions packages/monitor-v2/src/monitor-og/oSnapAutomation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,14 +195,12 @@ export const getSupportedSnapshotProposals = async (
return expandedProposals.filter((proposal) => isSafeSupported(proposal.safe, supportedModules, params.chainId));
};

// Get all proposals on provided oSnap modules that have not been discarded. Discards are most likely due to disputes,
// but can also occur on OOv3 upgrades.
const getUndiscardedProposals = async (
// Get all proposals posted on provided oSnap modules including the disputed ones.
const getAllProposals = async (
ogAddresses: string[],
params: MonitoringParams
): Promise<Array<TransactionsProposedEvent>> => {
// Get all proposals for all provided modules.
const allProposals = (
return (
await Promise.all(
ogAddresses.map(async (ogAddress) => {
const og = await getOgByAddress(params, ogAddress);
Expand All @@ -213,28 +211,35 @@ const getUndiscardedProposals = async (
})
)
).flat();
};

if (params.reproposeDisputed) {
// Get all deleted proposals for all provided modules.
const deletedProposals = (
await Promise.all(
ogAddresses.map(async (ogAddress) => {
const og = await getOgByAddress(params, ogAddress);
return runQueryFilter<ProposalDeletedEvent>(og, og.filters.ProposalDeleted(), {
start: 0,
end: params.blockRange.end,
});
})
)
).flat();
// Filters out all proposals that have been deleted. Discards are most likely due to disputes, but can also occur on
// OOv3 upgrades.
const removeDeletedProposals = async (
allProposals: TransactionsProposedEvent[],
params: MonitoringParams
): Promise<Array<TransactionsProposedEvent>> => {
// Get oSnap module addresses from all proposals.
const ogAddresses = Array.from(new Set(allProposals.map((proposal) => proposal.address)));

// Get all deleted proposals for all modules.
const deletedProposals = (
await Promise.all(
ogAddresses.map(async (ogAddress) => {
const og = await getOgByAddress(params, ogAddress);
return runQueryFilter<ProposalDeletedEvent>(og, og.filters.ProposalDeleted(), {
start: 0,
end: params.blockRange.end,
});
})
)
).flat();

// Filter out all proposals that have been deleted by matching assertionId. assertionId should be sufficient property
// for filtering as it is derived from module address, transaction content and assertion time among other factors.
const deletedAssertionIds = new Set(deletedProposals.map((deletedProposal) => deletedProposal.args.assertionId));
// Filter out all proposals that have been deleted by matching assertionId. assertionId should be sufficient property
// for filtering as it is derived from module address, transaction content and assertion time among other factors.
const deletedAssertionIds = new Set(deletedProposals.map((deletedProposal) => deletedProposal.args.assertionId));

return allProposals.filter((proposal) => !deletedAssertionIds.has(proposal.args.assertionId));
}
return allProposals;
return allProposals.filter((proposal) => !deletedAssertionIds.has(proposal.args.assertionId));
};

// Checks if a safeSnap safe from Snapshot proposal is supported by oSnap automation.
Expand Down Expand Up @@ -722,12 +727,19 @@ export const proposeTransactions = async (logger: typeof Logger, params: Monitor
// Get all finalized basic safeSnap/oSnap proposals for supported spaces and safes (returned in safeSnap format)
const supportedProposals = await getSupportedSnapshotProposals(logger, supportedModules, params);

// Get all undiscarded on-chain proposals for supported modules.
const onChainProposals = await getUndiscardedProposals(Object.keys(supportedModules), params);

// Filter Snapshot proposals that could potentially be proposed on-chain.
const potentialProposals = filterPotentialProposals(supportedProposals, onChainProposals, params);
const unblockedProposals = await filterUnblockedProposals(potentialProposals, onChainProposals, params);
// Get all on-chain proposals for supported modules and filter all proposals that have not been discarded.
const allOnChainProposals = await getAllProposals(Object.keys(supportedModules), params);
const undiscardedOnChainProposals = await removeDeletedProposals(allOnChainProposals, params);

// Filter Snapshot proposals that could potentially be proposed on-chain. This discards proposals that have been
// posted on-chain: when re-proposing of disputed proposals is enabled we only consider undiscarded proposals,
// otherwise all on-chain proposals are considered.
const potentialProposals = filterPotentialProposals(
supportedProposals,
params.reproposeDisputed ? undiscardedOnChainProposals : allOnChainProposals,
params
);
const unblockedProposals = await filterUnblockedProposals(potentialProposals, undiscardedOnChainProposals, params);
const verifiedProposals = await filterVerifiedProposals(unblockedProposals, supportedModules, params);

// Submit proposals.
Expand All @@ -736,7 +748,7 @@ export const proposeTransactions = async (logger: typeof Logger, params: Monitor

export const disputeProposals = async (logger: typeof Logger, params: MonitoringParams): Promise<void> => {
// Get all undiscarded on-chain proposals for all monitored modules.
const onChainProposals = await getUndiscardedProposals(params.ogAddresses, params);
const onChainProposals = await removeDeletedProposals(await getAllProposals(params.ogAddresses, params), params);

// Filter out all proposals that have been executed on-chain.
const unexecutedProposals = await filterUnexecutedProposals(onChainProposals, params);
Expand All @@ -757,7 +769,7 @@ export const disputeProposals = async (logger: typeof Logger, params: Monitoring

export const executeProposals = async (logger: typeof Logger, params: MonitoringParams): Promise<void> => {
// Get all undiscarded on-chain proposals for all monitored modules.
const onChainProposals = await getUndiscardedProposals(params.ogAddresses, params);
const onChainProposals = await removeDeletedProposals(await getAllProposals(params.ogAddresses, params), params);

// Filter out all proposals that have been executed on-chain.
const unexecutedProposals = await filterUnexecutedProposals(onChainProposals, params);
Expand Down

0 comments on commit 30ab4dd

Please sign in to comment.