Skip to content

Commit

Permalink
Improvements to the Asset Pallet (#1591)
Browse files Browse the repository at this point in the history
* Cherry-pick Add validate_ticker_registration_rules, base_create_asset_with_custom_type, validate_asset_creation_rules; Improve validate_asset_transfer; Remove old functions

* Remove fee if ticker registration expiry is still valid

* Add ensure_valid_asset_identifiers check for asset creation

* Add validate_and_create_asset function

* Remove clone
  • Loading branch information
HenriqueNogara authored Mar 8, 2024
1 parent 15b4cdd commit 83296f2
Show file tree
Hide file tree
Showing 9 changed files with 436 additions and 409 deletions.
6 changes: 5 additions & 1 deletion pallets/asset/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ decl_error! {
/// Number of asset mediators would exceed the maximum allowed.
NumberOfAssetMediatorsExceeded,
/// Invalid ticker character - valid set: A`..`Z` `0`..`9` `_` `-` `.` `/`.
InvalidTickerCharacter
InvalidTickerCharacter,
/// Failed to transfer the asset - asset is frozen.
InvalidTransferFrozenAsset,
/// Failed to transfer an NFT - compliance failed.
InvalidTransferComplianceFailure
}
}
716 changes: 359 additions & 357 deletions pallets/asset/src/lib.rs

Large diffs are not rendered by default.

50 changes: 43 additions & 7 deletions pallets/asset/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub enum AssetOwnershipRelation {
AssetOwned,
}

