Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 18 additions & 18 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 39 additions & 3 deletions pallets/fruniques/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,6 @@ pub mod pallet {
/// Maximum number of children a Frunique can have
#[pallet::constant]
type ChildMaxLen: Get<u32>;
/// Solution to fix issue with an optional BoundedVec
#[pallet::constant]
type LimitBoundedVec: Get<u8>;
}

#[pallet::pallet]
Expand All @@ -48,6 +45,8 @@ pub mod pallet {
FruniqueCreated(T::AccountId, T::AccountId, T::CollectionId, T::ItemId),
// A frunique/unique was successfully divided!
FruniqueDivided(T::AccountId, T::AccountId, T::CollectionId, T::ItemId),
// A frunique has been verified.
FruniqueVerified(T::AccountId, CollectionId, ItemId),
// Counter should work?
NextFrunique(u32),
}
Expand Down Expand Up @@ -82,6 +81,8 @@ pub mod pallet {
CollectionAlreadyExists,
// Frunique already exists
FruniqueAlreadyExists,
// Frunique already verified
FruniqueAlreadyVerified
}

#[pallet::storage]
Expand Down Expand Up @@ -122,6 +123,19 @@ pub mod pallet {
ValueQuery,
>;

#[pallet::storage]
#[pallet::getter(fn frunique_verified)]
/// Keeps track of verified fruniques.
pub(super) type FruniqueVerified<T: Config> = StorageDoubleMap<
_,
Blake2_128Concat,
CollectionId,
Blake2_128Concat,
ItemId,
bool,
ValueQuery,
>;

#[pallet::storage]
#[pallet::getter(fn frunique_child)]
/// Keeps track of hierarchical information for a frunique.
Expand Down Expand Up @@ -280,6 +294,28 @@ pub mod pallet {
Ok(())
}

/// ## Verification of the NFT
/// ### Parameters:
/// - `origin` must be signed by the owner of the frunique.
/// - `class_id` must be a valid class of the asset class.
/// - `instance_id` must be a valid instance of the asset class.
#[pallet::weight(10_000 + T::DbWeight::get().writes(1))]
pub fn verify(
origin: OriginFor<T>,
class_id: CollectionId,
instance_id: ItemId,
) -> DispatchResult {
ensure!(Self::item_exists(&class_id, &instance_id), <Error<T>>::FruniqueNotFound);

let owner: T::AccountId = ensure_signed(origin.clone())?;

<FruniqueVerified<T>>::insert(class_id, instance_id, true);

Self::deposit_event(Event::FruniqueVerified(owner, class_id, instance_id));

Ok(())
}

/// ## Force set counter
/// ### Parameters:
/// `origin` must be signed by the Root origin.
Expand Down
2 changes: 0 additions & 2 deletions pallets/fruniques/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ construct_runtime!(
parameter_types! {
pub const BlockHashCount: u64 = 250;
pub const ChildMaxLen: u32 = 10;
pub const LimitBoundedVec: u8 = 1;
}

impl frame_system::Config for Test {
Expand Down Expand Up @@ -61,7 +60,6 @@ impl pallet_fruniques::Config for Test {
type Event = Event;
type RemoveOrigin = EnsureRoot<Self::AccountId>;
type ChildMaxLen = ChildMaxLen;
type LimitBoundedVec = LimitBoundedVec;
}

parameter_types! {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
name = "pallet-proxy-financial"
name = "pallet-fund-admin"
version = "4.0.0-dev"
description = "Proxy Financial Pallet"
authors = ["Hashed <https://github.com/hashed-io"]
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl<T: Config> Pallet<T> {
Option<BoundedVec<FieldName, T::MaxBoundedVecs>>,
Option<ExpenditureType>,
Option<u64>,
Option<u32>,
Option<BoundedVec<FieldDescription, T::MaxBoundedVecs>>,
Option<u32>,
CUDAction,
Option<[u8;32]>,
Expand Down Expand Up @@ -398,7 +398,7 @@ impl<T: Config> Pallet<T> {
)?;
},
CUDAction::Delete => {
// Ensure admin cannot delete himself
// Ensure admin cannot delete themselves
ensure!(user.0 != admin, Error::<T>::AdministatorsCannotDeleteThemselves);

Self::do_delete_user(
Expand Down Expand Up @@ -566,7 +566,7 @@ impl<T: Config> Pallet<T> {
Option<BoundedVec<FieldName, T::MaxBoundedVecs>>, // 0: name
Option<ExpenditureType>, // 1: type
Option<u64>, // 2: amount
Option<u32>, // 3: naics code
Option<BoundedVec<FieldDescription, T::MaxBoundedVecs>>, // 3: naics code
Option<u32>, // 4: jobs multiplier
CUDAction, // 5: CUDAction
Option<[u8;32]>, // 6: expenditure_id
Expand Down Expand Up @@ -639,7 +639,7 @@ impl<T: Config> Pallet<T> {
name: BoundedVec<FieldName, T::MaxBoundedVecs>,
expenditure_type: ExpenditureType,
expenditure_amount: u64,
naics_code: Option<u32>,
naics_code: Option<BoundedVec<FieldDescription, T::MaxBoundedVecs>>,
jobs_multiplier: Option<u32>,
) -> DispatchResult {
//Ensure project exists
Expand All @@ -657,13 +657,21 @@ impl<T: Config> Pallet<T> {
// Create expenditure id
let expenditure_id = (project_id, name.clone(), expenditure_type, timestamp).using_encoded(blake2_256);

// NAICS code
let get_naics_code = match naics_code {
Some(mod_naics_code) => {
Some(mod_naics_code.into_inner()[0].clone())
},
None => None,
};

// Create expenditurte data
let expenditure_data = ExpenditureData {
project_id,
name: name.into_inner()[0].clone(),
expenditure_type,
expenditure_amount,
naics_code,
naics_code: get_naics_code,
jobs_multiplier,
};

Expand All @@ -687,7 +695,7 @@ impl<T: Config> Pallet<T> {
expenditure_id: [u8;32],
name: Option<BoundedVec<FieldName, T::MaxBoundedVecs>>,
expenditure_amount: Option<u64>,
naics_code: Option<u32>,
naics_code: Option<BoundedVec<FieldDescription, T::MaxBoundedVecs>>,
jobs_multiplier: Option<u32>,
) -> DispatchResult {
//Ensure project exists
Expand Down Expand Up @@ -715,7 +723,7 @@ impl<T: Config> Pallet<T> {
expenditure.expenditure_amount = mod_expenditure_amount;
}
if let Some(mod_naics_code) = naics_code {
expenditure.naics_code = Some(mod_naics_code);
expenditure.naics_code = Some(mod_naics_code.into_inner()[0].clone());
}
if let Some(mod_jobs_multiplier) = jobs_multiplier {
expenditure.jobs_multiplier = Some(mod_jobs_multiplier);
Expand Down Expand Up @@ -846,6 +854,7 @@ impl<T: Config> Pallet<T> {
<TransactionsInfo<T>>::try_mutate::<_,_,DispatchError,_>(transaction_id, |transaction_data| {
let transaction_data = transaction_data.as_mut().ok_or(Error::<T>::TransactionNotFound)?;
transaction_data.status = TransactionStatus::Submitted;
transaction_data.feedback = None;
Ok(())
})?;
}
Expand Down Expand Up @@ -1194,7 +1203,7 @@ impl<T: Config> Pallet<T> {
// B U L K U P L O A D T R A N S A C T I O N S

pub fn do_up_bulk_upload(
user: T::AccountId, //TODO: Remove underscore when permissions are implemented
user: T::AccountId,
project_id: [u8;32],
drawdown_id: [u8;32],
description: FieldDescription,
Expand All @@ -1213,10 +1222,13 @@ impl<T: Config> Pallet<T> {
// Ensure amount is valid
Self::is_amount_valid(total_amount)?;

//Ensure only Construction loan & developer equity drawdowns can be bulk uploaded
//Ensure only Construction loan & developer equity drawdowns can call bulk uploaded
let drawdown_data = DrawdownsInfo::<T>::get(drawdown_id).ok_or(Error::<T>::DrawdownNotFound)?;
ensure!(drawdown_data.drawdown_type == DrawdownType::ConstructionLoan || drawdown_data.drawdown_type == DrawdownType::DeveloperEquity, Error::<T>::DrawdownTypeNotSupportedForBulkUpload);

//Ensure drawdown status is draft or rejected
ensure!(drawdown_data.status == DrawdownStatus::Draft || drawdown_data.status == DrawdownStatus::Rejected, Error::<T>::DrawdownStatusNotSupportedForBulkUpload);

// Ensure documents is not empty
ensure!(!documents.is_empty(), Error::<T>::DocumentsIsEmpty);

Expand All @@ -1230,6 +1242,7 @@ impl<T: Config> Pallet<T> {
mod_drawdown_data.description = Some(description);
mod_drawdown_data.documents = Some(documents);
mod_drawdown_data.status = DrawdownStatus::Submitted;
mod_drawdown_data.feedback = None;
Ok(())
})?;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ pub mod pallet {
#[pallet::getter(fn users_info)]
pub(super) type UsersInfo<T: Config> = StorageMap<
_,
Identity,
Blake2_128Concat,
T::AccountId, // Key account_id
UserData<T>, // Value UserData<T>
OptionQuery,
Expand Down Expand Up @@ -157,7 +157,7 @@ pub mod pallet {
#[pallet::getter(fn projects_by_user)]
pub(super) type ProjectsByUser<T: Config> = StorageMap<
_,
Identity,
Blake2_128Concat,
T::AccountId, // Key account_id
BoundedVec<[u8;32], T::MaxProjectsPerUser>, // Value projects
ValueQuery,
Expand Down Expand Up @@ -447,6 +447,8 @@ pub mod pallet {
UserHasAssignedProjectsCannotUpdateRole,
/// Cannot delete user if the user is assigned to a project
UserHasAssignedProjectsCannotDelete,
/// Cannot send a bulkupload drawdown if the drawdown status isn't in draft or rejected
DrawdownStatusNotSupportedForBulkUpload,

}

Expand Down Expand Up @@ -539,7 +541,7 @@ pub mod pallet {
Option<BoundedVec<FieldName, T::MaxBoundedVecs>>,
Option<ExpenditureType>,
Option<u64>,
Option<u32>,
Option<BoundedVec<FieldDescription, T::MaxBoundedVecs>>,
Option<u32>,
CUDAction,
Option<[u8;32]>,
Expand Down Expand Up @@ -613,7 +615,7 @@ pub mod pallet {
Option<BoundedVec<FieldName, T::MaxBoundedVecs>>,
Option<ExpenditureType>,
Option<u64>,
Option<u32>,
Option<BoundedVec<FieldDescription, T::MaxBoundedVecs>>,
Option<u32>,
CUDAction,
Option<[u8;32]>,
Expand Down Expand Up @@ -698,7 +700,7 @@ pub mod pallet {
origin: OriginFor<T>,
project_id: [u8;32],
drawdown_id: [u8;32],
bulkupdate: Option<bool>,
bulkupload: Option<bool>,
transactions: Option<BoundedVec<(
Option<[u8;32]>, // expenditure_id
Option<u64>, // amount
Expand All @@ -710,7 +712,7 @@ pub mod pallet {
let who = ensure_signed(origin)?; // origin need to be an admin

// Match bulkupdate
match bulkupdate {
match bulkupload {
Some(approval) => {
// Execute bulkupload flow (construction loan & developer equity)
match approval {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ use sp_runtime::{
testing::Header,
traits::{BlakeTwo256, IdentityLookup},
};
use frame_system::EnsureRoot;


type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
type Block = frame_system::mocking::MockBlock<Test>;
use frame_system::EnsureRoot;

// Configure a mock runtime to test the pallet.
frame_support::construct_runtime!(
Expand All @@ -20,7 +19,7 @@ frame_support::construct_runtime!(
UncheckedExtrinsic = UncheckedExtrinsic,
{
System: frame_system::{Pallet, Call, Config, Storage, Event<T>},
Proxy: pallet_proxy_financial::{Pallet, Call, Storage, Event<T>},
FundAdmin: pallet_proxy_financial::{Pallet, Call, Storage, Event<T>},
Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent},
RBAC: pallet_rbac::{Pallet, Call, Storage, Event<T>},
}
Expand Down Expand Up @@ -115,13 +114,13 @@ impl pallet_timestamp::Config for Test {
}

parameter_types! {
pub const MaxScopesPerPallet: u32 = 2;
pub const MaxRolesPerPallet: u32 = 6;
pub const RoleMaxLen: u32 = 25;
pub const PermissionMaxLen: u32 = 25;
pub const MaxPermissionsPerRole: u32 = 11;
pub const MaxRolesPerUser: u32 = 2;
pub const MaxUsersPerRole: u32 = 2;
pub const MaxScopesPerPallet: u32 = 1000;
pub const MaxRolesPerPallet: u32 = 50;
pub const RoleMaxLen: u32 = 50;
pub const PermissionMaxLen: u32 = 50;
pub const MaxPermissionsPerRole: u32 = 100;
pub const MaxRolesPerUser: u32 = 10;
pub const MaxUsersPerRole: u32 = 2500;
}
impl pallet_rbac::Config for Test {
type Event = Event;
Expand All @@ -136,5 +135,7 @@ impl pallet_rbac::Config for Test {

// Build genesis storage according to the mock runtime.
pub fn new_test_ext() -> sp_io::TestExternalities {
system::GenesisConfig::default().build_storage::<Test>().unwrap().into()
}
let mut t: sp_io::TestExternalities = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap().into();
t.execute_with(|| FundAdmin::do_initial_setup().expect("Error on configuring initial setup"));
t
}
Loading