diff --git a/.dockerignore b/.dockerignore index 85bb54582e..bd596a7f0f 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,35 @@ -/.cargo/config.toml -/target -/Dockerfile -/launch/bin +# Generated by Cargo +# will have compiled files and executables +**/target/ +# These are backup files generated by rustfmt +**/*.rs.bk + +# node deps for e2e +node_modules + +# The directory caches for osx +.DS_Store + +# typescript language server logs and logs +*.log + +# rococo specs +rococo* + +# The cache for docker container dependency +.cargo + +# The cache for chain data in container +.local + +# Binaries for launching PINT with polkadot +bin + +# Libraries of js output +js/**/*/lib + +# Unknown +local-test + +# docker +docker \ No newline at end of file diff --git a/pallets/asset-index/src/benchmarking.rs b/pallets/asset-index/src/benchmarking.rs index 040d5cf9be..ec2cfb99fb 100644 --- a/pallets/asset-index/src/benchmarking.rs +++ b/pallets/asset-index/src/benchmarking.rs @@ -3,12 +3,12 @@ #![cfg(feature = "runtime-benchmarks")] -use frame_benchmarking::{account, benchmarks}; +use frame_benchmarking::{account, benchmarks, vec}; use frame_support::{ assert_ok, dispatch::UnfilteredDispatchable, sp_runtime::{traits::AccountIdConversion, FixedPointNumber}, - traits::{EnsureOrigin, Get}, + traits::{Currency as _, EnsureOrigin, Get}, }; use frame_system::RawOrigin; use orml_traits::MultiCurrency; @@ -34,7 +34,6 @@ fn whitelist_acc(acc: &T::AccountId) { benchmarks! { add_asset { - // ASSET_A_ID let asset_id: T::AssetId = 1_u32.into(); let origin = T::AdminOrigin::successful_origin(); let million = 1_000_000u32.into(); @@ -55,7 +54,89 @@ benchmarks! { T::Currency::total_balance(asset_id, &T::TreasuryPalletId::get().into_account()), million ); + } + + complete_withdraw { + let asset_id = 1_u32.into(); + let units = 100_u32.into(); + let tokens = 500_u32.into(); + let admin = T::AdminOrigin::successful_origin(); + let origin = whitelisted_account::("origin", 0); + let deposit_units = 1000_u32.into(); + + // create liquid assets + assert_ok!(>::add_asset( + admin, + asset_id, + units, + MultiLocation::Null, + tokens + )); + // deposit some funds into the index from an user account + assert_ok!(T::Currency::deposit(asset_id, &origin, deposit_units)); + assert_ok!(>::deposit(RawOrigin::Signed(origin.clone()).into(), asset_id, deposit_units)); + + // advance the block number so that the lock expires + >::set_block_number( + >::block_number() + + T::LockupPeriod::get() + + 1_u32.into(), + ); + + // start withdraw + assert_ok!(>::withdraw( + RawOrigin::Signed(origin.clone()).into(), + 42_u32.into(), + )); + }: _( + RawOrigin::Signed(origin.clone()) + ) verify { + assert_eq!(pallet::PendingWithdrawals::::get(&origin), None); + } + + deposit { + // ASSET_A_ID + let asset_id = 1_u32.into(); + let origin = T::AdminOrigin::successful_origin(); + let depositor = whitelisted_account::("depositor", 0); + let admin_deposit = 5u32.into(); + assert_ok!(AssetIndex::::add_asset(origin, asset_id, 100u32.into(),MultiLocation::Null,admin_deposit + )); + let units = 1_000u32.into(); + assert_ok!(T::Currency::deposit(asset_id, &depositor, units)); + let nav = AssetIndex::::nav().unwrap(); + }: _( + RawOrigin::Signed(depositor.clone()), + asset_id, + units + ) verify { + let deposit_value = T::PriceFeed::get_price(asset_id).unwrap().checked_mul_int(units.into()).unwrap(); + let received = nav.reciprocal().unwrap().saturating_mul_int(deposit_value); + assert_eq!(AssetIndex::::index_token_balance(&depositor).into(), received); + } + + remove_asset { + let asset_id = 1_u32.into(); + let origin = T::AdminOrigin::successful_origin(); + let units: u32 = 100; + let amount = 500u32.into(); + + assert_ok!(AssetIndex::::add_asset( + origin.clone(), + asset_id, + units.into(), + MultiLocation::Null, + amount, + )); + + // ensure + assert_eq!(T::IndexToken::total_balance(&Default::default()), 500u32.into()); + + // construct remove call + let call = Call::::remove_asset(asset_id, units.into(), None); + }: { call.dispatch_bypass_filter(origin.clone())? } verify { + assert_eq!(T::IndexToken::total_balance(&Default::default()), 0u32.into()); } register_asset { @@ -92,26 +173,57 @@ benchmarks! { assert_eq!(metadata.decimals, decimals); } - deposit { - // ASSET_A_ID + withdraw { + let asset_id = 1_u32.into(); + let units = 100_u32.into(); + let tokens = 500_u32.into(); + let admin = T::AdminOrigin::successful_origin(); + let origin = whitelisted_account::("origin", 0); + let deposit_units = 1_000_u32.into(); + + // create liquid assets + assert_ok!(>::add_asset( + admin, + asset_id, + units, + MultiLocation::Null, + tokens + )); + + // deposit some funds into the index from an user account + assert_ok!(T::Currency::deposit(asset_id, &origin, deposit_units)); + assert_ok!(>::deposit(RawOrigin::Signed(origin.clone()).into(), asset_id, deposit_units)); + + // advance the block number so that the lock expires + >::set_block_number( + >::block_number() + + T::LockupPeriod::get() + + 1_u32.into(), + ); + }: _( + RawOrigin::Signed(origin.clone()), + 42_u32.into() + ) verify { + assert_eq!(pallet::PendingWithdrawals::::get(&origin).expect("pending withdrawals should be present").len(), 1); + } + + unlock { let asset_id = 1_u32.into(); let origin = T::AdminOrigin::successful_origin(); let depositor = whitelisted_account::("depositor", 0); - let admin_deposit = 5u32.into(); - assert_ok!(AssetIndex::::add_asset(origin, asset_id, 100u32.into(),MultiLocation::Null,admin_deposit - )); - let units = 1_000u32.into(); + let amount = 500u32.into(); + let units = 100u32.into(); + + assert_ok!(AssetIndex::::add_asset(origin, asset_id, units, MultiLocation::Null, amount)); assert_ok!(T::Currency::deposit(asset_id, &depositor, units)); - let nav = AssetIndex::::nav().unwrap(); + assert_ok!(>::deposit(RawOrigin::Signed(depositor.clone()).into(), asset_id, units)); }: _( - RawOrigin::Signed(depositor.clone()), - asset_id, - units - ) - verify { - let deposit_value = T::PriceFeed::get_price(asset_id).unwrap().checked_mul_int(units.into()).unwrap(); - let received = nav.reciprocal().unwrap().saturating_mul_int(deposit_value); - assert_eq!(AssetIndex::::index_token_balance(&depositor).into(), received); + RawOrigin::Signed(depositor.clone()) + ) verify { + assert_eq!(>::get(&depositor), vec![types::IndexTokenLock{ + locked: 500_u32.into(), + end_block: >::block_number() + T::LockupPeriod::get(), + }]); } } @@ -130,6 +242,13 @@ mod tests { }); } + #[test] + fn complete_withdraw() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_complete_withdraw::()); + }); + } + #[test] fn set_metadata() { new_test_ext().execute_with(|| { @@ -150,4 +269,25 @@ mod tests { assert_ok!(test_benchmark_register_asset::()); }); } + + #[test] + fn remove_asset() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_remove_asset::()); + }); + } + + #[test] + fn unlock() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_unlock::()); + }); + } + + #[test] + fn withdraw() { + new_test_ext().execute_with(|| { + assert_ok!(test_benchmark_withdraw::()); + }); + } } diff --git a/pallets/asset-index/src/lib.rs b/pallets/asset-index/src/lib.rs index ff0b2da5ca..a5cf16dc9b 100644 --- a/pallets/asset-index/src/lib.rs +++ b/pallets/asset-index/src/lib.rs @@ -583,6 +583,7 @@ pub mod pallet { /// whether the other `AssetWithdrawal` of the same `PendingWithdrawal` /// entry can also be closed successfully. #[pallet::weight(10_000)] // TODO: Set weights + #[transactional] pub fn complete_withdraw(origin: OriginFor) -> DispatchResultWithPostInfo { let caller = ensure_signed(origin)?; diff --git a/pallets/asset-index/src/mock.rs b/pallets/asset-index/src/mock.rs index 3f50fb3bea..fe92fc2ec0 100644 --- a/pallets/asset-index/src/mock.rs +++ b/pallets/asset-index/src/mock.rs @@ -276,7 +276,7 @@ pub fn new_test_ext() -> sp_io::TestExternalities { let mut ext = ExtBuilder::default().build(); ext.execute_with(|| System::set_block_number(1)); - MockPriceFeed::set_prices([ + MockPriceFeed::set_prices(vec![ (ASSET_A_ID, Price::from(ASSET_A_PRICE_MULTIPLIER)), (ASSET_B_ID, Price::from(ASSET_B_PRICE_MULTIPLIER)), ]); @@ -288,7 +288,7 @@ pub fn new_test_ext_with_balance(balances: Vec<(AccountId, AssetId, Balance)>) - let mut ext = ExtBuilder::default().with_balances(balances).build(); ext.execute_with(|| System::set_block_number(1)); - MockPriceFeed::set_prices([ + MockPriceFeed::set_prices(vec![ (ASSET_A_ID, Price::from(ASSET_A_PRICE_MULTIPLIER)), (ASSET_B_ID, Price::from(ASSET_B_PRICE_MULTIPLIER)), ]);