From 5d7aa797df9dde7c552273808bd74c063ed42a77 Mon Sep 17 00:00:00 2001 From: tin-snowflake <56880684+chungquantin@users.noreply.github.com> Date: Tue, 23 Jul 2024 11:19:35 +0700 Subject: [PATCH 01/22] feat: implement transfer_from & add integration tests --- integration-tests/src/lib.rs | 11 +- pallets/api/src/fungibles/mod.rs | 45 ++++++-- pallets/api/src/fungibles/tests.rs | 46 +++++++- pallets/api/src/mock.rs | 9 +- .../integration-tests/src/local_fungibles.rs | 71 ++++++++++++ primitives/src/lib.rs | 23 ++-- runtime/devnet/src/config/proxy.rs | 108 +++++++++--------- runtime/devnet/src/config/xcm.rs | 4 +- runtime/devnet/src/extensions/mod.rs | 37 +++--- runtime/devnet/src/lib.rs | 14 +-- runtime/testnet/src/config/proxy.rs | 108 +++++++++--------- runtime/testnet/src/config/xcm.rs | 4 +- runtime/testnet/src/extensions.rs | 2 +- runtime/testnet/src/lib.rs | 8 +- scripts/fund-dev-accounts/main.rs | 16 +-- scripts/fund-dev-accounts/paseo_interface.rs | 37 +++--- scripts/fund-dev-accounts/pop_interface.rs | 13 +-- scripts/fund-dev-accounts/rococo_interface.rs | 37 +++--- 18 files changed, 360 insertions(+), 233 deletions(-) diff --git a/integration-tests/src/lib.rs b/integration-tests/src/lib.rs index 31e9860b..7f904051 100644 --- a/integration-tests/src/lib.rs +++ b/integration-tests/src/lib.rs @@ -17,8 +17,9 @@ use emulated_integration_tests_common::{ }, }; use frame_support::{ - dispatch::RawOrigin, pallet_prelude::Weight, sp_runtime::traits::Dispatchable, - sp_runtime::DispatchResult, + dispatch::RawOrigin, + pallet_prelude::Weight, + sp_runtime::{traits::Dispatchable, DispatchResult}, }; use polkadot_runtime_parachains::assigner_on_demand; use pop_runtime_common::Balance; @@ -424,7 +425,8 @@ fn reserve_transfer_native_asset_from_system_para_to_para() { fn reserve_transfer_native_asset_from_para_to_system_para() { init_tracing(); - // Setup: reserve transfer from AH to Pop, so that sovereign account accurate for return transfer + // Setup: reserve transfer from AH to Pop, so that sovereign account accurate for return + // transfer let amount_to_send: Balance = ASSET_HUB_ROCOCO_ED * 1000; fund_pop_from_system_para( AssetHubRococoParaSender::get(), @@ -488,7 +490,8 @@ fn place_coretime_spot_order_from_para_to_relay() { let beneficiary: sp_runtime::AccountId32 = [1u8; 32].into(); - // Setup: reserve transfer from relay to Pop, so that sovereign account accurate for return transfer + // Setup: reserve transfer from relay to Pop, so that sovereign account accurate for return + // transfer let amount_to_send: Balance = pop_runtime::UNIT * 1000; fund_pop_from_relay(RococoRelaySender::get(), amount_to_send, beneficiary.clone()); diff --git a/pallets/api/src/fungibles/mod.rs b/pallets/api/src/fungibles/mod.rs index 221da379..00565863 100644 --- a/pallets/api/src/fungibles/mod.rs +++ b/pallets/api/src/fungibles/mod.rs @@ -1,6 +1,6 @@ /// The fungibles pallet serves as a wrapper around the pallet_assets, offering a streamlined -/// interface for interacting with fungible assets. The goal is to provide a simplified, consistent -/// API that adheres to standards in the smart contract space. +/// interface for interacting with fungible assets. The goal is to provide a simplified, +/// consistent API that adheres to standards in the smart contract space. pub use pallet::*; #[cfg(test)] @@ -62,8 +62,8 @@ pub mod pallet { #[pallet::call] impl Pallet { - /// Transfers `value` amount of tokens from the caller's account to account `to`, with additional - /// `data` in unspecified format. + /// Transfers `value` amount of tokens from the caller's account to account `to`, with + /// additional `data` in unspecified format. /// /// # Arguments /// * `id` - The ID of the asset. @@ -84,6 +84,33 @@ pub mod pallet { Assets::::transfer_keep_alive(origin, id.into(), target, amount) } + /// Transfers `value` amount of tokens from the delegated account approved by the `owner` to + /// account `to`, with additional `data` in unspecified format. + /// + /// # Arguments + /// * `id` - The ID of the asset. + /// * `owner` - The account which previously approved for a transfer of at least `amount` + /// and + /// from which the asset balance will be withdrawn. + /// * `to` - The recipient account. + /// * `value` - The number of tokens to transfer. + /// + /// # Returns + /// Returns `Ok(())` if successful, or an error if the transfer fails. + #[pallet::call_index(1)] + #[pallet::weight(AssetsWeightInfo::::transfer_approved())] + pub fn transfer_from( + origin: OriginFor, + id: AssetIdOf, + owner: AccountIdOf, + target: AccountIdOf, + amount: BalanceOf, + ) -> DispatchResult { + let owner = T::Lookup::unlookup(owner); + let target = T::Lookup::unlookup(target); + Assets::::transfer_approved(origin, id.into(), owner, target, amount) + } + /// Approves an account to spend a specified number of tokens on behalf of the caller. /// /// # Arguments @@ -119,7 +146,8 @@ pub mod pallet { ) })?; } else { - // If the new value is less than the current allowance, cancel the approval and set the new value + // If the new value is less than the current allowance, cancel the approval and set + // the new value Assets::::cancel_approval(origin.clone(), id.clone(), spender.clone()).map_err( |e| { e.with_weight( @@ -167,8 +195,8 @@ pub mod pallet { Assets::::total_supply(id) } - /// Returns the account balance for the specified `owner` for a given asset ID. Returns `0` if - /// the account is non-existent. + /// Returns the account balance for the specified `owner` for a given asset ID. Returns `0` + /// if the account is non-existent. /// /// # Arguments /// * `id` - The ID of the asset. @@ -226,7 +254,8 @@ pub mod pallet { /// * `id` - The ID of the asset. /// /// # Returns - /// The number of decimals of the token as a byte vector, or an error if the operation fails. + /// The number of decimals of the token as a byte vector, or an error if the operation + /// fails. pub fn token_decimals(id: AssetIdOf) -> u8 { as MetadataInspect>>::decimals(id) } diff --git a/pallets/api/src/fungibles/tests.rs b/pallets/api/src/fungibles/tests.rs index 3f464ee8..a0e8a1f2 100644 --- a/pallets/api/src/fungibles/tests.rs +++ b/pallets/api/src/fungibles/tests.rs @@ -1,11 +1,20 @@ use crate::mock::*; use frame_support::{ - assert_ok, + assert_noop, assert_ok, traits::fungibles::{approvals::Inspect, metadata::Inspect as MetadataInspect}, }; +use sp_runtime::{DispatchError, ModuleError}; const ASSET: u32 = 42; +fn get_dispatch_error(index: u8, error_index: u8, error_message: &'static str) -> DispatchError { + DispatchError::Module(ModuleError { + index, + error: [error_index, 0, 0, 0], + message: Some(error_message), + }) +} + #[test] fn transfer_works() { new_test_ext().execute_with(|| { @@ -18,6 +27,41 @@ fn transfer_works() { }); } +#[test] +fn transfer_from_works() { + new_test_ext().execute_with(|| { + let amount: Balance = 100 * UNIT; + // Approve CHARLIE to transfer up to `amount` to BOB + create_asset_mint_and_approve(ALICE, ASSET, ALICE, amount * 2, CHARLIE, amount / 2); + + let transferred = amount / 2; + + assert_eq!(transferred, Assets::allowance(ASSET, &ALICE, &CHARLIE)); + assert_eq!(0, Assets::allowance(ASSET, &ALICE, &BOB)); + + // Transfer `amount` from an unapproved spender + assert_noop!( + Fungibles::transfer_from(signed(BOB), ASSET, ALICE, BOB, transferred), + get_dispatch_error(1, 10, "Unapproved") + ); + + // Transfer `amount` more than the allowed allowance + assert_noop!( + Fungibles::transfer_from(signed(CHARLIE), ASSET, ALICE, BOB, amount), + get_dispatch_error(1, 10, "Unapproved") + ); + + let alice_balance_before_transfer = Assets::balance(ASSET, &ALICE); + let bob_balance_before_transfer = Assets::balance(ASSET, &BOB); + assert_ok!(Fungibles::transfer_from(signed(CHARLIE), ASSET, ALICE, BOB, transferred)); + let alice_balance_after_transfer = Assets::balance(ASSET, &ALICE); + let bob_balance_after_transfer = Assets::balance(ASSET, &BOB); + // Check that BOB receives the `amount` and ALICE `amount` is spent successfully by CHARLIE + assert_eq!(bob_balance_after_transfer, bob_balance_before_transfer + transferred); + assert_eq!(alice_balance_after_transfer, alice_balance_before_transfer - transferred); + }); +} + // Non-additive, sets new value. #[test] fn approve_works() { diff --git a/pallets/api/src/mock.rs b/pallets/api/src/mock.rs index 5f0340a9..9d2c405e 100644 --- a/pallets/api/src/mock.rs +++ b/pallets/api/src/mock.rs @@ -102,6 +102,8 @@ impl crate::fungibles::Config for Test { pub(crate) const ALICE: AccountId = 1; pub(crate) const BOB: AccountId = 2; +pub(crate) const CHARLIE: AccountId = 3; +pub(crate) const DAVE: AccountId = 4; pub(crate) const INIT_AMOUNT: Balance = 100_000_000 * UNIT; pub(crate) const UNIT: Balance = 10_000_000_000; @@ -111,7 +113,12 @@ pub(crate) fn new_test_ext() -> sp_io::TestExternalities { .expect("Frame system builds valid default genesis config"); pallet_balances::GenesisConfig:: { - balances: vec![(ALICE, INIT_AMOUNT), (BOB, INIT_AMOUNT)], + balances: vec![ + (ALICE, INIT_AMOUNT), + (BOB, INIT_AMOUNT), + (CHARLIE, INIT_AMOUNT), + (DAVE, INIT_AMOUNT), + ], } .assimilate_storage(&mut t) .expect("Pallet balances storage can be assimilated"); diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index 3ff0bf52..ba72da18 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -79,6 +79,19 @@ fn transfer( result } +fn transfer_from( + addr: AccountId32, + asset_id: AssetId, + from: AccountId32, + to: AccountId32, + value: Balance, +) -> ExecReturnValue { + let function = function_selector("transfer_from"); + let params = [function, asset_id.encode(), from.encode(), to.encode(), value.encode()].concat(); + let result = bare_call(addr, params, 0).expect("should work"); + result +} + fn approve( addr: AccountId32, asset_id: AssetId, @@ -367,6 +380,64 @@ fn transfer_works() { }); } +#[test] +fn transfer_from_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = instantiate("contracts/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); + let amount: Balance = 100 * UNIT; + // TODO: Add approval process and finalize the integration test + // Asset does not exist. + assert_eq!( + decoded::(transfer_from(addr.clone(), 1, ALICE, BOB, amount,)), + Module { index: 52, error: 3 }, + ); + // Create asset with Alice as owner and mint `amount` to contract address. + let asset = create_asset_and_mint_to(ALICE, 1, addr.clone(), amount); + // Asset is not live, i.e. frozen or being destroyed. + freeze_asset(ALICE, asset); + assert_eq!( + decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount,)), + Module { index: 52, error: 16 }, + ); + thaw_asset(ALICE, asset); + // Not enough balance. + assert_eq!( + decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount + 1 * UNIT)), + Module { index: 52, error: 0 }, + ); + // Not enough balance due to ED. + assert_eq!( + decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount)), + Module { index: 52, error: 0 }, + ); + // Successful transfer. + let alice_balance_before_transfer = Assets::balance(asset, &ALICE); + let bob_balance_before_transfer = Assets::balance(asset, &BOB); + + let result = transfer_from(addr.clone(), asset, ALICE, BOB, amount / 2); + assert!(!result.did_revert(), "Contract reverted!"); + + let alice_balance_after_transfer = Assets::balance(asset, &BOB); + let bob_balance_after_transfer = Assets::balance(asset, &BOB); + + assert_eq!(bob_balance_after_transfer, bob_balance_before_transfer + amount / 2); + assert_eq!(alice_balance_after_transfer, alice_balance_before_transfer - amount / 2); + + // Transfer asset to account that does not exist. + assert_eq!( + decoded::(transfer_from(addr.clone(), asset, ALICE, FERDIE, amount / 4)), + Token(CannotCreate) + ); + // Asset is not live, i.e. frozen or being destroyed. + start_destroy_asset(ALICE, asset); + assert_eq!( + decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount / 4)), + Module { index: 52, error: 16 }, + ); + }); +} + #[test] fn approve_works() { new_test_ext().execute_with(|| { diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index a51661ea..65504a6b 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -20,12 +20,13 @@ pub mod v0 { #[allow(clippy::unnecessary_cast)] pub enum Error { /// An unknown error occurred. This variant captures any unexpected errors that the - /// contract cannot specifically handle. It is useful for cases where there are breaking - /// changes in the runtime or when an error falls outside the predefined categories. The - /// variant includes: + /// contract cannot specifically handle. It is useful for cases where there are + /// breaking changes in the runtime or when an error falls outside the predefined + /// categories. The variant includes: /// /// - `dispatch_error_index`: The index within the `DispatchError`. - /// - `error_index`: The index within the `DispatchError` variant (e.g. a `TokenError`). + /// - `error_index`: The index within the `DispatchError` variant (e.g. a + /// `TokenError`). /// - `error`: The specific error code or sub-index, providing additional context (e.g. /// `error` in `ModuleError`). Other { dispatch_error_index: u8, error_index: u8, error: u8 } = 0, @@ -48,14 +49,16 @@ pub mod v0 { Token(TokenError) = 7, /// An arithmetic error. Arithmetic(ArithmeticError) = 8, - /// The number of transactional layers has been reached, or we are not in a transactional - /// layer. + /// The number of transactional layers has been reached, or we are not in a + /// transactional layer. Transactional(TransactionalError) = 9, - /// Resources exhausted, e.g. attempt to read/write data which is too large to manipulate. + /// Resources exhausted, e.g. attempt to read/write data which is too large to + /// manipulate. Exhausted = 10, /// The state is corrupt; this is generally not going to fix itself. Corruption = 11, - /// Some resource (e.g. a preimage) is unavailable right now. This might fix itself later. + /// Some resource (e.g. a preimage) is unavailable right now. This might fix itself + /// later. Unavailable = 12, /// Root origin is not allowed. RootNotAllowed = 13, @@ -83,8 +86,8 @@ pub mod v0 { pub enum TokenError { /// Funds are unavailable. FundsUnavailable, - /// Some part of the balance gives the only provider reference to the account and thus cannot - /// be (re)moved. + /// Some part of the balance gives the only provider reference to the account and thus + /// cannot be (re)moved. OnlyProvider, /// Account cannot exist with the funds that would be given. BelowMinimum, diff --git a/runtime/devnet/src/config/proxy.rs b/runtime/devnet/src/config/proxy.rs index 07d5f0f8..c1142126 100644 --- a/runtime/devnet/src/config/proxy.rs +++ b/runtime/devnet/src/config/proxy.rs @@ -13,77 +13,77 @@ impl InstanceFilter for ProxyType { ProxyType::Any => true, ProxyType::NonTransfer => !matches!( c, - RuntimeCall::Balances { .. } - | RuntimeCall::Assets { .. } - | RuntimeCall::Nfts { .. } + RuntimeCall::Balances { .. } | + RuntimeCall::Assets { .. } | + RuntimeCall::Nfts { .. } ), ProxyType::CancelProxy => matches!( c, - RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) - | RuntimeCall::Utility { .. } - | RuntimeCall::Multisig { .. } + RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) | + RuntimeCall::Utility { .. } | + RuntimeCall::Multisig { .. } ), ProxyType::Assets => { matches!( c, - RuntimeCall::Assets { .. } - | RuntimeCall::Utility { .. } - | RuntimeCall::Multisig { .. } - | RuntimeCall::Nfts { .. } + RuntimeCall::Assets { .. } | + RuntimeCall::Utility { .. } | + RuntimeCall::Multisig { .. } | + RuntimeCall::Nfts { .. } ) }, ProxyType::AssetOwner => matches!( c, - RuntimeCall::Assets(AssetsCall::create { .. }) - | RuntimeCall::Assets(AssetsCall::start_destroy { .. }) - | RuntimeCall::Assets(AssetsCall::destroy_accounts { .. }) - | RuntimeCall::Assets(AssetsCall::destroy_approvals { .. }) - | RuntimeCall::Assets(AssetsCall::finish_destroy { .. }) - | RuntimeCall::Assets(AssetsCall::transfer_ownership { .. }) - | RuntimeCall::Assets(AssetsCall::set_team { .. }) - | RuntimeCall::Assets(AssetsCall::set_metadata { .. }) - | RuntimeCall::Assets(AssetsCall::clear_metadata { .. }) - | RuntimeCall::Assets(AssetsCall::set_min_balance { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::transfer_ownership { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::set_team { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::set_collection_max_supply { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::lock_collection { .. }) - | RuntimeCall::Utility { .. } - | RuntimeCall::Multisig { .. } + RuntimeCall::Assets(AssetsCall::create { .. }) | + RuntimeCall::Assets(AssetsCall::start_destroy { .. }) | + RuntimeCall::Assets(AssetsCall::destroy_accounts { .. }) | + RuntimeCall::Assets(AssetsCall::destroy_approvals { .. }) | + RuntimeCall::Assets(AssetsCall::finish_destroy { .. }) | + RuntimeCall::Assets(AssetsCall::transfer_ownership { .. }) | + RuntimeCall::Assets(AssetsCall::set_team { .. }) | + RuntimeCall::Assets(AssetsCall::set_metadata { .. }) | + RuntimeCall::Assets(AssetsCall::clear_metadata { .. }) | + RuntimeCall::Assets(AssetsCall::set_min_balance { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::transfer_ownership { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::set_team { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::set_collection_max_supply { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::lock_collection { .. }) | + RuntimeCall::Utility { .. } | + RuntimeCall::Multisig { .. } ), ProxyType::AssetManager => matches!( c, - RuntimeCall::Assets(AssetsCall::mint { .. }) - | RuntimeCall::Assets(AssetsCall::burn { .. }) - | RuntimeCall::Assets(AssetsCall::freeze { .. }) - | RuntimeCall::Assets(AssetsCall::block { .. }) - | RuntimeCall::Assets(AssetsCall::thaw { .. }) - | RuntimeCall::Assets(AssetsCall::freeze_asset { .. }) - | RuntimeCall::Assets(AssetsCall::thaw_asset { .. }) - | RuntimeCall::Assets(AssetsCall::touch_other { .. }) - | RuntimeCall::Assets(AssetsCall::refund_other { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::set_attributes_pre_signed { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::lock_item_transfer { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::unlock_item_transfer { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::lock_item_properties { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::set_metadata { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::clear_metadata { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::set_collection_metadata { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::clear_collection_metadata { .. }) - | RuntimeCall::Utility { .. } - | RuntimeCall::Multisig { .. } + RuntimeCall::Assets(AssetsCall::mint { .. }) | + RuntimeCall::Assets(AssetsCall::burn { .. }) | + RuntimeCall::Assets(AssetsCall::freeze { .. }) | + RuntimeCall::Assets(AssetsCall::block { .. }) | + RuntimeCall::Assets(AssetsCall::thaw { .. }) | + RuntimeCall::Assets(AssetsCall::freeze_asset { .. }) | + RuntimeCall::Assets(AssetsCall::thaw_asset { .. }) | + RuntimeCall::Assets(AssetsCall::touch_other { .. }) | + RuntimeCall::Assets(AssetsCall::refund_other { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::set_attributes_pre_signed { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::lock_item_transfer { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::unlock_item_transfer { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::lock_item_properties { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::set_metadata { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::clear_metadata { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::set_collection_metadata { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::clear_collection_metadata { .. }) | + RuntimeCall::Utility { .. } | + RuntimeCall::Multisig { .. } ), ProxyType::Collator => matches!( c, - RuntimeCall::CollatorSelection { .. } - | RuntimeCall::Utility { .. } - | RuntimeCall::Multisig { .. } + RuntimeCall::CollatorSelection { .. } | + RuntimeCall::Utility { .. } | + RuntimeCall::Multisig { .. } ), } } diff --git a/runtime/devnet/src/config/xcm.rs b/runtime/devnet/src/config/xcm.rs index a210f7a4..303cfd32 100644 --- a/runtime/devnet/src/config/xcm.rs +++ b/runtime/devnet/src/config/xcm.rs @@ -115,8 +115,8 @@ pub struct NativeAssetFrom(PhantomData); impl> ContainsPair for NativeAssetFrom { fn contains(asset: &Asset, origin: &Location) -> bool { let loc = T::get(); - &loc == origin - && matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } + &loc == origin && + matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } if *asset_loc == Location::from(Parent)) } } diff --git a/runtime/devnet/src/extensions/mod.rs b/runtime/devnet/src/extensions/mod.rs index 4496c458..e01a3683 100644 --- a/runtime/devnet/src/extensions/mod.rs +++ b/runtime/devnet/src/extensions/mod.rs @@ -68,19 +68,17 @@ where let result = match FuncId::try_from(function_id) { Ok(function_id) => { - // Read encoded parameters from buffer and calculate weight for reading `len` bytes`. - // reference: https://github.com/paritytech/polkadot-sdk/blob/117a9433dac88d5ac00c058c9b39c511d47749d2/substrate/frame/contracts/src/wasm/runtime.rs#L267 + // Read encoded parameters from buffer and calculate weight for reading `len` + // bytes`. reference: https://github.com/paritytech/polkadot-sdk/blob/117a9433dac88d5ac00c058c9b39c511d47749d2/substrate/frame/contracts/src/wasm/runtime.rs#L267 let len = env.in_len(); env.charge_weight(contract_host_weight.return_per_byte.saturating_mul(len.into()))?; let params = env.read(len)?; log::debug!(target: LOG_TARGET, "Read input successfully"); match function_id { - FuncId::Dispatch => { - dispatch::(&mut env, version, pallet_index, call_index, params) - }, - FuncId::ReadState => { - read_state::(&mut env, version, pallet_index, call_index, params) - }, + FuncId::Dispatch => + dispatch::(&mut env, version, pallet_index, call_index, params), + FuncId::ReadState => + read_state::(&mut env, version, pallet_index, call_index, params), } }, Err(e) => Err(e), @@ -201,13 +199,14 @@ enum VersionedDispatch { V0(RuntimeCall), } -// Converts a `DispatchError` to a `u32` status code based on the version of the API the contract uses. -// The contract calling the chain extension can convert the status code to the descriptive `Error`. +// Converts a `DispatchError` to a `u32` status code based on the version of the API the contract +// uses. The contract calling the chain extension can convert the status code to the descriptive +// `Error`. // // For `Error` see `primitives::::error::Error`. // -// The error encoding can vary per version, allowing for flexible and backward-compatible error handling. -// As a result, contracts maintain compatibility across different versions of the runtime. +// The error encoding can vary per version, allowing for flexible and backward-compatible error +// handling. As a result, contracts maintain compatibility across different versions of the runtime. // // # Parameters // @@ -226,10 +225,11 @@ pub(crate) fn convert_to_status_code(error: DispatchError, version: u8) -> u32 { let mut encoded_error = encoded_error.try_into().expect("qed, resized to 4 bytes line above"); match version { // If an unknown variant of the `DispatchError` is detected the error needs to be converted - // into the encoded value of `Error::Other`. This conversion is performed by shifting the bytes one - // position forward (discarding the last byte as it is not used) and setting the first byte to the - // encoded value of `Other` (0u8). This ensures the error is correctly categorized as an `Other` - // variant which provides all the necessary information to debug which error occurred in the runtime. + // into the encoded value of `Error::Other`. This conversion is performed by shifting the + // bytes one position forward (discarding the last byte as it is not used) and setting the + // first byte to the encoded value of `Other` (0u8). This ensures the error is correctly + // categorized as an `Other` variant which provides all the necessary information to debug + // which error occurred in the runtime. // // Byte layout explanation: // - Byte 0: index of the variant within `Error` @@ -296,9 +296,8 @@ where match key { TotalSupply(id) => Ok(fungibles::Pallet::::total_supply(id).encode()), BalanceOf(id, owner) => Ok(fungibles::Pallet::::balance_of(id, &owner).encode()), - Allowance(id, owner, spender) => { - Ok(fungibles::Pallet::::allowance(id, &owner, &spender).encode()) - }, + Allowance(id, owner, spender) => + Ok(fungibles::Pallet::::allowance(id, &owner, &spender).encode()), TokenName(id) => Ok(fungibles::Pallet::::token_name(id).encode()), TokenSymbol(id) => Ok(fungibles::Pallet::::token_symbol(id).encode()), TokenDecimals(id) => Ok(fungibles::Pallet::::token_decimals(id).encode()), diff --git a/runtime/devnet/src/lib.rs b/runtime/devnet/src/lib.rs index 4d4ffc7c..8c8be97f 100644 --- a/runtime/devnet/src/lib.rs +++ b/runtime/devnet/src/lib.rs @@ -243,10 +243,10 @@ impl Contains for FilteredCalls { matches!( c, RuntimeCall::Balances( - force_adjust_total_issuance { .. } - | force_set_balance { .. } - | force_transfer { .. } - | force_unreserve { .. } + force_adjust_total_issuance { .. } | + force_set_balance { .. } | + force_transfer { .. } | + force_unreserve { .. } ) ) } @@ -260,9 +260,9 @@ impl Contains for AllowedApiCalls { matches!( c, RuntimeCall::Fungibles( - FungiblesCall::transfer { .. } - | FungiblesCall::approve { .. } - | FungiblesCall::increase_allowance { .. } + FungiblesCall::transfer { .. } | + FungiblesCall::approve { .. } | + FungiblesCall::increase_allowance { .. } ) ) } diff --git a/runtime/testnet/src/config/proxy.rs b/runtime/testnet/src/config/proxy.rs index 07d5f0f8..c1142126 100644 --- a/runtime/testnet/src/config/proxy.rs +++ b/runtime/testnet/src/config/proxy.rs @@ -13,77 +13,77 @@ impl InstanceFilter for ProxyType { ProxyType::Any => true, ProxyType::NonTransfer => !matches!( c, - RuntimeCall::Balances { .. } - | RuntimeCall::Assets { .. } - | RuntimeCall::Nfts { .. } + RuntimeCall::Balances { .. } | + RuntimeCall::Assets { .. } | + RuntimeCall::Nfts { .. } ), ProxyType::CancelProxy => matches!( c, - RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) - | RuntimeCall::Utility { .. } - | RuntimeCall::Multisig { .. } + RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) | + RuntimeCall::Utility { .. } | + RuntimeCall::Multisig { .. } ), ProxyType::Assets => { matches!( c, - RuntimeCall::Assets { .. } - | RuntimeCall::Utility { .. } - | RuntimeCall::Multisig { .. } - | RuntimeCall::Nfts { .. } + RuntimeCall::Assets { .. } | + RuntimeCall::Utility { .. } | + RuntimeCall::Multisig { .. } | + RuntimeCall::Nfts { .. } ) }, ProxyType::AssetOwner => matches!( c, - RuntimeCall::Assets(AssetsCall::create { .. }) - | RuntimeCall::Assets(AssetsCall::start_destroy { .. }) - | RuntimeCall::Assets(AssetsCall::destroy_accounts { .. }) - | RuntimeCall::Assets(AssetsCall::destroy_approvals { .. }) - | RuntimeCall::Assets(AssetsCall::finish_destroy { .. }) - | RuntimeCall::Assets(AssetsCall::transfer_ownership { .. }) - | RuntimeCall::Assets(AssetsCall::set_team { .. }) - | RuntimeCall::Assets(AssetsCall::set_metadata { .. }) - | RuntimeCall::Assets(AssetsCall::clear_metadata { .. }) - | RuntimeCall::Assets(AssetsCall::set_min_balance { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::transfer_ownership { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::set_team { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::set_collection_max_supply { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::lock_collection { .. }) - | RuntimeCall::Utility { .. } - | RuntimeCall::Multisig { .. } + RuntimeCall::Assets(AssetsCall::create { .. }) | + RuntimeCall::Assets(AssetsCall::start_destroy { .. }) | + RuntimeCall::Assets(AssetsCall::destroy_accounts { .. }) | + RuntimeCall::Assets(AssetsCall::destroy_approvals { .. }) | + RuntimeCall::Assets(AssetsCall::finish_destroy { .. }) | + RuntimeCall::Assets(AssetsCall::transfer_ownership { .. }) | + RuntimeCall::Assets(AssetsCall::set_team { .. }) | + RuntimeCall::Assets(AssetsCall::set_metadata { .. }) | + RuntimeCall::Assets(AssetsCall::clear_metadata { .. }) | + RuntimeCall::Assets(AssetsCall::set_min_balance { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::transfer_ownership { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::set_team { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::set_collection_max_supply { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::lock_collection { .. }) | + RuntimeCall::Utility { .. } | + RuntimeCall::Multisig { .. } ), ProxyType::AssetManager => matches!( c, - RuntimeCall::Assets(AssetsCall::mint { .. }) - | RuntimeCall::Assets(AssetsCall::burn { .. }) - | RuntimeCall::Assets(AssetsCall::freeze { .. }) - | RuntimeCall::Assets(AssetsCall::block { .. }) - | RuntimeCall::Assets(AssetsCall::thaw { .. }) - | RuntimeCall::Assets(AssetsCall::freeze_asset { .. }) - | RuntimeCall::Assets(AssetsCall::thaw_asset { .. }) - | RuntimeCall::Assets(AssetsCall::touch_other { .. }) - | RuntimeCall::Assets(AssetsCall::refund_other { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::set_attributes_pre_signed { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::lock_item_transfer { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::unlock_item_transfer { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::lock_item_properties { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::set_metadata { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::clear_metadata { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::set_collection_metadata { .. }) - | RuntimeCall::Nfts(pallet_nfts::Call::clear_collection_metadata { .. }) - | RuntimeCall::Utility { .. } - | RuntimeCall::Multisig { .. } + RuntimeCall::Assets(AssetsCall::mint { .. }) | + RuntimeCall::Assets(AssetsCall::burn { .. }) | + RuntimeCall::Assets(AssetsCall::freeze { .. }) | + RuntimeCall::Assets(AssetsCall::block { .. }) | + RuntimeCall::Assets(AssetsCall::thaw { .. }) | + RuntimeCall::Assets(AssetsCall::freeze_asset { .. }) | + RuntimeCall::Assets(AssetsCall::thaw_asset { .. }) | + RuntimeCall::Assets(AssetsCall::touch_other { .. }) | + RuntimeCall::Assets(AssetsCall::refund_other { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::set_attributes_pre_signed { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::lock_item_transfer { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::unlock_item_transfer { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::lock_item_properties { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::set_metadata { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::clear_metadata { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::set_collection_metadata { .. }) | + RuntimeCall::Nfts(pallet_nfts::Call::clear_collection_metadata { .. }) | + RuntimeCall::Utility { .. } | + RuntimeCall::Multisig { .. } ), ProxyType::Collator => matches!( c, - RuntimeCall::CollatorSelection { .. } - | RuntimeCall::Utility { .. } - | RuntimeCall::Multisig { .. } + RuntimeCall::CollatorSelection { .. } | + RuntimeCall::Utility { .. } | + RuntimeCall::Multisig { .. } ), } } diff --git a/runtime/testnet/src/config/xcm.rs b/runtime/testnet/src/config/xcm.rs index a210f7a4..303cfd32 100644 --- a/runtime/testnet/src/config/xcm.rs +++ b/runtime/testnet/src/config/xcm.rs @@ -115,8 +115,8 @@ pub struct NativeAssetFrom(PhantomData); impl> ContainsPair for NativeAssetFrom { fn contains(asset: &Asset, origin: &Location) -> bool { let loc = T::get(); - &loc == origin - && matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } + &loc == origin && + matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } if *asset_loc == Location::from(Parent)) } } diff --git a/runtime/testnet/src/extensions.rs b/runtime/testnet/src/extensions.rs index a6e309f9..fc228b03 100644 --- a/runtime/testnet/src/extensions.rs +++ b/runtime/testnet/src/extensions.rs @@ -1,7 +1,7 @@ -use frame_support::traits::{Contains, OriginTrait}; use frame_support::{ dispatch::{GetDispatchInfo, RawOrigin}, pallet_prelude::*, + traits::{Contains, OriginTrait}, }; use pallet_contracts::chain_extension::{ BufInBufOutState, ChainExtension, ChargedAmount, Environment, Ext, InitState, RetVal, diff --git a/runtime/testnet/src/lib.rs b/runtime/testnet/src/lib.rs index 5573ef18..8ba54f7f 100644 --- a/runtime/testnet/src/lib.rs +++ b/runtime/testnet/src/lib.rs @@ -240,10 +240,10 @@ impl Contains for FilteredCalls { matches!( c, RuntimeCall::Balances( - force_adjust_total_issuance { .. } - | force_set_balance { .. } - | force_transfer { .. } - | force_unreserve { .. } + force_adjust_total_issuance { .. } | + force_set_balance { .. } | + force_transfer { .. } | + force_unreserve { .. } ) ) } diff --git a/scripts/fund-dev-accounts/main.rs b/scripts/fund-dev-accounts/main.rs index 74a82b0f..8a836475 100644 --- a/scripts/fund-dev-accounts/main.rs +++ b/scripts/fund-dev-accounts/main.rs @@ -1,9 +1,8 @@ -/// As Pop Network uses the relay chain token as native, the dev accounts are not funded by default. -/// Therefore, after network launch there needs to be a reserve transfer from the relay chain -/// to the dev accounts. +/// As Pop Network uses the relay chain token as native, the dev accounts are not funded by +/// default. Therefore, after network launch there needs to be a reserve transfer from the +/// relay chain to the dev accounts. /// /// This script performs these reserve transfers to fund the dev accounts from the relay chain. -/// use subxt::{OnlineClient, PolkadotConfig}; use subxt_signer::sr25519::{dev, Keypair}; @@ -27,11 +26,9 @@ mod relay { use runtime::runtime_types::{ staging_xcm::v4::{ - asset::Fungibility::Fungible, - asset::{Asset, AssetId, Assets}, + asset::{Asset, AssetId, Assets, Fungibility::Fungible}, junction::Junction, - junctions::Junctions, - junctions::Junctions::X1, + junctions::{Junctions, Junctions::X1}, location::Location, }, xcm::{v3::WeightLimit, VersionedAssets, VersionedLocation}, @@ -81,8 +78,7 @@ mod relay { xcm::{ v3::{ junction::Junction, - junctions::Junctions, - junctions::Junctions::X1, + junctions::{Junctions, Junctions::X1}, multiasset::{ AssetId::Concrete, Fungibility::Fungible, MultiAsset as Asset, MultiAssets as Assets, diff --git a/scripts/fund-dev-accounts/paseo_interface.rs b/scripts/fund-dev-accounts/paseo_interface.rs index 5f1ff09e..0343e1fb 100644 --- a/scripts/fund-dev-accounts/paseo_interface.rs +++ b/scripts/fund-dev-accounts/paseo_interface.rs @@ -29,8 +29,7 @@ pub mod api { runtime_apis::RuntimeApi } pub mod runtime_apis { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; use ::subxt::ext::codec::Encode; pub struct RuntimeApi; impl RuntimeApi {} @@ -92,23 +91,21 @@ pub mod api { .only_these_pallets(&PALLETS) .only_these_runtime_apis(&RUNTIME_APIS) .hash(); - runtime_metadata_hash - == [ + runtime_metadata_hash == + [ 82u8, 104u8, 44u8, 240u8, 121u8, 224u8, 140u8, 145u8, 17u8, 39u8, 7u8, 69u8, 27u8, 213u8, 213u8, 74u8, 128u8, 149u8, 138u8, 190u8, 113u8, 2u8, 184u8, 74u8, 59u8, 106u8, 239u8, 75u8, 247u8, 199u8, 233u8, 255u8, ] } pub mod system { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; #[doc = "Error for the System pallet"] pub type Error = runtime_types::frame_system::pallet::Error; #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] pub type Call = runtime_types::frame_system::pallet::Call; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; type DispatchError = runtime_types::sp_runtime::DispatchError; pub mod types { use super::runtime_types; @@ -1210,15 +1207,13 @@ pub mod api { } } pub mod balances { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; #[doc = "The `Error` enum of this pallet."] pub type Error = runtime_types::pallet_balances::pallet::Error; #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] pub type Call = runtime_types::pallet_balances::pallet::Call; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; type DispatchError = runtime_types::sp_runtime::DispatchError; pub mod types { use super::runtime_types; @@ -2485,15 +2480,13 @@ pub mod api { } } pub mod utility { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; #[doc = "The `Error` enum of this pallet."] pub type Error = runtime_types::pallet_utility::pallet::Error; #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] pub type Call = runtime_types::pallet_utility::pallet::Call; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; type DispatchError = runtime_types::sp_runtime::DispatchError; pub mod types { use super::runtime_types; @@ -2891,15 +2884,13 @@ pub mod api { } } pub mod xcm_pallet { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; #[doc = "The `Error` enum of this pallet."] pub type Error = runtime_types::pallet_xcm::pallet::Error; #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] pub type Call = runtime_types::pallet_xcm::pallet::Call; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; type DispatchError = runtime_types::sp_runtime::DispatchError; pub mod types { use super::runtime_types; @@ -4688,15 +4679,13 @@ pub mod api { } } pub mod sudo { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; #[doc = "Error for the Sudo pallet"] pub type Error = runtime_types::pallet_sudo::pallet::Error; #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] pub type Call = runtime_types::pallet_sudo::pallet::Call; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; type DispatchError = runtime_types::sp_runtime::DispatchError; pub mod types { use super::runtime_types; diff --git a/scripts/fund-dev-accounts/pop_interface.rs b/scripts/fund-dev-accounts/pop_interface.rs index aaa0be92..02ef0f74 100644 --- a/scripts/fund-dev-accounts/pop_interface.rs +++ b/scripts/fund-dev-accounts/pop_interface.rs @@ -29,8 +29,7 @@ pub mod api { runtime_apis::RuntimeApi } pub mod runtime_apis { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; use ::subxt::ext::codec::Encode; pub struct RuntimeApi; impl RuntimeApi {} @@ -65,23 +64,21 @@ pub mod api { .only_these_pallets(&PALLETS) .only_these_runtime_apis(&RUNTIME_APIS) .hash(); - runtime_metadata_hash - == [ + runtime_metadata_hash == + [ 74u8, 207u8, 135u8, 96u8, 69u8, 193u8, 218u8, 235u8, 61u8, 20u8, 111u8, 118u8, 177u8, 147u8, 168u8, 117u8, 100u8, 13u8, 8u8, 14u8, 57u8, 147u8, 212u8, 238u8, 148u8, 3u8, 147u8, 143u8, 28u8, 212u8, 245u8, 53u8, ] } pub mod system { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; #[doc = "Error for the System pallet"] pub type Error = runtime_types::frame_system::pallet::Error; #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] pub type Call = runtime_types::frame_system::pallet::Call; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; type DispatchError = runtime_types::sp_runtime::DispatchError; pub mod types { use super::runtime_types; diff --git a/scripts/fund-dev-accounts/rococo_interface.rs b/scripts/fund-dev-accounts/rococo_interface.rs index 406dfcd4..91ce76fb 100644 --- a/scripts/fund-dev-accounts/rococo_interface.rs +++ b/scripts/fund-dev-accounts/rococo_interface.rs @@ -29,8 +29,7 @@ pub mod api { runtime_apis::RuntimeApi } pub mod runtime_apis { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; use ::subxt::ext::codec::Encode; pub struct RuntimeApi; impl RuntimeApi {} @@ -92,23 +91,21 @@ pub mod api { .only_these_pallets(&PALLETS) .only_these_runtime_apis(&RUNTIME_APIS) .hash(); - runtime_metadata_hash - == [ + runtime_metadata_hash == + [ 121u8, 186u8, 37u8, 30u8, 184u8, 214u8, 205u8, 84u8, 149u8, 180u8, 203u8, 113u8, 173u8, 114u8, 80u8, 174u8, 240u8, 176u8, 242u8, 3u8, 106u8, 158u8, 242u8, 132u8, 170u8, 190u8, 142u8, 252u8, 102u8, 164u8, 219u8, 83u8, ] } pub mod system { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; #[doc = "Error for the System pallet"] pub type Error = runtime_types::frame_system::pallet::Error; #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] pub type Call = runtime_types::frame_system::pallet::Call; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; type DispatchError = runtime_types::sp_runtime::DispatchError; pub mod types { use super::runtime_types; @@ -1377,15 +1374,13 @@ pub mod api { } } pub mod balances { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; #[doc = "The `Error` enum of this pallet."] pub type Error = runtime_types::pallet_balances::pallet::Error; #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] pub type Call = runtime_types::pallet_balances::pallet::Call; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; type DispatchError = runtime_types::sp_runtime::DispatchError; pub mod types { use super::runtime_types; @@ -2706,15 +2701,13 @@ pub mod api { } } pub mod utility { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; #[doc = "The `Error` enum of this pallet."] pub type Error = runtime_types::pallet_utility::pallet::Error; #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] pub type Call = runtime_types::pallet_utility::pallet::Call; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; type DispatchError = runtime_types::sp_runtime::DispatchError; pub mod types { use super::runtime_types; @@ -3112,15 +3105,13 @@ pub mod api { } } pub mod xcm_pallet { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; #[doc = "The `Error` enum of this pallet."] pub type Error = runtime_types::pallet_xcm::pallet::Error; #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] pub type Call = runtime_types::pallet_xcm::pallet::Call; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; type DispatchError = runtime_types::sp_runtime::DispatchError; pub mod types { use super::runtime_types; @@ -4990,15 +4981,13 @@ pub mod api { } } pub mod sudo { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; #[doc = "Error for the Sudo pallet."] pub type Error = runtime_types::pallet_sudo::pallet::Error; #[doc = "Contains a variant per dispatchable extrinsic that this pallet has."] pub type Call = runtime_types::pallet_sudo::pallet::Call; pub mod calls { - use super::root_mod; - use super::runtime_types; + use super::{root_mod, runtime_types}; type DispatchError = runtime_types::sp_runtime::DispatchError; pub mod types { use super::runtime_types; From 1bb23d33fa650202972327db918a42b953c8907f Mon Sep 17 00:00:00 2001 From: tin-snowflake <56880684+chungquantin@users.noreply.github.com> Date: Tue, 23 Jul 2024 16:17:50 +0700 Subject: [PATCH 02/22] stable channel format --- pop-api/integration-tests/src/lib.rs | 3 +- .../integration-tests/src/local_fungibles.rs | 19 ++- runtime/devnet/src/config/proxy.rs | 108 +++++++++--------- runtime/devnet/src/config/xcm.rs | 4 +- runtime/devnet/src/extensions/mod.rs | 15 ++- runtime/devnet/src/lib.rs | 14 +-- runtime/testnet/src/config/proxy.rs | 108 +++++++++--------- runtime/testnet/src/config/xcm.rs | 4 +- runtime/testnet/src/lib.rs | 8 +- scripts/fund-dev-accounts/paseo_interface.rs | 4 +- scripts/fund-dev-accounts/pop_interface.rs | 4 +- scripts/fund-dev-accounts/rococo_interface.rs | 4 +- 12 files changed, 157 insertions(+), 138 deletions(-) diff --git a/pop-api/integration-tests/src/lib.rs b/pop-api/integration-tests/src/lib.rs index ea5ccb05..0e8140c0 100644 --- a/pop-api/integration-tests/src/lib.rs +++ b/pop-api/integration-tests/src/lib.rs @@ -23,6 +23,7 @@ type Balance = u128; const ALICE: AccountId32 = AccountId32::new([1_u8; 32]); const BOB: AccountId32 = AccountId32::new([2_u8; 32]); +const CHARLIE: AccountId32 = AccountId32::new([3_u8; 32]); const DEBUG_OUTPUT: pallet_contracts::DebugInfo = pallet_contracts::DebugInfo::UnsafeDebug; // FERDIE has no initial balance. const FERDIE: AccountId32 = AccountId32::new([3_u8; 32]); @@ -36,7 +37,7 @@ fn new_test_ext() -> sp_io::TestExternalities { .expect("Frame system builds valid default genesis config"); pallet_balances::GenesisConfig:: { - balances: vec![(ALICE, INIT_AMOUNT), (BOB, INIT_AMOUNT)], + balances: vec![(ALICE, INIT_AMOUNT), (BOB, INIT_AMOUNT), (CHARLIE, INIT_AMOUNT)], } .assimilate_storage(&mut t) .expect("Pallet balances storage can be assimilated"); diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index ba72da18..2a4fd5eb 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -386,12 +386,27 @@ fn transfer_from_works() { let _ = env_logger::try_init(); let addr = instantiate("contracts/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); let amount: Balance = 100 * UNIT; - // TODO: Add approval process and finalize the integration test + + // Allow CHARLIE to spend `amount` owned by ALICE + create_asset_mint_and_approve( + addr.clone(), + ASSET_ID, + ALICE, + amount * 2, + CHARLIE, + amount * 2, + ); + assert_eq!( + Assets::allowance(ASSET_ID, &ALICE, &CHARLIE), + allowance(addr.clone(), ASSET_ID, ALICE, CHARLIE) + ); + // Asset does not exist. assert_eq!( - decoded::(transfer_from(addr.clone(), 1, ALICE, BOB, amount,)), + decoded::(transfer_from(addr.clone(), 1, CHARLIE, BOB, amount,)), Module { index: 52, error: 3 }, ); + // Create asset with Alice as owner and mint `amount` to contract address. let asset = create_asset_and_mint_to(ALICE, 1, addr.clone(), amount); // Asset is not live, i.e. frozen or being destroyed. diff --git a/runtime/devnet/src/config/proxy.rs b/runtime/devnet/src/config/proxy.rs index c1142126..07d5f0f8 100644 --- a/runtime/devnet/src/config/proxy.rs +++ b/runtime/devnet/src/config/proxy.rs @@ -13,77 +13,77 @@ impl InstanceFilter for ProxyType { ProxyType::Any => true, ProxyType::NonTransfer => !matches!( c, - RuntimeCall::Balances { .. } | - RuntimeCall::Assets { .. } | - RuntimeCall::Nfts { .. } + RuntimeCall::Balances { .. } + | RuntimeCall::Assets { .. } + | RuntimeCall::Nfts { .. } ), ProxyType::CancelProxy => matches!( c, - RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) | - RuntimeCall::Utility { .. } | - RuntimeCall::Multisig { .. } + RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) + | RuntimeCall::Utility { .. } + | RuntimeCall::Multisig { .. } ), ProxyType::Assets => { matches!( c, - RuntimeCall::Assets { .. } | - RuntimeCall::Utility { .. } | - RuntimeCall::Multisig { .. } | - RuntimeCall::Nfts { .. } + RuntimeCall::Assets { .. } + | RuntimeCall::Utility { .. } + | RuntimeCall::Multisig { .. } + | RuntimeCall::Nfts { .. } ) }, ProxyType::AssetOwner => matches!( c, - RuntimeCall::Assets(AssetsCall::create { .. }) | - RuntimeCall::Assets(AssetsCall::start_destroy { .. }) | - RuntimeCall::Assets(AssetsCall::destroy_accounts { .. }) | - RuntimeCall::Assets(AssetsCall::destroy_approvals { .. }) | - RuntimeCall::Assets(AssetsCall::finish_destroy { .. }) | - RuntimeCall::Assets(AssetsCall::transfer_ownership { .. }) | - RuntimeCall::Assets(AssetsCall::set_team { .. }) | - RuntimeCall::Assets(AssetsCall::set_metadata { .. }) | - RuntimeCall::Assets(AssetsCall::clear_metadata { .. }) | - RuntimeCall::Assets(AssetsCall::set_min_balance { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::transfer_ownership { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::set_team { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::set_collection_max_supply { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::lock_collection { .. }) | - RuntimeCall::Utility { .. } | - RuntimeCall::Multisig { .. } + RuntimeCall::Assets(AssetsCall::create { .. }) + | RuntimeCall::Assets(AssetsCall::start_destroy { .. }) + | RuntimeCall::Assets(AssetsCall::destroy_accounts { .. }) + | RuntimeCall::Assets(AssetsCall::destroy_approvals { .. }) + | RuntimeCall::Assets(AssetsCall::finish_destroy { .. }) + | RuntimeCall::Assets(AssetsCall::transfer_ownership { .. }) + | RuntimeCall::Assets(AssetsCall::set_team { .. }) + | RuntimeCall::Assets(AssetsCall::set_metadata { .. }) + | RuntimeCall::Assets(AssetsCall::clear_metadata { .. }) + | RuntimeCall::Assets(AssetsCall::set_min_balance { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::transfer_ownership { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::set_team { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::set_collection_max_supply { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::lock_collection { .. }) + | RuntimeCall::Utility { .. } + | RuntimeCall::Multisig { .. } ), ProxyType::AssetManager => matches!( c, - RuntimeCall::Assets(AssetsCall::mint { .. }) | - RuntimeCall::Assets(AssetsCall::burn { .. }) | - RuntimeCall::Assets(AssetsCall::freeze { .. }) | - RuntimeCall::Assets(AssetsCall::block { .. }) | - RuntimeCall::Assets(AssetsCall::thaw { .. }) | - RuntimeCall::Assets(AssetsCall::freeze_asset { .. }) | - RuntimeCall::Assets(AssetsCall::thaw_asset { .. }) | - RuntimeCall::Assets(AssetsCall::touch_other { .. }) | - RuntimeCall::Assets(AssetsCall::refund_other { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::set_attributes_pre_signed { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::lock_item_transfer { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::unlock_item_transfer { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::lock_item_properties { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::set_metadata { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::clear_metadata { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::set_collection_metadata { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::clear_collection_metadata { .. }) | - RuntimeCall::Utility { .. } | - RuntimeCall::Multisig { .. } + RuntimeCall::Assets(AssetsCall::mint { .. }) + | RuntimeCall::Assets(AssetsCall::burn { .. }) + | RuntimeCall::Assets(AssetsCall::freeze { .. }) + | RuntimeCall::Assets(AssetsCall::block { .. }) + | RuntimeCall::Assets(AssetsCall::thaw { .. }) + | RuntimeCall::Assets(AssetsCall::freeze_asset { .. }) + | RuntimeCall::Assets(AssetsCall::thaw_asset { .. }) + | RuntimeCall::Assets(AssetsCall::touch_other { .. }) + | RuntimeCall::Assets(AssetsCall::refund_other { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::set_attributes_pre_signed { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::lock_item_transfer { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::unlock_item_transfer { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::lock_item_properties { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::set_metadata { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::clear_metadata { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::set_collection_metadata { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::clear_collection_metadata { .. }) + | RuntimeCall::Utility { .. } + | RuntimeCall::Multisig { .. } ), ProxyType::Collator => matches!( c, - RuntimeCall::CollatorSelection { .. } | - RuntimeCall::Utility { .. } | - RuntimeCall::Multisig { .. } + RuntimeCall::CollatorSelection { .. } + | RuntimeCall::Utility { .. } + | RuntimeCall::Multisig { .. } ), } } diff --git a/runtime/devnet/src/config/xcm.rs b/runtime/devnet/src/config/xcm.rs index 303cfd32..a210f7a4 100644 --- a/runtime/devnet/src/config/xcm.rs +++ b/runtime/devnet/src/config/xcm.rs @@ -115,8 +115,8 @@ pub struct NativeAssetFrom(PhantomData); impl> ContainsPair for NativeAssetFrom { fn contains(asset: &Asset, origin: &Location) -> bool { let loc = T::get(); - &loc == origin && - matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } + &loc == origin + && matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } if *asset_loc == Location::from(Parent)) } } diff --git a/runtime/devnet/src/extensions/mod.rs b/runtime/devnet/src/extensions/mod.rs index e01a3683..1e765184 100644 --- a/runtime/devnet/src/extensions/mod.rs +++ b/runtime/devnet/src/extensions/mod.rs @@ -75,10 +75,12 @@ where let params = env.read(len)?; log::debug!(target: LOG_TARGET, "Read input successfully"); match function_id { - FuncId::Dispatch => - dispatch::(&mut env, version, pallet_index, call_index, params), - FuncId::ReadState => - read_state::(&mut env, version, pallet_index, call_index, params), + FuncId::Dispatch => { + dispatch::(&mut env, version, pallet_index, call_index, params) + }, + FuncId::ReadState => { + read_state::(&mut env, version, pallet_index, call_index, params) + }, } }, Err(e) => Err(e), @@ -296,8 +298,9 @@ where match key { TotalSupply(id) => Ok(fungibles::Pallet::::total_supply(id).encode()), BalanceOf(id, owner) => Ok(fungibles::Pallet::::balance_of(id, &owner).encode()), - Allowance(id, owner, spender) => - Ok(fungibles::Pallet::::allowance(id, &owner, &spender).encode()), + Allowance(id, owner, spender) => { + Ok(fungibles::Pallet::::allowance(id, &owner, &spender).encode()) + }, TokenName(id) => Ok(fungibles::Pallet::::token_name(id).encode()), TokenSymbol(id) => Ok(fungibles::Pallet::::token_symbol(id).encode()), TokenDecimals(id) => Ok(fungibles::Pallet::::token_decimals(id).encode()), diff --git a/runtime/devnet/src/lib.rs b/runtime/devnet/src/lib.rs index 8c8be97f..4d4ffc7c 100644 --- a/runtime/devnet/src/lib.rs +++ b/runtime/devnet/src/lib.rs @@ -243,10 +243,10 @@ impl Contains for FilteredCalls { matches!( c, RuntimeCall::Balances( - force_adjust_total_issuance { .. } | - force_set_balance { .. } | - force_transfer { .. } | - force_unreserve { .. } + force_adjust_total_issuance { .. } + | force_set_balance { .. } + | force_transfer { .. } + | force_unreserve { .. } ) ) } @@ -260,9 +260,9 @@ impl Contains for AllowedApiCalls { matches!( c, RuntimeCall::Fungibles( - FungiblesCall::transfer { .. } | - FungiblesCall::approve { .. } | - FungiblesCall::increase_allowance { .. } + FungiblesCall::transfer { .. } + | FungiblesCall::approve { .. } + | FungiblesCall::increase_allowance { .. } ) ) } diff --git a/runtime/testnet/src/config/proxy.rs b/runtime/testnet/src/config/proxy.rs index c1142126..07d5f0f8 100644 --- a/runtime/testnet/src/config/proxy.rs +++ b/runtime/testnet/src/config/proxy.rs @@ -13,77 +13,77 @@ impl InstanceFilter for ProxyType { ProxyType::Any => true, ProxyType::NonTransfer => !matches!( c, - RuntimeCall::Balances { .. } | - RuntimeCall::Assets { .. } | - RuntimeCall::Nfts { .. } + RuntimeCall::Balances { .. } + | RuntimeCall::Assets { .. } + | RuntimeCall::Nfts { .. } ), ProxyType::CancelProxy => matches!( c, - RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) | - RuntimeCall::Utility { .. } | - RuntimeCall::Multisig { .. } + RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) + | RuntimeCall::Utility { .. } + | RuntimeCall::Multisig { .. } ), ProxyType::Assets => { matches!( c, - RuntimeCall::Assets { .. } | - RuntimeCall::Utility { .. } | - RuntimeCall::Multisig { .. } | - RuntimeCall::Nfts { .. } + RuntimeCall::Assets { .. } + | RuntimeCall::Utility { .. } + | RuntimeCall::Multisig { .. } + | RuntimeCall::Nfts { .. } ) }, ProxyType::AssetOwner => matches!( c, - RuntimeCall::Assets(AssetsCall::create { .. }) | - RuntimeCall::Assets(AssetsCall::start_destroy { .. }) | - RuntimeCall::Assets(AssetsCall::destroy_accounts { .. }) | - RuntimeCall::Assets(AssetsCall::destroy_approvals { .. }) | - RuntimeCall::Assets(AssetsCall::finish_destroy { .. }) | - RuntimeCall::Assets(AssetsCall::transfer_ownership { .. }) | - RuntimeCall::Assets(AssetsCall::set_team { .. }) | - RuntimeCall::Assets(AssetsCall::set_metadata { .. }) | - RuntimeCall::Assets(AssetsCall::clear_metadata { .. }) | - RuntimeCall::Assets(AssetsCall::set_min_balance { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::transfer_ownership { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::set_team { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::set_collection_max_supply { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::lock_collection { .. }) | - RuntimeCall::Utility { .. } | - RuntimeCall::Multisig { .. } + RuntimeCall::Assets(AssetsCall::create { .. }) + | RuntimeCall::Assets(AssetsCall::start_destroy { .. }) + | RuntimeCall::Assets(AssetsCall::destroy_accounts { .. }) + | RuntimeCall::Assets(AssetsCall::destroy_approvals { .. }) + | RuntimeCall::Assets(AssetsCall::finish_destroy { .. }) + | RuntimeCall::Assets(AssetsCall::transfer_ownership { .. }) + | RuntimeCall::Assets(AssetsCall::set_team { .. }) + | RuntimeCall::Assets(AssetsCall::set_metadata { .. }) + | RuntimeCall::Assets(AssetsCall::clear_metadata { .. }) + | RuntimeCall::Assets(AssetsCall::set_min_balance { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::create { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::destroy { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::redeposit { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::transfer_ownership { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::set_team { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::set_collection_max_supply { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::lock_collection { .. }) + | RuntimeCall::Utility { .. } + | RuntimeCall::Multisig { .. } ), ProxyType::AssetManager => matches!( c, - RuntimeCall::Assets(AssetsCall::mint { .. }) | - RuntimeCall::Assets(AssetsCall::burn { .. }) | - RuntimeCall::Assets(AssetsCall::freeze { .. }) | - RuntimeCall::Assets(AssetsCall::block { .. }) | - RuntimeCall::Assets(AssetsCall::thaw { .. }) | - RuntimeCall::Assets(AssetsCall::freeze_asset { .. }) | - RuntimeCall::Assets(AssetsCall::thaw_asset { .. }) | - RuntimeCall::Assets(AssetsCall::touch_other { .. }) | - RuntimeCall::Assets(AssetsCall::refund_other { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::set_attributes_pre_signed { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::lock_item_transfer { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::unlock_item_transfer { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::lock_item_properties { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::set_metadata { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::clear_metadata { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::set_collection_metadata { .. }) | - RuntimeCall::Nfts(pallet_nfts::Call::clear_collection_metadata { .. }) | - RuntimeCall::Utility { .. } | - RuntimeCall::Multisig { .. } + RuntimeCall::Assets(AssetsCall::mint { .. }) + | RuntimeCall::Assets(AssetsCall::burn { .. }) + | RuntimeCall::Assets(AssetsCall::freeze { .. }) + | RuntimeCall::Assets(AssetsCall::block { .. }) + | RuntimeCall::Assets(AssetsCall::thaw { .. }) + | RuntimeCall::Assets(AssetsCall::freeze_asset { .. }) + | RuntimeCall::Assets(AssetsCall::thaw_asset { .. }) + | RuntimeCall::Assets(AssetsCall::touch_other { .. }) + | RuntimeCall::Assets(AssetsCall::refund_other { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::force_mint { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::update_mint_settings { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::mint_pre_signed { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::set_attributes_pre_signed { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::lock_item_transfer { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::unlock_item_transfer { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::lock_item_properties { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::set_metadata { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::clear_metadata { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::set_collection_metadata { .. }) + | RuntimeCall::Nfts(pallet_nfts::Call::clear_collection_metadata { .. }) + | RuntimeCall::Utility { .. } + | RuntimeCall::Multisig { .. } ), ProxyType::Collator => matches!( c, - RuntimeCall::CollatorSelection { .. } | - RuntimeCall::Utility { .. } | - RuntimeCall::Multisig { .. } + RuntimeCall::CollatorSelection { .. } + | RuntimeCall::Utility { .. } + | RuntimeCall::Multisig { .. } ), } } diff --git a/runtime/testnet/src/config/xcm.rs b/runtime/testnet/src/config/xcm.rs index 303cfd32..a210f7a4 100644 --- a/runtime/testnet/src/config/xcm.rs +++ b/runtime/testnet/src/config/xcm.rs @@ -115,8 +115,8 @@ pub struct NativeAssetFrom(PhantomData); impl> ContainsPair for NativeAssetFrom { fn contains(asset: &Asset, origin: &Location) -> bool { let loc = T::get(); - &loc == origin && - matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } + &loc == origin + && matches!(asset, Asset { id: AssetId(asset_loc), fun: Fungible(_a) } if *asset_loc == Location::from(Parent)) } } diff --git a/runtime/testnet/src/lib.rs b/runtime/testnet/src/lib.rs index 8ba54f7f..5573ef18 100644 --- a/runtime/testnet/src/lib.rs +++ b/runtime/testnet/src/lib.rs @@ -240,10 +240,10 @@ impl Contains for FilteredCalls { matches!( c, RuntimeCall::Balances( - force_adjust_total_issuance { .. } | - force_set_balance { .. } | - force_transfer { .. } | - force_unreserve { .. } + force_adjust_total_issuance { .. } + | force_set_balance { .. } + | force_transfer { .. } + | force_unreserve { .. } ) ) } diff --git a/scripts/fund-dev-accounts/paseo_interface.rs b/scripts/fund-dev-accounts/paseo_interface.rs index 0343e1fb..f6d2e101 100644 --- a/scripts/fund-dev-accounts/paseo_interface.rs +++ b/scripts/fund-dev-accounts/paseo_interface.rs @@ -91,8 +91,8 @@ pub mod api { .only_these_pallets(&PALLETS) .only_these_runtime_apis(&RUNTIME_APIS) .hash(); - runtime_metadata_hash == - [ + runtime_metadata_hash + == [ 82u8, 104u8, 44u8, 240u8, 121u8, 224u8, 140u8, 145u8, 17u8, 39u8, 7u8, 69u8, 27u8, 213u8, 213u8, 74u8, 128u8, 149u8, 138u8, 190u8, 113u8, 2u8, 184u8, 74u8, 59u8, 106u8, 239u8, 75u8, 247u8, 199u8, 233u8, 255u8, diff --git a/scripts/fund-dev-accounts/pop_interface.rs b/scripts/fund-dev-accounts/pop_interface.rs index 02ef0f74..f6416c2f 100644 --- a/scripts/fund-dev-accounts/pop_interface.rs +++ b/scripts/fund-dev-accounts/pop_interface.rs @@ -64,8 +64,8 @@ pub mod api { .only_these_pallets(&PALLETS) .only_these_runtime_apis(&RUNTIME_APIS) .hash(); - runtime_metadata_hash == - [ + runtime_metadata_hash + == [ 74u8, 207u8, 135u8, 96u8, 69u8, 193u8, 218u8, 235u8, 61u8, 20u8, 111u8, 118u8, 177u8, 147u8, 168u8, 117u8, 100u8, 13u8, 8u8, 14u8, 57u8, 147u8, 212u8, 238u8, 148u8, 3u8, 147u8, 143u8, 28u8, 212u8, 245u8, 53u8, diff --git a/scripts/fund-dev-accounts/rococo_interface.rs b/scripts/fund-dev-accounts/rococo_interface.rs index 91ce76fb..54a1ad53 100644 --- a/scripts/fund-dev-accounts/rococo_interface.rs +++ b/scripts/fund-dev-accounts/rococo_interface.rs @@ -91,8 +91,8 @@ pub mod api { .only_these_pallets(&PALLETS) .only_these_runtime_apis(&RUNTIME_APIS) .hash(); - runtime_metadata_hash == - [ + runtime_metadata_hash + == [ 121u8, 186u8, 37u8, 30u8, 184u8, 214u8, 205u8, 84u8, 149u8, 180u8, 203u8, 113u8, 173u8, 114u8, 80u8, 174u8, 240u8, 176u8, 242u8, 3u8, 106u8, 158u8, 242u8, 132u8, 170u8, 190u8, 142u8, 252u8, 102u8, 164u8, 219u8, 83u8, From 4b2b9dab658b651447994ed95bc72b8a599f7981 Mon Sep 17 00:00:00 2001 From: tin-snowflake <56880684+chungquantin@users.noreply.github.com> Date: Tue, 23 Jul 2024 17:56:34 +0700 Subject: [PATCH 03/22] fix: integration test for transfer --- pop-api/integration-tests/src/lib.rs | 15 +++- .../integration-tests/src/local_fungibles.rs | 77 ++++++------------- 2 files changed, 35 insertions(+), 57 deletions(-) diff --git a/pop-api/integration-tests/src/lib.rs b/pop-api/integration-tests/src/lib.rs index 0e8140c0..51d429cc 100644 --- a/pop-api/integration-tests/src/lib.rs +++ b/pop-api/integration-tests/src/lib.rs @@ -26,7 +26,7 @@ const BOB: AccountId32 = AccountId32::new([2_u8; 32]); const CHARLIE: AccountId32 = AccountId32::new([3_u8; 32]); const DEBUG_OUTPUT: pallet_contracts::DebugInfo = pallet_contracts::DebugInfo::UnsafeDebug; // FERDIE has no initial balance. -const FERDIE: AccountId32 = AccountId32::new([3_u8; 32]); +const FERDIE: AccountId32 = AccountId32::new([99_u8; 32]); const GAS_LIMIT: Weight = Weight::from_parts(100_000_000_000, 3 * 1024 * 1024); const INIT_AMOUNT: Balance = 100_000_000 * UNIT; const INIT_VALUE: Balance = 100 * UNIT; @@ -61,13 +61,14 @@ fn function_selector(name: &str) -> Vec { [hash[0..4].to_vec()].concat() } -fn bare_call( +fn bare_call_by( addr: AccountId32, + caller: AccountId32, input: Vec, value: u128, ) -> Result { let result = Contracts::bare_call( - ALICE, + caller, addr.into(), value.into(), GAS_LIMIT, @@ -80,6 +81,14 @@ fn bare_call( result.result } +fn bare_call( + addr: AccountId32, + input: Vec, + value: u128, +) -> Result { + bare_call_by(addr, ALICE, input, value) +} + // Deploy, instantiate and return contract address. fn instantiate(contract: &str, init_value: u128, salt: Vec) -> AccountId32 { let (wasm_binary, _) = diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index 2a4fd5eb..cb509d17 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -4,6 +4,7 @@ use primitives::error::{ Error::{self, *}, TokenError::*, }; +use std::result::Result; const ASSET_ID: AssetId = 1; @@ -14,6 +15,11 @@ fn decoded(result: ExecReturnValue) -> T { } } +fn checked_decoded(result: ExecReturnValue) -> Result { + ::decode(&mut &result.data[2..]) + .map_err(|_| format!("Test failed by trying to decode `{:?}` into `T`", result).to_string()) +} + // Call total_supply contract message. fn total_supply(addr: AccountId32, asset_id: AssetId) -> Balance { let function = function_selector("total_supply"); @@ -81,6 +87,7 @@ fn transfer( fn transfer_from( addr: AccountId32, + spender: AccountId32, asset_id: AssetId, from: AccountId32, to: AccountId32, @@ -88,7 +95,7 @@ fn transfer_from( ) -> ExecReturnValue { let function = function_selector("transfer_from"); let params = [function, asset_id.encode(), from.encode(), to.encode(), value.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); + let result = bare_call_by(addr, spender, params, 0).expect("should work"); result } @@ -185,7 +192,7 @@ fn create_asset_mint_and_approve( mint: Balance, spender: AccountId32, approve: Balance, -) { +) -> AssetId { create_asset_and_mint_to(owner.clone(), asset_id, to.clone(), mint); assert_ok!(Assets::approve_transfer( RuntimeOrigin::signed(to.into()), @@ -193,6 +200,7 @@ fn create_asset_mint_and_approve( spender.into(), approve, )); + asset_id } // Freeze an asset. @@ -388,7 +396,7 @@ fn transfer_from_works() { let amount: Balance = 100 * UNIT; // Allow CHARLIE to spend `amount` owned by ALICE - create_asset_mint_and_approve( + let asset_id = create_asset_mint_and_approve( addr.clone(), ASSET_ID, ALICE, @@ -397,59 +405,20 @@ fn transfer_from_works() { amount * 2, ); assert_eq!( - Assets::allowance(ASSET_ID, &ALICE, &CHARLIE), - allowance(addr.clone(), ASSET_ID, ALICE, CHARLIE) - ); - - // Asset does not exist. - assert_eq!( - decoded::(transfer_from(addr.clone(), 1, CHARLIE, BOB, amount,)), - Module { index: 52, error: 3 }, - ); - - // Create asset with Alice as owner and mint `amount` to contract address. - let asset = create_asset_and_mint_to(ALICE, 1, addr.clone(), amount); - // Asset is not live, i.e. frozen or being destroyed. - freeze_asset(ALICE, asset); - assert_eq!( - decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount,)), - Module { index: 52, error: 16 }, - ); - thaw_asset(ALICE, asset); - // Not enough balance. - assert_eq!( - decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount + 1 * UNIT)), - Module { index: 52, error: 0 }, - ); - // Not enough balance due to ED. - assert_eq!( - decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount)), - Module { index: 52, error: 0 }, + Assets::allowance(asset_id, &ALICE, &CHARLIE), + allowance(addr.clone(), asset_id, ALICE, CHARLIE) ); - // Successful transfer. - let alice_balance_before_transfer = Assets::balance(asset, &ALICE); - let bob_balance_before_transfer = Assets::balance(asset, &BOB); + assert_eq!(allowance(addr.clone(), asset_id, ALICE, CHARLIE), amount * 2); - let result = transfer_from(addr.clone(), asset, ALICE, BOB, amount / 2); - assert!(!result.did_revert(), "Contract reverted!"); - - let alice_balance_after_transfer = Assets::balance(asset, &BOB); - let bob_balance_after_transfer = Assets::balance(asset, &BOB); - - assert_eq!(bob_balance_after_transfer, bob_balance_before_transfer + amount / 2); - assert_eq!(alice_balance_after_transfer, alice_balance_before_transfer - amount / 2); - - // Transfer asset to account that does not exist. - assert_eq!( - decoded::(transfer_from(addr.clone(), asset, ALICE, FERDIE, amount / 4)), - Token(CannotCreate) - ); - // Asset is not live, i.e. frozen or being destroyed. - start_destroy_asset(ALICE, asset); - assert_eq!( - decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount / 4)), - Module { index: 52, error: 16 }, - ); + // Successfully transfer + assert_ok!(checked_decoded::(transfer_from( + addr.clone(), + CHARLIE, + asset_id, + ALICE, + BOB, + amount * 2, + ))); }); } From ff0f3e89ae7ccc9915a4aca57502ec5b15c9920f Mon Sep 17 00:00:00 2001 From: tin-snowflake <56880684+chungquantin@users.noreply.github.com> Date: Tue, 23 Jul 2024 18:38:04 +0700 Subject: [PATCH 04/22] implement decrease_allowance --- pallets/api/src/fungibles/mod.rs | 63 ++++++++++++++++--- pallets/api/src/fungibles/tests.rs | 17 +++++ .../integration-tests/src/local_fungibles.rs | 12 ++++ 3 files changed, 83 insertions(+), 9 deletions(-) diff --git a/pallets/api/src/fungibles/mod.rs b/pallets/api/src/fungibles/mod.rs index 00565863..e0213230 100644 --- a/pallets/api/src/fungibles/mod.rs +++ b/pallets/api/src/fungibles/mod.rs @@ -17,7 +17,10 @@ pub mod pallet { }; use frame_system::pallet_prelude::*; use pallet_assets::WeightInfo; - use sp_runtime::{traits::StaticLookup, Saturating}; + use sp_runtime::{ + traits::{StaticLookup, Zero}, + Saturating, + }; use sp_std::vec::Vec; pub(crate) type AccountIdOf = ::AccountId; @@ -26,6 +29,7 @@ pub mod pallet { >>::AssetId; type AssetIdParameterOf = >>::AssetIdParameter; + type AccountIdLookupOf = <::Lookup as StaticLookup>::Source; type Assets = pallet_assets::Pallet>; type AssetsInstanceOf = ::AssetsInstance; type AssetsWeightInfo = >>::WeightInfo; @@ -148,14 +152,7 @@ pub mod pallet { } else { // If the new value is less than the current allowance, cancel the approval and set // the new value - Assets::::cancel_approval(origin.clone(), id.clone(), spender.clone()).map_err( - |e| { - e.with_weight( - T::DbWeight::get().reads(2) + AssetsWeightInfo::::cancel_approval(), - ) - }, - )?; - Assets::::approve_transfer(origin, id, spender, value)?; + Self::do_set_allowance(origin, id, spender, value)?; } Ok(().into()) @@ -181,6 +178,34 @@ pub mod pallet { let spender = T::Lookup::unlookup(spender); Assets::::approve_transfer(origin, id.into(), spender, value) } + + /// Decreases the allowance of a spender. + /// + /// # Arguments + /// * `id` - The ID of the asset. + /// * `spender` - The account that is allowed to spend the tokens. + /// * `value` - The number of tokens to decrease the allowance by. + /// + /// # Returns + /// Returns `Ok(())` if successful, or an error if the operation fails. + #[pallet::call_index(4)] + #[pallet::weight(T::DbWeight::get().reads(2) + AssetsWeightInfo::::cancel_approval() + AssetsWeightInfo::::approve_transfer())] + pub fn decrease_allowance( + origin: OriginFor, + id: AssetIdOf, + spender: AccountIdOf, + value: BalanceOf, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin.clone()) + .map_err(|e| e.with_weight(T::DbWeight::get().reads(1)))?; + let mut current_allowance = Assets::::allowance(id.clone(), &who, &spender); + let spender = T::Lookup::unlookup(spender); + let id: AssetIdParameterOf = id.into(); + + current_allowance.saturating_reduce(value); + Self::do_set_allowance(origin, id, spender, current_allowance)?; + Ok(().into()) + } } impl Pallet { @@ -259,5 +284,25 @@ pub mod pallet { pub fn token_decimals(id: AssetIdOf) -> u8 { as MetadataInspect>>::decimals(id) } + + /// Set the allowance `value` of the `spender` delegated by `origin` + pub(crate) fn do_set_allowance( + origin: OriginFor, + id: AssetIdParameterOf, + spender: AccountIdLookupOf, + value: BalanceOf, + ) -> DispatchResultWithPostInfo { + Assets::::cancel_approval(origin.clone(), id.clone(), spender.clone()).map_err( + |e| { + e.with_weight( + T::DbWeight::get().reads(2) + AssetsWeightInfo::::cancel_approval(), + ) + }, + )?; + if value > Zero::zero() { + Assets::::approve_transfer(origin, id, spender, value)?; + } + Ok(().into()) + } } } diff --git a/pallets/api/src/fungibles/tests.rs b/pallets/api/src/fungibles/tests.rs index a0e8a1f2..920c5fcc 100644 --- a/pallets/api/src/fungibles/tests.rs +++ b/pallets/api/src/fungibles/tests.rs @@ -97,6 +97,23 @@ fn increase_allowance_works() { }); } +#[test] +fn decrease_allowance_works() { + new_test_ext().execute_with(|| { + let amount: Balance = 100 * UNIT; + create_asset_and_mint_to(ALICE, ASSET, ALICE, amount); + assert_ok!(Fungibles::increase_allowance(signed(ALICE), ASSET, BOB, amount)); + assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount); + + assert_ok!(Fungibles::decrease_allowance(signed(ALICE), ASSET, BOB, amount / 2)); + assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount / 2); + + // Saturating if the allowance value is already zeros + assert_ok!(Fungibles::decrease_allowance(signed(ALICE), ASSET, BOB, amount / 2 + 1 * UNIT)); + assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), 0); + }); +} + #[test] fn total_supply_works() { new_test_ext().execute_with(|| { diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index cb509d17..500cdf8d 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -123,6 +123,18 @@ fn increase_allowance( result } +fn decrease_allowance( + addr: AccountId32, + asset_id: AssetId, + spender: AccountId32, + value: Balance, +) -> ExecReturnValue { + let function = function_selector("decrease_allowance"); + let params = [function, asset_id.encode(), spender.encode(), value.encode()].concat(); + let result = bare_call(addr, params, 0).expect("should work"); + result +} + // fn asset_exists(addr: AccountId32, asset_id: AssetId) -> bool { // let function = function_selector("asset_exists"); // let params = [function, asset_id.encode()].concat(); From 01d713d0692b869557c22491064ec2a2c2f4fb95 Mon Sep 17 00:00:00 2001 From: tin-snowflake <56880684+chungquantin@users.noreply.github.com> Date: Tue, 23 Jul 2024 19:13:05 +0700 Subject: [PATCH 05/22] test: add contract integration test --- pop-api/integration-tests/src/local_fungibles.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index 500cdf8d..a0f412ce 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -423,6 +423,7 @@ fn transfer_from_works() { assert_eq!(allowance(addr.clone(), asset_id, ALICE, CHARLIE), amount * 2); // Successfully transfer + // TODO: Fix assert_ok!(checked_decoded::(transfer_from( addr.clone(), CHARLIE, @@ -525,6 +526,21 @@ fn increase_allowance_works() { }); } +#[test] +fn decrease_allowance_works() { + new_test_ext().execute_with(|| { + let _ = env_logger::try_init(); + let addr = instantiate("contracts/fungibles/target/ink/fungibles.wasm", 0, vec![]); + let amount: Balance = 100 * UNIT; + // Asset does not exist. + // TODO: Fix + assert_eq!( + checked_decoded::(decrease_allowance(addr.clone(), 0, BOB, amount)), + Ok(Module { index: 52, error: 3 }), + ); + }); +} + /// 2. PSP-22 Metadata Interface: /// - token_name /// - token_symbol From 7eed7b427c2651f022425a874f697e4aff1dbe32 Mon Sep 17 00:00:00 2001 From: tin-snowflake <56880684+chungquantin@users.noreply.github.com> Date: Tue, 23 Jul 2024 19:52:04 +0700 Subject: [PATCH 06/22] update devnet extension --- .../integration-tests/src/local_fungibles.rs | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index a0f412ce..6b0a0191 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -87,7 +87,6 @@ fn transfer( fn transfer_from( addr: AccountId32, - spender: AccountId32, asset_id: AssetId, from: AccountId32, to: AccountId32, @@ -95,7 +94,7 @@ fn transfer_from( ) -> ExecReturnValue { let function = function_selector("transfer_from"); let params = [function, asset_id.encode(), from.encode(), to.encode(), value.encode()].concat(); - let result = bare_call_by(addr, spender, params, 0).expect("should work"); + let result = bare_call(addr, params, 0).expect("should work"); result } @@ -408,30 +407,27 @@ fn transfer_from_works() { let amount: Balance = 100 * UNIT; // Allow CHARLIE to spend `amount` owned by ALICE + let delegate = addr.clone(); let asset_id = create_asset_mint_and_approve( addr.clone(), ASSET_ID, ALICE, amount * 2, - CHARLIE, + delegate.clone(), amount * 2, ); assert_eq!( - Assets::allowance(asset_id, &ALICE, &CHARLIE), - allowance(addr.clone(), asset_id, ALICE, CHARLIE) + Assets::allowance(asset_id, &ALICE, &delegate.clone()), + allowance(addr.clone(), asset_id, ALICE, delegate.clone()) ); - assert_eq!(allowance(addr.clone(), asset_id, ALICE, CHARLIE), amount * 2); + assert_eq!(allowance(addr.clone(), asset_id, ALICE, delegate.clone()), amount * 2); // Successfully transfer // TODO: Fix - assert_ok!(checked_decoded::(transfer_from( - addr.clone(), - CHARLIE, - asset_id, - ALICE, - BOB, - amount * 2, - ))); + // CHARLIE trying to send from ALICE to BOB + let result = transfer_from(addr.clone(), asset_id, ALICE, BOB, amount * 2); + assert_eq!(decoded::(result.clone()), Module { index: 52, error: 16 },); + assert!(!result.did_revert(), "Contract reverted!"); }); } From 149906a29e0e39e08378321ff86f202429e50eaf Mon Sep 17 00:00:00 2001 From: tin-snowflake <56880684+chungquantin@users.noreply.github.com> Date: Tue, 23 Jul 2024 19:57:41 +0700 Subject: [PATCH 07/22] Update lib.rs --- runtime/devnet/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/runtime/devnet/src/lib.rs b/runtime/devnet/src/lib.rs index 4d4ffc7c..7200cb72 100644 --- a/runtime/devnet/src/lib.rs +++ b/runtime/devnet/src/lib.rs @@ -261,8 +261,10 @@ impl Contains for AllowedApiCalls { c, RuntimeCall::Fungibles( FungiblesCall::transfer { .. } + | FungiblesCall::transfer_from { .. } | FungiblesCall::approve { .. } | FungiblesCall::increase_allowance { .. } + | FungiblesCall::decrease_allowance { .. } ) ) } From 9d2276cb474d206910d50ed2e46014864155ef33 Mon Sep 17 00:00:00 2001 From: Daanvdplas Date: Tue, 23 Jul 2024 14:51:50 +0200 Subject: [PATCH 08/22] chore: benchmark approve --- pallets/api/Cargo.toml | 2 + pallets/api/src/fungibles/benchmarking.rs | 60 +++++++++++++++++++++++ pallets/api/src/fungibles/mod.rs | 13 +++-- 3 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 pallets/api/src/fungibles/benchmarking.rs diff --git a/pallets/api/Cargo.toml b/pallets/api/Cargo.toml index 3f462a55..4ad921dc 100644 --- a/pallets/api/Cargo.toml +++ b/pallets/api/Cargo.toml @@ -33,6 +33,8 @@ runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", + "pallet-assets/runtime-benchmarks", + "pallet-balances/runtime-benchmarks", "sp-runtime/runtime-benchmarks", ] std = [ diff --git a/pallets/api/src/fungibles/benchmarking.rs b/pallets/api/src/fungibles/benchmarking.rs new file mode 100644 index 00000000..7c0ad6ce --- /dev/null +++ b/pallets/api/src/fungibles/benchmarking.rs @@ -0,0 +1,60 @@ +//! Benchmarking setup for pallet-cards + +use super::{AccountIdOf, AssetIdOf, Assets, AssetsInstanceOf, BalanceOf, Call, Config, Pallet}; +use frame_benchmarking::{account, v2::*}; +use frame_support::{ + assert_ok, + traits::{ + fungibles::{ + approvals::{Inspect as ApprovalInspect, Mutate}, + Create, Inspect, + }, + Currency, + }, +}; +use frame_system::RawOrigin; +use sp_runtime::traits::Zero; + +const SEED: u32 = 1; + +#[benchmarks( + where + > as Inspect<::AccountId>>::AssetId: Zero, +)] +mod benchmarks { + use super::*; + + // The worst case scenario is when the allowance is set to a value which is lower than the + // current allowance. + #[benchmark] + fn approve() -> Result<(), BenchmarkError> { + let asset = AssetIdOf::::zero(); + let decreased_value = >::from(50u32); + let min_balance = >::from(1u32); + let owner: AccountIdOf = account("Alice", 0, SEED); + let spender: AccountIdOf = account("Bob", 0, SEED); + let value = >::from(100u32); + T::Currency::make_free_balance_be(&owner, 100u32.into()); + assert_ok!( as Create>>::create( + asset.clone().into(), + owner.clone(), + true, + min_balance + )); + assert_ok!( as Mutate>>::approve( + asset.clone(), + &owner, + &spender, + value + )); + + #[extrinsic_call] + _(RawOrigin::Signed(owner.clone()), asset.clone(), spender.clone(), decreased_value); + + assert_eq!(Assets::::allowance(asset, &owner, &spender), decreased_value); + + Ok(()) + } + + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); +} diff --git a/pallets/api/src/fungibles/mod.rs b/pallets/api/src/fungibles/mod.rs index 221da379..3b096490 100644 --- a/pallets/api/src/fungibles/mod.rs +++ b/pallets/api/src/fungibles/mod.rs @@ -3,6 +3,8 @@ /// API that adheres to standards in the smart contract space. pub use pallet::*; +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; #[cfg(test)] mod tests; @@ -26,8 +28,8 @@ pub mod pallet { >>::AssetId; type AssetIdParameterOf = >>::AssetIdParameter; - type Assets = pallet_assets::Pallet>; - type AssetsInstanceOf = ::AssetsInstance; + pub(crate) type Assets = pallet_assets::Pallet>; + pub(crate) type AssetsInstanceOf = ::AssetsInstance; type AssetsWeightInfo = >>::WeightInfo; pub(crate) type BalanceOf = > as Inspect< ::AccountId, @@ -94,7 +96,7 @@ pub mod pallet { /// # Returns /// Returns `Ok(())` if successful, or an error if the approval fails. #[pallet::call_index(2)] - #[pallet::weight(T::DbWeight::get().reads(2) + AssetsWeightInfo::::cancel_approval() + AssetsWeightInfo::::approve_transfer())] + #[pallet::weight(T::DbWeight::get().reads(1) + AssetsWeightInfo::::cancel_approval() + AssetsWeightInfo::::approve_transfer())] pub fn approve( origin: OriginFor, id: AssetIdOf, @@ -102,6 +104,7 @@ pub mod pallet { mut value: BalanceOf, ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin.clone()) + // To have the caller pay some fees. .map_err(|e| e.with_weight(T::DbWeight::get().reads(1)))?; let current_allowance = Assets::::allowance(id.clone(), &who, &spender); let spender = T::Lookup::unlookup(spender); @@ -115,7 +118,7 @@ pub mod pallet { value.saturating_reduce(current_allowance); Assets::::approve_transfer(origin, id, spender, value).map_err(|e| { e.with_weight( - T::DbWeight::get().reads(2) + AssetsWeightInfo::::approve_transfer(), + T::DbWeight::get().reads(1) + AssetsWeightInfo::::approve_transfer(), ) })?; } else { @@ -123,7 +126,7 @@ pub mod pallet { Assets::::cancel_approval(origin.clone(), id.clone(), spender.clone()).map_err( |e| { e.with_weight( - T::DbWeight::get().reads(2) + AssetsWeightInfo::::cancel_approval(), + T::DbWeight::get().reads(1) + AssetsWeightInfo::::cancel_approval(), ) }, )?; From 2dcf5d77bbbaf4ad2dba45434d59203502be3185 Mon Sep 17 00:00:00 2001 From: tin-snowflake <56880684+chungquantin@users.noreply.github.com> Date: Tue, 23 Jul 2024 22:30:41 +0700 Subject: [PATCH 09/22] fix missing data params --- .../integration-tests/src/local_fungibles.rs | 71 ++++++++++++++----- 1 file changed, 53 insertions(+), 18 deletions(-) diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index 6b0a0191..1e46db03 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -88,13 +88,17 @@ fn transfer( fn transfer_from( addr: AccountId32, asset_id: AssetId, + delegate: AccountId32, from: AccountId32, to: AccountId32, value: Balance, + data: Vec, ) -> ExecReturnValue { let function = function_selector("transfer_from"); - let params = [function, asset_id.encode(), from.encode(), to.encode(), value.encode()].concat(); - let result = bare_call(addr, params, 0).expect("should work"); + let params = + [function, asset_id.encode(), from.encode(), to.encode(), value.encode(), data.encode()] + .concat(); + let result = bare_call_by(addr, delegate, params, 0).expect("should work"); result } @@ -405,29 +409,60 @@ fn transfer_from_works() { let _ = env_logger::try_init(); let addr = instantiate("contracts/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); let amount: Balance = 100 * UNIT; + let delegate = CHARLIE; + let asset = ASSET_ID; + + // Asset does not exist + assert_eq!( + decoded::(transfer_from( + addr.clone(), + asset, + delegate.clone(), + ALICE, + BOB, + 1, + vec![] + )), + Module { index: 52, error: 3 }, + ); - // Allow CHARLIE to spend `amount` owned by ALICE - let delegate = addr.clone(); - let asset_id = create_asset_mint_and_approve( + // Allow `delegate` to spend `amount` owned by contract address + let owner = addr.clone(); + let asset = create_asset_and_mint_to(ALICE, ASSET_ID, owner.clone(), amount * 2); + // `delegate` transfer from the `owner` with approval + let unapproved_result = transfer_from( addr.clone(), - ASSET_ID, - ALICE, - amount * 2, + asset, delegate.clone(), - amount * 2, + owner.clone(), + BOB, + amount / 2, + vec![], ); - assert_eq!( - Assets::allowance(asset_id, &ALICE, &delegate.clone()), - allowance(addr.clone(), asset_id, ALICE, delegate.clone()) + assert_eq!(decoded::(unapproved_result), Module { index: 52, error: 10 },); + + // Check if the allowance is correct + assert_eq!(0, Assets::allowance(asset, &addr, &delegate.clone())); + assert!( + !approve(owner.clone(), asset, delegate.clone(), amount).did_revert(), + "Contract reverted!" ); - assert_eq!(allowance(addr.clone(), asset_id, ALICE, delegate.clone()), amount * 2); + assert_eq!(Assets::allowance(asset, &owner, &delegate.clone()), amount); // Successfully transfer - // TODO: Fix - // CHARLIE trying to send from ALICE to BOB - let result = transfer_from(addr.clone(), asset_id, ALICE, BOB, amount * 2); - assert_eq!(decoded::(result.clone()), Module { index: 52, error: 16 },); - assert!(!result.did_revert(), "Contract reverted!"); + let bob_balance_before_transfer = Assets::balance(asset, &BOB); + let approved_result = transfer_from( + addr.clone(), + asset, + delegate.clone(), + owner.clone(), + BOB, + amount / 2, + vec![], + ); + assert!(!approved_result.did_revert(), "Contract reverted!"); + let bob_balance_after_transfer = Assets::balance(asset, &BOB); + assert_eq!(bob_balance_after_transfer, bob_balance_before_transfer + amount / 2); }); } From a3443a068ca710cd76d5c8ecd25c00dce5ead5c1 Mon Sep 17 00:00:00 2001 From: tin-snowflake <56880684+chungquantin@users.noreply.github.com> Date: Tue, 23 Jul 2024 22:52:31 +0700 Subject: [PATCH 10/22] fix wording --- pop-api/integration-tests/src/local_fungibles.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index 1e46db03..9dbde3b1 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -409,6 +409,7 @@ fn transfer_from_works() { let _ = env_logger::try_init(); let addr = instantiate("contracts/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); let amount: Balance = 100 * UNIT; + let owner = addr.clone(); let delegate = CHARLIE; let asset = ASSET_ID; @@ -427,9 +428,8 @@ fn transfer_from_works() { ); // Allow `delegate` to spend `amount` owned by contract address - let owner = addr.clone(); let asset = create_asset_and_mint_to(ALICE, ASSET_ID, owner.clone(), amount * 2); - // `delegate` transfer from the `owner` with approval + // `delegate` transfer from the `owner` without approval let unapproved_result = transfer_from( addr.clone(), asset, @@ -442,7 +442,7 @@ fn transfer_from_works() { assert_eq!(decoded::(unapproved_result), Module { index: 52, error: 10 },); // Check if the allowance is correct - assert_eq!(0, Assets::allowance(asset, &addr, &delegate.clone())); + assert_eq!(0, Assets::allowance(asset, &owner, &delegate.clone())); assert!( !approve(owner.clone(), asset, delegate.clone(), amount).did_revert(), "Contract reverted!" From 48fec3764edf495a63f50a640727499c5afce46f Mon Sep 17 00:00:00 2001 From: Tin Chung <56880684+chungquantin@users.noreply.github.com> Date: Wed, 24 Jul 2024 14:50:25 +0800 Subject: [PATCH 11/22] Update pop-api/integration-tests/src/local_fungibles.rs Co-authored-by: Daan van der Plas <93204684+Daanvdplas@users.noreply.github.com> --- pop-api/integration-tests/src/local_fungibles.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index 9dbde3b1..3b20b10e 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -409,9 +409,6 @@ fn transfer_from_works() { let _ = env_logger::try_init(); let addr = instantiate("contracts/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); let amount: Balance = 100 * UNIT; - let owner = addr.clone(); - let delegate = CHARLIE; - let asset = ASSET_ID; // Asset does not exist assert_eq!( From ece65ade1e529c86c3be0520b97b9f6aa237014a Mon Sep 17 00:00:00 2001 From: Tin Chung <56880684+chungquantin@users.noreply.github.com> Date: Wed, 24 Jul 2024 14:50:34 +0800 Subject: [PATCH 12/22] Update pop-api/integration-tests/src/local_fungibles.rs Co-authored-by: Daan van der Plas <93204684+Daanvdplas@users.noreply.github.com> --- pop-api/integration-tests/src/local_fungibles.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index 3b20b10e..6e83489b 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -425,7 +425,7 @@ fn transfer_from_works() { ); // Allow `delegate` to spend `amount` owned by contract address - let asset = create_asset_and_mint_to(ALICE, ASSET_ID, owner.clone(), amount * 2); + let asset = create_asset_and_mint_to(ALICE, ASSET_ID, ALICE, amount * 2); // `delegate` transfer from the `owner` without approval let unapproved_result = transfer_from( addr.clone(), From 11bb67e8192d5e4da7ee8c4ac6c39f9de4428f24 Mon Sep 17 00:00:00 2001 From: Tin Chung <56880684+chungquantin@users.noreply.github.com> Date: Wed, 24 Jul 2024 14:50:40 +0800 Subject: [PATCH 13/22] Update pop-api/integration-tests/src/local_fungibles.rs Co-authored-by: Daan van der Plas <93204684+Daanvdplas@users.noreply.github.com> --- pop-api/integration-tests/src/local_fungibles.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index 6e83489b..46e37dd5 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -426,7 +426,7 @@ fn transfer_from_works() { // Allow `delegate` to spend `amount` owned by contract address let asset = create_asset_and_mint_to(ALICE, ASSET_ID, ALICE, amount * 2); - // `delegate` transfer from the `owner` without approval + // Unapproved let unapproved_result = transfer_from( addr.clone(), asset, From 63cfbcfc83d7d01512ea2e42aab1598a9f656c74 Mon Sep 17 00:00:00 2001 From: Tin Chung <56880684+chungquantin@users.noreply.github.com> Date: Wed, 24 Jul 2024 14:57:02 +0800 Subject: [PATCH 14/22] Update pallets/api/src/fungibles/tests.rs Co-authored-by: Daan van der Plas <93204684+Daanvdplas@users.noreply.github.com> --- pallets/api/src/fungibles/tests.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/pallets/api/src/fungibles/tests.rs b/pallets/api/src/fungibles/tests.rs index 920c5fcc..9ccf5cf2 100644 --- a/pallets/api/src/fungibles/tests.rs +++ b/pallets/api/src/fungibles/tests.rs @@ -102,14 +102,12 @@ fn decrease_allowance_works() { new_test_ext().execute_with(|| { let amount: Balance = 100 * UNIT; create_asset_and_mint_to(ALICE, ASSET, ALICE, amount); - assert_ok!(Fungibles::increase_allowance(signed(ALICE), ASSET, BOB, amount)); + assert_ok!(Assets::increase_allowance(signed(ALICE), ASSET, BOB, amount)); assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount); - assert_ok!(Fungibles::decrease_allowance(signed(ALICE), ASSET, BOB, amount / 2)); assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount / 2); - - // Saturating if the allowance value is already zeros - assert_ok!(Fungibles::decrease_allowance(signed(ALICE), ASSET, BOB, amount / 2 + 1 * UNIT)); + // Saturating if the allowance value is already zero. + assert_ok!(Fungibles::decrease_allowance(signed(ALICE), ASSET, BOB, amount)); assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), 0); }); } From ecb6af02506ee94d66bf9dfe1d4c7fea23426f05 Mon Sep 17 00:00:00 2001 From: tin-snowflake <56880684+chungquantin@users.noreply.github.com> Date: Wed, 24 Jul 2024 16:17:10 +0700 Subject: [PATCH 15/22] finalize contract integration tests --- .../integration-tests/src/local_fungibles.rs | 102 +++++++++++------- 1 file changed, 61 insertions(+), 41 deletions(-) diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index 46e37dd5..a4078b8a 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -88,7 +88,6 @@ fn transfer( fn transfer_from( addr: AccountId32, asset_id: AssetId, - delegate: AccountId32, from: AccountId32, to: AccountId32, value: Balance, @@ -98,7 +97,7 @@ fn transfer_from( let params = [function, asset_id.encode(), from.encode(), to.encode(), value.encode(), data.encode()] .concat(); - let result = bare_call_by(addr, delegate, params, 0).expect("should work"); + let result = bare_call(addr, params, 0).expect("should work"); result } @@ -410,54 +409,51 @@ fn transfer_from_works() { let addr = instantiate("contracts/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); let amount: Balance = 100 * UNIT; - // Asset does not exist + // Asset does not exist. + assert_eq!( + decoded::(transfer_from(addr.clone(), 1, ALICE, BOB, amount / 2, vec![])), + Module { index: 52, error: 3 }, + ); + + // Create asset with Alice as owner and mint `amount` to contract address. + let asset = create_asset_and_mint_to(ALICE, 1, ALICE, amount); + // Unapproved transfer + assert_eq!( + decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount / 2, vec![])), + Module { index: 52, error: 10 } + ); + + assert_ok!(Assets::approve_transfer( + RuntimeOrigin::signed(ALICE.into()), + asset.into(), + addr.clone().into(), + amount + 1 * UNIT, + )); + + // Asset is not live, i.e. frozen or being destroyed. + freeze_asset(ALICE, asset); + assert_eq!( + decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount, vec![])), + Module { index: 52, error: 16 }, + ); + thaw_asset(ALICE, asset); + // Not enough balance. assert_eq!( decoded::(transfer_from( addr.clone(), asset, - delegate.clone(), ALICE, BOB, - 1, + amount + 1 * UNIT, vec![] )), - Module { index: 52, error: 3 }, - ); - - // Allow `delegate` to spend `amount` owned by contract address - let asset = create_asset_and_mint_to(ALICE, ASSET_ID, ALICE, amount * 2); - // Unapproved - let unapproved_result = transfer_from( - addr.clone(), - asset, - delegate.clone(), - owner.clone(), - BOB, - amount / 2, - vec![], - ); - assert_eq!(decoded::(unapproved_result), Module { index: 52, error: 10 },); - - // Check if the allowance is correct - assert_eq!(0, Assets::allowance(asset, &owner, &delegate.clone())); - assert!( - !approve(owner.clone(), asset, delegate.clone(), amount).did_revert(), - "Contract reverted!" + Module { index: 52, error: 0 }, ); - assert_eq!(Assets::allowance(asset, &owner, &delegate.clone()), amount); - // Successfully transfer + // Successful transfer. let bob_balance_before_transfer = Assets::balance(asset, &BOB); - let approved_result = transfer_from( - addr.clone(), - asset, - delegate.clone(), - owner.clone(), - BOB, - amount / 2, - vec![], - ); - assert!(!approved_result.did_revert(), "Contract reverted!"); + let result = transfer_from(addr.clone(), asset, ALICE, BOB, amount / 2, vec![]); + assert!(!result.did_revert(), "Contract reverted!"); let bob_balance_after_transfer = Assets::balance(asset, &BOB); assert_eq!(bob_balance_after_transfer, bob_balance_before_transfer + amount / 2); }); @@ -558,14 +554,38 @@ fn increase_allowance_works() { fn decrease_allowance_works() { new_test_ext().execute_with(|| { let _ = env_logger::try_init(); - let addr = instantiate("contracts/fungibles/target/ink/fungibles.wasm", 0, vec![]); + let addr = instantiate("contracts/fungibles/target/ink/fungibles.wasm", INIT_VALUE, vec![]); let amount: Balance = 100 * UNIT; // Asset does not exist. - // TODO: Fix assert_eq!( checked_decoded::(decrease_allowance(addr.clone(), 0, BOB, amount)), Ok(Module { index: 52, error: 3 }), ); + + // Create asset and mint to the address contract, delegate Bob to spend the `amount` + let asset = + create_asset_mint_and_approve(addr.clone(), 0, addr.clone(), amount, BOB, amount); + // Asset is not live, i.e. frozen or being destroyed. + freeze_asset(addr.clone(), asset); + assert_eq!( + decoded::(decrease_allowance(addr.clone(), asset, BOB, amount)), + Module { index: 52, error: 16 }, + ); + thaw_asset(addr.clone(), asset); + + // Successfully decrease allowance + let bob_allowance_before = Assets::allowance(asset, &addr, &BOB); + let result = decrease_allowance(addr.clone(), 0, BOB, amount / 2 - 1 * UNIT); + assert!(!result.did_revert(), "Contract reverted!"); + let bob_allowance_after = Assets::allowance(asset, &addr, &BOB); + assert_eq!(bob_allowance_before - bob_allowance_after, amount / 2 - 1 * UNIT); + + // Asset is not live, i.e. frozen or being destroyed. + start_destroy_asset(addr.clone(), asset); + assert_eq!( + decoded::(decrease_allowance(addr.clone(), asset, BOB, amount)), + Module { index: 52, error: 16 }, + ); }); } From d6f6703419f9ccfe9eae2171cbc8ac2742e29ee3 Mon Sep 17 00:00:00 2001 From: tin-snowflake <56880684+chungquantin@users.noreply.github.com> Date: Wed, 24 Jul 2024 16:17:24 +0700 Subject: [PATCH 16/22] finalize contract integration tests --- pallets/api/src/fungibles/tests.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pallets/api/src/fungibles/tests.rs b/pallets/api/src/fungibles/tests.rs index 9ccf5cf2..84e45364 100644 --- a/pallets/api/src/fungibles/tests.rs +++ b/pallets/api/src/fungibles/tests.rs @@ -101,11 +101,11 @@ fn increase_allowance_works() { fn decrease_allowance_works() { new_test_ext().execute_with(|| { let amount: Balance = 100 * UNIT; - create_asset_and_mint_to(ALICE, ASSET, ALICE, amount); - assert_ok!(Assets::increase_allowance(signed(ALICE), ASSET, BOB, amount)); + create_asset_mint_and_approve(ALICE, ASSET, ALICE, amount, BOB, amount); + assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount); - assert_ok!(Fungibles::decrease_allowance(signed(ALICE), ASSET, BOB, amount / 2)); - assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount / 2); + assert_ok!(Fungibles::decrease_allowance(signed(ALICE), ASSET, BOB, amount / 2 - 1 * UNIT)); + assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), amount / 2 + 1 * UNIT); // Saturating if the allowance value is already zero. assert_ok!(Fungibles::decrease_allowance(signed(ALICE), ASSET, BOB, amount)); assert_eq!(Assets::allowance(ASSET, &ALICE, &BOB), 0); From 71b96b05a69414d6e2a419381143d1532474fbd3 Mon Sep 17 00:00:00 2001 From: tin-snowflake <56880684+chungquantin@users.noreply.github.com> Date: Wed, 24 Jul 2024 16:21:36 +0700 Subject: [PATCH 17/22] refractor: remove bare_call_by --- pop-api/integration-tests/src/lib.rs | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/pop-api/integration-tests/src/lib.rs b/pop-api/integration-tests/src/lib.rs index 51d429cc..1bdbe835 100644 --- a/pop-api/integration-tests/src/lib.rs +++ b/pop-api/integration-tests/src/lib.rs @@ -61,14 +61,13 @@ fn function_selector(name: &str) -> Vec { [hash[0..4].to_vec()].concat() } -fn bare_call_by( +fn bare_call( addr: AccountId32, - caller: AccountId32, input: Vec, value: u128, ) -> Result { let result = Contracts::bare_call( - caller, + ALICE, addr.into(), value.into(), GAS_LIMIT, @@ -81,14 +80,6 @@ fn bare_call_by( result.result } -fn bare_call( - addr: AccountId32, - input: Vec, - value: u128, -) -> Result { - bare_call_by(addr, ALICE, input, value) -} - // Deploy, instantiate and return contract address. fn instantiate(contract: &str, init_value: u128, salt: Vec) -> AccountId32 { let (wasm_binary, _) = From f0b14a846870cc27147ac5cffe2c117795daeb6d Mon Sep 17 00:00:00 2001 From: tin-snowflake <56880684+chungquantin@users.noreply.github.com> Date: Wed, 24 Jul 2024 16:27:04 +0700 Subject: [PATCH 18/22] refractor: remove data param in transfer_from() method --- .../integration-tests/src/local_fungibles.rs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index a4078b8a..7c27c745 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -91,9 +91,9 @@ fn transfer_from( from: AccountId32, to: AccountId32, value: Balance, - data: Vec, ) -> ExecReturnValue { let function = function_selector("transfer_from"); + let data: Vec = vec![]; let params = [function, asset_id.encode(), from.encode(), to.encode(), value.encode(), data.encode()] .concat(); @@ -411,7 +411,7 @@ fn transfer_from_works() { // Asset does not exist. assert_eq!( - decoded::(transfer_from(addr.clone(), 1, ALICE, BOB, amount / 2, vec![])), + decoded::(transfer_from(addr.clone(), 1, ALICE, BOB, amount / 2)), Module { index: 52, error: 3 }, ); @@ -419,7 +419,7 @@ fn transfer_from_works() { let asset = create_asset_and_mint_to(ALICE, 1, ALICE, amount); // Unapproved transfer assert_eq!( - decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount / 2, vec![])), + decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount / 2)), Module { index: 52, error: 10 } ); @@ -433,26 +433,19 @@ fn transfer_from_works() { // Asset is not live, i.e. frozen or being destroyed. freeze_asset(ALICE, asset); assert_eq!( - decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount, vec![])), + decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount)), Module { index: 52, error: 16 }, ); thaw_asset(ALICE, asset); // Not enough balance. assert_eq!( - decoded::(transfer_from( - addr.clone(), - asset, - ALICE, - BOB, - amount + 1 * UNIT, - vec![] - )), + decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount + 1 * UNIT,)), Module { index: 52, error: 0 }, ); // Successful transfer. let bob_balance_before_transfer = Assets::balance(asset, &BOB); - let result = transfer_from(addr.clone(), asset, ALICE, BOB, amount / 2, vec![]); + let result = transfer_from(addr.clone(), asset, ALICE, BOB, amount / 2); assert!(!result.did_revert(), "Contract reverted!"); let bob_balance_after_transfer = Assets::balance(asset, &BOB); assert_eq!(bob_balance_after_transfer, bob_balance_before_transfer + amount / 2); From b77ee5741c262924e58d0599093f0ffcf66de4d1 Mon Sep 17 00:00:00 2001 From: Tin Chung <56880684+chungquantin@users.noreply.github.com> Date: Wed, 24 Jul 2024 16:27:54 +0700 Subject: [PATCH 19/22] Update pop-api/integration-tests/src/local_fungibles.rs Co-authored-by: Daan van der Plas <93204684+Daanvdplas@users.noreply.github.com> --- pop-api/integration-tests/src/local_fungibles.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index 7c27c745..54bd058b 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -414,7 +414,6 @@ fn transfer_from_works() { decoded::(transfer_from(addr.clone(), 1, ALICE, BOB, amount / 2)), Module { index: 52, error: 3 }, ); - // Create asset with Alice as owner and mint `amount` to contract address. let asset = create_asset_and_mint_to(ALICE, 1, ALICE, amount); // Unapproved transfer From b8afcddc80b0e8485f2d1b799e04d79bfcbdb728 Mon Sep 17 00:00:00 2001 From: Tin Chung <56880684+chungquantin@users.noreply.github.com> Date: Wed, 24 Jul 2024 16:28:10 +0700 Subject: [PATCH 20/22] Update pop-api/integration-tests/src/local_fungibles.rs Co-authored-by: Daan van der Plas <93204684+Daanvdplas@users.noreply.github.com> --- pop-api/integration-tests/src/local_fungibles.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index 54bd058b..63ff2b0e 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -421,7 +421,6 @@ fn transfer_from_works() { decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount / 2)), Module { index: 52, error: 10 } ); - assert_ok!(Assets::approve_transfer( RuntimeOrigin::signed(ALICE.into()), asset.into(), From 3daa73eed2e3263a1fa8305158af30ee85020ed2 Mon Sep 17 00:00:00 2001 From: Tin Chung <56880684+chungquantin@users.noreply.github.com> Date: Wed, 24 Jul 2024 16:28:20 +0700 Subject: [PATCH 21/22] Update pop-api/integration-tests/src/local_fungibles.rs Co-authored-by: Daan van der Plas <93204684+Daanvdplas@users.noreply.github.com> --- pop-api/integration-tests/src/local_fungibles.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/pop-api/integration-tests/src/local_fungibles.rs b/pop-api/integration-tests/src/local_fungibles.rs index 63ff2b0e..9c127fe9 100644 --- a/pop-api/integration-tests/src/local_fungibles.rs +++ b/pop-api/integration-tests/src/local_fungibles.rs @@ -440,7 +440,6 @@ fn transfer_from_works() { decoded::(transfer_from(addr.clone(), asset, ALICE, BOB, amount + 1 * UNIT,)), Module { index: 52, error: 0 }, ); - // Successful transfer. let bob_balance_before_transfer = Assets::balance(asset, &BOB); let result = transfer_from(addr.clone(), asset, ALICE, BOB, amount / 2); From d0ebcdfd44a7d688cd901250a0e7fcf159ea964d Mon Sep 17 00:00:00 2001 From: tin-snowflake <56880684+chungquantin@users.noreply.github.com> Date: Wed, 24 Jul 2024 16:35:00 +0700 Subject: [PATCH 22/22] reformat --- pallets/api/src/fungibles/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pallets/api/src/fungibles/mod.rs b/pallets/api/src/fungibles/mod.rs index 486c4de3..38d0ecee 100644 --- a/pallets/api/src/fungibles/mod.rs +++ b/pallets/api/src/fungibles/mod.rs @@ -31,7 +31,8 @@ pub mod pallet { >>::AssetId; type AssetIdParameterOf = >>::AssetIdParameter; - pub(crate) type AccountIdLookupOf = <::Lookup as StaticLookup>::Source; + pub(crate) type AccountIdLookupOf = + <::Lookup as StaticLookup>::Source; pub(crate) type Assets = pallet_assets::Pallet>; pub(crate) type AssetsInstanceOf = ::AssetsInstance; type AssetsWeightInfo = >>::WeightInfo;