Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: classify signalling mutlisig proposals as succeeded after the end date has passed #303

Merged
merged 17 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions modules/client-common/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ TEMPLATE:

## [UPCOMING]

### Changed

- Updated subgraph version to 1.4.0


## [1.11.0]

### Added

- Added `UPGRADE_PLUGIN_PERMISSION` to `PermissionType` enum
Expand Down
2 changes: 1 addition & 1 deletion modules/client-common/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@aragon/sdk-client-common",
"author": "Aragon Association",
"version": "1.11.1",
"version": "1.12.0",
heueristik marked this conversation as resolved.
Show resolved Hide resolved
heueristik marked this conversation as resolved.
Show resolved Hide resolved
"license": "MIT",
"main": "dist/index.js",
"module": "dist/sdk-client-common.esm.js",
Expand Down
2 changes: 1 addition & 1 deletion modules/client-common/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export const UNAVAILABLE_PROPOSAL_METADATA: ProposalMetadata = {
const getGraphqlNode = (network: SupportedNetwork): string => {
return `https://subgraph.satsuma-prod.com/qHR2wGfc5RLi6/aragon/osx-${
SupportedNetworksToGraphqlNetworks[network]
}/version/v1.3.1/api`;
}/version/v1.4.0/api`;
};

export const GRAPHQL_NODES: { [K in SupportedNetwork]: { url: string }[] } = {
Expand Down
7 changes: 5 additions & 2 deletions modules/client/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,13 @@ TEMPLATE:
### Fixed
- Fixed proposal id not being transformed


## [1.19.1]

### Added

- Classify signalling multisig proposals as succeeded even after the end date is passed using the subgraph `isSignalling` attribute.

### Changed

- Add grant and revoke for permission `UPGRADE_PLUGIN_PERMISSION` in `applyUpdate` encoder
Expand All @@ -44,8 +49,6 @@ TEMPLATE:
- Rename `isPluginUpdateAction` to `containsPluginUpdateAction`
- Rename `isPluginUpdateActionBlockWithRootPermission` to `containsPluginUpdateActionBlockWithRootPermission`



## [1.19.0]

### Added
Expand Down
2 changes: 1 addition & 1 deletion modules/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
},
"dependencies": {
"@aragon/osx-ethers": "1.3.0-rc0.4",
"@aragon/sdk-client-common": "^1.11.1",
"@aragon/sdk-client-common": "^1.12.0",
heueristik marked this conversation as resolved.
Show resolved Hide resolved
"@aragon/sdk-ipfs": "^1.1.0",
"@ethersproject/abstract-signer": "^5.5.0",
"@ethersproject/bignumber": "^5.6.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ query AddresslistVotingProposal($proposalId: ID!) {
endDate
executed
earlyExecutable
potentiallyExecutable
approvalReached
isSignaling
heueristik marked this conversation as resolved.
Show resolved Hide resolved
executionTxHash
voters{
voter{
Expand Down Expand Up @@ -64,7 +65,8 @@ query AddresslistVotingProposals($where: AddresslistVotingProposal_filter!, $lim
endDate
executed
earlyExecutable
potentiallyExecutable
approvalReached
isSignaling
voters{
voter{
address
Expand Down
32 changes: 28 additions & 4 deletions modules/client/src/addresslistVoting/internal/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,19 +166,38 @@ export function computeProposalStatus(
parseInt(proposal.startDate) * 1000,
);
const endDate = new Date(parseInt(proposal.endDate) * 1000);
// The proposal is executed so the status becomes EXECUTED
// independently of the other conditions
if (proposal.executed) {
return ProposalStatus.EXECUTED;
}
// The proposal is not executed and the start date is in the future
// so the status becomes PENDING
if (startDate >= now) {
return ProposalStatus.PENDING;
}
if (proposal.potentiallyExecutable || proposal.earlyExecutable) {
// The proposal is not executed and the start date is in the past.
// Accordingly, we check if the proposal reached enough approval
// (i.e., that the supportThreshold and minParticipation criteria are both met).
// If the approvalReached = true and the vote has ended (end date is in the past) it has succeeded.
// This applies to normal mode and vote replacement mode.
if (proposal.approvalReached && endDate <= now) {
return ProposalStatus.SUCCEEDED;
}
if (endDate >= now) {
// In early exeuction mode, we calculate if subsequent voting can change the result of the vote.
// If not, the proposal is early executable and is therefore succeeded as well.
if(proposal.earlyExecutable){
return ProposalStatus.SUCCEEDED;
}
// The proposal is not executed and the start date is in the past
// and the approval threshold is not reached
// If the end date is in the future this means that you can still vote
// so the status becomes ACTIVE
if (now < endDate) {
return ProposalStatus.ACTIVE;
}
return ProposalStatus.DEFEATED;
// If none of the other conditions are met the status becomes DEFEATED
return ProposalStatus.DEFEATED
}

export function computeProposalStatusFilter(status: ProposalStatus) {
Expand All @@ -195,7 +214,12 @@ export function computeProposalStatusFilter(status: ProposalStatus) {
where = { executed: true };
break;
case ProposalStatus.SUCCEEDED:
where = { potentiallyExecutable: true, endDate_lt: now };
where = {
or: [
{ approvalReached: true, endDate_lt: now },
{ earlyExecutable: true },
],
};
break;
case ProposalStatus.DEFEATED:
where = {
Expand Down
3 changes: 2 additions & 1 deletion modules/client/src/client-common/types/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ export type SubgraphProposalBase = {
startDate: string;
endDate: string;
executed: boolean;
potentiallyExecutable: boolean;
approvalReached: boolean;
isSignaling: boolean;
actions: SubgraphAction[]
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ query MultisigProposal($proposalId: ID!) {
minApprovals
executionTxHash
executed
potentiallyExecutable
approvalReached
isSignaling
approvers{
id
}
Expand All @@ -45,7 +46,8 @@ query MultisigProposals($where: MultisigProposal_filter!, $limit:Int!, $skip: In
creator
metadata
executed
potentiallyExecutable
approvalReached
isSignaling
approvals
startDate
endDate
Expand Down
2 changes: 1 addition & 1 deletion modules/client/src/multisig/internal/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { SubgraphProposalBase } from "../../client-common";
export type SubgraphMultisigProposalBase = SubgraphProposalBase & {
plugin: SubgraphMultisigVotingSettings;
minApprovals: number;
potentiallyExecutable: boolean;
approvalReached: boolean;
approvers: { id: string }[];
// TODO change on subgraph fix
// approvers: SubgraphMultisigApproversListItem[];
Expand Down
35 changes: 30 additions & 5 deletions modules/client/src/multisig/internal/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,18 +122,38 @@ export function computeProposalStatus(
parseInt(proposal.startDate) * 1000,
);
const endDate = new Date(parseInt(proposal.endDate) * 1000);
// The proposal is executed so the status becomes EXECUTED
// independently of the other conditions
if (proposal.executed) {
return ProposalStatus.EXECUTED;
}
if (now < startDate) {
// The proposal is not executed and the start date is in the future
// so the status becomes PENDING
if (startDate >= now) {
return ProposalStatus.PENDING;
}
if (proposal.potentiallyExecutable && now < endDate) {
return ProposalStatus.SUCCEEDED;
// The proposal is not executed and the start date is in the past
// So we must check if the proposal reached the approval threshold
// If it reached the approval threshold and it's a signaling proposal
// the status becomes SUCCEEDED
// If it reached the approval threshold and it's not a signaling proposal
// the status becomes SUCCEEDED if if it hasn't reached the end date
if (proposal.approvalReached) {
if (proposal.isSignaling) {
return ProposalStatus.SUCCEEDED;
}
if (now <= endDate) {
return ProposalStatus.SUCCEEDED;
}
}
if (now < endDate) {
// The proposal is not executed and the start date is in the past
// and the approval threshold is not reached
// If the end date is in the future this means that you can still vote
// so the status becomes ACTIVE
if (now <= endDate) {
return ProposalStatus.ACTIVE;
}
// If none of the other conditions are met the status becomes DEFEATED
return ProposalStatus.DEFEATED;
}

Expand All @@ -151,7 +171,12 @@ export function computeProposalStatusFilter(status: ProposalStatus) {
where = { executed: true };
break;
case ProposalStatus.SUCCEEDED:
where = { potentiallyExecutable: true, endDate_gte: now };
where = {
or: [
{ approvalReached: true, endDate_lt: now, isSignaling: false },
{ approvalReached: true, isSignaling: true },
],
};
break;
case ProposalStatus.DEFEATED:
where = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ query TokenVotingProposal($proposalId: ID!) {
endDate
executed
earlyExecutable
potentiallyExecutable
approvalReached
isSignaling
executionTxHash
voters{
voter{
Expand Down Expand Up @@ -80,7 +81,8 @@ query TokenVotingProposals($where: TokenVotingProposal_filter!, $limit:Int!, $sk
endDate
executed
earlyExecutable
potentiallyExecutable
approvalReached
isSignaling
votingMode
supportThreshold
minVotingPower
Expand Down
32 changes: 28 additions & 4 deletions modules/client/src/tokenVoting/internal/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,19 +300,38 @@ export function computeProposalStatus(
parseInt(proposal.startDate) * 1000,
);
const endDate = new Date(parseInt(proposal.endDate) * 1000);
// The proposal is executed so the status becomes EXECUTED
// independently of the other conditions
if (proposal.executed) {
return ProposalStatus.EXECUTED;
}
// The proposal is not executed and the start date is in the future
// so the status becomes PENDING
if (startDate >= now) {
return ProposalStatus.PENDING;
}
if (proposal.potentiallyExecutable || proposal.earlyExecutable) {
// The proposal is not executed and the start date is in the past.
// Accordingly, we check if the proposal reached enough approval
// (i.e., that the supportThreshold and minParticipation criteria are both met).
// If the approvalReached = true and the vote has ended (end date is in the past) it has succeeded.
// This applies to normal mode and vote replacement mode.
if (proposal.approvalReached && endDate <= now) {
return ProposalStatus.SUCCEEDED;
}
if (endDate >= now) {
// In early exeuction mode, we calculate if subsequent voting can change the result of the vote.
// If not, the proposal is early executable and is therefore succeeded as well.
if(proposal.earlyExecutable){
return ProposalStatus.SUCCEEDED;
}
// The proposal is not executed and the start date is in the past
// and the approval threshold is not reached
// If the end date is in the future this means that you can still vote
// so the status becomes ACTIVE
if (now < endDate) {
return ProposalStatus.ACTIVE;
}
return ProposalStatus.DEFEATED;
// If none of the other conditions are met the status becomes DEFEATED
return ProposalStatus.DEFEATED
}

export function computeProposalStatusFilter(status: ProposalStatus) {
Expand All @@ -329,7 +348,12 @@ export function computeProposalStatusFilter(status: ProposalStatus) {
where = { executed: true };
break;
case ProposalStatus.SUCCEEDED:
where = { potentiallyExecutable: true, endDate_lt: now };
where = {
or: [
{ approvalReached: true, endDate_lt: now },
{ earlyExecutable: true },
],
};
break;
case ProposalStatus.DEFEATED:
where = {
Expand Down
3 changes: 2 additions & 1 deletion modules/client/test/integration/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ export const SUBGRAPH_PROPOSAL_BASE: SubgraphProposalBase = {
executed: false,
startDate: Math.round(Date.now() / 1000).toString(),
endDate: Math.round(Date.now() / 1000).toString(),
potentiallyExecutable: false,
approvalReached: false,
isSignaling: false,
metadata: `ipfs://${IPFS_CID}`,
};

Expand Down
Loading