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

Add governance docs #9

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
48 changes: 48 additions & 0 deletions docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
sidebar_position: 1
title: PSP22 Votes
---
This feature provides a way to use your token as a voting power. You can use it in your [Governor](../../governance/governor.md) contract.
To cast a vote in [Governor](../../governance/governor.md) contract you need to have some amount of tokens and delegate them to be used for voting.
The more tokens you have, the more voting power you have. The extension implements the [Votes](https://github.com/Brushfam/openbrush-contracts/tree/main/contracts/src/governance/utils/votes) trait which provides the ability to delegate tokens from one account to another for voting,
check the number of votes for a proposal, and check the number of votes delegated by a user.
It's a required tool to create a [Governor](../../governance/governor.md) contract.
You can check the [Compound’s Governor Alpha & Bravo](https://docs.compound.finance/v2/governance/) documentation for more information about governance.

This page describes how to create your own [PSP22Votes](/) contract.
## Step 1: Import default implementation

First, you should implement basic version of [PSP22](../psp22.md).

With [default `Cargo.toml`](../../overview.md/#the-default-toml-of-your-project-with-openbrush),
you need to enable `governance` and `psp22` feature. Also, you need to use the implementation macro
for PSP22Votes and Nonces:
```rust
#[openbrush::implementation(..., PSP22Votes, Nonces, ...)]
#[openbrush::contract]
pub mod your_contract {
...
}
```

You can check [this section](../../overview.md/#reuse-implementation-of-traits-from-openbrush) to understand how it works.


## Step 2: Set up your Storage
You need to add a storage field of type `votes::Data`, which will store the information about delegations, the number of votes at a certain time, and the total number of votes, at a certain time.
Also, you will need a storage field of type `nonces::Data`, which stores the number of nonces for each account. Nonce is a number that is incremented each time a user delegates tokens to another account.
```rust
#[ink(storage)]
#[derive(Default, Storage)]
pub struct Contract {
...
#[storage_field]
votes: votes::Data,
#[storage_field]
nonces: nonces::Data,
...
}
```
That's it! Now we have a [PSP22Votes](/) contract. You can use it in your [Governor](../../governance/governor.md) contract to count your votes.

You can check an example of the usage of [PSP22Votes](https://github.com/Brushfam/openbrush-contracts/tree/main/examples/psp22_extensions/votes) and [Governor](https://github.com/Brushfam/openbrush-contracts/tree/main/examples/governance/governor)
41 changes: 41 additions & 0 deletions docs/OpenBrush/smart-contracts/governance/Extensions/counting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
sidebar_position: 1
title: GovernorCounting
---
This extension gives Governor contract the ability to manage and count votes of the contract.
You can see if a user has voted for a proposal, and get the number of votes for a proposal.
Also, this extension allows you to count your votes when you cast them, to see when the quorum is reached, and when the voting succeeds.
You can check the [Compound’s Governor Alpha & Bravo](https://docs.compound.finance/v2/governance/) documentation for more information about governance.

This page describes how to connect [GovernorCounting](/) to [Governor](../governor.md) contract.

## Step 1: Import default implementation

With [default `Cargo.toml`](../../overview.md/#the-default-toml-of-your-project-with-openbrush),
you need to enable `governance` feature. Also, you need to use implementation macro
for GovernorCounting:
```rust
#[openbrush::implementation(..., GovernorCounting, ...)]
#[openbrush::contract]
pub mod your_contract {
...
}
```
You can check [this section](../../overview.md/#reuse-implementation-of-traits-from-openbrush) to understand how it works.

## Step 2: Add GovernorCounting field in your Storage
Add a storage field of type `governor_counting::Data`, which stores the number of votes for all proposals, and information about whether a user has voted for a proposal.
```rust
#[ink(storage)]
#[derive(Default, Storage)]
pub struct Contract {
...
#[storage_field]
governor_counting: governor_counting::Data,
...
}
```

That's it! Now you can use [GovernorCounting](/) extension in your [Governor](../governor.md) contract.

You can check an example of the usage of [Governance](https://github.com/Brushfam/openbrush-contracts/tree/main/examples/governance/governor).
64 changes: 64 additions & 0 deletions docs/OpenBrush/smart-contracts/governance/Extensions/quorum.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
sidebar_position: 1
title: GovernorQuorum
---
This extension gives Governor contract the ability to manage how quorum is calculated.
There are two parameters that affect quorum calculation: `quorum_numerator` and `quorum_denominator`.
Quorum is calculated as `quorum_numerator * total_votes / quorum_denominator`.
Of course, the value of total votes is not constant, it changes with every vote.
So, the quorum calculates in specific moments of time. It is possible because all votes are stored in [checkpoints]() structure,
that is updated every time when a vote is created or changed.
You can check the [Compound’s Governor Alpha & Bravo](https://docs.compound.finance/v2/governance/) documentation for more information about governance.

This page describes how to connect [GovernorQuorum](/) to [Governor](../governor.md) contract.

## Step 1: Import default implementation

With [default `Cargo.toml`](../../overview.md/#the-default-toml-of-your-project-with-openbrush),
you need to enable `governance` feature. Also, you need to use implementation macro
for GovernorQuorum:
```rust
#[openbrush::implementation(..., GovernorQuorum, ...)]
#[openbrush::contract]
pub mod your_contract {
...
}
```
You can check [that section](../../overview.md/#reuse-implementation-of-traits-from-openbrush) to understand how it works.

## Step 2: Include GovernorQuorum initialization in constructor

We need to initialize [GovernorQuorum](/) extension in the constructor of [Governor](../governor.md) contract.
We are setting an initial value of quorum numerator. It can be changed. For example, by voting.

```rust
impl Contract {
#[ink(constructor)]
pub fn new(
token: AccountId,
voting_delay: u64,
voting_period: u64,
proposal_threshold: u128,
numerator: u128,
) -> Self {
...
instance._init_quorum_numerator(numerator).unwrap();
...
}
}
```
## Step 3: Add GovernorQuorum field in your Storage
Add a storage field of type `governor_quorum::Data`, which stores the history of quorum numerator changes.
```rust
#[ink(storage)]
#[derive(Default, Storage)]
pub struct Contract {
...
#[storage_field]
quorum: governor_quorum::Data,
...
}
```
That's it! Now you can use [GovernorQuorum](/) extension in your [Governor](../governor.md) contract.

You can check an example of the usage of [Governance](https://github.com/Brushfam/openbrush-contracts/tree/main/examples/governance/governor).
65 changes: 65 additions & 0 deletions docs/OpenBrush/smart-contracts/governance/Extensions/settings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
sidebar_position: 1
title: GovernorSettings
---
This extension gives Governor contract the ability to set and get settings of the contract.
With this extension, you can set and get voting delay(The time between proposing and vote starting),
voting period, proposal threshold(The amount of votes required to propose a proposal).
You can check the [Compound’s Governor Alpha & Bravo](https://docs.compound.finance/v2/governance/) documentation for more information about governance.

This page describes how to connect [GovernorSettings](/) to [Governor](../governor.md) contract.

## Step 1: Import default implementation

With [default `Cargo.toml`](../../overview.md/#the-default-toml-of-your-project-with-openbrush),
you need to enable `governance` feature. Also, you need to use implementation macro
for GovernorSettings:
```rust
#[openbrush::implementation(..., GovernorSettings, ...)]
#[openbrush::contract]
pub mod your_contract {
...
}
```
You can check [this section](../../overview.md/#reuse-implementation-of-traits-from-openbrush) to understand how it works.
## Step 2: Include GovernorSettings initialization in constructor

We need to initialize [GovernorSettings](/) extension in the constructor of [Governor](../governor.md) contract.
We are setting an initial value of voting delay, voting period, proposal threshold. It can be changed. For example, by voting.

```rust
impl Contract {
#[ink(constructor)]
pub fn new(
token: AccountId,
voting_delay: u64,
voting_period: u64,
proposal_threshold: u128,
numerator: u128,
) -> Self {
...
instance
._init_governor_settings(voting_delay, voting_period, proposal_threshold)
.unwrap();
...
}
}
```
## Step 3: Add GovernorSettings field in your Storage
Add a storage field of type `governor_settings::Data`, which stores the values of voting delay, voting period, proposal threshold.
```rust
#[ink(storage)]
#[derive(Default, Storage)]
pub struct Contract {
...
#[storage_field]
settings: governor_settings::Data,
...
}
```


That's it! Now you can use [GovernorSettings](/) extension in your [Governor](../governor.md) contract.


You can check an example of the usage of [Governance](https://github.com/Brushfam/openbrush-contracts/tree/main/examples/governance/governor).
66 changes: 66 additions & 0 deletions docs/OpenBrush/smart-contracts/governance/Extensions/votes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
sidebar_position: 1
title: GovernorVotes
---
This extension gives Governor contract the ability to communicate with [PSP22Votes](../../PSP22/Extensions/votes.md) token.
The main purpose of this extension is to provide a way to check how much voting power a voter has.
Also, it provides the ability to delegate tokens from one account to another for voting.
You can check the [Compound’s Governor Alpha & Bravo](https://docs.compound.finance/v2/governance/) documentation for more information about governance.

This page describes how to connect [Governor](../governor.md) with [PSP22Votes](../../PSP22/Extensions/votes.md) token using [GovernorVotes](/) extension.

## Step 1: Import default implementation

With [default `Cargo.toml`](../../overview.md/#the-default-toml-of-your-project-with-openbrush),
you need to enable `governance` feature. Also, you need to use implementation macro
for GovernorVotes:
```rust
#[openbrush::implementation(..., GovernorVotes, ...)]
#[openbrush::contract]
pub mod your_contract {
...
}
```

You can check [this section](../../overview.md/#reuse-implementation-of-traits-from-openbrush) to understand how it works.

The main trait is `Governor`.

## Step 2: Include GovernorVotes initialization in constructor

We need to initialize [GovernorVotes](/) extension in the constructor of [Governor](../governor.md) contract with the address of [PSP22Votes](../../PSP22/Extensions/votes.md) token.

```rust
impl Contract {
#[ink(constructor)]
pub fn new(
token: AccountId,
voting_delay: u64,
voting_period: u64,
proposal_threshold: u128,
numerator: u128,
) -> Self {
...
instance._init_governor_votes(token).unwrap();
...
}
}
```
## Step 3: Add GovernorVotes field in your Storage
Add a storage field of type `governor_votes::Data`, which stores the AccountId of [PSP22Votes](../../PSP22/Extensions/votes.md) token.
```rust
#[ink(storage)]
#[derive(Default, Storage)]
pub struct Contract {
...
#[storage_field]
governor_votes: governor_votes::Data,
...
}
```


That's it! Now you can use [GovernorVotes](/) extension in your [Governor](../governor.md) contract.


You can check an example of the usage of [Governance](https://github.com/Brushfam/openbrush-contracts/tree/main/examples/governance/governor).
80 changes: 80 additions & 0 deletions docs/OpenBrush/smart-contracts/governance/governor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
sidebar_position: 1
title: Governance
---
This feature provides a governance mechanism. It allows token holders to vote on proposals and change the token's parameters.
Everybody who has enough votes can create a proposal to call a method of some contract with some arguments. Then token holders can vote for or against the proposal.
When the voting period ends, the proposal can be executed if the proposal status is `Succeeded` and the quorum is reached.
This example shows how you can use the implementation of [Governance](https://github.com/Brushfam/openbrush-contracts/tree/main/contracts/src/governance) token.
You can check the [Compound’s Governor Alpha & Bravo](https://docs.compound.finance/v2/governance/) documentation for more information about governance.

## Step 1: Import default implementation

With [default `Cargo.toml`](../overview.md/#the-default-toml-of-your-project-with-openbrush),
you need to enable `governance` feature. Also, you need to use implementation macro
for Governor and all required extensions:
```rust
#[openbrush::implementation(Governor, GovernorVotes, GovernorSettings, GovernorCounting, GovernorQuorum)]
#[openbrush::contract]
pub mod your_contract {
...
}
```
You can check [this section](../overview.md/#reuse-implementation-of-traits-from-openbrush) to understand how it works.

## Step 2: Define constructor

Define constructor where you initialize required extensions [GovernorVotes](Extensions/votes.md), [GovernorSettings](Extensions/settings.md) and [GovernorQuorum](Extensions/quorum.md).

```rust
impl Contract {
#[ink(constructor)]
pub fn new(
token: AccountId,
voting_delay: u64,
voting_period: u64,
proposal_threshold: u128,
numerator: u128,
) -> Self {
let mut instance = Self::default();

let caller = Self::env().caller();

instance._init_governor_votes(token).unwrap();
instance
._init_governor_settings(voting_delay, voting_period, proposal_threshold)
.unwrap();
instance._init_quorum_numerator(numerator).unwrap();
instance.mock_timestamp = Self::env().block_timestamp();

instance
}
}
```
## Step 3: Set up your Storage
It should have all fields for [Governor](/) and required extensions: [GovernorVotes](Extensions/votes.md), [GovernorSettings](Extensions/settings.md), [GovernorCounting](Extensions/counting.md), [GovernorQuorum](Extensions/quorum.md).
```rust
#[ink(storage)]
#[derive(Default, Storage)]
pub struct Contract {
#[storage_field]
governor: governor::Data,
#[storage_field]
governor_counting: governor_counting::Data,
#[storage_field]
governor_votes: governor_votes::Data,
#[storage_field]
settings: governor_settings::Data,
#[storage_field]
quorum: governor_quorum::Data,
}
```


## Step 4: Make your PSP22Voting contract

Make your PSP22Voting contract which will be used for voting. You can use [PSP22Votes](../PSP22/Extensions/votes.md) for this purpose.
The AccountId of this token will then be used as a constructor parameter of this contract. You can check our [PSP22Votes](https://github.com/Brushfam/openbrush-contracts/tree/main/examples/psp22_extensions/votes) contract example.


You can check an example of the usage of [Governance](https://github.com/Brushfam/openbrush-contracts/tree/main/examples/governance/governor).
Loading