Skip to content

Commit

Permalink
Fix/rewards market GASP-1681 (#855)
Browse files Browse the repository at this point in the history
  • Loading branch information
vanderian authored Dec 5, 2024
1 parent ca3b61d commit f65a480
Show file tree
Hide file tree
Showing 23 changed files with 757 additions and 737 deletions.
272 changes: 137 additions & 135 deletions Cargo.lock

Large diffs are not rendered by default.

265 changes: 132 additions & 133 deletions Cargo.toml

Large diffs are not rendered by default.

29 changes: 27 additions & 2 deletions pallets/bootstrap/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ use frame_support::{
WithdrawReasons,
},
};
use mangata_support::traits::ActivationReservesProviderTrait;
use mangata_support::{
pools::{PoolInfo, Valuate, ValuateFor},
traits::ActivationReservesProviderTrait,
};
use mangata_types::multipurpose_liquidity::ActivateKind;
use orml_tokens::MultiTokenCurrencyAdapter;
use orml_traits::parameter_type_with_key;
Expand Down Expand Up @@ -139,6 +142,28 @@ impl pallet_xyk::Config for Test {
type FeeLockWeight = ();
}

mockall::mock! {
pub ValuationApi {}

impl Valuate for ValuationApi {
type CurrencyId = TokenId;
type Balance = Balance;

fn find_paired_pool(base_id: TokenId, asset_id: TokenId) -> Result<PoolInfo<TokenId, Balance>, DispatchError>;

fn check_can_valuate(base_id: TokenId, pool_id: TokenId) -> Result<(), DispatchError>;

fn check_pool_exist(pool_id: TokenId) -> Result<(), DispatchError>;

fn get_reserve_and_lp_supply(base_id: TokenId, pool_id: TokenId) -> Option<(Balance, Balance)>;

fn get_valuation_for_paired(base_id: TokenId, pool_id: TokenId, amount: Balance) -> Balance;

fn find_valuation(base_id: TokenId, asset_id: TokenId, amount: Balance) -> Result<Balance, DispatchError>;
}
}
impl ValuateFor<NativeCurrencyId> for MockValuationApi {}

