diff --git a/runtime-modules/project-token/src/lib.rs b/runtime-modules/project-token/src/lib.rs index 4d86e311ea..5bd78e9361 100644 --- a/runtime-modules/project-token/src/lib.rs +++ b/runtime-modules/project-token/src/lib.rs @@ -890,6 +890,7 @@ decl_module! { /// - user usable JOY balance must be enough for buying (+ existential deposit) /// - slippage tolerance constraints respected if provided /// - token total supply and amount value must be s.t. `eval` function doesn't overflow + /// - token supply can be modified (there is no active revenue split) /// /// Postconditions /// - `amount` CRT minted into account (which is created if necessary with existential deposit transferred to it) @@ -911,6 +912,8 @@ decl_module! { )?; let token_data = Self::ensure_token_exists(token_id)?; + token_data.ensure_can_modify_supply::()?; + let curve = token_data.amm_curve.ok_or(Error::::NotInAmmState)?; let user_account_data_exists = AccountInfoByTokenAndMember::::contains_key(token_id, member_id); @@ -975,6 +978,7 @@ decl_module! { /// - slippage tolerance constraints respected if provided /// - token total supply and amount value must be s.t. `eval` function doesn't overflow /// - amm treasury account must have sufficient JOYs for the operation + /// - token supply can be modified (there is no active revenue split) /// /// Postconditions /// - `amount` burned from user account @@ -997,6 +1001,8 @@ decl_module! { )?; let token_data = Self::ensure_token_exists(token_id)?; + token_data.ensure_can_modify_supply::()?; + let curve = token_data.amm_curve.ok_or(Error::::NotInAmmState)?; let user_acc_data = Self::ensure_account_data_exists(token_id, &member_id)?; diff --git a/runtime-modules/project-token/src/tests/amm.rs b/runtime-modules/project-token/src/tests/amm.rs index f60e3d6538..b11c9bb2c1 100644 --- a/runtime-modules/project-token/src/tests/amm.rs +++ b/runtime-modules/project-token/src/tests/amm.rs @@ -151,6 +151,34 @@ fn amm_buy_succeeds_with_existing_user() { }) } +#[test] +fn amm_buy_fails_with_revenue_split() { + let (user_member_id, user_account_id) = member!(1); + build_default_test_externalities_with_balances(vec![( + user_account_id, + DEFAULT_SPLIT_REVENUE + + amm_function_buy_values_with_tx_fees(DEFAULT_AMM_BUY_AMOUNT, Zero::zero()) + + ed(), + )]) + .execute_with(|| { + IssueTokenFixture::default().execute_call().unwrap(); + ActivateAmmFixture::default().execute_call().unwrap(); + + IssueRevenueSplitFixture::default().execute_call().unwrap(); + + let result = AmmBuyFixture::default() + .with_sender(user_account_id) + .with_amount(DEFAULT_AMM_BUY_AMOUNT) + .with_member_id(user_member_id) + .execute_call(); + + assert_err!( + result, + Error::::CannotModifySupplyWhenRevenueSplitsAreActive + ); + }) +} + #[test] fn amm_buy_failed_with_slippage_constraint_violated() { let slippage_tolerance = (Permill::zero(), Balance::zero()); @@ -875,6 +903,29 @@ fn amm_sell_ok_with_event_deposited() { }) } +#[test] +fn amm_sell_fails_with_revenue_split() { + build_default_test_externalities_with_balances(vec![( + member!(1).1, + DEFAULT_AMM_BUY_AMOUNT + DEFAULT_SPLIT_REVENUE + ExistentialDeposit::get(), + )]) + .execute_with(|| { + IssueTokenFixture::default().execute_call().unwrap(); + TransferFixture::default().execute_call().unwrap(); + IssueRevenueSplitFixture::default().execute_call().unwrap(); + ActivateAmmFixture::default().execute_call().unwrap(); + + let result = AmmSellFixture::default() + .with_amount(DEFAULT_AMM_BUY_AMOUNT) + .execute_call(); + + assert_err!( + result, + Error::::CannotModifySupplyWhenRevenueSplitsAreActive + ); + }) +} + // ------------------- DEACTIVATE --------------------------------------- #[test]