From 8546680c308989b4e121cec28bdd34aee98f9e0c Mon Sep 17 00:00:00 2001 From: prxgr4mm3r Date: Wed, 16 Aug 2023 20:16:40 +0300 Subject: [PATCH 1/7] add governor documentation --- .../smart-contracts/PSP22/Extensions/votes.md | 0 .../smart-contracts/governance/governor.md | 76 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md create mode 100644 docs/OpenBrush/smart-contracts/governance/governor.md diff --git a/docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md b/docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/OpenBrush/smart-contracts/governance/governor.md b/docs/OpenBrush/smart-contracts/governance/governor.md new file mode 100644 index 0000000..3226da2 --- /dev/null +++ b/docs/OpenBrush/smart-contracts/governance/governor.md @@ -0,0 +1,76 @@ +--- +sidebar_position: 1 +title: PSP22 +--- + +This example shows how you can reuse the implementation of [Governance](https://github.com/Brushfam/openbrush-contracts/tree/main/contracts/src/governance) token. Also, this example shows how you can customize the logic, for example, to reject transferring tokens to `hated_account`. + +## 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, embed modules data structures and implement them via `#[openbrush::implementation]` macro +as described in [that section](../overview.md/#reuse-implementation-of-traits-from-openbrush). + +The main trait is `Governor`. + +## Step 2: Define constructor + +Define constructor where you initialize required extentions [GovernorVotes](), [GovernorSettings]() and [GovernorQuorum](). + +```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(); + access_control::Internal::_init_with_admin(&mut instance, Some(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 [Governance]() and required extensions: [GovernorVotes](), [GovernorSettings](), [GovernorCounting](), [Quorum](), [Nonces](), [Votes](). +```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] + nonces: nonces::Data, + #[storage_field] + settings: governor_settings::Data, + #[storage_field] + quorum: governor_quorum::Data, + #[storage_field] + votes: votes::Data, + } +``` + + +## Step 4: Make your PSP22Voting contract + +Make your PSP22Voting contract which will be used for voting. You can use [PSP22Votes]() for this purpose. +And then enter the address of this contract in the `token` field of the constructor. You can check our [PSP22Votes]() contract example. + + +You can check an example of the usage of [Governance](https://github.com/Brushfam/openbrush-contracts/tree/main/examples/governance). From 49ca4473185498db19d5759129dedf422614838f Mon Sep 17 00:00:00 2001 From: prxgr4mm3r Date: Wed, 16 Aug 2023 22:32:35 +0300 Subject: [PATCH 2/7] add documentation for governor extensions --- .../governance/Extensions/counting.md | 35 +++++++++++ .../governance/Extensions/quorum.md | 59 ++++++++++++++++++ .../governance/Extensions/settings.md | 60 +++++++++++++++++++ .../governance/Extensions/votes.md | 56 +++++++++++++++++ .../smart-contracts/governance/governor.md | 21 ++++--- 5 files changed, 220 insertions(+), 11 deletions(-) create mode 100644 docs/OpenBrush/smart-contracts/governance/Extensions/counting.md create mode 100644 docs/OpenBrush/smart-contracts/governance/Extensions/quorum.md create mode 100644 docs/OpenBrush/smart-contracts/governance/Extensions/settings.md create mode 100644 docs/OpenBrush/smart-contracts/governance/Extensions/votes.md diff --git a/docs/OpenBrush/smart-contracts/governance/Extensions/counting.md b/docs/OpenBrush/smart-contracts/governance/Extensions/counting.md new file mode 100644 index 0000000..df2b58e --- /dev/null +++ b/docs/OpenBrush/smart-contracts/governance/Extensions/counting.md @@ -0,0 +1,35 @@ +--- +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 provides the ability to count your votes when you cast them, to realize when the quorum is reached, and to realize when the voting is succeeded. + +This page describes how to connect GovernorCounting to Governor 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, embed modules data structures and implement them via `#[openbrush::implementation]` macro +as described in [that section](../../overview.md/#reuse-implementation-of-traits-from-openbrush). + +The main trait is `Governor`. + +## Step 2: Add GovernorCounting field in your Storage +GovernorQuorum field in your Storage should be named `governor_counting` and have type `governor_counting::Data`. +It 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). diff --git a/docs/OpenBrush/smart-contracts/governance/Extensions/quorum.md b/docs/OpenBrush/smart-contracts/governance/Extensions/quorum.md new file mode 100644 index 0000000..839b232 --- /dev/null +++ b/docs/OpenBrush/smart-contracts/governance/Extensions/quorum.md @@ -0,0 +1,59 @@ +--- +sidebar_position: 1 +title: GovernorSettings +--- +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. + +This page describes how to connect GovernorQuorum to Governor 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, embed modules data structures and implement them via `#[openbrush::implementation]` macro +as described in [that section](../../overview.md/#reuse-implementation-of-traits-from-openbrush). + +The main trait is `Governor`. + +## 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 +GovernorQuorum field in your Storage should be named `quorum` and have type `governor_quorum::Data`. +It 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). diff --git a/docs/OpenBrush/smart-contracts/governance/Extensions/settings.md b/docs/OpenBrush/smart-contracts/governance/Extensions/settings.md new file mode 100644 index 0000000..54bca2d --- /dev/null +++ b/docs/OpenBrush/smart-contracts/governance/Extensions/settings.md @@ -0,0 +1,60 @@ +--- +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 that need to propose a proposal). + +This page describes how to connect GovernorSettings to Governor 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, embed modules data structures and implement them via `#[openbrush::implementation]` macro +as described in [that section](../../overview.md/#reuse-implementation-of-traits-from-openbrush). + +The main trait is `Governor`. + +## 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 +GovernorSettings field in your Storage should be named `settings` and have type `governor_settings::Data`. +It stores the values of voting delay, voting period, proposal threshold. +```rust +#[ink(storage)] + #[derive(Default, Storage)] + pub struct Contract { + ... + #[storage_field] + governor_votes: governor_votes::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). diff --git a/docs/OpenBrush/smart-contracts/governance/Extensions/votes.md b/docs/OpenBrush/smart-contracts/governance/Extensions/votes.md new file mode 100644 index 0000000..e9c6431 --- /dev/null +++ b/docs/OpenBrush/smart-contracts/governance/Extensions/votes.md @@ -0,0 +1,56 @@ +--- +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. + +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, embed modules data structures and implement them via `#[openbrush::implementation]` macro +as described in [that section](../../overview.md/#reuse-implementation-of-traits-from-openbrush). + +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 +GovernorVotes field in your Storage should be named `governor_votes` and have type `governor_votes::Data`. +It stores the address 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). diff --git a/docs/OpenBrush/smart-contracts/governance/governor.md b/docs/OpenBrush/smart-contracts/governance/governor.md index 3226da2..d1104d1 100644 --- a/docs/OpenBrush/smart-contracts/governance/governor.md +++ b/docs/OpenBrush/smart-contracts/governance/governor.md @@ -1,9 +1,11 @@ --- sidebar_position: 1 -title: PSP22 +title: Governance --- - -This example shows how you can reuse the implementation of [Governance](https://github.com/Brushfam/openbrush-contracts/tree/main/contracts/src/governance) token. Also, this example shows how you can customize the logic, for example, to reject transferring tokens to `hated_account`. +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, against the proposal, or abstain. +When the voting period ends, the proposal can be executed if the proposal status is `Succeeded` and the quorum is reached or declined otherwise. +This example shows how you can use the implementation of [Governance](https://github.com/Brushfam/openbrush-contracts/tree/main/contracts/src/governance) token. ## Step 1: Import default implementation @@ -15,7 +17,7 @@ The main trait is `Governor`. ## Step 2: Define constructor -Define constructor where you initialize required extentions [GovernorVotes](), [GovernorSettings]() and [GovernorQuorum](). +Define constructor where you initialize required extensions [GovernorVotes](Extensions/votes.md), [GovernorSettings](Extensions/settings.md) and [GovernorQuorum](Extensions/quorum.md). ```rust impl Contract { @@ -30,8 +32,7 @@ impl Contract { let mut instance = Self::default(); let caller = Self::env().caller(); - access_control::Internal::_init_with_admin(&mut instance, Some(caller)); - + instance._init_governor_votes(token).unwrap(); instance ._init_governor_settings(voting_delay, voting_period, proposal_threshold) @@ -44,7 +45,7 @@ impl Contract { } ``` ## Step 3: Set up your Storage -It should have all fields for [Governance]() and required extensions: [GovernorVotes](), [GovernorSettings](), [GovernorCounting](), [Quorum](), [Nonces](), [Votes](). +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), [Nonces](). ```rust #[ink(storage)] #[derive(Default, Storage)] @@ -61,16 +62,14 @@ It should have all fields for [Governance]() and required extensions: [GovernorV settings: governor_settings::Data, #[storage_field] quorum: governor_quorum::Data, - #[storage_field] - votes: votes::Data, } ``` ## Step 4: Make your PSP22Voting contract -Make your PSP22Voting contract which will be used for voting. You can use [PSP22Votes]() for this purpose. -And then enter the address of this contract in the `token` field of the constructor. You can check our [PSP22Votes]() contract example. +Make your PSP22Voting contract which will be used for voting. You can use [PSP22Votes](../PSP22/Extensions/votes.md) for this purpose. +And then enter the address of this contract in the `token` field of the constructor. 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). From 1bc55d0ae2621f7fdac0689206b969d0af6527e4 Mon Sep 17 00:00:00 2001 From: prxgr4mm3r Date: Thu, 17 Aug 2023 10:58:54 +0300 Subject: [PATCH 3/7] add PSP22Votes documentation --- .../smart-contracts/PSP22/Extensions/votes.md | 42 +++++++++++++++++++ .../smart-contracts/governance/governor.md | 4 +- .../OpenBrush/smart-contracts/utils/nonces.md | 33 +++++++++++++++ 3 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 docs/OpenBrush/smart-contracts/utils/nonces.md diff --git a/docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md b/docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md index e69de29..273564c 100644 --- a/docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md +++ b/docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md @@ -0,0 +1,42 @@ +--- +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. + +This page describes how to create your own [PSP22Votes](/) contract. +## Step 1: 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 `PSP22Votes` feature, embed modules data structures and implement them via `#[openbrush::implementation]` macro +as described in [that section](../overview.md/#reuse-implementation-of-traits-from-openbrush). + + + + +## Step 2: Set up your Storage +It should add a `votes` field in your Storage. It should be named `votes` and have the type `votes::Data`. +It stores information about delegations, checkpoints for each account, which stores the number of votes at a certain time, and the total number of votes, also at a certain time. +Also, Storage should have a `nonces` field. It should be named `nonces` and have the type `nonces::Data`. +It stores the number of nonces for each account. Nonce is a number that is incremented each time a user delegates tokens to another account by signature. +```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, as a voting power. + +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) diff --git a/docs/OpenBrush/smart-contracts/governance/governor.md b/docs/OpenBrush/smart-contracts/governance/governor.md index d1104d1..e8220da 100644 --- a/docs/OpenBrush/smart-contracts/governance/governor.md +++ b/docs/OpenBrush/smart-contracts/governance/governor.md @@ -45,7 +45,7 @@ impl Contract { } ``` ## 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), [Nonces](). +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)] @@ -57,8 +57,6 @@ It should have all fields for [Governor](/) and required extensions: [GovernorVo #[storage_field] governor_votes: governor_votes::Data, #[storage_field] - nonces: nonces::Data, - #[storage_field] settings: governor_settings::Data, #[storage_field] quorum: governor_quorum::Data, diff --git a/docs/OpenBrush/smart-contracts/utils/nonces.md b/docs/OpenBrush/smart-contracts/utils/nonces.md new file mode 100644 index 0000000..099b37e --- /dev/null +++ b/docs/OpenBrush/smart-contracts/utils/nonces.md @@ -0,0 +1,33 @@ +--- +sidebar_position: 1 +title: Nonces +--- +This utility provides a way to prevent replay attacks. + +This page describes how to connect GovernorCounting to Governor 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, embed modules data structures and implement them via `#[openbrush::implementation]` macro +as described in [that section](../../overview.md/#reuse-implementation-of-traits-from-openbrush). + +The main trait is `Governor`. + +## Step 2: Add GovernorCounting field in your Storage +GovernorQuorum field in your Storage should be named `governor_counting` and have type `governor_counting::Data`. +It 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). From 0841eca863a49c152d17ad22a384e5333488fbcf Mon Sep 17 00:00:00 2001 From: prxgr4mm3r Date: Thu, 17 Aug 2023 12:34:40 +0300 Subject: [PATCH 4/7] add Nonces and Checkpoints docs --- .../smart-contracts/PSP22/Extensions/votes.md | 6 +-- .../governance/Extensions/counting.md | 18 ++++----- .../governance/Extensions/quorum.md | 20 +++++----- .../governance/Extensions/settings.md | 16 ++++---- .../governance/Extensions/votes.md | 16 ++++---- .../smart-contracts/governance/governor.md | 2 +- .../smart-contracts/utils/checkpoints.md | 39 +++++++++++++++++++ .../OpenBrush/smart-contracts/utils/nonces.md | 37 +++++++++--------- 8 files changed, 96 insertions(+), 58 deletions(-) create mode 100644 docs/OpenBrush/smart-contracts/utils/checkpoints.md diff --git a/docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md b/docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md index 273564c..e3e0a28 100644 --- a/docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md +++ b/docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md @@ -13,16 +13,16 @@ This page describes how to create your own [PSP22Votes](/) contract. First, you should implement basic version of [PSP22](../psp22.md). -With [default `Cargo.toml`](../overview.md/#the-default-toml-of-your-project-with-openbrush), +With [default `Cargo.toml`](../../overview.md/#the-default-toml-of-your-project-with-openbrush), you need to enable `PSP22Votes` feature, embed modules data structures and implement them via `#[openbrush::implementation]` macro -as described in [that section](../overview.md/#reuse-implementation-of-traits-from-openbrush). +as described in [that section](../../overview.md/#reuse-implementation-of-traits-from-openbrush). ## Step 2: Set up your Storage It should add a `votes` field in your Storage. It should be named `votes` and have the type `votes::Data`. -It stores information about delegations, checkpoints for each account, which stores the number of votes at a certain time, and the total number of votes, also at a certain time. +It stores information about delegations, [checkpoints]() for each account, which stores the number of votes at a certain time, and the total number of votes, also at a certain time. Also, Storage should have a `nonces` field. It should be named `nonces` and have the type `nonces::Data`. It stores the number of nonces for each account. Nonce is a number that is incremented each time a user delegates tokens to another account by signature. ```rust diff --git a/docs/OpenBrush/smart-contracts/governance/Extensions/counting.md b/docs/OpenBrush/smart-contracts/governance/Extensions/counting.md index df2b58e..ec45672 100644 --- a/docs/OpenBrush/smart-contracts/governance/Extensions/counting.md +++ b/docs/OpenBrush/smart-contracts/governance/Extensions/counting.md @@ -17,19 +17,19 @@ as described in [that section](../../overview.md/#reuse-implementation-of-traits The main trait is `Governor`. ## Step 2: Add GovernorCounting field in your Storage -GovernorQuorum field in your Storage should be named `governor_counting` and have type `governor_counting::Data`. +GovernorCounting field in your Storage should be named `governor_counting` and have type `governor_counting::Data`. It 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, - ... - } +#[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). +You can check an example of the usage of [Governance](https://github.com/Brushfam/openbrush-contracts/tree/main/examples/governance/governor). diff --git a/docs/OpenBrush/smart-contracts/governance/Extensions/quorum.md b/docs/OpenBrush/smart-contracts/governance/Extensions/quorum.md index 839b232..7e4e05a 100644 --- a/docs/OpenBrush/smart-contracts/governance/Extensions/quorum.md +++ b/docs/OpenBrush/smart-contracts/governance/Extensions/quorum.md @@ -1,12 +1,12 @@ --- sidebar_position: 1 -title: GovernorSettings +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, +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. This page describes how to connect GovernorQuorum to Governor contract. @@ -45,15 +45,15 @@ GovernorQuorum field in your Storage should be named `quorum` and have type `gov It stores the history of quorum numerator changes. ```rust #[ink(storage)] - #[derive(Default, Storage)] - pub struct Contract { - ... - #[storage_field] - quorum: governor_quorum::Data, - ... - } +#[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). +You can check an example of the usage of [Governance](https://github.com/Brushfam/openbrush-contracts/tree/main/examples/governance/governor). diff --git a/docs/OpenBrush/smart-contracts/governance/Extensions/settings.md b/docs/OpenBrush/smart-contracts/governance/Extensions/settings.md index 54bca2d..d3825cb 100644 --- a/docs/OpenBrush/smart-contracts/governance/Extensions/settings.md +++ b/docs/OpenBrush/smart-contracts/governance/Extensions/settings.md @@ -44,17 +44,17 @@ GovernorSettings field in your Storage should be named `settings` and have type It stores the values of voting delay, voting period, proposal threshold. ```rust #[ink(storage)] - #[derive(Default, Storage)] - pub struct Contract { - ... - #[storage_field] - governor_votes: governor_votes::Data, - ... - } +#[derive(Default, Storage)] +pub struct Contract { + ... + #[storage_field] + governor_votes: governor_votes::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). +You can check an example of the usage of [Governance](https://github.com/Brushfam/openbrush-contracts/tree/main/examples/governance/governor). diff --git a/docs/OpenBrush/smart-contracts/governance/Extensions/votes.md b/docs/OpenBrush/smart-contracts/governance/Extensions/votes.md index e9c6431..3c36850 100644 --- a/docs/OpenBrush/smart-contracts/governance/Extensions/votes.md +++ b/docs/OpenBrush/smart-contracts/governance/Extensions/votes.md @@ -40,17 +40,17 @@ GovernorVotes field in your Storage should be named `governor_votes` and have ty It stores the address of [PSP22Votes](../../PSP22/Extensions/votes.md) token. ```rust #[ink(storage)] - #[derive(Default, Storage)] - pub struct Contract { - ... - #[storage_field] - governor_votes: governor_votes::Data, - ... - } +#[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). +You can check an example of the usage of [Governance](https://github.com/Brushfam/openbrush-contracts/tree/main/examples/governance/governor). diff --git a/docs/OpenBrush/smart-contracts/governance/governor.md b/docs/OpenBrush/smart-contracts/governance/governor.md index e8220da..1b2c29a 100644 --- a/docs/OpenBrush/smart-contracts/governance/governor.md +++ b/docs/OpenBrush/smart-contracts/governance/governor.md @@ -70,4 +70,4 @@ Make your PSP22Voting contract which will be used for voting. You can use [PSP22 And then enter the address of this contract in the `token` field of the constructor. 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). +You can check an example of the usage of [Governance](https://github.com/Brushfam/openbrush-contracts/tree/main/examples/governance/governor). diff --git a/docs/OpenBrush/smart-contracts/utils/checkpoints.md b/docs/OpenBrush/smart-contracts/utils/checkpoints.md new file mode 100644 index 0000000..2cf12d3 --- /dev/null +++ b/docs/OpenBrush/smart-contracts/utils/checkpoints.md @@ -0,0 +1,39 @@ +--- +sidebar_position: 1 +title: Checkpoints +--- +This structure provides the ability to store and manage checkpoints. +It allows to make a snapshot of the state of the contract at a certain moment and restore it later. +To add your value to the checkpoint, you need to call the `push` method. It has two arguments: `key`(usually it's a timestamp) and `value`. +There are several methods to get the value from the checkpoint: +- `lower_lookup` - Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if there is none. +- `upper_lookup` - Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none. +- `upper_lookup_recent` - This is a variant of `upper_lookup` that is optimised to find "recent" checkpoint (checkpoints with high keys). +- `latest` - Returns the value in the most recent checkpoint, or 0 if there are no checkpoints. +- `latest_checkpoint` - Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value in the most recent checkpoint. + +This page describes how to use Checkpoints in your contract. + +## Step 1: Import checkpoints module + +```rust +use openbrush::utils::checkpoints::Checkpoints; +``` + +## Step 2: Add field in your Storage, that uses Checkpoints +For example, you want to save how total supply of your token changes over time. +Then you need to add a field in your Storage, that uses Checkpoints. +```rust +#[ink(storage)] +#[derive(Default, Storage)] +pub struct Contract { + ... + #[storage_field] + total_supply_history: Checkpoints, + ... +} +``` + +That's it! Now you can use [Checkpoints](/) structure in your contract. + +You can check an example of the usage of [Checkpoints](https://github.com/Brushfam/openbrush-contracts/tree/main/contracts/src/utils/checkpoints) in our [Votes](https://github.com/Brushfam/openbrush-contracts/tree/main/contracts/governance/utils/votes) implementation. diff --git a/docs/OpenBrush/smart-contracts/utils/nonces.md b/docs/OpenBrush/smart-contracts/utils/nonces.md index 099b37e..0ea2477 100644 --- a/docs/OpenBrush/smart-contracts/utils/nonces.md +++ b/docs/OpenBrush/smart-contracts/utils/nonces.md @@ -1,33 +1,32 @@ ---- +~~--- sidebar_position: 1 title: Nonces --- -This utility provides a way to prevent replay attacks. - -This page describes how to connect GovernorCounting to Governor contract. +This utility provides tracking nonces for each user. Nonces will only increment. +For example, you can use this utility to prevent replay attacks when you use signatures. +It has three main methods: `nonces` - that just returns the next unused nonce for the user, `use_nonce` - that marks the nonce as used and increment it, and `use_check_nonce` - that checks if the right nonce is used and marks it as used. +This page describes how to use [Nonces](/) in your 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, embed modules data structures and implement them via `#[openbrush::implementation]` macro +you need to enable `Nonces` feature, embed modules data structures and implement them via `#[openbrush::implementation]` macro as described in [that section](../../overview.md/#reuse-implementation-of-traits-from-openbrush). -The main trait is `Governor`. - -## Step 2: Add GovernorCounting field in your Storage -GovernorQuorum field in your Storage should be named `governor_counting` and have type `governor_counting::Data`. -It stores the number of votes for all proposals, and information about whether a user has voted for a proposal. +## Step 2: Add Nonces field in your Storage +Nonces field in your Storage should be named `nonces` and have type `nonces::Data`. +It stores nonces Mapping, which stores the next unused nonce for each user. ```rust #[ink(storage)] - #[derive(Default, Storage)] - pub struct Contract { - ... - #[storage_field] - governor_counting: governor_counting::Data, - ... - } +#[derive(Default, Storage)] +pub struct Contract { + ... + #[storage_field] + nonces: nonces::Data, + ... +} ``` -That's it! Now you can use [GovernorCounting](/) extension in your [Governor](../governor.md) contract. +That's it! Now you can use [Nonces](/) in your contract. -You can check an example of the usage of [Governance](https://github.com/Brushfam/openbrush-contracts/tree/main/examples/governance). +You can check an example of the usage of [Nonces](https://github.com/Brushfam/openbrush-contracts/tree/main/contracts/src/utils/nonces) in our [PSP22Votes](https://github.com/Brushfam/openbrush-contracts/tree/main/examples/psp22_extensions/votes) contract example.~~ From 75dda2c774e6ec2c1243f55013b48614e0608df3 Mon Sep 17 00:00:00 2001 From: prxgr4mm3r Date: Fri, 18 Aug 2023 16:44:36 +0300 Subject: [PATCH 5/7] fix governance docs --- .../smart-contracts/PSP22/Extensions/votes.md | 18 +++++++++++++----- .../governance/Extensions/counting.md | 17 ++++++++++++----- .../governance/Extensions/quorum.md | 18 ++++++++++++------ .../governance/Extensions/settings.md | 18 ++++++++++++------ .../governance/Extensions/votes.md | 15 +++++++++++++-- .../smart-contracts/governance/governor.md | 18 +++++++++++++----- 6 files changed, 75 insertions(+), 29 deletions(-) diff --git a/docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md b/docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md index e3e0a28..9d2a247 100644 --- a/docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md +++ b/docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md @@ -6,18 +6,26 @@ This feature provides a way to use your token as a voting power. You can use it 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. +It's a required tool to create a [Governor](../../governance/governor.md) contract. +Also, you can check the [documentation](https://docs.openzeppelin.com/contracts/4.x/api/token/erc20#ERC20Votes) in OpenZeppelin Contracts for more information about the voting mechanism. This page describes how to create your own [PSP22Votes](/) contract. -## Step 1: Default implementation +## 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 `PSP22Votes` feature, embed modules data structures and implement them via `#[openbrush::implementation]` macro -as described in [that section](../../overview.md/#reuse-implementation-of-traits-from-openbrush). - +you need to enable `governance` feature. Also, you need to use implementation macro +for PSP22Votes and Nonces: +```rust +#[openbrush::implementation(..., PSP22Votes, Nonces, ...)] +#[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: Set up your Storage diff --git a/docs/OpenBrush/smart-contracts/governance/Extensions/counting.md b/docs/OpenBrush/smart-contracts/governance/Extensions/counting.md index ec45672..16a4d9c 100644 --- a/docs/OpenBrush/smart-contracts/governance/Extensions/counting.md +++ b/docs/OpenBrush/smart-contracts/governance/Extensions/counting.md @@ -5,16 +5,23 @@ 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 provides the ability to count your votes when you cast them, to realize when the quorum is reached, and to realize when the voting is succeeded. +You can check the [documentation](https://docs.openzeppelin.com/contracts/4.x/api/governance#GovernorCountingSimple) in OpenZeppelin Contracts for more information about the counting mechanism. -This page describes how to connect GovernorCounting to Governor contract. +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, embed modules data structures and implement them via `#[openbrush::implementation]` macro -as described in [that section](../../overview.md/#reuse-implementation-of-traits-from-openbrush). - -The main trait is `Governor`. +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 [that section](../../overview.md/#reuse-implementation-of-traits-from-openbrush) to understand how it works. ## Step 2: Add GovernorCounting field in your Storage GovernorCounting field in your Storage should be named `governor_counting` and have type `governor_counting::Data`. diff --git a/docs/OpenBrush/smart-contracts/governance/Extensions/quorum.md b/docs/OpenBrush/smart-contracts/governance/Extensions/quorum.md index 7e4e05a..f730cba 100644 --- a/docs/OpenBrush/smart-contracts/governance/Extensions/quorum.md +++ b/docs/OpenBrush/smart-contracts/governance/Extensions/quorum.md @@ -8,16 +8,23 @@ 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. +Also, you can check the [documentation](https://docs.openzeppelin.com/contracts/4.x/api/governance#GovernorQuorumFraction) in OpenZeppelin Contracts for more information about the quorum calculation mechanism. -This page describes how to connect GovernorQuorum to Governor contract. +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, embed modules data structures and implement them via `#[openbrush::implementation]` macro -as described in [that section](../../overview.md/#reuse-implementation-of-traits-from-openbrush). - -The main trait is `Governor`. +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 @@ -53,7 +60,6 @@ pub struct Contract { ... } ``` - 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). diff --git a/docs/OpenBrush/smart-contracts/governance/Extensions/settings.md b/docs/OpenBrush/smart-contracts/governance/Extensions/settings.md index d3825cb..d4fdac8 100644 --- a/docs/OpenBrush/smart-contracts/governance/Extensions/settings.md +++ b/docs/OpenBrush/smart-contracts/governance/Extensions/settings.md @@ -5,17 +5,23 @@ 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 that need to propose a proposal). +Also, you can check the [documentation](https://docs.openzeppelin.com/contracts/4.x/api/governance#GovernorSettings) in OpenZeppelin Contracts for more information about the settings mechanism. -This page describes how to connect GovernorSettings to Governor contract. +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, embed modules data structures and implement them via `#[openbrush::implementation]` macro -as described in [that section](../../overview.md/#reuse-implementation-of-traits-from-openbrush). - -The main trait is `Governor`. - +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 [that 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. diff --git a/docs/OpenBrush/smart-contracts/governance/Extensions/votes.md b/docs/OpenBrush/smart-contracts/governance/Extensions/votes.md index 3c36850..45f36ce 100644 --- a/docs/OpenBrush/smart-contracts/governance/Extensions/votes.md +++ b/docs/OpenBrush/smart-contracts/governance/Extensions/votes.md @@ -4,14 +4,25 @@ 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 [documentation](https://docs.openzeppelin.com/contracts/4.x/api/governance#GovernorVotes) in OpenZeppelin Contracts for more information about the voting mechanism. 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, embed modules data structures and implement them via `#[openbrush::implementation]` macro -as described in [that section](../../overview.md/#reuse-implementation-of-traits-from-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 [that section](../../overview.md/#reuse-implementation-of-traits-from-openbrush) to understand how it works. The main trait is `Governor`. diff --git a/docs/OpenBrush/smart-contracts/governance/governor.md b/docs/OpenBrush/smart-contracts/governance/governor.md index 1b2c29a..b3b0515 100644 --- a/docs/OpenBrush/smart-contracts/governance/governor.md +++ b/docs/OpenBrush/smart-contracts/governance/governor.md @@ -5,15 +5,23 @@ 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, against the proposal, or abstain. When the voting period ends, the proposal can be executed if the proposal status is `Succeeded` and the quorum is reached or declined otherwise. -This example shows how you can use the implementation of [Governance](https://github.com/Brushfam/openbrush-contracts/tree/main/contracts/src/governance) token. +This example shows how you can use the implementation of [Governance](https://github.com/Brushfam/openbrush-contracts/tree/main/contracts/src/governance) token. +Also you can check the [documentation](https://docs.openzeppelin.com/contracts/4.x/api/governance) in OpenZeppelin Contracts +for more information about the governance mechanism. ## 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, embed modules data structures and implement them via `#[openbrush::implementation]` macro -as described in [that section](../overview.md/#reuse-implementation-of-traits-from-openbrush). - -The main trait is `Governor`. +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 [that section](../overview.md/#reuse-implementation-of-traits-from-openbrush) to understand how it works. ## Step 2: Define constructor From 4e1855b40e2442d0f6ba0bf406b2401eb08d5b58 Mon Sep 17 00:00:00 2001 From: prxgr4mm3r Date: Tue, 29 Aug 2023 10:45:19 +0300 Subject: [PATCH 6/7] fix docs --- .../smart-contracts/PSP22/Extensions/votes.md | 12 +++++------- .../governance/Extensions/counting.md | 7 +++---- .../governance/Extensions/quorum.md | 3 +-- .../governance/Extensions/settings.md | 9 ++++----- .../governance/Extensions/votes.md | 5 ++--- .../smart-contracts/governance/governor.md | 10 +++++----- .../smart-contracts/utils/checkpoints.md | 19 +++++++++++++++++-- .../OpenBrush/smart-contracts/utils/nonces.md | 5 ++--- 8 files changed, 39 insertions(+), 31 deletions(-) diff --git a/docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md b/docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md index 9d2a247..64c162a 100644 --- a/docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md +++ b/docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md @@ -15,7 +15,7 @@ This page describes how to create your own [PSP22Votes](/) contract. 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` feature. Also, you need to use implementation macro +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, ...)] @@ -25,14 +25,12 @@ pub mod your_contract { } ``` -You can check [that section](../../overview.md/#reuse-implementation-of-traits-from-openbrush) to understand how it works. +You can check [this section](../../overview.md/#reuse-implementation-of-traits-from-openbrush) to understand how it works. ## Step 2: Set up your Storage -It should add a `votes` field in your Storage. It should be named `votes` and have the type `votes::Data`. -It stores information about delegations, [checkpoints]() for each account, which stores the number of votes at a certain time, and the total number of votes, also at a certain time. -Also, Storage should have a `nonces` field. It should be named `nonces` and have the type `nonces::Data`. -It stores the number of nonces for each account. Nonce is a number that is incremented each time a user delegates tokens to another account by signature. +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)] @@ -45,6 +43,6 @@ pub struct Contract { ... } ``` -That's it! Now we have a [PSP22Votes](/) contract. You can use it in your [Governor](../../governance/governor.md) contract, as a voting power. +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) diff --git a/docs/OpenBrush/smart-contracts/governance/Extensions/counting.md b/docs/OpenBrush/smart-contracts/governance/Extensions/counting.md index 16a4d9c..64492f9 100644 --- a/docs/OpenBrush/smart-contracts/governance/Extensions/counting.md +++ b/docs/OpenBrush/smart-contracts/governance/Extensions/counting.md @@ -4,7 +4,7 @@ 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 provides the ability to count your votes when you cast them, to realize when the quorum is reached, and to realize when the voting is succeeded. +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 [documentation](https://docs.openzeppelin.com/contracts/4.x/api/governance#GovernorCountingSimple) in OpenZeppelin Contracts for more information about the counting mechanism. This page describes how to connect [GovernorCounting](/) to [Governor](../governor.md) contract. @@ -21,11 +21,10 @@ pub mod your_contract { ... } ``` -You can check [that section](../../overview.md/#reuse-implementation-of-traits-from-openbrush) to understand how it works. +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 -GovernorCounting field in your Storage should be named `governor_counting` and have type `governor_counting::Data`. -It stores the number of votes for all proposals, and information about whether a user has voted for a proposal. +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)] diff --git a/docs/OpenBrush/smart-contracts/governance/Extensions/quorum.md b/docs/OpenBrush/smart-contracts/governance/Extensions/quorum.md index f730cba..23e5531 100644 --- a/docs/OpenBrush/smart-contracts/governance/Extensions/quorum.md +++ b/docs/OpenBrush/smart-contracts/governance/Extensions/quorum.md @@ -48,8 +48,7 @@ impl Contract { } ``` ## Step 3: Add GovernorQuorum field in your Storage -GovernorQuorum field in your Storage should be named `quorum` and have type `governor_quorum::Data`. -It stores the history of quorum numerator changes. +Add a storage field of type `governor_quorum::Data`, which stores the history of quorum numerator changes. ```rust #[ink(storage)] #[derive(Default, Storage)] diff --git a/docs/OpenBrush/smart-contracts/governance/Extensions/settings.md b/docs/OpenBrush/smart-contracts/governance/Extensions/settings.md index d4fdac8..c70bbb3 100644 --- a/docs/OpenBrush/smart-contracts/governance/Extensions/settings.md +++ b/docs/OpenBrush/smart-contracts/governance/Extensions/settings.md @@ -4,7 +4,7 @@ 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 that need to propose a proposal). +voting period, proposal threshold(The amount of votes required to propose a proposal). Also, you can check the [documentation](https://docs.openzeppelin.com/contracts/4.x/api/governance#GovernorSettings) in OpenZeppelin Contracts for more information about the settings mechanism. This page describes how to connect [GovernorSettings](/) to [Governor](../governor.md) contract. @@ -21,7 +21,7 @@ pub mod your_contract { ... } ``` -You can check [that section](../../overview.md/#reuse-implementation-of-traits-from-openbrush) to understand how it works. +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. @@ -46,15 +46,14 @@ impl Contract { } ``` ## Step 3: Add GovernorSettings field in your Storage -GovernorSettings field in your Storage should be named `settings` and have type `governor_settings::Data`. -It stores the values of voting delay, voting period, proposal threshold. +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] - governor_votes: governor_votes::Data, + settings: governor_settings::Data, ... } ``` diff --git a/docs/OpenBrush/smart-contracts/governance/Extensions/votes.md b/docs/OpenBrush/smart-contracts/governance/Extensions/votes.md index 45f36ce..7783f9a 100644 --- a/docs/OpenBrush/smart-contracts/governance/Extensions/votes.md +++ b/docs/OpenBrush/smart-contracts/governance/Extensions/votes.md @@ -22,7 +22,7 @@ pub mod your_contract { } ``` -You can check [that section](../../overview.md/#reuse-implementation-of-traits-from-openbrush) to understand how it works. +You can check [this section](../../overview.md/#reuse-implementation-of-traits-from-openbrush) to understand how it works. The main trait is `Governor`. @@ -47,8 +47,7 @@ impl Contract { } ``` ## Step 3: Add GovernorVotes field in your Storage -GovernorVotes field in your Storage should be named `governor_votes` and have type `governor_votes::Data`. -It stores the address of [PSP22Votes](../../PSP22/Extensions/votes.md) token. +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)] diff --git a/docs/OpenBrush/smart-contracts/governance/governor.md b/docs/OpenBrush/smart-contracts/governance/governor.md index b3b0515..8773bea 100644 --- a/docs/OpenBrush/smart-contracts/governance/governor.md +++ b/docs/OpenBrush/smart-contracts/governance/governor.md @@ -3,8 +3,8 @@ 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, against the proposal, or abstain. -When the voting period ends, the proposal can be executed if the proposal status is `Succeeded` and the quorum is reached or declined otherwise. +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. Also you can check the [documentation](https://docs.openzeppelin.com/contracts/4.x/api/governance) in OpenZeppelin Contracts for more information about the governance mechanism. @@ -21,7 +21,7 @@ pub mod your_contract { ... } ``` -You can check [that section](../overview.md/#reuse-implementation-of-traits-from-openbrush) to understand how it works. +You can check [this section](../overview.md/#reuse-implementation-of-traits-from-openbrush) to understand how it works. ## Step 2: Define constructor @@ -74,8 +74,8 @@ It should have all fields for [Governor](/) and required extensions: [GovernorVo ## 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. -And then enter the address of this contract in the `token` field of the constructor. You can check our [PSP22Votes](https://github.com/Brushfam/openbrush-contracts/tree/main/examples/psp22_extensions/votes) contract example. +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). diff --git a/docs/OpenBrush/smart-contracts/utils/checkpoints.md b/docs/OpenBrush/smart-contracts/utils/checkpoints.md index 2cf12d3..5e17f37 100644 --- a/docs/OpenBrush/smart-contracts/utils/checkpoints.md +++ b/docs/OpenBrush/smart-contracts/utils/checkpoints.md @@ -12,7 +12,8 @@ There are several methods to get the value from the checkpoint: - `latest` - Returns the value in the most recent checkpoint, or 0 if there are no checkpoints. - `latest_checkpoint` - Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value in the most recent checkpoint. -This page describes how to use Checkpoints in your contract. +This page describes how to use Checkpoints in your contract. For example, you want to save how total supply of your token changes over time. +Then you can use Checkpoints to do it. ## Step 1: Import checkpoints module @@ -21,7 +22,6 @@ use openbrush::utils::checkpoints::Checkpoints; ``` ## Step 2: Add field in your Storage, that uses Checkpoints -For example, you want to save how total supply of your token changes over time. Then you need to add a field in your Storage, that uses Checkpoints. ```rust #[ink(storage)] @@ -34,6 +34,21 @@ pub struct Contract { } ``` +## Step 3: Use Checkpoints in your contract +Modify all functions that change the value of total supply. For example, if you want to use Checkpoints to save the total supply of your token, you need to modify `_mint` function: +```rust +impl Contract { + ... + fn _mint(&mut self, to: &AccountId, amount: Balance) -> Result<(), Error> { + ... + self.total_supply_history.push(self.total_supply(), self.env().block_timestamp()); + ... + } + ... +} +``` + + That's it! Now you can use [Checkpoints](/) structure in your contract. You can check an example of the usage of [Checkpoints](https://github.com/Brushfam/openbrush-contracts/tree/main/contracts/src/utils/checkpoints) in our [Votes](https://github.com/Brushfam/openbrush-contracts/tree/main/contracts/governance/utils/votes) implementation. diff --git a/docs/OpenBrush/smart-contracts/utils/nonces.md b/docs/OpenBrush/smart-contracts/utils/nonces.md index 0ea2477..c3a0fd4 100644 --- a/docs/OpenBrush/smart-contracts/utils/nonces.md +++ b/docs/OpenBrush/smart-contracts/utils/nonces.md @@ -11,11 +11,10 @@ This page describes how to use [Nonces](/) in your contract. With [default `Cargo.toml`](../../overview.md/#the-default-toml-of-your-project-with-openbrush), you need to enable `Nonces` feature, embed modules data structures and implement them via `#[openbrush::implementation]` macro -as described in [that section](../../overview.md/#reuse-implementation-of-traits-from-openbrush). +as described in [this section](../../overview.md/#reuse-implementation-of-traits-from-openbrush). ## Step 2: Add Nonces field in your Storage -Nonces field in your Storage should be named `nonces` and have type `nonces::Data`. -It stores nonces Mapping, which stores the next unused nonce for each user. +Add a storage field of type `governor_settings::Data`, which stores nonces Mapping, which stores the next unused nonce for each user. ```rust #[ink(storage)] #[derive(Default, Storage)] From 24a9d5be26e2f46cb108e17548e51f315f784930 Mon Sep 17 00:00:00 2001 From: prxgr4mm3r Date: Wed, 30 Aug 2023 18:54:25 +0300 Subject: [PATCH 7/7] remove links ot OpenZeppelin --- docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md | 2 +- .../smart-contracts/governance/Extensions/counting.md | 2 +- docs/OpenBrush/smart-contracts/governance/Extensions/quorum.md | 2 +- .../smart-contracts/governance/Extensions/settings.md | 2 +- docs/OpenBrush/smart-contracts/governance/Extensions/votes.md | 2 +- docs/OpenBrush/smart-contracts/governance/governor.md | 3 +-- 6 files changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md b/docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md index 64c162a..95bf6fa 100644 --- a/docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md +++ b/docs/OpenBrush/smart-contracts/PSP22/Extensions/votes.md @@ -7,7 +7,7 @@ To cast a vote in [Governor](../../governance/governor.md) contract you need to 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. -Also, you can check the [documentation](https://docs.openzeppelin.com/contracts/4.x/api/token/erc20#ERC20Votes) in OpenZeppelin Contracts for more information about the voting mechanism. +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 diff --git a/docs/OpenBrush/smart-contracts/governance/Extensions/counting.md b/docs/OpenBrush/smart-contracts/governance/Extensions/counting.md index 64492f9..67efc9a 100644 --- a/docs/OpenBrush/smart-contracts/governance/Extensions/counting.md +++ b/docs/OpenBrush/smart-contracts/governance/Extensions/counting.md @@ -5,7 +5,7 @@ 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 [documentation](https://docs.openzeppelin.com/contracts/4.x/api/governance#GovernorCountingSimple) in OpenZeppelin Contracts for more information about the counting mechanism. +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. diff --git a/docs/OpenBrush/smart-contracts/governance/Extensions/quorum.md b/docs/OpenBrush/smart-contracts/governance/Extensions/quorum.md index 23e5531..92ce624 100644 --- a/docs/OpenBrush/smart-contracts/governance/Extensions/quorum.md +++ b/docs/OpenBrush/smart-contracts/governance/Extensions/quorum.md @@ -8,7 +8,7 @@ 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. -Also, you can check the [documentation](https://docs.openzeppelin.com/contracts/4.x/api/governance#GovernorQuorumFraction) in OpenZeppelin Contracts for more information about the quorum calculation mechanism. +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. diff --git a/docs/OpenBrush/smart-contracts/governance/Extensions/settings.md b/docs/OpenBrush/smart-contracts/governance/Extensions/settings.md index c70bbb3..59298f3 100644 --- a/docs/OpenBrush/smart-contracts/governance/Extensions/settings.md +++ b/docs/OpenBrush/smart-contracts/governance/Extensions/settings.md @@ -5,7 +5,7 @@ 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). -Also, you can check the [documentation](https://docs.openzeppelin.com/contracts/4.x/api/governance#GovernorSettings) in OpenZeppelin Contracts for more information about the settings mechanism. +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. diff --git a/docs/OpenBrush/smart-contracts/governance/Extensions/votes.md b/docs/OpenBrush/smart-contracts/governance/Extensions/votes.md index 7783f9a..e18c5fd 100644 --- a/docs/OpenBrush/smart-contracts/governance/Extensions/votes.md +++ b/docs/OpenBrush/smart-contracts/governance/Extensions/votes.md @@ -5,7 +5,7 @@ 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 [documentation](https://docs.openzeppelin.com/contracts/4.x/api/governance#GovernorVotes) in OpenZeppelin Contracts for more information about the voting mechanism. +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. diff --git a/docs/OpenBrush/smart-contracts/governance/governor.md b/docs/OpenBrush/smart-contracts/governance/governor.md index 8773bea..248e1fa 100644 --- a/docs/OpenBrush/smart-contracts/governance/governor.md +++ b/docs/OpenBrush/smart-contracts/governance/governor.md @@ -6,8 +6,7 @@ This feature provides a governance mechanism. It allows token holders to vote on 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. -Also you can check the [documentation](https://docs.openzeppelin.com/contracts/4.x/api/governance) in OpenZeppelin Contracts -for more information about the governance mechanism. +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