Skip to content

Commit

Permalink
Merge pull request #254 from Fair-Squares/fix-role-pallet-total-members
Browse files Browse the repository at this point in the history
Fix role pallet total members
  • Loading branch information
cuteolaf authored Feb 25, 2023
2 parents 74bdf69 + 7a7eabf commit ea32c5e
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 88 deletions.
51 changes: 25 additions & 26 deletions pallets/asset_management/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub use scale_info::prelude::boxed::Box;
pub use sp_core::H256;
use sp_runtime::traits::{StaticLookup, Zero};
impl<T: Config> Pallet<T> {
pub fn approve_representative(origin: OriginFor<T>, who: T::AccountId) -> DispatchResult {
pub fn approve_representative_role(origin: OriginFor<T>, who: T::AccountId) -> DispatchResult {
let caller = ensure_signed(origin.clone())?;

let mut representative = Roles::Pallet::<T>::get_pending_representatives(&who).unwrap();
Expand All @@ -18,7 +18,7 @@ impl<T: Config> Pallet<T> {
//Check if we're dealing with an already registered representative
let registered = Roles::RepresentativeLog::<T>::contains_key(&who);

if registered == false {
if !registered {
representative.activated = true;
representative.assets_accounts.clear();
representative.assets_accounts.push(caller);
Expand Down Expand Up @@ -49,7 +49,7 @@ impl<T: Config> Pallet<T> {
}
}

if check0 == false {
if !check0 {
//Set the representative as a registrar
Ident::Pallet::<T>::add_registrar(origin, who2).ok();

Expand All @@ -63,7 +63,7 @@ impl<T: Config> Pallet<T> {
let fees = bals0.ident_bal;
Ident::Pallet::<T>::set_fee(origin2, index, fees).ok();

if registered == false {
if !registered {
//Update Rep number if not yet a registered Representative
index += 1;
Roles::RepNumber::<T>::put(index);
Expand All @@ -73,7 +73,7 @@ impl<T: Config> Pallet<T> {
Ok(())
}

pub fn revoke_representative(who: T::AccountId) -> DispatchResult {
pub fn revoke_representative_role(who: T::AccountId) -> DispatchResult {
Roles::RepresentativeLog::<T>::mutate(&who, |val| {
let mut val0 = val.clone().unwrap();
val0.activated = false;
Expand Down Expand Up @@ -116,7 +116,7 @@ impl<T: Config> Pallet<T> {

//Store payment details
let details = Payment::Pallet::<T>::get_payment_details(&from, &creator).unwrap();
GuarantyPayment::<T>::insert(from.clone(), creator.clone(), details);
GuarantyPayment::<T>::insert(from, creator, details);

Ok(())
}
Expand Down Expand Up @@ -171,7 +171,7 @@ impl<T: Config> Pallet<T> {
let rent = bals.roles_bal;
bals = BalanceType::<T>::convert_to_balance(rent1);
let year_rent = bals.roles_bal;
val0.rent = rent.into();
val0.rent = rent;
val0.asset_account = Some(asset_account);
val0.remaining_rent = year_rent;
val0.remaining_payments = time as u8;
Expand Down Expand Up @@ -227,7 +227,7 @@ impl<T: Config> Pallet<T> {
match Dem::Pallet::<T>::note_preimage(origin, proposal_encoded) {
Ok(_) => (),
Err(x) if x == Error::<T>::DuplicatePreimage.into() => (),
Err(x) => panic!("{:?}", x),
Err(x) => panic!("{x:?}"),
}
proposal_hash
}
Expand Down Expand Up @@ -306,7 +306,7 @@ impl<T: Config> Pallet<T> {
let tenants = Roles::Pallet::<T>::tenant_list();
for i in tenants {
let tenant = Roles::Pallet::<T>::tenants(i).unwrap();
if !tenant.asset_account.is_none() {
if tenant.asset_account.is_some() {
let time = <T as Config>::Lease::get();
let remaining_p = tenant.remaining_payments;
let contract_begin = tenant.contract_start;
Expand All @@ -317,7 +317,7 @@ impl<T: Config> Pallet<T> {

//Calculate rent per block
let total_blocks = <T as Config>::ContractLength::get();
let mut rpb = Self::blocknumber_to_u128(total_blocks.clone()).unwrap();
let mut rpb = Self::blocknumber_to_u128(total_blocks).unwrap();
let mut rpb_float = rpb as f64;
rpb_float = (rent_float / rpb_float).round();
rpb = rpb_float as u128;
Expand All @@ -327,7 +327,7 @@ impl<T: Config> Pallet<T> {
let amount_due = blocks.saturating_mul(rpb);

//check how many rents were payed
let payed = (time as u128 - remaining_p as u128) * rent.clone();
let payed = (time as u128 - remaining_p as u128) * rent;
let asset_account = tenant.asset_account.clone().unwrap();
let asset_account_free_balance =
<T as Config>::Currency::free_balance(&asset_account);
Expand All @@ -345,33 +345,32 @@ impl<T: Config> Pallet<T> {

//Get Asset_tokens infos
let token_id = infos.token_id;
let total_issuance =
Assetss::Pallet::<T>::total_supply(token_id.clone().into());
let total_issuance = Assetss::Pallet::<T>::total_supply(token_id.into());
let total_issuance_float =
Self::assets_bal_to_u128(total_issuance).unwrap() as f64;

//Remove maintenance fees from rent and convert it to f64
let maintenance = T::Maintenance::get() * rent1.clone();
let distribute = rent1.saturating_sub(maintenance.clone());
let maintenance = T::Maintenance::get() * rent1;
let distribute = rent1.saturating_sub(maintenance);

//Get the total amount to distribute
let distribute_float = (Self::manage_bal_to_u128(distribute.clone())
.unwrap() * infos.rent_nbr as u128) as f64;
let distribute_float = (Self::manage_bal_to_u128(distribute).unwrap() *
infos.rent_nbr as u128) as f64;

debug_assert!(distribute.clone() > Zero::zero());
debug_assert!(distribute.clone() < rent1.clone());
debug_assert!(maintenance.clone() < asset_account_free_balance);
debug_assert!(distribute > Zero::zero());
debug_assert!(distribute < rent1);
debug_assert!(maintenance < asset_account_free_balance);

//Reserve maintenance fees
let reservation =
<T as Config>::Currency::reserve(&asset_account, maintenance.into());
<T as Config>::Currency::reserve(&asset_account, maintenance);

//Emmit maintenance fee payment event
Self::deposit_event(Event::MaintenanceFeesPayment {
tenant: tenant.account_id.clone(),
when: now,
asset_account: tenant.asset_account.unwrap(),
amount: maintenance.clone(),
amount: maintenance,
});

debug_assert!(reservation.is_ok());
Expand All @@ -381,10 +380,10 @@ impl<T: Config> Pallet<T> {
//Get owner's share: we divide
//the owner's tokens by the total token issuance, and multiply the
// result by the total amount to be distributed.
let share = Assetss::Pallet::<T>::balance(token_id.clone().into(), &i);
let share = Assetss::Pallet::<T>::balance(token_id.into(), &i);
let share_float = Self::assets_bal_to_u128(share).unwrap() as f64 /
total_issuance_float;
let amount_float = share_float * distribute_float.clone();
let amount_float = share_float * distribute_float;
let bals0 = BalanceType::<T>::convert_to_balance(amount_float as u128);
let amount = bals0.manage_bal;
<T as Config>::Currency::transfer(
Expand All @@ -406,9 +405,9 @@ impl<T: Config> Pallet<T> {
//Now return the awaiting payment number to 0
let ownership_infos = Share::Virtual::<T>::iter_keys();
for (i, j) in ownership_infos {
let infos = Share::Pallet::<T>::virtual_acc(&i, &j).unwrap();
let infos = Share::Pallet::<T>::virtual_acc(i, j).unwrap();
if infos.virtual_account == asset_account {
Share::Virtual::<T>::mutate(i.clone(), j.clone(), |val| {
Share::Virtual::<T>::mutate(i, j, |val| {
let mut val0 = val.clone().unwrap();
val0.rent_nbr = 0;
*val = Some(val0);
Expand Down
132 changes: 82 additions & 50 deletions pallets/asset_management/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
//! proposals:
//! - Admit a Tenant for a given asset.
//! - Evict a Tenant from a given asset.
//! The Representative has to submit a judgement about the tenant profile. This judgement
//! The Representative has to submit a judgement about the tenant profile. This judgement
//! will be considered by the owners before voting.
//! Representatives receive a judgement fee from the aspiring tenant.
//! A positive result of the referendum will send a guaranty_deposit payment request to the
Expand Down Expand Up @@ -251,12 +251,20 @@ pub mod pallet {
NotARepresentative,
/// Not an active Representative
NotAnActiveRepresentative,
/// The asset is already linked with a representative
AssetAlreadyLinkedWithRepresentative,
/// The asset is not linked with a representative
AssetNotLinkedWithRepresentative,
/// The given representative is not linked with the asset
InvalidRepresentative,
/// The asset is not linked to the representative
AssetOutOfControl,
/// The candidate is not a tenant
NotATenant,
/// An asset is already linked to the provided account
AlreadyLinkedWithAsset,
/// An asset is already linked with the representative
RepresentativeAlreadyLinkedWithAsset,
/// An asset is already linked with the tenant
TenantAlreadyLinkedWithAsset,
/// The tenant is not linked to the asset
TenantAssetNotLinked,
/// Errors should have helpful documentation associated with them.
Expand Down Expand Up @@ -331,52 +339,75 @@ pub mod pallet {
) -> DispatchResultWithPostInfo {
let caller = ensure_signed(origin.clone())?;

//Get the asset virtual account if it exists
// Get asset virtual account if it exists
let collection_id: T::NftCollectionId = asset_type.value().into();

let ownership = Share::Pallet::<T>::virtual_acc(collection_id, asset_id);
ensure!(ownership.is_some(), Error::<T>::NotAnAsset);
let ownership = ownership.unwrap();

//Ensure that the caller is an owner related to the virtual account
ensure!(
Self::caller_can_vote(&caller, ownership.clone().unwrap()),
Error::<T>::NotAnOwner
);
let asset = Onboarding::Pallet::<T>::houses(collection_id, asset_id);
ensure!(asset.is_some(), Error::<T>::NotAnAsset);
let asset = asset.unwrap();

let virtual_account = ownership.clone().unwrap().virtual_account;
let deposit = T::MinimumDeposit::get();
// Ensure that the caller is one of the asset owners
ensure!(ownership.owners.contains(&caller), Error::<T>::NotAnOwner);

//Ensure that the virtual account has enough funds
for f in ownership.unwrap().owners {
<T as Dem::Config>::Currency::transfer(
&f,
&virtual_account,
deposit,
ExistenceRequirement::AllowDeath,
)
.ok();
}
let virtual_account = ownership.virtual_account;

//Create the call
// Create the call
let proposal_call = match proposal {
VoteProposals::Election => {
//Check that the account is in the representative waiting list
// Check if the account is in the representative waiting list
let rep = Roles::Pallet::<T>::get_pending_representatives(&representative);
ensure!(rep.is_some(), Error::<T>::NotAPendingRepresentative);

// Ensure that the asset doesn't have a representative yet
ensure!(
asset.representative.is_none(),
Error::<T>::AssetAlreadyLinkedWithRepresentative
);

//Ensure that the Representative is not already connected to this asset
ensure!(
Roles::Pallet::<T>::get_pending_representatives(&representative).is_some(),
Error::<T>::NotAPendingRepresentative
!rep.unwrap().assets_accounts.contains(&virtual_account),
Error::<T>::RepresentativeAlreadyLinkedWithAsset
);

Call::<T>::representative_approval {
rep_account: representative.clone(),
collection: collection_id,
item: asset_id,
}
},
VoteProposals::Demotion => Call::<T>::demote_representative {
rep_account: representative.clone(),
collection: collection_id,
item: asset_id,
VoteProposals::Demotion => {
// Ensure that the asset is linked with the representative
let asset_rep = asset.representative;
ensure!(asset_rep.is_some(), Error::<T>::AssetNotLinkedWithRepresentative);
ensure!(
asset_rep == Some(representative.clone()),
Error::<T>::InvalidRepresentative
);
Call::<T>::demote_representative {
rep_account: representative.clone(),
collection: collection_id,
item: asset_id,
}
},
};

let deposit = T::MinimumDeposit::get();
//Ensure that the virtual account has enough funds
for f in ownership.owners {
<T as Dem::Config>::Currency::transfer(
&f,
&virtual_account,
deposit,
ExistenceRequirement::AllowDeath,
)
.ok();
}

//Format the call and create the proposal Hash
let proposal_hash =
Self::create_proposal_hash_and_note(virtual_account.clone(), proposal_call);
Expand Down Expand Up @@ -476,18 +507,16 @@ pub mod pallet {
Share::Pallet::<T>::virtual_acc(collection, item).unwrap().virtual_account;

//Check that the caller is a stored virtual account
ensure!(caller == asset_account.clone(), Error::<T>::NotAnAssetAccount);

//Ensure that the Representative is not already connected to this asset
let representative =
Roles::Pallet::<T>::get_pending_representatives(&rep_account).unwrap();
let rep_assets = representative.assets_accounts;
for i in rep_assets {
ensure!(i != asset_account, Error::<T>::AlreadyLinkedWithAsset);
}
ensure!(caller == asset_account, Error::<T>::NotAnAssetAccount);

Onboarding::Houses::<T>::mutate(collection, item, |asset| {
let mut asset0 = asset.clone().unwrap();
asset0.representative = Some(rep_account.clone());
*asset = Some(asset0);
});

//Approve role request
Self::approve_representative(origin, rep_account.clone()).ok();
Self::approve_representative_role(origin, rep_account.clone()).ok();

Self::deposit_event(Event::RepresentativeCandidateApproved {
candidate: rep_account,
Expand Down Expand Up @@ -520,7 +549,12 @@ pub mod pallet {
);

//revoke Representative Role
Self::revoke_representative(rep_account.clone()).ok();
Self::revoke_representative_role(rep_account.clone()).ok();
Onboarding::Houses::<T>::mutate(collection, item, |asset| {
let mut asset0 = asset.clone().unwrap();
asset0.representative = None;
*asset = Some(asset0);
});

Self::deposit_event(Event::RepresentativeDemoted {
candidate: rep_account,
Expand Down Expand Up @@ -561,7 +595,7 @@ pub mod pallet {
//Compare guaranty payment amount+fees with tenant free_balance
let guaranty = Self::calculate_guaranty(collection_id, asset_id);
let fee0 = Self::manage_bal_to_u128(T::RepFees::get()).unwrap();
let bals0 = BalanceType::<T>::convert_to_balance(guaranty.clone());
let bals0 = BalanceType::<T>::convert_to_balance(guaranty);
let fee1 = T::IncentivePercentage::get() * bals0.manage_bal;
let total_amount = guaranty + fee0 + Self::manage_bal_to_u128(fee1).unwrap();
let tenant_bal0: BalanceOf<T> = <T as Config>::Currency::free_balance(&tenant);
Expand All @@ -575,13 +609,16 @@ pub mod pallet {
ensure!(tenant0.is_some(), Error::<T>::NotATenant);
// Ensure that the tenant is registered
let tenant_infos = Roles::Pallet::<T>::tenants(tenant.clone()).unwrap();
ensure!(tenant_infos.registered == true, Error::<T>::NotARegisteredTenant);
ensure!(tenant_infos.registered, Error::<T>::NotARegisteredTenant);

let tenant0 = tenant0.unwrap();
match proposal {
VoteProposals::Election => {
// Ensure that the tenant is not linked to an asset
ensure!(tenant0.asset_account.is_none(), Error::<T>::AlreadyLinkedWithAsset);
ensure!(
tenant0.asset_account.is_none(),
Error::<T>::TenantAlreadyLinkedWithAsset
);
//Ensure there is no existing payment request for this asset
ensure!(
Self::guaranty(&tenant0.account_id, &asset_account).is_none(),
Expand All @@ -592,13 +629,8 @@ pub mod pallet {
//provide judgement
let index = rep.index;
let target = T::Lookup::unlookup(tenant.clone());
Ident::Pallet::<T>::provide_judgement(
origin.clone(),
index.into(),
target,
judgement.clone(),
)
.ok();
Ident::Pallet::<T>::provide_judgement(origin.clone(), index, target, judgement)
.ok();
},
VoteProposals::Demotion => {
// Ensure that the tenant is linked to the asset
Expand Down
2 changes: 1 addition & 1 deletion pallets/asset_management/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ impl pallet_sudo::Config for Test {
}

parameter_types! {
pub const MaxMembers:u32 =7;
pub const MaxMembers:u32 =8;
}
impl pallet_roles::Config for Test {
type Event = Event;
Expand Down
Loading

0 comments on commit ea32c5e

Please sign in to comment.