impl pallet_proof_of_stake::Config for Test {
type RuntimeEvent = RuntimeEvent;
type ActivationReservesProvider = TokensActivationPassthrough<Test>;
Expand All @@ -150,7 +175,7 @@ impl pallet_proof_of_stake::Config for Test {
type RewardsSchedulesLimit = ConstU32<10>;
type Min3rdPartyRewardValutationPerSession = ConstU128<10>;
type Min3rdPartyRewardVolume = ConstU128<10>;
type ValuationApi = Xyk;
type ValuationApi = MockValuationApi;
type SchedulesPerBlock = ConstU32<5>;
type NontransferableTokens = Nothing;
}
Expand Down
1 change: 1 addition & 0 deletions pallets/fee-lock/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ env_logger.workspace = true
lazy_static.workspace = true
serial_test.workspace = true
test-case.workspace = true
mockall.workspace = true

sp-io = { workspace = true, default-features = false }

Expand Down
8 changes: 2 additions & 6 deletions pallets/fee-lock/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,9 @@ benchmarks! {

// Order of tokens in the create_pool call below is important
#[cfg(not(test))]
assert_ok!(<T as Config>::PoolReservesProvider::create_pool(caller, valuating_token_id, pool_amount, token_id, pool_amount.saturating_mul(2u8.into())));
assert_ok!(<T as Config>::Xyk::create_pool(caller, valuating_token_id, pool_amount, token_id, pool_amount.saturating_mul(2u8.into())));

// We want to avoid having the value being 1000, since that is what get_swap_valuation_for_token returns if the valuating_token_id is the native token id
#[cfg(test)]
let value: BalanceOf<T> = 500_u32.into();
#[cfg(not(test))]
let value: BalanceOf<T> = 2000_u32.into();
let value: BalanceOf<T> = 1980_u32.into();
let mut valuation: Option<BalanceOf<T>> = None;
}: {valuation = FeeLock::<T>::get_swap_valuation_for_token(valuating_token_id, valuating_token_amount);}
verify{
Expand Down
44 changes: 16 additions & 28 deletions pallets/fee-lock/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ use frame_support::{
transactional,
};
use frame_system::{ensure_signed, pallet_prelude::*};
use mangata_support::traits::{FeeLockTriggerTrait, Valuate, XykFunctionsTrait};
use mangata_support::{
pools::ValuateFor,
traits::{FeeLockTriggerTrait, XykFunctionsTrait},
};
use orml_tokens::{MultiTokenCurrencyExtended, MultiTokenReservableCurrency};
use sp_arithmetic::per_things::Rounding;
use sp_runtime::helpers_128bit::multiply_by_rational_with_rounding;

use sp_runtime::{
traits::{Bounded, CheckedAdd, SaturatedConversion, Zero},
traits::{CheckedAdd, Zero},
Saturating,
};
use sp_std::{convert::TryInto, prelude::*};
Expand Down Expand Up @@ -225,14 +226,16 @@ pub mod pallet {
type MaxCuratedTokens: Get<u32>;
type Tokens: MultiTokenCurrencyExtended<Self::AccountId>
+ MultiTokenReservableCurrency<Self::AccountId>;
#[cfg(not(all(feature = "runtime-benchmarks", not(test))))]
type PoolReservesProvider: Valuate<BalanceOf<Self>, CurrencyIdOf<Self>>;
#[cfg(all(feature = "runtime-benchmarks", not(test)))]
type PoolReservesProvider: Valuate<BalanceOf<Self>, CurrencyIdOf<Self>>
+ XykFunctionsTrait<Self::AccountId, BalanceOf<Self>, CurrencyIdOf<Self>>;
type ValuateForNative: ValuateFor<
Self::NativeTokenId,
Balance = BalanceOf<Self>,
CurrencyId = CurrencyIdOf<Self>,
>;
#[pallet::constant]
type NativeTokenId: Get<CurrencyIdOf<Self>>;
type WeightInfo: WeightInfo;
#[cfg(all(feature = "runtime-benchmarks", not(test)))]
type Xyk: XykFunctionsTrait<Self::AccountId, BalanceOf<Self>, CurrencyIdOf<Self>>;
}

#[pallet::genesis_config]
Expand Down Expand Up @@ -393,25 +396,10 @@ impl<T: Config> FeeLockTriggerTrait<T::AccountId, BalanceOf<T>, CurrencyIdOf<T>>
if T::NativeTokenId::get() == valuating_token_id {
return Some(valuating_token_amount)
}
let (native_token_pool_reserve, valuating_token_pool_reserve) =
<T::PoolReservesProvider as Valuate<BalanceOf<T>, CurrencyIdOf<T>>>::get_reserves(
T::NativeTokenId::get(),
valuating_token_id,
)
.ok()?;
if native_token_pool_reserve.is_zero() || valuating_token_pool_reserve.is_zero() {
return None
}
Some(
multiply_by_rational_with_rounding(
valuating_token_amount.into(),
native_token_pool_reserve.into(),
valuating_token_pool_reserve.into(),
Rounding::Down,
)
.map(SaturatedConversion::saturated_into)
.unwrap_or(BalanceOf::<T>::max_value()),
)
let value =
T::ValuateForNative::find_valuation_for(valuating_token_id, valuating_token_amount)
.ok()?;
Some(value)
}

fn process_fee_lock(who: &T::AccountId) -> DispatchResult {
Expand Down
70 changes: 28 additions & 42 deletions pallets/fee-lock/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use frame_support::{
PalletId,
};
use frame_system as system;
use mangata_support::pools::{PoolInfo, Valuate, ValuateFor};
use orml_traits::parameter_type_with_key;
use sp_runtime::{traits::AccountIdConversion, BuildStorage};
use sp_std::convert::TryFrom;
Expand Down Expand Up @@ -77,63 +78,48 @@ parameter_types! {
pub const BnbTreasurySubAccDerive: [u8; 4] = *b"bnbt";
}

pub struct MockPoolReservesProvider<T>(PhantomData<T>);
pub struct MockValuateForNative {}
impl ValuateFor<NativeCurrencyId> for MockValuateForNative {}
impl Valuate for MockValuateForNative {
type Balance = Balance;
type CurrencyId = TokenId;

impl<T: pallet_fee_lock::Config> Valuate<Balance, TokenId> for MockPoolReservesProvider<T> {
fn get_liquidity_asset(
_first_asset_id: TokenId,
_second_asset_id: TokenId,
) -> Result<TokenId, DispatchError> {
fn find_paired_pool(
base_id: Self::CurrencyId,
asset_id: Self::CurrencyId,
) -> Result<PoolInfo<Self::CurrencyId, Self::Balance>, DispatchError> {
unimplemented!()
}

fn get_liquidity_token_mga_pool(
_liquidity_token_id: TokenId,
) -> Result<(TokenId, TokenId), DispatchError> {
fn check_can_valuate(_: Self::CurrencyId, _: Self::CurrencyId) -> Result<(), DispatchError> {
unimplemented!()
}

fn valuate_liquidity_token(
_liquidity_token_id: TokenId,
_liquidity_token_amount: Balance,
) -> Balance {
fn check_pool_exist(pool_id: Self::CurrencyId) -> Result<(), DispatchError> {
unimplemented!()
}

fn scale_liquidity_by_mga_valuation(
_mga_valuation: Balance,
_liquidity_token_amount: Balance,
_mga_token_amount: Balance,
) -> Balance {
fn get_reserve_and_lp_supply(
_: Self::CurrencyId,
pool_id: Self::CurrencyId,
) -> Option<(Self::Balance, Self::Balance)> {
unimplemented!()
}

fn get_pool_state(_liquidity_token_id: TokenId) -> Option<(Balance, Balance)> {
fn get_valuation_for_paired(
_: Self::CurrencyId,
_: Self::CurrencyId,
amount: Self::Balance,
) -> Self::Balance {
unimplemented!()
}

fn get_reserves(
first_asset_id: TokenId,
second_asset_id: TokenId,
) -> Result<(Balance, Balance), DispatchError> {
match (first_asset_id, second_asset_id) {
(0, 1) => Ok((5000, 10000)),
(0, 2) => Ok((10000, 5000)),
(0, 3) => Ok((0, 10000)),
(0, 4) => Ok((5000, 0)),
_ => Err(pallet_fee_lock::Error::<T>::UnexpectedFailure.into()),
}
}

fn is_liquidity_token(liquidity_asset_id: TokenId) -> bool {
unimplemented!()
}

fn valuate_non_liquidity_token(
liquidity_token_id: TokenId,
liquidity_token_amount: Balance,
) -> Balance {
unimplemented!()
fn find_valuation(
_: Self::CurrencyId,
_: Self::CurrencyId,
_: Self::Balance,
) -> Result<Self::Balance, DispatchError> {
Ok(1980_u128)
}
}

Expand All @@ -146,7 +132,7 @@ impl pallet_fee_lock::Config for Test {
type RuntimeEvent = RuntimeEvent;
type MaxCuratedTokens = MaxCuratedTokens;
type Tokens = orml_tokens::MultiTokenCurrencyAdapter<Test>;
type PoolReservesProvider = MockPoolReservesProvider<Test>;
type ValuateForNative = MockValuateForNative;
type NativeTokenId = NativeCurrencyId;
type WeightInfo = ();
}
Expand Down
93 changes: 1 addition & 92 deletions pallets/fee-lock/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,7 @@ fn unlock_fee_works() {
}

#[test]
// valuation removed, we are not testing mocks & external apis
fn whitelist_and_valuation_works() {
new_test_ext().execute_with(|| {
assert_ok!(FeeLock::update_fee_lock_metadata(
Expand Down Expand Up @@ -654,98 +655,6 @@ fn whitelist_and_valuation_works() {
assert!(<FeeLock as FeeLockTriggerTrait<_, _, _>>::is_whitelisted(2));

assert!(!<FeeLock as FeeLockTriggerTrait<_, _, _>>::is_whitelisted(3));

assert_eq!(
<FeeLock as FeeLockTriggerTrait<_, _, _>>::get_swap_valuation_for_token(0, 1000),
Some(1000)
);
assert_eq!(
<FeeLock as FeeLockTriggerTrait<_, _, _>>::get_swap_valuation_for_token(0, 0),
Some(0)
);
assert_eq!(
<FeeLock as FeeLockTriggerTrait<_, _, _>>::get_swap_valuation_for_token(
0,
u128::max_value()
),
Some(u128::max_value())
);

assert_eq!(
<FeeLock as FeeLockTriggerTrait<_, _, _>>::get_swap_valuation_for_token(1, 1000),
Some(500)
);
assert_eq!(
<FeeLock as FeeLockTriggerTrait<_, _, _>>::get_swap_valuation_for_token(1, 0),
Some(0)
);
assert_eq!(
<FeeLock as FeeLockTriggerTrait<_, _, _>>::get_swap_valuation_for_token(
1,
u128::max_value()
),
Some(u128::max_value() / 2)
);
assert_eq!(
<FeeLock as FeeLockTriggerTrait<_, _, _>>::get_swap_valuation_for_token(2, 1000),
Some(2000)
);
assert_eq!(
<FeeLock as FeeLockTriggerTrait<_, _, _>>::get_swap_valuation_for_token(2, 0),
Some(0)
);
assert_eq!(
<FeeLock as FeeLockTriggerTrait<_, _, _>>::get_swap_valuation_for_token(
2,
u128::max_value()
),
Some(u128::max_value())
);
assert_eq!(
<FeeLock as FeeLockTriggerTrait<_, _, _>>::get_swap_valuation_for_token(3, 1000),
None
);
assert_eq!(
<FeeLock as FeeLockTriggerTrait<_, _, _>>::get_swap_valuation_for_token(3, 0),
None
);
assert_eq!(
<FeeLock as FeeLockTriggerTrait<_, _, _>>::get_swap_valuation_for_token(
3,
u128::max_value()
),
None
);
assert_eq!(
<FeeLock as FeeLockTriggerTrait<_, _, _>>::get_swap_valuation_for_token(4, 1000),
None
);
assert_eq!(
<FeeLock as FeeLockTriggerTrait<_, _, _>>::get_swap_valuation_for_token(4, 0),
None
);
assert_eq!(
<FeeLock as FeeLockTriggerTrait<_, _, _>>::get_swap_valuation_for_token(
4,
u128::max_value()
),
None
);
assert_eq!(
<FeeLock as FeeLockTriggerTrait<_, _, _>>::get_swap_valuation_for_token(5, 1000),
None
);
assert_eq!(
<FeeLock as FeeLockTriggerTrait<_, _, _>>::get_swap_valuation_for_token(5, 0),
None
);
assert_eq!(
<FeeLock as FeeLockTriggerTrait<_, _, _>>::get_swap_valuation_for_token(
5,
u128::max_value()
),
None
);
})
}

Expand Down
Loading

0 comments on commit f65a480

Please sign in to comment.