Proposals

Proposals are implemented through a collection of submodules under proposals: 1 library module containing the core interface and implementation, and 1 submodule per proposal kind.

Stored Information

A proposal is submitted with at least the following information kept in a struct:

ProposalInfo (struct)

Basic information saved per submitted proposal.

  • id (felt): An incremental identifier for the proposal.

  • kind (felt): The proposal's kind as a short-string.

  • submittedBy (felt): Address of the submiter.

  • submittedAt (felt): Number of the block which includes the proposal's submission.

  • status (felt): The actual state of the proposal in its lifecycle.

  • description (felt): A short string describing the proposal's content.

Additional information can be included that depends on the proposal's kind. In that case, it is handled by the kind's submodule directly, so that no further assumption is needed.

The DAO records the list of all proposals that were ever submitted onchain through the following 2 storage variables:

proposalsLength (storage_var)

The number of proposals ever submitted to the DAO.

Returns:

  • length (felt)

proposals (storage_var)

The list of all proposals' info.

Arguments:

  • id (felt): the positional index of the proposal, which is also its proposalId

Returns:

  • proposal (ProposalInfo)

Lifecycle

A proposal goes through a few phases in its lifecycle. A proposal's status records which phase it is in, one from the following enum:

Proposal (namespace):
  • SUBMITTED = 'submitted' : in voting period

  • ACCEPTED = 'accepted' : accepted and in grace period

  • REJECTED = 'rejected' : rejected

  • FORCED = 'forced' : sent directly to grace period

The following status are final, meaning the proposal has been closed:

  • ABORTED = 'aborted' : did not go completely through voting

  • EXECUTED = 'executed' : Execution is finalised and successful

  • FAILED = 'failed' : execution failed

Parametrisation

Proposals can be parametrised on a per kind basis (e.g.: member onboarding, or swaps), as each kind can have different needs. The parameters govern all proposals' lifecycle of its kind. All parameters are kept in the following structure:

ProposalParams

Parameters pertaining to proposals' lifecycle.

Members:

  • majority (felt): reject proposal if the percentage of YES votes among eligible votes is lower than majority.

  • quorum (felt): reject proposal if the percentage of casted votes among eligible votes is lower than quorum.

  • votingDuration (felt): duration of the voting period in block numbers.

  • graceDuration (felt): duration of the grace period in block numbers.

The DAO keeps the current parametrisation in a mapping between proposal kind and parameters:

proposalParams

Arguments

  • proposalKind (felt): the proposal kind to which the parameters apply

Returns

  • ProposalParams

Misparametrisation of proposal kinds can lead to security issues. For example, setting the graceDuration to zero effectively disables the grace period, bypassing ragequit security mecanism for proposals of this kind.

Implementing proposals

All proposals follow the following minimum interface, where functions are allowed to have more arguments than default ones if necessary:

submit (external function)

Arguments

  • description: felt

  • more if needed

Returns

  • success: felt

execute (external function)

Arguments

  • proposalId: felt

Returns

  • success: felt

Last updated