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 169 170 171 172 173 174
//! Contains Variable Repository Contract definition and related abstractions.
//!
//! Variable Repository Contract stores governance variables. Values can be altered
//! as a result of [Repo Voting].
//!
//! # Available keys
//!
//! | Parameter name | Initial value | Stored value | Type | Description |
//! |------------------------------------|---------------|--------------|---------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
//! | PostJobDOSFee | 10 | 10000 | float | A DOS fee that the JobPoster needs to attach to the Post Job query. The value is the minimum amount of Fiat currency to be attached as CSPR using FiatConversionRate |
//! | InternalAuctionTime | 7 days | 604800 | seconds | The time of the Internal Auction |
//! | PublicAuctionTime | 10 days | 864000 | seconds | The time of the External Auction |
//! | DefaultPolicingRate | 0.3 | 300 | float | This rate defines how many Reputation tokens are given to the VA’s for their community audit/vote on a work product.. In case of value of 0.3, 30% of the payment is redistributed between VA’s and 70% is given to the Worker. |
//! | ReputationConversionRate | 0.1 | 100 | float | This parameter tells how much Reputation is minted for each unit of currency paid for Work. For value equal to 0.1, 1 Reputation is minted for each 10 CSPR. |
//! | FiatConversionRateAddress | | | address | An address of a contract that will return the conversion rate between Fiat and CSPR |
//! | ForumKYCRequired | true | true | bool | Defines if KYC is required to post on Forum |
//! | BidEscrowInformalQuorumRatio | 0.5 | 500 | float | How many holders of the Reputation tokens (VA’s) are needed for an informal voting quorum |
//! | BidEscrowFormalQuorumRatio | 0.5 | 500 | float | How many holders of the Reputation tokens (VA’s) are needed for a bid escrow formal vote quorum. For example, if 100 accounts hold tokens, the quorum would be 51 votes. |
//! | InformalQuorumRatio | 0.5 | 500 | float | How many holders of the Reputation tokens (VA’s) are needed for a regular informal voting quorum. |
//! | FormalQuorumRatio | 0.5 | 500 | float | How many holders of the Reputation tokens (VA’s) are needed for a regular formal voting quorum. |
//! | BidEscrowInformalVotingTime | 5 days | 432000 | seconds | Time for the informal part of the Bid Escrow voting |
//! | BidEscrowFormalVotingTime | 5 days | 432000 | seconds | Time for the formal part of the Bid Escrow voting |
//! | InformalVotingTime | 5 days | 432000 | seconds | Time for the informal part of other voting |
//! | FormalVotingTime | 5 days | 432000 | seconds | Time for the formal part of other voting |
//! | InformalStakeReputation | true | true | bool | Tells if the Informal Voting should stake the reputation or only simulate it. |
//! | TimeBetweenInformalAndFormalVoting | 1 day | 86400 | seconds | Time between Informal and Formal Voting |
//! | VABidAcceptanceTimeout | 2 days | 172800 | seconds | How much time the bid wait for the acceptance. After this time, the bid can be cancelled |
//! | VACanBidOnPublicAuction | false | false | bool | Whether or not VA’s can take part in the Public Auction part of the Bidding process. |
//! | DistributePaymentToNonVoters | true | false | bool | Determines if the Payment for the Job should be distributed between all VA’s or only to those who voted |
//! | DefaultReputationSlash | 0.1 | 100 | float | How much reputation of an Internal Worker is slashed after not completing a Job |
//! | VotingClearnessDelta | 8 | 8000 | int | If the difference between 50/50 and result of the Informal Voting is bigger than the value, the time between votings should be doubled. |
//! | VotingStartAfterJobWorkerSubmisson | 3 days | 259200 | seconds | Time between the worker job submission and the internal voting start. |
//! | BidEscrowPaymentRatio | 0.1 | 100 | float | How much CSPR is sent to GovernanceWallet after the Job is finished |
//! | BidEscrowWalletAddress | | | address | An address of a multisig wallet of the DAO.
//!
//! [Repo Voting]: crate::voting_contracts::RepoVoterContract
use crate::modules::{AccessControl, Record, Repository};
use crate::utils::Error;
use odra::contract_env::caller;
use odra::prelude::{collections::BTreeMap, string::String};
use odra::types::{Address, Bytes};
use odra::UnwrapOrRevert;
/// Variable Repository Contract.
#[odra::module]
pub struct VariableRepositoryContract {
pub access_control: AccessControl,
pub repository: Repository,
}
#[odra::module]
impl VariableRepositoryContract {
delegate! {
to self.access_control {
/// Checks whether the given address is added to the whitelist.
/// [`Read more`](AccessControl::is_whitelisted()).
pub fn is_whitelisted(&self, address: Address) -> bool;
/// Returns the address of the current owner.
/// [`Read more`](AccessControl::get_owner()).
pub fn get_owner(&self) -> Option<Address>;
/// Changes the ownership of the contract. Transfers ownership to the `owner`.
/// Only the current owner is permitted to call this method.
/// [`Read more`](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.
/// [`Read more`](AccessControl::accept_new_owner())
pub fn accept_new_owner(&mut self);
/// Adds a new address to the whitelist.
/// [`Read more`](AccessControl::add_to_whitelist())
pub fn add_to_whitelist(&mut self, address: Address);
/// Remove address from the whitelist.
/// [`Read more`](AccessControl::remove_from_whitelist())
pub fn remove_from_whitelist(&mut self, address: Address);
}
}
/// Constructor function.
///
/// # Note
/// Initializes contract elements:
/// * Sets the default configuration of the [`Repository`](crate::modules::repository::Repository)
/// * Sets [`caller`] as the owner of the contract.
/// * Adds [`caller`] to the whitelist.
///
/// # Events
/// * [`OwnerChanged`](crate::modules::owner::events::OwnerChanged),
/// * [`AddedToWhitelist`](crate::modules::whitelist::events::AddedToWhitelist),
/// * multiple [`ValueUpdated`](crate::modules::repository::events::ValueUpdated) events,
/// one per value of the default repository configuration.
#[odra(init)]
pub fn init(
&mut self,
fiat_conversion: Address,
bid_escrow_wallet: Address,
voting_ids: Address,
) {
let deployer = caller();
self.access_control.init(deployer);
self.repository
.init(fiat_conversion, bid_escrow_wallet, voting_ids);
}
/// Inserts or updates the value under the given key.
///
/// # Note
/// * The activation time is represented as a unix timestamp.
/// * If the activation time is `None` the value is updated immediately.
/// * If some future time in the future is passed as an argument, the [`Self::get`] function
/// returns the previously set value.
///
/// # Events
/// * [`ValueUpdated`](crate::modules::repository::events::ValueUpdated).
///
/// # Errors
/// * [`NotWhitelisted`](crate::utils::Error::NotWhitelisted) if the caller
/// is not a whitelisted user.
/// * [`ActivationTimeInPast`](crate::utils::Error::ActivationTimeInPast) if
/// the activation time has passed already.
pub fn update_at(&mut self, key: String, value: Bytes, activation_time: Option<u64>) {
self.access_control.ensure_whitelisted();
self.repository.update_at(key, value, activation_time);
}
/// Returns the value stored under the given key.
///
/// If the key does not exist, the `None` value is returned.
pub fn get(&self, key: String) -> Option<Bytes> {
self.repository.get(key)
}
/// Returns the full (current and future) value stored under the given key.
/// See [`Record`](Record).
///
/// If the key does not exist, the `None` value is returned.
pub fn get_full_value(&self, key: String) -> Option<Record> {
self.repository.get_full_value(key)
}
/// Returns the value stored under the given index.
///
/// Every freshly added key has the previous key index increased by 1.
/// The index range is 0 to #keys-1.
///
/// If the given index exceeds #keys-1 the `None` value is returned.
pub fn get_key_at(&self, index: u32) -> Option<String> {
self.repository.all_keys.get(index)
}
/// Returns the number of existing keys in the [`Repository`](crate::modules::repository::Repository).
pub fn keys_count(&self) -> u32 {
self.repository.all_keys.len()
}
/// Reads all the stored variables and returns a map key to value.
pub fn all_variables(&self) -> BTreeMap<String, Bytes> {
let mut result: BTreeMap<String, Bytes> = BTreeMap::new();
for key in 0..self.repository.all_keys.len() {
let repo_key = self
.repository
.all_keys
.get(key)
.unwrap_or_revert_with(Error::RepositoryError);
let value = self
.repository
.get(repo_key.clone())
.unwrap_or_revert_with(Error::RepositoryError);
result.insert(repo_key, value);
}
result
}
}