From bf4c94e3e4f877a9efb93345ebceb9a282d269cb Mon Sep 17 00:00:00 2001 From: Allen Pocket Date: Tue, 28 Sep 2021 15:47:06 +0800 Subject: [PATCH 1/2] :bug: ($PALLET) Fix dust white list --- node/primitives/src/traits.rs | 24 +++++++- pallets/liquidity-mining/src/mock.rs | 23 +++++-- pallets/liquidity-mining/src/tests.rs | 87 +++++++++++++++++++++++++++ runtime/bifrost/src/lib.rs | 5 +- 4 files changed, 131 insertions(+), 8 deletions(-) diff --git a/node/primitives/src/traits.rs b/node/primitives/src/traits.rs index 2d74a5bfa4..d51e532e25 100644 --- a/node/primitives/src/traits.rs +++ b/node/primitives/src/traits.rs @@ -20,8 +20,11 @@ #![allow(clippy::unnecessary_cast)] -use codec::FullCodec; -use frame_support::{dispatch::DispatchError, sp_runtime::TokenError}; +use codec::{Decode, Encode, FullCodec}; +use frame_support::{ + dispatch::DispatchError, + sp_runtime::{traits::AccountIdConversion, TokenError, TypeId}, +}; use sp_runtime::{ traits::{AtLeast32BitUnsigned, MaybeSerializeDeserialize}, DispatchResult, @@ -175,3 +178,20 @@ impl BancorHandler for () { DispatchResult::from(DispatchError::Token(TokenError::NoFunds)) } } + +pub trait CheckSubAccount { + fn check_sub_account(&self, account: &T) -> bool; +} + +impl CheckSubAccount for Id +where + T: Encode + Decode + Default, + Id: Encode + Decode + TypeId + AccountIdConversion + Eq, +{ + fn check_sub_account(&self, account: &T) -> bool { + match Id::try_from_sub_account::(account) { + Some((id, _)) => id.eq(self), + None => false, + } + } +} diff --git a/pallets/liquidity-mining/src/mock.rs b/pallets/liquidity-mining/src/mock.rs index 174ba5e4cc..4a77bcecb7 100644 --- a/pallets/liquidity-mining/src/mock.rs +++ b/pallets/liquidity-mining/src/mock.rs @@ -24,12 +24,14 @@ use frame_support::{ traits::{BlakeTwo256, IdentifyAccount, IdentityLookup, Verify}, BuildStorage, MultiSignature, }, + traits::Contains, PalletId, }; -use node_primitives::{Amount, Balance, CurrencyId, TokenSymbol}; +use node_primitives::{traits::CheckSubAccount, Amount, Balance, CurrencyId, TokenSymbol}; use sp_core::H256; use crate as lm; +use crate::PoolId; pub(crate) type AccountId = <::Signer as IdentifyAccount>::AccountId; pub(crate) type Block = frame_system::mocking::MockBlock; @@ -125,10 +127,23 @@ impl orml_currencies::Config for Test { orml_traits::parameter_type_with_key! { pub ExistentialDeposits: |_currency_id: CurrencyId| -> Balance { - 0 + 1_000_000 }; } +parameter_types! { + pub BifrostTreasuryFakeAccount: AccountId = AccountId::new([155u8;32]); +} + +pub struct DustRemovalWhitelist; +impl Contains for DustRemovalWhitelist { + fn contains(a: &AccountId) -> bool { + *a == BifrostTreasuryFakeAccount::get() || + *a == INVESTOR || + LiquidityMiningPalletId::get().check_sub_account::(a) + } +} + impl orml_tokens::Config for Test { type Amount = Amount; type Balance = Balance; @@ -136,9 +151,9 @@ impl orml_tokens::Config for Test { type Event = Event; type ExistentialDeposits = ExistentialDeposits; type MaxLocks = MaxLocks; - type OnDust = (); + type OnDust = orml_tokens::TransferDust; type WeightInfo = (); - type DustRemovalWhitelist = (); + type DustRemovalWhitelist = DustRemovalWhitelist; } parameter_types! { diff --git a/pallets/liquidity-mining/src/tests.rs b/pallets/liquidity-mining/src/tests.rs index ffeed95d5e..5adfe9f133 100644 --- a/pallets/liquidity-mining/src/tests.rs +++ b/pallets/liquidity-mining/src/tests.rs @@ -2298,3 +2298,90 @@ fn simple_integration_test() { assert!(LM::user_deposit_data(0, USER_2).is_none()); }); } + +#[test] +fn fuck_bug() { + new_test_ext().execute_with(|| { + const ALICE: AccountId = AccountId::new([0u8; 32]); + const BOB: AccountId = AccountId::new([1u8; 32]); + const CHARLIE: AccountId = AccountId::new([2u8; 32]); + + const INIT_AMOUNT: Balance = 1_000_000_000 * UNIT; + + const REWARD_TOKEN: CurrencyId = CurrencyId::Token(TokenSymbol::KSM); + const REWARD_AMOUNT: Balance = 10 * UNIT; + + const DEPOSIT_TOKEN_1: CurrencyId = CurrencyId::VSToken(TokenSymbol::KSM); + const DEPOSIT_TOKEN_2: CurrencyId = CurrencyId::VSBond(TokenSymbol::KSM, 2001, 13, 20); + + assert_ok!(Tokens::set_balance(Origin::root(), ALICE, REWARD_TOKEN, INIT_AMOUNT, 0)); + assert_ok!(Tokens::set_balance(Origin::root(), BOB, DEPOSIT_TOKEN_1, 0, INIT_AMOUNT)); + assert_ok!(Tokens::set_balance(Origin::root(), BOB, DEPOSIT_TOKEN_2, 0, INIT_AMOUNT)); + assert_ok!(Tokens::set_balance(Origin::root(), CHARLIE, DEPOSIT_TOKEN_1, 0, INIT_AMOUNT)); + assert_ok!(Tokens::set_balance(Origin::root(), CHARLIE, DEPOSIT_TOKEN_2, 0, INIT_AMOUNT)); + + run_to_block(134); + + assert_ok!(LM::create_eb_farming_pool( + pallet_collective::RawOrigin::Member(TC_MEMBER_1).into(), + 2001, + 13, + 20, + (REWARD_TOKEN, REWARD_AMOUNT), + vec![].try_into().unwrap(), + 23, + UNIT, + 0 + )); + + run_to_block(135); + + assert_ok!(LM::charge(Some(ALICE).into(), 0)); + + run_to_block(138); + + assert_ok!(LM::deposit(Some(BOB).into(), 0, 13 * UNIT)); + + run_to_block(140); + + assert_ok!(LM::deposit(Some(CHARLIE).into(), 0, 187 * UNIT)); + + run_to_block(179); + + assert_ok!(LM::redeem_all(Some(BOB).into(), 0)); + assert_ok!(LM::redeem_all(Some(CHARLIE).into(), 0)); + + assert!(LM::pool(200).is_none()); + + assert_ok!(LM::create_eb_farming_pool( + pallet_collective::RawOrigin::Member(TC_MEMBER_1).into(), + 2001, + 13, + 20, + (REWARD_TOKEN, REWARD_AMOUNT), + vec![].try_into().unwrap(), + 23, + UNIT, + 0 + )); + + run_to_block(235); + + assert_ok!(LM::charge(Some(ALICE).into(), 1)); + + run_to_block(250); + + assert_ok!(LM::deposit(Some(BOB).into(), 1, 23 * UNIT)); + + run_to_block(265); + + assert_ok!(LM::deposit(Some(CHARLIE).into(), 1, 167 * UNIT)); + + run_to_block(280); + + assert_ok!(LM::redeem_all(Some(BOB).into(), 1)); + assert_ok!(LM::redeem_all(Some(CHARLIE).into(), 1)); + + assert!(LM::pool(1).is_none()); + }); +} diff --git a/runtime/bifrost/src/lib.rs b/runtime/bifrost/src/lib.rs index bf47a2e94e..7d79c789cc 100644 --- a/runtime/bifrost/src/lib.rs +++ b/runtime/bifrost/src/lib.rs @@ -89,6 +89,7 @@ pub use node_primitives::{ AccountId, Amount, Balance, BlockNumber, CurrencyId, ExtraFeeName, Moment, Nonce, ParaId, ParachainDerivedProxyAccountType, ParachainTransactProxyType, ParachainTransactType, PoolId, RpcContributionStatus, TokenSymbol, TransferOriginType, XcmBaseWeight, + traits::CheckSubAccount, }; // orml imports use orml_currencies::BasicCurrencyAdapter; @@ -237,7 +238,6 @@ pub fn get_all_pallet_accounts() -> Vec { vec![ TreasuryPalletId::get().into_account(), BifrostCrowdloanId::get().into_account(), - LiquidityMiningPalletId::get().into_account(), ] } @@ -892,7 +892,8 @@ orml_traits::parameter_type_with_key! { pub struct DustRemovalWhitelist; impl Contains for DustRemovalWhitelist { fn contains(a: &AccountId) -> bool { - get_all_pallet_accounts().contains(a) + get_all_pallet_accounts().contains(a) || + LiquidityMiningPalletId::get().check_sub_account::(a) } } From ea6b832123d5ca7b2219b252e481ce2f64a6db1e Mon Sep 17 00:00:00 2001 From: Allen Pocket Date: Tue, 28 Sep 2021 16:05:27 +0800 Subject: [PATCH 2/2] :art: ($PALLET) Format code --- runtime/bifrost/src/lib.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/runtime/bifrost/src/lib.rs b/runtime/bifrost/src/lib.rs index 7d79c789cc..33365d87ff 100644 --- a/runtime/bifrost/src/lib.rs +++ b/runtime/bifrost/src/lib.rs @@ -86,10 +86,10 @@ use frame_support::{ use frame_system::{EnsureOneOf, EnsureRoot, RawOrigin}; use hex_literal::hex; pub use node_primitives::{ - AccountId, Amount, Balance, BlockNumber, CurrencyId, ExtraFeeName, Moment, Nonce, ParaId, - ParachainDerivedProxyAccountType, ParachainTransactProxyType, ParachainTransactType, PoolId, - RpcContributionStatus, TokenSymbol, TransferOriginType, XcmBaseWeight, - traits::CheckSubAccount, + traits::CheckSubAccount, AccountId, Amount, Balance, BlockNumber, CurrencyId, ExtraFeeName, + Moment, Nonce, ParaId, ParachainDerivedProxyAccountType, ParachainTransactProxyType, + ParachainTransactType, PoolId, RpcContributionStatus, TokenSymbol, TransferOriginType, + XcmBaseWeight, }; // orml imports use orml_currencies::BasicCurrencyAdapter; @@ -235,10 +235,7 @@ parameter_types! { } pub fn get_all_pallet_accounts() -> Vec { - vec![ - TreasuryPalletId::get().into_account(), - BifrostCrowdloanId::get().into_account(), - ] + vec![TreasuryPalletId::get().into_account(), BifrostCrowdloanId::get().into_account()] } impl frame_system::Config for Runtime {