From a7ba9f86f19370fd05afe89af6a5559c49ddcb7a Mon Sep 17 00:00:00 2001 From: Sorin Petreasca Date: Mon, 17 Feb 2025 17:04:24 +0200 Subject: [PATCH 1/4] Max limit on unbond locked tokens --- .../token-unstake/src/unbond_tokens.rs | 8 +++- .../token-unstake/tests/token_unstake_test.rs | 42 ++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/locked-asset/token-unstake/src/unbond_tokens.rs b/locked-asset/token-unstake/src/unbond_tokens.rs index 20aeb1843..1141222a9 100644 --- a/locked-asset/token-unstake/src/unbond_tokens.rs +++ b/locked-asset/token-unstake/src/unbond_tokens.rs @@ -2,6 +2,8 @@ use crate::events; multiversx_sc::imports!(); +pub const MAX_CLAIM_UNLOCKED_TOKENS: u64 = 30; + #[multiversx_sc::module] pub trait UnbondTokensModule: crate::tokens_per_user::TokensPerUserModule @@ -16,9 +18,11 @@ pub trait UnbondTokensModule: let current_epoch = self.blockchain().get_block_epoch(); let mut output_payments = ManagedVec::new(); let mut penalty_tokens = ManagedVec::::new(); + let mut processed_count = 0; + self.unlocked_tokens_for_user(&caller) .update(|user_entries| { - while !user_entries.is_empty() { + while !user_entries.is_empty() && processed_count < MAX_CLAIM_UNLOCKED_TOKENS { let entry = user_entries.get(0); if current_epoch < entry.unlock_epoch { break; @@ -48,6 +52,8 @@ pub trait UnbondTokensModule: output_payments.push(unlocked_tokens); user_entries.remove(0); + + processed_count += 1; } }); diff --git a/locked-asset/token-unstake/tests/token_unstake_test.rs b/locked-asset/token-unstake/tests/token_unstake_test.rs index e247a4a0d..03f08ab31 100644 --- a/locked-asset/token-unstake/tests/token_unstake_test.rs +++ b/locked-asset/token-unstake/tests/token_unstake_test.rs @@ -9,7 +9,10 @@ use multiversx_sc_scenario::{ use num_bigint::ToBigInt; use num_traits::cast::ToPrimitive; use simple_lock::locked_token::LockedTokenAttributes; -use token_unstake::tokens_per_user::{TokensPerUserModule, UnstakePair}; +use token_unstake::{ + tokens_per_user::{TokensPerUserModule, UnstakePair}, + unbond_tokens::MAX_CLAIM_UNLOCKED_TOKENS, +}; use token_unstake_setup::*; pub struct ResultWrapper @@ -99,6 +102,43 @@ fn cancel_unbond_test() { assert_eq!(user_energy, expected_energy); } +#[test] +fn unstake_multiple_position_test() { + let mut setup = + TokenUnstakeSetup::new(energy_factory::contract_obj, token_unstake::contract_obj); + let first_user = setup.first_user.clone(); + + let _ = setup.lock( + &first_user, + BASE_ASSET_TOKEN_ID, + USER_BALANCE, + LOCK_OPTIONS[2], + ); + + let number_of_unlocks = MAX_CLAIM_UNLOCKED_TOKENS * 2; + for _ in 0..number_of_unlocks { + let _ = setup.unlock_early(&first_user, 1, USER_BALANCE / number_of_unlocks); + } + + // unbond epochs pass + setup.b_mock.set_block_epoch(10 + UNBOND_EPOCHS); + // unbond ok + setup.unbond(&first_user).assert_ok(); + let mut balance_after_half_unlocks = rust_biguint!(USER_BALANCE as u128 / 2 * 2000 / 10000); // 80% fee on half balance + balance_after_half_unlocks += &rust_biguint!(20u64); // rounding difference + setup.b_mock.check_esdt_balance( + &first_user, + BASE_ASSET_TOKEN_ID, + &balance_after_half_unlocks, + ); + + setup.unbond(&first_user).assert_ok(); + let balance_after_all_unlocks = balance_after_half_unlocks * 2u64; + setup + .b_mock + .check_esdt_balance(&first_user, BASE_ASSET_TOKEN_ID, &balance_after_all_unlocks); +} + fn unbond_test_common( energy_factory_builder: EnergyFactoryBuilder, unstake_sc_builder: UnstakeScBuilder, From a4f64c4fff387667f1f49da6263dbfda658b5215 Mon Sep 17 00:00:00 2001 From: Sorin Petreasca Date: Mon, 17 Feb 2025 17:06:28 +0200 Subject: [PATCH 2/4] github actions v4.2.2 --- .github/workflows/actions.yml | 4 ++-- .github/workflows/release.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index f50d01216..bf93561f9 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -20,9 +20,9 @@ permissions: jobs: contracts: name: Contracts - uses: multiversx/mx-sc-actions/.github/workflows/contracts.yml@v4.2.1 + uses: multiversx/mx-sc-actions/.github/workflows/contracts.yml@v4.2.2 with: rust-toolchain: stable coverage-args: --ignore-filename-regex='/.cargo/git' --output ./coverage.md secrets: - token: ${{ secrets.GITHUB_TOKEN }} + token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8672e0210..b4c91728d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,7 +9,7 @@ permissions: jobs: build: - uses: multiversx/mx-sc-actions/.github/workflows/reproducible-build.yml@v4.2.1 + uses: multiversx/mx-sc-actions/.github/workflows/reproducible-build.yml@v4.2.2 with: image_tag: v7.0.0 - attach_to_existing_release: true + attach_to_existing_release: true \ No newline at end of file From 4e553f78b7cdbf7c27ea2815d4b4484f75b30d25 Mon Sep 17 00:00:00 2001 From: Sorin Petreasca Date: Tue, 25 Feb 2025 10:59:45 +0200 Subject: [PATCH 3/4] updated MAX_CLAIM_UNLOCKED_TOKENS constant --- locked-asset/token-unstake/src/unbond_tokens.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locked-asset/token-unstake/src/unbond_tokens.rs b/locked-asset/token-unstake/src/unbond_tokens.rs index 1141222a9..74635fa2a 100644 --- a/locked-asset/token-unstake/src/unbond_tokens.rs +++ b/locked-asset/token-unstake/src/unbond_tokens.rs @@ -2,7 +2,7 @@ use crate::events; multiversx_sc::imports!(); -pub const MAX_CLAIM_UNLOCKED_TOKENS: u64 = 30; +pub const MAX_CLAIM_UNLOCKED_TOKENS: u64 = 20; #[multiversx_sc::module] pub trait UnbondTokensModule: From 180b1adb488f40d96794cdc16fff42448ba7f424 Mon Sep 17 00:00:00 2001 From: Sorin Petreasca Date: Tue, 25 Feb 2025 11:10:07 +0200 Subject: [PATCH 4/4] fixed unit test --- locked-asset/token-unstake/tests/token_unstake_test.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/locked-asset/token-unstake/tests/token_unstake_test.rs b/locked-asset/token-unstake/tests/token_unstake_test.rs index 03f08ab31..5627c6d1e 100644 --- a/locked-asset/token-unstake/tests/token_unstake_test.rs +++ b/locked-asset/token-unstake/tests/token_unstake_test.rs @@ -124,8 +124,7 @@ fn unstake_multiple_position_test() { setup.b_mock.set_block_epoch(10 + UNBOND_EPOCHS); // unbond ok setup.unbond(&first_user).assert_ok(); - let mut balance_after_half_unlocks = rust_biguint!(USER_BALANCE as u128 / 2 * 2000 / 10000); // 80% fee on half balance - balance_after_half_unlocks += &rust_biguint!(20u64); // rounding difference + let balance_after_half_unlocks = rust_biguint!(USER_BALANCE as u128 / 2 * 2000 / 10000); // 80% fee on half balance setup.b_mock.check_esdt_balance( &first_user, BASE_ASSET_TOKEN_ID,