diff --git a/assets/pallet_template/src/weights.rs b/assets/pallet_template/src/weights.rs index dfdb1026..b4d897f0 100644 --- a/assets/pallet_template/src/weights.rs +++ b/assets/pallet_template/src/weights.rs @@ -61,8 +61,8 @@ impl WeightInfo for SubstrateWeight { // Storage: TemplateModule Something (r:0 w:1) /// The range of component `s` is `[0, 100]`. fn do_something(_s: u32, ) -> Weight { - Weight::from_ref_time(15_009_000 as u64) - .saturating_add(T::DbWeight::get().writes(1 as u64)) + Weight::from_ref_time(15_009_000_u64) + .saturating_add(T::DbWeight::get().writes(1_u64)) } } @@ -71,7 +71,7 @@ impl WeightInfo for () { // Storage: TemplateModule Something (r:0 w:1) /// The range of component `s` is `[0, 100]`. fn do_something(_s: u32, ) -> Weight { - Weight::from_ref_time(15_009_000 as u64) - .saturating_add(RocksDbWeight::get().writes(1 as u64)) + Weight::from_ref_time(15_009_000_u64) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } } \ No newline at end of file diff --git a/pallets/asset_management/src/functions.rs b/pallets/asset_management/src/functions.rs index f10ce5f1..b0a54cf0 100644 --- a/pallets/asset_management/src/functions.rs +++ b/pallets/asset_management/src/functions.rs @@ -7,7 +7,7 @@ pub use sp_core::H256; use sp_runtime::traits::{StaticLookup, Zero}; impl Pallet { pub fn approve_representative_role(origin: OriginFor, who: T::AccountId) -> DispatchResult { - let caller = ensure_signed(origin.clone())?; + let caller = ensure_signed(origin)?; let mut representative = Roles::Pallet::::get_pending_representatives(&who).unwrap(); Roles::RepApprovalList::::remove(&who); @@ -226,7 +226,7 @@ impl Pallet { let proposal_hash = T::Hashing::hash_of(&call_dispatch); let proposal_encoded: Vec = call_dispatch.encode(); Dem::Pallet::::note_preimage(origin, proposal_encoded).ok(); - + proposal_hash } diff --git a/pallets/asset_management/src/lib.rs b/pallets/asset_management/src/lib.rs index f0b4dc50..aaff79c4 100644 --- a/pallets/asset_management/src/lib.rs +++ b/pallets/asset_management/src/lib.rs @@ -30,11 +30,11 @@ //! - 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 -//! 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 +//! 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 //! tenant. When the tenant finally pays the guaranty_deposit,his account is connected to the -//! asset through `link_tenant_to_asset` and this marks the start of his contract with the owners. +//! asset through `link_tenant_to_asset` and this marks the start of his contract with the owners. //! //! * `link_tenant_to_asset` - Call used as a proposal to link an accepted tenant with an existing //! asset. diff --git a/pallets/bidding/src/lib.rs b/pallets/bidding/src/lib.rs index 7ee54327..4041df25 100644 --- a/pallets/bidding/src/lib.rs +++ b/pallets/bidding/src/lib.rs @@ -68,6 +68,11 @@ pub mod pallet { type NewAssetScanPeriod: Get; } + pub type HousingFundAccount = Housing_Fund::AccountIdOf; + pub type HousingFundBalance = Housing_Fund::BalanceOf; + pub type EligibleContribution = (HousingFundAccount, HousingFundBalance, HousingFundBalance); + pub type UserBalance = (HousingFundAccount, HousingFundBalance); + #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] #[pallet::without_storage_info] @@ -80,29 +85,29 @@ pub mod pallet { HousingFundNotEnough( T::NftCollectionId, T::NftItemId, - Housing_Fund::BalanceOf, + HousingFundBalance, BlockNumberOf, ), /// Bidding on the house is successful HouseBiddingSucceeded( T::NftCollectionId, T::NftItemId, - Housing_Fund::BalanceOf, + HousingFundBalance, BlockNumberOf, ), /// Bidding on the house failed HouseBiddingFailed( T::NftCollectionId, T::NftItemId, - Housing_Fund::BalanceOf, + HousingFundBalance, BlockNumberOf, - Vec<(Housing_Fund::AccountIdOf, Housing_Fund::BalanceOf)>, + Vec>, ), /// Failed to assemble a list of investors for an onboarded asset FailedToAssembleInvestors( T::NftCollectionId, T::NftItemId, - Housing_Fund::BalanceOf, + HousingFundBalance, BlockNumberOf, ), /// No new onboarded houses found @@ -111,7 +116,7 @@ pub mod pallet { NotEnoughAmongEligibleInvestors( T::NftCollectionId, T::NftItemId, - Housing_Fund::BalanceOf, + HousingFundBalance, BlockNumberOf, ), /// No new finalised houses found @@ -123,14 +128,14 @@ pub mod pallet { SellAssetToInvestorsFailed(T::NftCollectionId, T::NftItemId, BlockNumberOf), /// Processing an asset - ProcessingAsset(T::NftCollectionId, T::NftItemId, Housing_Fund::BalanceOf), + ProcessingAsset(T::NftCollectionId, T::NftItemId, HousingFundBalance), /// Potential owners list successfully created InvestorListCreationSuccessful( T::NftCollectionId, T::NftItemId, - Housing_Fund::BalanceOf, - Vec<(Housing_Fund::AccountIdOf, Housing_Fund::BalanceOf)>, + HousingFundBalance, + Vec>, ), } @@ -333,9 +338,9 @@ impl Pallet { /// - no less than T::MinimumSharePerInvestor share per investor /// The total contribution from the investor list should be equal to the asset's price fn create_investor_list( - amount: Housing_Fund::BalanceOf, - ) -> Vec<(Housing_Fund::AccountIdOf, Housing_Fund::BalanceOf)> { - let mut result: Vec<(Housing_Fund::AccountIdOf, Housing_Fund::BalanceOf)> = + amount: HousingFundBalance, + ) -> Vec> { + let mut result: Vec> = Vec::new(); let percent = Self::u64_to_balance_option(100).unwrap(); // We get contributions following the min-max rules @@ -384,16 +389,12 @@ impl Pallet { /// Get a list of tuple of account id and their contribution set at the same amount fn get_common_investor_distribution( - amount: Housing_Fund::BalanceOf, - common_share: Housing_Fund::BalanceOf, - eligible_contributions: Vec<( - Housing_Fund::AccountIdOf, - Housing_Fund::BalanceOf, - Housing_Fund::BalanceOf, - )>, - ) -> Vec<(Housing_Fund::AccountIdOf, Housing_Fund::BalanceOf)> { + amount: HousingFundBalance, + common_share: HousingFundBalance, + eligible_contributions: Vec>, + ) -> Vec> { let percent = Self::u64_to_balance_option(100).unwrap(); - let mut result: Vec<(Housing_Fund::AccountIdOf, Housing_Fund::BalanceOf)> = + let mut result: Vec> = Vec::new(); for item in eligible_contributions.iter() { @@ -406,17 +407,17 @@ impl Pallet { /// Get a list of tuple of account id and their contribution with different values /// The contribubtions follow the min-max rule of the amount fn get_investor_distribution( - amount: Housing_Fund::BalanceOf, + amount: HousingFundBalance, eligible_contributions: Vec<( - Housing_Fund::AccountIdOf, - Housing_Fund::BalanceOf, - Housing_Fund::BalanceOf, + HousingFundAccount, + HousingFundBalance, + HousingFundBalance, )>, - ) -> Vec<(Housing_Fund::AccountIdOf, Housing_Fund::BalanceOf)> { + ) -> Vec> { let percent = Self::u64_to_balance_option(100).unwrap(); let zero_percent = Self::u64_to_balance_option(0).unwrap(); - let mut actual_percentage: Housing_Fund::BalanceOf = percent; - let mut result: Vec<(Housing_Fund::AccountIdOf, Housing_Fund::BalanceOf)> = + let mut actual_percentage: HousingFundBalance = percent; + let mut result: Vec> = Vec::new(); let mut count: u64 = 1; let contributions_length: u64 = eligible_contributions.len() as u64; @@ -476,24 +477,24 @@ impl Pallet { /// - a list of tuples (AccountId, Share, Amount) following the min-max share rule /// - the total amount of the list fn get_eligible_investors_contribution( - amount: Housing_Fund::BalanceOf, + amount: HousingFundBalance, ) -> ( - Housing_Fund::BalanceOf, - Vec<(Housing_Fund::AccountIdOf, Housing_Fund::BalanceOf, Housing_Fund::BalanceOf)>, + HousingFundBalance, + Vec<(HousingFundAccount, HousingFundBalance, HousingFundBalance)>, ) { let mut result: Vec<( - Housing_Fund::AccountIdOf, - Housing_Fund::BalanceOf, - Housing_Fund::BalanceOf, + HousingFundAccount, + HousingFundBalance, + HousingFundBalance, )> = Vec::new(); let contributions = Housing_Fund::Pallet::::get_contributions(); - let mut ordered_account_id_list: Vec> = Vec::new(); + let mut ordered_account_id_list: Vec> = Vec::new(); let mut ordered_contributions: Vec<( - Housing_Fund::AccountIdOf, + HousingFundAccount, Housing_Fund::Contribution, )> = Vec::new(); let zero_percent = Self::u64_to_balance_option(0).unwrap(); - let mut total_share: Housing_Fund::BalanceOf = Self::u64_to_balance_option(0).unwrap(); + let mut total_share: HousingFundBalance = Self::u64_to_balance_option(0).unwrap(); // the contributions are ordered by block number ascending order for _ in 0..contributions.len() { @@ -521,11 +522,11 @@ impl Pallet { /// Get the oldest contribution which accountId is not present in the ordered_list fn get_oldest_contribution( - ordered_list: Vec>, - contributions: Vec<(Housing_Fund::AccountIdOf, Housing_Fund::Contribution)>, - ) -> (Housing_Fund::AccountIdOf, Housing_Fund::Contribution) { + ordered_list: Vec>, + contributions: Vec<(HousingFundAccount, Housing_Fund::Contribution)>, + ) -> (HousingFundAccount, Housing_Fund::Contribution) { let mut contributions_cut: Vec<( - Housing_Fund::AccountIdOf, + HousingFundAccount, Housing_Fund::Contribution, )> = Vec::new(); @@ -549,11 +550,11 @@ impl Pallet { // Get the share of the house price from a given contribution fn get_investor_share( - amount: Housing_Fund::BalanceOf, + amount: HousingFundBalance, contribution: Housing_Fund::Contribution, - ) -> (Housing_Fund::BalanceOf, Housing_Fund::BalanceOf) { - let mut share: Housing_Fund::BalanceOf = Self::u64_to_balance_option(0).unwrap(); - let mut value: Housing_Fund::BalanceOf = Self::u64_to_balance_option(0).unwrap(); + ) -> (HousingFundBalance, HousingFundBalance) { + let mut share: HousingFundBalance = Self::u64_to_balance_option(0).unwrap(); + let mut value: HousingFundBalance = Self::u64_to_balance_option(0).unwrap(); // If the available amount is greater than the maximum amount, then the maximum amount is // returned if contribution.available_balance >= @@ -576,20 +577,20 @@ impl Pallet { } fn get_amount_percentage( - amount: Housing_Fund::BalanceOf, + amount: HousingFundBalance, percentage: u64, - ) -> Housing_Fund::BalanceOf { + ) -> HousingFundBalance { amount * Self::u64_to_balance_option(percentage).unwrap() / Self::u64_to_balance_option(100).unwrap() } - fn convert_balance(amount: Onboarding::BalanceOf) -> Option> { + fn convert_balance(amount: Onboarding::BalanceOf) -> Option> { let value: Option = amount.try_into().ok(); - let result: Option> = value.unwrap().try_into().ok(); + let result: Option> = value.unwrap().try_into().ok(); result } - pub fn u64_to_balance_option(input: u64) -> Option> { + pub fn u64_to_balance_option(input: u64) -> Option> { input.try_into().ok() } } diff --git a/pallets/payment/src/weights.rs b/pallets/payment/src/weights.rs index 85795348..497f644a 100644 --- a/pallets/payment/src/weights.rs +++ b/pallets/payment/src/weights.rs @@ -96,7 +96,7 @@ impl WeightInfo for SubstrateWeight { fn request_payment() -> Weight { Weight::from_ref_time(17_000_000) .saturating_add(T::DbWeight::get().reads(2 as u64)) - .saturating_add(T::DbWeight::get().writes(1 as u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) } // Storage: Payment Payment (r:1 w:1) // Storage: Assets Accounts (r:2 w:2) @@ -109,8 +109,8 @@ impl WeightInfo for SubstrateWeight { // Storage: Payment ScheduledTasks (r:1 w:1) fn remove_task() -> Weight { Weight::from_ref_time(4_000_000) - .saturating_add(T::DbWeight::get().reads(1 as u64)) - .saturating_add(T::DbWeight::get().writes(1 as u64)) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) } } @@ -166,7 +166,7 @@ impl WeightInfo for () { fn request_payment() -> Weight { Weight::from_ref_time(17_000_000) .saturating_add(RocksDbWeight::get().reads(2 as u64)) - .saturating_add(RocksDbWeight::get().writes(1 as u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } // Storage: Payment Payment (r:1 w:1) // Storage: Assets Accounts (r:2 w:2) @@ -179,7 +179,7 @@ impl WeightInfo for () { // Storage: Payment ScheduledTasks (r:1 w:1) fn remove_task() -> Weight { Weight::from_ref_time(4_000_000) - .saturating_add(RocksDbWeight::get().reads(1 as u64)) - .saturating_add(RocksDbWeight::get().writes(1 as u64)) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } } \ No newline at end of file diff --git a/pallets/roles/src/types.rs b/pallets/roles/src/types.rs index 5356ef79..109bba1b 100644 --- a/pallets/roles/src/types.rs +++ b/pallets/roles/src/types.rs @@ -26,10 +26,11 @@ pub type BlockNumberOf = ::BlockNumber; pub type Idle = (Vec>, Vec>); ///This enum contains the roles selectable at account creation -#[derive(Clone, Encode, Decode, PartialEq, Eq, TypeInfo, Copy)] +#[derive(Clone, Encode, Decode, Default, PartialEq, Eq, TypeInfo, Copy)] #[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))] pub enum Accounts { INVESTOR, + #[default] SELLER, TENANT, SERVICER, @@ -37,12 +38,6 @@ pub enum Accounts { REPRESENTATIVE, } -impl Default for Accounts { - fn default() -> Self { - Accounts::SELLER - } -} - //------------------------------------------------------------------------------------- //-------------INVESTOR STRUCT DECLARATION & IMPLEMENTATION_BEGIN---------------------- #[derive(Clone, Encode, Decode, Default, PartialEq, Eq, TypeInfo)] diff --git a/pallets/tenancy/src/functions.rs b/pallets/tenancy/src/functions.rs index fd61f833..718dd451 100644 --- a/pallets/tenancy/src/functions.rs +++ b/pallets/tenancy/src/functions.rs @@ -50,11 +50,11 @@ impl Pallet { // in the Share_distributor --> Virtual storage --> Ownership struct let ownership_infos = Share::Virtual::::iter_keys(); for (i, j) in ownership_infos { - let infos = Share::Pallet::::virtual_acc(&i, &j).unwrap(); + let infos = Share::Pallet::::virtual_acc(i, j).unwrap(); if infos.virtual_account == asset_account { - Share::Virtual::::mutate(i.clone(), j.clone(), |val| { + Share::Virtual::::mutate(i, j, |val| { let mut val0 = val.clone().unwrap(); - val0.rent_nbr = 1 + val0.rent_nbr; + val0.rent_nbr += 1; *val = Some(val0); }); } @@ -72,7 +72,7 @@ impl Pallet { let tenant = ensure_signed(from.clone())?; //Accept and pay the guaranty - Payment::Pallet::::accept_and_pay(from.clone(), virtual_account.clone()).ok(); + Payment::Pallet::::accept_and_pay(from, virtual_account.clone()).ok(); let origin2 = frame_system::RawOrigin::Signed(virtual_account.clone()); //Change payment state in Asset_Management storage diff --git a/pallets/tenancy/src/lib.rs b/pallets/tenancy/src/lib.rs index df8b5758..3fde0c18 100644 --- a/pallets/tenancy/src/lib.rs +++ b/pallets/tenancy/src/lib.rs @@ -138,9 +138,9 @@ pub mod pallet { let tenant = Roles::Pallet::::tenants(tenant_account.clone()).unwrap(); //Check that the Tenant is connected to the asset - ensure!(!tenant.asset_account.clone().is_none(), Error::::TenantAssetNotLinked); + ensure!(tenant.asset_account.is_some(), Error::::TenantAssetNotLinked); //Check that the remaining rent-to-pay is greater than 1 - ensure!(tenant.remaining_payments.clone() > 0, Error::::NoRentToPay); + ensure!(tenant.remaining_payments > 0, Error::::NoRentToPay); //Pay the rent Self::rent_helper(tenant_account.clone()).ok(); @@ -173,8 +173,6 @@ pub mod pallet { let caller = ensure_signed(origin.clone())?; // Ensure that the caller has the tenancy role ensure!(Roles::TenantLog::::contains_key(caller.clone()), Error::::NotATenant); - - // Ensure that the asset is valid let collection_id: T::NftCollectionId = asset_type.value().into(); @@ -182,14 +180,19 @@ pub mod pallet { ensure!(ownership.is_some(), Error::::NotAnAsset); let virtual_account = ownership.unwrap().virtual_account; - if !Tenants::::contains_key(caller.clone()){ - RegisteredTenant::::new(caller.clone(), info.clone(), Some(virtual_account.clone())).ok(); - }else{ + if !Tenants::::contains_key(caller.clone()) { + RegisteredTenant::::new( + caller.clone(), + info.clone(), + Some(virtual_account.clone()), + ) + .ok(); + } else { let mut val0 = Self::infos(&caller).unwrap(); - Tenants::::mutate(&caller,|val|{ + Tenants::::mutate(&caller, |val| { val0.asset_requested = Some(virtual_account.clone()); *val = Some(val0); - }); + }); } Self::request_helper(origin.clone(), virtual_account.clone(), info).ok(); @@ -237,12 +240,9 @@ pub mod pallet { Error::::NotAValidPayment ); - Self::payment_helper(origin, virtual_account.clone(), collection_id, asset_id).ok(); let now = >::block_number(); - - Self::deposit_event(Event::GuarantyDepositPayment { tenant: caller, when: now, diff --git a/pallets/tenancy/src/weights.rs b/pallets/tenancy/src/weights.rs index dfdb1026..b4d897f0 100644 --- a/pallets/tenancy/src/weights.rs +++ b/pallets/tenancy/src/weights.rs @@ -61,8 +61,8 @@ impl WeightInfo for SubstrateWeight { // Storage: TemplateModule Something (r:0 w:1) /// The range of component `s` is `[0, 100]`. fn do_something(_s: u32, ) -> Weight { - Weight::from_ref_time(15_009_000 as u64) - .saturating_add(T::DbWeight::get().writes(1 as u64)) + Weight::from_ref_time(15_009_000_u64) + .saturating_add(T::DbWeight::get().writes(1_u64)) } } @@ -71,7 +71,7 @@ impl WeightInfo for () { // Storage: TemplateModule Something (r:0 w:1) /// The range of component `s` is `[0, 100]`. fn do_something(_s: u32, ) -> Weight { - Weight::from_ref_time(15_009_000 as u64) - .saturating_add(RocksDbWeight::get().writes(1 as u64)) + Weight::from_ref_time(15_009_000_u64) + .saturating_add(RocksDbWeight::get().writes(1_u64)) } } \ No newline at end of file diff --git a/pallets/voting/src/lib.rs b/pallets/voting/src/lib.rs index 1f60c8e5..a8538797 100644 --- a/pallets/voting/src/lib.rs +++ b/pallets/voting/src/lib.rs @@ -238,15 +238,18 @@ pub mod pallet { let voting_proposal: VotingProposal>::Proposal>> = VotingProposal::new( who.clone(), - proposal, - collective_passed_call, - collective_failed_call, - democracy_failed_call, - proposal_hash, - collective_index, - democracy_call_formatted.clone(), - T::Hashing::hash_of(&democracy_call_formatted), - T::Hashing::hash_of(&call_dispatch), + ProposalParams { call: proposal, hash: proposal_hash }, + CollectiveParams { + call: democracy_call_formatted.clone(), + call_pass: collective_passed_call, + call_fail: collective_failed_call, + index: collective_index, + hash: T::Hashing::hash_of(&democracy_call_formatted), + }, + DemocracyParams { + call_fail: democracy_failed_call, + hash: T::Hashing::hash_of(&call_dispatch), + }, ); VotingProposals::::insert(proposal_hash, voting_proposal); diff --git a/pallets/voting/src/structs.rs b/pallets/voting/src/structs.rs index e423cfad..a197fdf3 100644 --- a/pallets/voting/src/structs.rs +++ b/pallets/voting/src/structs.rs @@ -12,20 +12,44 @@ pub type AccountIdOf = ::AccountId; pub type BalanceOf = <::LocalCurrency as Currency>>::Balance; pub type BlockNumberOf = ::BlockNumber; +#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] +#[scale_info(skip_type_params(T))] +pub struct ProposalParams { + pub call: Box<::Call>, + pub hash: T::Hash, +} + +#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] +#[scale_info(skip_type_params(T))] +pub struct CollectiveParams { + pub call_pass: Box<::Call>, + pub call_fail: Box<::Call>, + pub index: u32, + pub call: U, + pub hash: T::Hash, +} + +#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] +#[scale_info(skip_type_params(T))] +pub struct DemocracyParams { + pub call_fail: Box<::Call>, + pub hash: T::Hash, +} + #[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] #[scale_info(skip_type_params(T))] pub struct VotingProposal { pub account_id: AccountIdOf, pub proposal_call: Box<::Call>, + pub proposal_hash: T::Hash, + pub collective_call: U, pub collective_passed_call: Box<::Call>, pub collective_failed_call: Box<::Call>, - pub democracy_failed_call: Box<::Call>, - pub proposal_hash: T::Hash, pub collective_index: u32, - pub collective_call: U, pub collective_hash: T::Hash, pub collective_step: bool, pub collective_closed: bool, + pub democracy_failed_call: Box<::Call>, pub democracy_referendum_index: u32, pub democracy_hash: T::Hash, pub proposal_executed: bool, @@ -33,28 +57,22 @@ pub struct VotingProposal { impl VotingProposal { pub fn new( account_id: AccountIdOf, - proposal_call: Box<::Call>, - collective_passed_call: Box<::Call>, - collective_failed_call: Box<::Call>, - democracy_failed_call: Box<::Call>, - proposal_hash: T::Hash, - collective_index: u32, - collective_call: U, - collective_hash: T::Hash, - democracy_hash: T::Hash, + proposal: ProposalParams, + collective: CollectiveParams, + democracy: DemocracyParams, ) -> VotingProposal { Self { account_id, - proposal_call, - collective_passed_call, - collective_failed_call, - democracy_failed_call, - proposal_hash, - collective_index, - collective_call, - collective_hash, + proposal_call: proposal.call, + proposal_hash: proposal.hash, + collective_passed_call: collective.call_pass, + collective_failed_call: collective.call_fail, + collective_index: collective.index, + collective_call: collective.call, + collective_hash: collective.hash, + democracy_failed_call: democracy.call_fail, + democracy_hash: democracy.hash, democracy_referendum_index: 0, - democracy_hash, proposal_executed: false, collective_step: false, collective_closed: false,