/// struct to store the token details.
/// Stores the details of a security token.
#[derive(Clone, Debug, Decode, Default, Encode, TypeInfo, PartialEq, Eq)]
pub struct SecurityToken {
pub total_supply: Balance,
Expand All @@ -25,6 +25,23 @@ pub struct SecurityToken {
pub asset_type: AssetType,
}

impl SecurityToken {
/// Creates a new [`SecurityToken`] instance.
pub fn new(
total_supply: Balance,
owner_did: IdentityId,
divisible: bool,
asset_type: AssetType,
) -> Self {
Self {
total_supply,
owner_did,
divisible,
asset_type,
}
}
}

/// struct to store the ticker registration details.
#[derive(Clone, Debug, Decode, Default, Encode, TypeInfo, PartialEq, Eq)]
pub struct TickerRegistration<T> {
Expand All @@ -40,10 +57,29 @@ pub struct TickerRegistrationConfig<T> {
pub registration_length: Option<T>,
}

/// Enum that represents the current status of a ticker.
#[derive(Clone, Debug, Decode, Encode, PartialEq, Eq)]
pub enum TickerRegistrationStatus {
RegisteredByOther,
Available,
RegisteredByDid,
/// Tracks information regarding ticker registration.
#[derive(Clone, Debug)]
pub struct TickerRegistrationStatus {
can_reregister: bool,
charge_fee: bool,
}

impl TickerRegistrationStatus {
/// Creates a new [`TickerRegistrationStatus`] instance.
pub fn new(can_reregister: bool, charge_fee: bool) -> Self {
TickerRegistrationStatus {
can_reregister,
charge_fee,
}
}

/// Returns `true` if the ticker can be reregistered.
pub fn can_reregister(&self) -> bool {
self.can_reregister
}

/// Returns `true` if the ticker registration fee must be charged.
pub fn charge_fee(&self) -> bool {
self.charge_fee
}
}
5 changes: 0 additions & 5 deletions pallets/common/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,8 @@ pub mod queue_priority {

// ERC1400 transfer status codes
pub const ERC1400_TRANSFER_FAILURE: u8 = 0x50;
pub const ERC1400_TRANSFER_SUCCESS: u8 = 0x51;
pub const ERC1400_INSUFFICIENT_BALANCE: u8 = 0x52;
pub const ERC1400_INSUFFICIENT_ALLOWANCE: u8 = 0x53;
pub const ERC1400_TRANSFERS_HALTED: u8 = 0x54;
pub const ERC1400_FUNDS_LOCKED: u8 = 0x55;
pub const ERC1400_INVALID_SENDER: u8 = 0x56;
pub const ERC1400_INVALID_RECEIVER: u8 = 0x57;
Expand All @@ -59,15 +57,12 @@ pub const ERC1400_INVALID_OPERATOR: u8 = 0x58;
// Application-specific status codes
pub const INVALID_SENDER_DID: u8 = 0xa0;
pub const INVALID_RECEIVER_DID: u8 = 0xa1;
pub const COMPLIANCE_MANAGER_FAILURE: u8 = 0xa2;
pub const INVALID_GRANULARITY: u8 = 0xa4;
pub const APP_TX_VOLUME_LIMIT_REACHED: u8 = 0xa5;
pub const APP_BLOCKED_TX: u8 = 0xa6;
pub const APP_FUNDS_LOCKED: u8 = 0xa7;
pub const APP_FUNDS_LIMIT_REACHED: u8 = 0xa8;
pub const PORTFOLIO_FAILURE: u8 = 0xa9;
pub const CUSTODIAN_ERROR: u8 = 0xaa;
pub const TRANSFER_MANAGER_FAILURE: u8 = 0xac;

// PIP pallet constants.
pub const PIP_MAX_REPORTING_SIZE: usize = 1024;
Expand Down
7 changes: 5 additions & 2 deletions pallets/runtime/tests/src/asset_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,10 @@ fn valid_transfers_pass() {

// Should fail as sender matches receiver.
let transfer = |from, to| transfer(ticker, from, to, 500);
assert_noop!(transfer(owner, owner), AssetError::InvalidTransfer);
assert_noop!(
transfer(owner, owner),
PortfolioError::DestinationIsSamePortfolio
);
assert_ok!(transfer(owner, alice));

assert_eq!(Asset::balance_of(&ticker, owner.did), TOTAL_SUPPLY - 500);
Expand Down Expand Up @@ -486,7 +489,7 @@ fn controller_transfer() {
// Should fail as sender matches receiver.
assert_noop!(
transfer(ticker, owner, owner, 500),
AssetError::InvalidTransfer
PortfolioError::DestinationIsSamePortfolio
);

assert_ok!(transfer(ticker, owner, alice, 500));
Expand Down
36 changes: 15 additions & 21 deletions pallets/runtime/tests/src/compliance_manager_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use sp_std::prelude::*;

use pallet_compliance_manager::Error as CMError;
use polymesh_common_utilities::compliance_manager::ComplianceFnConfig;
use polymesh_common_utilities::constants::ERC1400_TRANSFER_SUCCESS;
use polymesh_primitives::agent::AgentGroup;
use polymesh_primitives::compliance_manager::{
AssetComplianceResult, ComplianceRequirement, ComplianceRequirementResult,
Expand Down Expand Up @@ -35,32 +34,27 @@ type EAError = pallet_external_agents::Error<TestStorage>;
macro_rules! assert_invalid_transfer {
($ticker:expr, $from:expr, $to:expr, $amount:expr) => {
let mut weight_meter = WeightMeter::max_limit_no_minimum();
assert_ne!(
Asset::_is_valid_transfer(
&$ticker,
PortfolioId::default_portfolio($from),
PortfolioId::default_portfolio($to),
$amount,
&mut weight_meter
),
Ok(ERC1400_TRANSFER_SUCCESS)
);
assert!(Asset::validate_asset_transfer(
&$ticker,
&PortfolioId::default_portfolio($from),
&PortfolioId::default_portfolio($to),
$amount,
&mut weight_meter
)
.is_err(),);
};
}

macro_rules! assert_valid_transfer {
($ticker:expr, $from:expr, $to:expr, $amount:expr) => {
let mut weight_meter = WeightMeter::max_limit_no_minimum();
assert_eq!(
Asset::_is_valid_transfer(
&$ticker,
PortfolioId::default_portfolio($from),
PortfolioId::default_portfolio($to),
$amount,
&mut weight_meter
),
Ok(ERC1400_TRANSFER_SUCCESS)
);
assert_ok!(Asset::validate_asset_transfer(
&$ticker,
&PortfolioId::default_portfolio($from),
&PortfolioId::default_portfolio($to),
$amount,
&mut weight_meter
),);
};
}

Expand Down
2 changes: 1 addition & 1 deletion pallets/runtime/tests/src/corporate_actions_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2024,7 +2024,7 @@ fn dist_claim_misc_bad() {

// Travel back in time. Now dist is active, but compliance rules not met, so transfer fails.
set_timestamp(5);
noop(AssetError::InvalidTransfer.into());
noop(AssetError::InvalidTransferComplianceFailure.into());
});
}

Expand Down
18 changes: 7 additions & 11 deletions pallets/runtime/tests/src/settlement_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ use pallet_settlement::{
UserVenues, VenueInstructions,
};
use polymesh_common_utilities::constants::currency::ONE_UNIT;
use polymesh_common_utilities::constants::ERC1400_TRANSFER_SUCCESS;
use polymesh_primitives::asset::{AssetType, NonFungibleType};
use polymesh_primitives::asset_metadata::{
AssetMetadataKey, AssetMetadataLocalKey, AssetMetadataValue,
Expand Down Expand Up @@ -1430,16 +1429,13 @@ fn test_weights_for_settlement_transaction() {
assert_affirm_instruction!(bob_signed.clone(), instruction_id, bob_did);

let mut weight_meter = WeightMeter::max_limit_no_minimum();
assert_ok!(
Asset::_is_valid_transfer(
&TICKER,
PortfolioId::default_portfolio(alice_did),
PortfolioId::default_portfolio(bob_did),
100,
&mut weight_meter
),
ERC1400_TRANSFER_SUCCESS
);
assert_ok!(Asset::validate_asset_transfer(
&TICKER,
&PortfolioId::default_portfolio(alice_did),
&PortfolioId::default_portfolio(bob_did),
100,
&mut weight_meter
),);
});
}

Expand Down
5 changes: 1 addition & 4 deletions pallets/runtime/tests/src/transfer_compliance_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -463,10 +463,7 @@ impl AssetTracker {

#[track_caller]
pub fn ensure_invalid_transfer(&mut self, from: u64, to: u64, amount: u128) {
assert_noop!(
self.do_transfer(from, to, amount),
AssetError::InvalidTransfer
);
assert_noop!(self.do_transfer(from, to, amount), Error::InvalidTransfer);
}

pub fn fetch_stats_key2(&self, stat_type: &StatType) -> Vec<Stat2ndKey> {
Expand Down

0 comments on commit 83296f2

Please sign in to comment.