diff --git a/Makefile b/Makefile
index 2c485aa7..cc365062 100644
--- a/Makefile
+++ b/Makefile
@@ -21,3 +21,6 @@ lint: clippy
clean:
cargo clean
rm -rf tests/wasm/*.wasm
+
+docs:
+ cargo doc --features test-support --no-deps --open
\ No newline at end of file
diff --git a/README.md b/README.md
index bc1022c8..b187984a 100644
--- a/README.md
+++ b/README.md
@@ -1,44 +1,29 @@
-# contracts
+# MVPR DAO for Casper
-Voting contract
- data:
- - voting_address - Address
+Reusable smart contracts for building DAOs on top of Casper.
-Reputation contract
- data:
- - reputation_address - Address
- - owner - Address
- - whitelist - Vec
+Repository contains following modules:
+- `contract` provides smart contracts implementation,
+- `utils` and `macros` makes writing code easier,
+- `tests` contain integration tests,
+- `client` implements a JavaScript client for smart contracts interactions.
- methods:
- only_onwer:
- - change_onwership(new_owner: Address)
- - add_to_whitelist(addr: Address)
- - remove_from_whitelist(addr: Address)
-
- whitelist_only:
- - mint
- - burn
- - transfer_from
- - stake
+## Build contracts
+Build `WASM` files.
-Variable Repository
- data:
- ...
-
- methods:
- only_onwer:
- - change_onwership(new_owner: Address)
- - add_to_whitelist(addr: Address)
- - remove_from_whitelist(addr: Address)
-
- whitelist_only:
- - set_string(name: String, value: String)
- - set_u256(name: String, value: U256)
+```bash
+$ make build-contracts
+```
- all:
- - get_string(name: String) -> String
- - get_u256(name: String) -> U256
+## Test
+Run integration tests.
-Master Voting Contract:
- - vote for whitelist changes.
\ No newline at end of file
+```bash
+$ make test
+```
+
+## Docs
+Generate `rustdoc`. Opens a new browser window.
+```bash
+$ make docs
+```
diff --git a/contracts/Cargo.toml b/contracts/Cargo.toml
index d1524a2b..148e62c1 100644
--- a/contracts/Cargo.toml
+++ b/contracts/Cargo.toml
@@ -14,6 +14,7 @@ path = "bin/reputation_contract.rs"
bench = false
doctest = false
test = false
+doc = false
[profile.release]
codegen-units = 1
diff --git a/contracts/src/reputation.rs b/contracts/src/reputation.rs
index b34e7f46..a7c5ac37 100644
--- a/contracts/src/reputation.rs
+++ b/contracts/src/reputation.rs
@@ -17,18 +17,108 @@ use casper_types::{
EntryPointType, EntryPoints, Group, RuntimeArgs, URef, U256,
};
+/// Interface of the Reputation Contract.
+///
+/// It should be implemented by [`ReputationContract`], [`ReputationContractCaller`]
+/// and [`ReputationContractTest`].
pub trait ReputationContractInterface {
+ /// Constructor method.
+ ///
+ /// It initializes contract elements:
+ /// * Events dictionary.
+ /// * Named keys of [`TokenWithStaking`], [`Owner`] and [`Whitelist`].
+ /// * Set [`caller`] as the owner of the contract.
+ /// * Add [`caller`] to the whitelist.
+ ///
+ /// It emits [`OwnerChanged`](casper_dao_utils::owner::events::OwnerChanged),
+ /// [`AddedToWhitelist`](casper_dao_utils::whitelist::events::AddedToWhitelist) events.
fn init(&mut self);
+
+ /// Mint new tokens. Add `amount` of new tokens to the balance of the `recipient` and
+ /// increment the total supply. Only whitelisted addresses are permited to call this method.
+ ///
+ /// It throws [`NotWhitelisted`](casper_dao_utils::Error::NotWhitelisted) if caller
+ /// is not whitelisted.
+ ///
+ /// It emits [`Mint`](casper_dao_utils::token::events::Mint) event.
fn mint(&mut self, recipient: Address, amount: U256);
+
+ /// Burn existing tokens. Remove `amount` of existing tokens from the balance of the `owner`
+ /// and decrement the total supply. Only whitelisted addresses are permited to call this
+ /// method.
+ ///
+ /// It throws [`NotWhitelisted`](casper_dao_utils::Error::NotWhitelisted) if caller
+ /// is not whitelisted.
+ ///
+ /// It emits [`Burn`](casper_dao_utils::token::events::Burn) event.
fn burn(&mut self, owner: Address, amount: U256);
+
+ /// Transfer `amount` of tokens from `owner` to `recipient`. Only whitelisted addresses are
+ /// permited to call this method.
+ ///
+ /// It throws [`NotWhitelisted`](casper_dao_utils::Error::NotWhitelisted) if caller
+ /// is not whitelisted.
+ ///
+ /// It throws [`InsufficientBalance`](casper_dao_utils::Error::InsufficientBalance)
+ /// if `recipient`'s balance is less then `amount`.
+ ///
+ /// It emits [`Transfer`](casper_dao_utils::token::events::Transfer) event.
fn transfer_from(&mut self, owner: Address, recipient: Address, amount: U256);
+
+ /// Change ownership of the contract. Transfer the ownership to the `owner`. Only current owner
+ /// is permited to call this method.
+ ///
+ /// It throws [`NotAnOwner`](casper_dao_utils::Error::NotAnOwner) if caller
+ /// is not the current owner.
+ ///
+ /// It emits [`OwnerChanged`](casper_dao_utils::owner::events::OwnerChanged),
+ /// [`AddedToWhitelist`](casper_dao_utils::whitelist::events::AddedToWhitelist) events.
fn change_ownership(&mut self, owner: Address);
+
+ /// Add new address to the whitelist.
+ ///
+ /// It throws [`NotAnOwner`](casper_dao_utils::Error::NotAnOwner) if caller
+ /// is not the current owner.
+ ///
+ /// It emits [`AddedToWhitelist`](casper_dao_utils::whitelist::events::AddedToWhitelist) event.
fn add_to_whitelist(&mut self, address: Address);
+
+ /// Remove address from the whitelist.
+ ///
+ /// It throws [`NotAnOwner`](casper_dao_utils::Error::NotAnOwner) if caller
+ /// is not the current owner.
+ ///
+ /// It emits [`RemovedFromWhitelist`](casper_dao_utils::whitelist::events::RemovedFromWhitelist)
+ /// event.
fn remove_from_whitelist(&mut self, address: Address);
+
+ /// Stake `amount` of tokens for the `address`. It decrements `address`'s balance by `amount`.
+ ///
+ /// It throws [`NotAnOwner`](casper_dao_utils::Error::NotAnOwner) if caller
+ /// is not the current owner.
+ ///
+ /// It throws [`InsufficientBalance`](casper_dao_utils::Error::InsufficientBalance)
+ /// if `address`'s balance is less then `amount`.
+ ///
+ /// It emits [`TokensStaked`](casper_dao_utils::staking::events::TokensStaked)
+ /// event.
fn stake(&mut self, address: Address, amount: U256);
+
+ /// Unstake `amount` of tokens for the `address`. It increments `address`'s balance by
+ /// `amount`.
+ ///
+ /// It throws [`NotAnOwner`](casper_dao_utils::Error::NotAnOwner) if caller
+ /// is not the current owner.
+ ///
+ /// It throws [`InsufficientBalance`](casper_dao_utils::Error::InsufficientBalance)
+ /// if `address`'s staked amount is less then `amount`.
+ ///
+ /// It emits [`TokensUnstaked`](casper_dao_utils::staking::events::TokensUnstaked)
+ /// event.
fn unstake(&mut self, address: Address, amount: U256);
}
+/// Implementation of the Reputation Contract. See [`ReputationContractInterface`].
#[derive(Default)]
pub struct ReputationContract {
pub token: TokenWithStaking,
@@ -148,6 +238,7 @@ impl ReputationContract {
}
}
+/// Implementation of the Reputation Contract Caller. See [`ReputationContractInterface`].
pub struct ReputationContractCaller {
contract_package_hash: ContractPackageHash,
}
@@ -275,6 +366,7 @@ mod tests {
use crate::{ReputationContract, ReputationContractInterface};
+ /// Implementation of the Reputation Contract Test. See [`ReputationContractInterface`].
pub struct ReputationContractTest {
env: TestEnv,
package_hash: ContractPackageHash,
diff --git a/macros/src/lib.rs b/macros/src/lib.rs
index f3ce29c8..af36f200 100644
--- a/macros/src/lib.rs
+++ b/macros/src/lib.rs
@@ -3,6 +3,7 @@ use proc_macro2::TokenStream as TokenStream2;
use quote::{quote, TokenStreamExt};
use syn::{parse_macro_input, Data, DataStruct, DeriveInput, Fields};
+/// Derive events on top of any struct.
#[proc_macro_derive(Event)]
pub fn derive_events(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
diff --git a/tests/Cargo.toml b/tests/Cargo.toml
index 0ae80320..b620ee9f 100644
--- a/tests/Cargo.toml
+++ b/tests/Cargo.toml
@@ -13,4 +13,4 @@ name = "reputation-tests"
path = "src/reputation_tests.rs"
bench = false
doctest = false
-
+doc = false
\ No newline at end of file
diff --git a/utils/src/casper_env.rs b/utils/src/casper_env.rs
index 5e17392e..dafed490 100644
--- a/utils/src/casper_env.rs
+++ b/utils/src/casper_env.rs
@@ -1,3 +1,5 @@
+//! Interact with the CasperVM inside the contract.
+
use std::convert::TryInto;
use casper_contract::{
@@ -10,8 +12,9 @@ use casper_types::{
CLTyped,
};
-use crate::{modules::events::Events, Address};
+use crate::{Address, Events};
+/// Read value from the storage.
pub fn get_key(name: &str) -> Option {
match runtime::get_key(name) {
None => None,
@@ -23,6 +26,7 @@ pub fn get_key(name: &str) -> Option {
}
}
+/// Save value to the storage.
pub fn set_key(name: &str, value: T) {
match runtime::get_key(name) {
Some(key) => {
@@ -44,8 +48,8 @@ fn call_stack_element_to_address(call_stack_element: CallStackElement) -> Addres
match call_stack_element {
CallStackElement::Session { account_hash } => Address::from(account_hash),
CallStackElement::StoredSession { account_hash, .. } => {
- // Stored session code acts in account's context, so if stored session wants to interact
- // with an ERC20 token caller's address will be used.
+ // Stored session code acts in account's context, so if stored session
+ // wants to interact, caller's address will be used.
Address::from(account_hash)
}
CallStackElement::StoredContract {
@@ -71,14 +75,17 @@ pub fn caller() -> Address {
call_stack_element_to_address(second_elem)
}
+/// Initialize events dictionary.
pub fn init_events() {
Events::default().init();
}
+/// Record event to the contract's storage.
pub fn emit(event: T) {
Events::default().emit(event);
}
+/// Convert any key to base64.
pub fn to_dictionary_key(key: &T) -> String {
let preimage = key.to_bytes().unwrap_or_revert();
base64::encode(&preimage)
diff --git a/utils/src/lib.rs b/utils/src/lib.rs
index bfa3eacc..926594ed 100644
--- a/utils/src/lib.rs
+++ b/utils/src/lib.rs
@@ -15,6 +15,7 @@ pub use modules::owner;
pub use modules::staking;
pub use modules::token;
pub use modules::whitelist;
+use modules::Events;
#[cfg(feature = "test-support")]
mod test_env;
diff --git a/utils/src/modules/mod.rs b/utils/src/modules/mod.rs
index 0a6fe545..03bfe229 100644
--- a/utils/src/modules/mod.rs
+++ b/utils/src/modules/mod.rs
@@ -1,5 +1,7 @@
-pub mod events;
+mod events;
pub mod owner;
pub mod staking;
pub mod token;
pub mod whitelist;
+
+pub(crate) use events::Events;
diff --git a/utils/src/modules/owner.rs b/utils/src/modules/owner.rs
index 51072ab4..ff8bf687 100644
--- a/utils/src/modules/owner.rs
+++ b/utils/src/modules/owner.rs
@@ -1,3 +1,5 @@
+//! Single-owner-based access control system.
+
use casper_contract::contract_api::runtime;
use crate::{
@@ -7,6 +9,7 @@ use crate::{
use self::events::OwnerChanged;
+/// The Owner module.
pub struct Owner {
pub owner: Variable