1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
use odra::prelude::collections::BTreeMap;
use crate::modules::AccessControl;
use odra::{
contract_env,
prelude::vec::Vec,
types::{Address, Balance},
};
use super::{
agg::{AggregatedBalance, BalanceAggregates},
balances::BalanceStorage,
stakes::StakesStorage,
};
/// Implementation of the Reputation Contract.
#[odra::module]
pub struct ReputationContract {
#[odra(using = "access_control")]
reputation_storage: BalanceStorage,
#[odra(using = "access_control")]
passive_reputation_storage: BalanceStorage,
#[odra(using = "access_control, reputation_storage")]
stakes_storage: StakesStorage,
#[odra(using = "reputation_storage")]
aggregates: BalanceAggregates,
access_control: AccessControl,
}
#[odra::module]
impl ReputationContract {
delegate! {
to self.access_control {
/// Changes ownership of the contract. Transfer the ownership to the `owner`. Only the current owner
/// is permitted to call this method.
///
/// See [AccessControl](AccessControl::propose_new_owner())
pub fn propose_new_owner(&mut self, owner: Address);
/// Accepts the new owner proposition. This can be called only by the proposed owner.
/// See [AccessControl](AccessControl::accept_new_owner())
pub fn accept_new_owner(&mut self);
/// Adds a new address to the whitelist.
///
/// See [AccessControl](AccessControl::add_to_whitelist())
pub fn add_to_whitelist(&mut self, address: Address);
/// Removes address from the whitelist.
///
/// See [AccessControl](AccessControl::remove_from_whitelist())
pub fn remove_from_whitelist(&mut self, address: Address);
/// Checks whether the given address is added to the whitelist.
pub fn is_whitelisted(&self, address: Address) -> bool;
/// Returns the address of the current owner.
pub fn get_owner(&self) -> Option<Address>;
}
to self.reputation_storage {
/// Mints new tokens. Adds `amount` of new tokens to the balance of the `recipient` and
/// increments the total supply. Only whitelisted addresses are permitted to call this method.
///
/// # Errors
/// * [`NotWhitelisted`](crate::utils::Error::NotWhitelisted) if caller
/// is not whitelisted.
///
/// # Events
/// * [`Mint`](events::Mint).
pub fn mint(&mut self, recipient: Address, amount: Balance);
/// Burns existing tokens. Removes `amount` of existing tokens from the balance of the `owner`
/// and decrements the total supply. Only whitelisted addresses are permitted to call this
/// method.
///
/// # Errors
/// * [`NotWhitelisted`](crate::utils::Error::NotWhitelisted) if caller
/// is not whitelisted.
///
/// # Events
/// * [`Burn`](events::Burn) event.
pub fn burn(&mut self, owner: Address, amount: Balance);
/// Returns the total token supply.
pub fn total_supply(&self) -> Balance;
/// Returns the current token balance of the given address.
pub fn balance_of(&self, address: Address) -> Balance;
/// Redistributes the reputation based on the voting summary
pub fn bulk_mint_burn(&mut self, mints: BTreeMap<Address, Balance>, burns: BTreeMap<Address, Balance>);
/// Burns all the tokens of the `owner`.
pub fn burn_all(&mut self, owner: Address);
}
to self.stakes_storage {
pub fn stake(&mut self, voter: Address, stake: Balance);
pub fn unstake(&mut self, voter: Address, stake: Balance);
pub fn bulk_unstake(&mut self, stakes: Vec<(Address, Balance)>);
pub fn get_stake(&self, address: Address) -> Balance;
}
to self.aggregates {
/// Gets balances of all the token holders.
pub fn all_balances(&self) -> AggregatedBalance;
/// Gets balances of the given account addresses.
pub fn partial_balances(&self, addresses: Vec<Address>) -> AggregatedBalance;
}
}
/// Constructor method.
///
/// It initializes contract elements:
/// * Events dictionary.
/// * Named keys of [`AccessControl`].
/// * Set `caller` as the owner of the contract.
/// * Add `caller` to the whitelist.
///
/// # Events
/// * [`OwnerChanged`](crate::modules::owner::events::OwnerChanged),
/// * [`AddedToWhitelist`](crate::modules::whitelist::events::AddedToWhitelist).
#[odra(init)]
pub fn init(&mut self) {
let deployer = contract_env::caller();
self.access_control.init(deployer);
}
/// Increases the balance of the passive reputation of the given address.
///
/// # Errors
/// * [`NotWhitelisted`](crate::utils::Error::NotWhitelisted) if caller
/// is not whitelisted.
pub fn mint_passive(&mut self, recipient: Address, amount: Balance) {
self.passive_reputation_storage.mint(recipient, amount);
}
/// Decreases the balance of the passive reputation of the given address.
///
/// # Errors
/// * [`NotWhitelisted`](crate::utils::Error::NotWhitelisted) if caller
/// is not whitelisted.
/// * [`InsufficientBalance`](crate::utils::Error::InsufficientBalance) if the passed
/// amount exceeds the balance of the passive reputation of the given address.
pub fn burn_passive(&mut self, owner: Address, amount: Balance) {
self.passive_reputation_storage.burn(owner, amount);
}
/// Returns the current passive balance of the given address.
pub fn passive_balance_of(&self, address: Address) -> Balance {
self.passive_reputation_storage.balance_of(address)
}
}
pub mod events {
use odra::{
types::{Address, Balance},
Event,
};
/// Event emitted when tokens have been burnt.
#[derive(Debug, PartialEq, Eq, Event)]
pub struct Burn {
pub address: Address,
pub amount: Balance,
}
/// Event emitted when tokens have been minted.
#[derive(Debug, PartialEq, Eq, Event)]
pub struct Mint {
pub address: Address,
pub amount: Balance,
}
}