1Hive / dandelion-voting-app

Contains the Dandelion Voting app which implements an ACLOracle
GNU General Public License v3.0
5 stars 8 forks source link

Document requirements #2

Closed lkngtn closed 5 years ago

lkngtn commented 5 years ago

Voting Improvements (Dissent Oracle)

Initially I thought that the dissent app would just need to validate that the user has either abstained or voted no in the most recent closed vote. But...if multiple votes have been created in a short period of time, this becomes an ineffective solution. I thought we may be able to check multiple votes, or all votes within a certain period of time, but we can't guarantee that will be bounded to a reasonable amount.

I think a more practical solution than implementing the dissent app as a standalone forwarder may be to fork the voting app and implement a function that acts as an "ACL Oracle" this is a feature of aragonOS that I don't think is documented that well but may fit our use case better then a forwarder app.

The fork of the voting app would need to remove the ability for a user to change their vote, and have the vote function keep track of no votes so that it can respond to ACL requests. The data structure would probably need to be something like address:time of most recent no vote. And the function would take an argument of dissent_window, and return true or false depending on if the users most recent no vote after is current_time - dissent_window.

We would also need to provide a way to include this parameter when creating/assigning permissions using the CLI (since there is no ui in permissions for ACL parameters).

There are a few other simple things that have been discussed as upgrades to the voting app we may want to also include at the same time:

fabriziovigevani commented 5 years ago

Really interesting!

What im not yet seeing is when the action would be executed (e.g Redeem). Should we implement in all apps using dissent, an ACL request?

and return true or false depending on if the users most recent no vote after is current_time - dissent_window

Here would be ${user most recent no vote} < current_time - dissent_window ?

Add an early execution role

What would this role consist on?

lkngtn commented 5 years ago

What im not yet seeing is when the action would be executed (e.g Redeem).

The way I think this would work is that you would grant the redeem role to ANY_ENTITY but pass an array of parameters which would further validate using the ACL oracle request to the improved voting app.

Suggest reading the sections on hack.aragon.org about ACL params and IACLOracle

I think we may not be able to pass the dissent_window argument in the permission though, in which case the fallback would be to store this as a setting in the voting app instance.

Should we implement in all apps using dissent, an ACL request?

No we shouldn't need to modify any other applications, we would just be able to assign the permission. However, there is currently no UI for assigning complex permissions using parameters, and I don't even think there is any indication that a complex parameter is being used (it would just show up as ANY_ENTITY in the permissions app despite it being clearly restricted). I don't think we should worry about this, and instead just make sure there is a way using the CLI to add the permission.

${user most recent no vote} < current_time - dissent_window ?

Yup this would be the logic of the canPerform() function that is part of the IACL oracle interface.

Add an early execution role

This is related to this issue, right now the voting app will automatically execute when some casts a vote that is guaranteed to be decisive even before the duration of the vote has ended. This change would make it so executing early would require a specific role.

lkngtn commented 5 years ago

Some additional considerations:

willjgriff commented 5 years ago

ACL Oracle's look like the way to go, another great feature I wasn't aware of.

No we shouldn't need to modify any other applications, we would just be able to assign the permission.

I think this is true, whatever permission restrictions are currently applied to a function, I think we can still apply a param requirement of an ACL Oracle for them to pass. However, if you wanted to pass in the dissent_window as implied with:

I think we may not be able to pass the dissent_window argument in the permission though, in which case the fallback would be to store this as a setting in the voting app instance.

I think you could change the function in the specific apps to use authP() eg for redeem() it would look something like authP(REDEEM_ROLE, arr(dissent_window)) removing the need to store it in the ACL Oracle but requiring a change to the individual functions using it.

In fact you could probably do both. If the dissent_window isn't specified in authP() then fallback to using a value specified in the ACL Oracle Voting app.

  • We probably actually want to track Yes votes rather than No votes, and have the logic be that if they have voted yes within the recent time frame, then canPerform() function would return no.

I believe this means that abstaining from voting is the same as voting No, could this discourage voting?

fabriziovigevani commented 5 years ago

I think you could change the function in the specific apps to use authP() eg for redeem() it would look something like authP(REDEEM_ROLE, arr(dissent_window)) removing the need to store it in the ACL Oracle but requiring a change to the individual functions using it.

Where you thinking something like setting the dissent_window value upon initialization of the app that will use the ACLOracle?

In fact you could probably do both. If the dissent_window isn't specified in authP() then fallback to using a value specified in the ACL Oracle Voting app.

Yes, this is a more flexible approach.

I believe this means that abstaining from voting is the same as voting No, could this discourage voting?

I have my doubts, how could this be a problem?

For the implementation i was thinking to make the dissent-voting a contract which inherits the voting app and override the necessary functions (eg. vote, canVote...).

Something like contract DissentVoting is Voting, IACLOracle {}

Do you agree?

willjgriff commented 5 years ago

I believe this means that abstaining from voting is the same as voting No, could this discourage voting?

I have my doubts, how could this be a problem?

If you vote yes in recent votes, you can redeem. If you vote no in recent votes, you can not redeem. I guess I wonder if someone who wishes to vote no, but doesn't want to give up the chance of redeeming, might delay voting until enough others have voted no for the vote to fail, or until the last minute. Just brainstorming.

For the implementation i was thinking to make the dissent-voting a contract which inherits the voting app and override the necessary functions (eg. vote, canVote...).

I'm unsure, I would probably just copy and modify the Voting app. The overwritten functionality isn't needed and I imagine we'll want to add/change the data structures.

fabriziovigevani commented 5 years ago

If you vote yes in recent votes, you can redeem. If you vote no in recent votes, you can not redeem.

I think is the other way around, and someone correct me if i got the wrong idea, but for what i understood, the main idea is that if you vote yes on a recent vote, you are committing to the organization on some action (e.g develop a next functionality for some app). Hence you cannot redeem your tokens. On the other hand, if you wont commit to a certain action, you can easily quit the org by redeeming your tokens.

I'm unsure, I would probably just copy and modify the Voting app. The overwritten functionality isn't needed and I imagine we'll want to add/change the data structures.

The downside i found with this is that some of the new functionalities are already being implemented on the original voting app. For example there's already a PR of the early execution implementation on the repo which made me wonder if it would be a good idea to implement all these new functionalities if they were going to be implemented anyways in the original voting app.

What's more im uncertain of how much the data structure will change. If we decide to implement new functionalities (pause vote, cancel vote) then probably will need to change the Vote struct yes, but in the other case i think we will only have to add data structures and make some tweaking on functions.

lkngtn commented 5 years ago

I think is the other way around, and someone correct me if i got the wrong idea, but for what i understood, the main idea is that if you vote yes on a recent vote, you are committing to the organization on some action (e.g develop a next functionality for some app). Hence you cannot redeem your tokens. On the other hand, if you wont commit to a certain action, you can easily quit the org by redeeming your tokens.

This is the intention, so if you voted yes within the window, the ACL Oracle should return no. The idea is that you might use this in combination with an app like Redemptions or Fundraising to prevent people from voting yes and then exiting so they don't face the consequences of their actions.

I'm unsure, I would probably just copy and modify the Voting app. The overwritten functionality isn't needed and I imagine we'll want to add/change the data structures.

Im also a bit unsure about inheritance versus manually incorporating upstream changes on a fork.

Agree that if some of the additional functionality like pause, cancel, and early execute functionality that was proposed is being prioritized in the main voting app, that i may make sense for us to focus on the oracle component, and then see where the main voting app ends up.

fabriziovigevani commented 5 years ago

If we end up taking this path, i will be happy to help with these issues on the original voting app if at the time no one has them assigned.