Skip to content

Commit

Permalink
Merge pull request #812 from multiversx/fix/escrow-wrapper-unlockable…
Browse files Browse the repository at this point in the history
…-withdrawal-time

Fix: escrow transfers
  • Loading branch information
CostinCarabas authored Jan 15, 2024
2 parents ae6a9cf + 8b09f30 commit a246ee2
Show file tree
Hide file tree
Showing 2 changed files with 198 additions and 0 deletions.
1 change: 1 addition & 0 deletions locked-asset/lkmex-transfer/src/energy_transfer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub trait EnergyTransferModule:
let epoch_diff = current_epoch - attributes.unlock_epoch;
let simulated_deplete_amount = &token.amount * epoch_diff;
energy.remove_energy_raw(BigUint::zero(), simulated_deplete_amount);
energy.add_energy_raw(token.amount, BigInt::zero());
}
}

Expand Down
197 changes: 197 additions & 0 deletions locked-asset/lkmex-transfer/tests/lkmex_transfer_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,3 +619,200 @@ fn cancel_transfer_test() {
})
.assert_ok();
}

#[test]
fn transfer_locked_token_after_unlock_period_test() {
let rust_zero = rust_biguint!(0);
let mut b_mock = BlockchainStateWrapper::new();

let user_addr = b_mock.create_user_account(&rust_zero);
let claimer_addr = b_mock.create_user_account(&rust_zero);
let owner_addr = b_mock.create_user_account(&rust_zero);
let transfer_sc_wrapper = b_mock.create_sc_account(
&rust_zero,
Some(&owner_addr),
lkmex_transfer::contract_obj,
"Some path",
);
let factory_sc_wrapper = b_mock.create_sc_account(
&rust_zero,
Some(&owner_addr),
energy_factory::contract_obj,
"Some other path",
);

b_mock.set_block_epoch(5);

// Setup transfer SC
b_mock
.execute_tx(&owner_addr, &transfer_sc_wrapper, &rust_zero, |sc| {
sc.init(
managed_address!(factory_sc_wrapper.address_ref()),
managed_token_id!(LOCKED_TOKEN_ID),
4,
EPOCHS_IN_YEAR,
);
})
.assert_ok();

b_mock.set_esdt_local_roles(
transfer_sc_wrapper.address_ref(),
LOCKED_TOKEN_ID,
&[EsdtLocalRole::Transfer],
);

// setup energy factory SC
b_mock
.execute_tx(&owner_addr, &factory_sc_wrapper, &rust_zero, |sc| {
let mut lock_options = MultiValueEncoded::new();
for (option, penalty) in LOCK_OPTIONS.iter().zip(PENALTY_PERCENTAGES.iter()) {
lock_options.push((*option, *penalty).into());
}

// sc addresses don't matter here, we don't test that part
sc.init(
managed_token_id!(BASE_ASSET_TOKEN_ID),
managed_token_id!(LEGACY_LOCKED_TOKEN_ID),
managed_address!(transfer_sc_wrapper.address_ref()),
0,
lock_options,
);

sc.locked_token()
.set_token_id(managed_token_id!(LOCKED_TOKEN_ID));
sc.token_transfer_whitelist()
.add(&managed_address!(transfer_sc_wrapper.address_ref()));
sc.set_paused(false);
})
.assert_ok();

b_mock.set_esdt_local_roles(
factory_sc_wrapper.address_ref(),
BASE_ASSET_TOKEN_ID,
&[EsdtLocalRole::Mint, EsdtLocalRole::Burn],
);
b_mock.set_esdt_local_roles(
factory_sc_wrapper.address_ref(),
LOCKED_TOKEN_ID,
&[
EsdtLocalRole::NftCreate,
EsdtLocalRole::NftAddQuantity,
EsdtLocalRole::NftBurn,
EsdtLocalRole::Transfer,
],
);
b_mock.set_esdt_local_roles(
factory_sc_wrapper.address_ref(),
LEGACY_LOCKED_TOKEN_ID,
&[EsdtLocalRole::NftBurn],
);

// setup user balance

b_mock.set_esdt_balance(
&user_addr,
BASE_ASSET_TOKEN_ID,
&rust_biguint!(USER_BALANCE),
);

// lock tokens
b_mock
.execute_esdt_transfer(
&user_addr,
&factory_sc_wrapper,
BASE_ASSET_TOKEN_ID,
0,
&rust_biguint!(USER_BALANCE),
|sc| {
sc.lock_tokens_endpoint(LOCK_OPTIONS[0], OptionalValue::None);

let unlock_epoch = sc.unlock_epoch_to_start_of_month(5 + LOCK_OPTIONS[0]);
let lock_epochs = unlock_epoch - 5;
let expected_energy_amount =
BigInt::from(USER_BALANCE as i64) * BigInt::from(lock_epochs as i64);
let expected_energy =
Energy::new(expected_energy_amount, 5, managed_biguint!(USER_BALANCE));
let actual_energy = sc.user_energy(&managed_address!(&user_addr)).get();
assert_eq!(expected_energy, actual_energy);
},
)
.assert_ok();

// transfer half of the LKMEX to other user
b_mock
.execute_esdt_transfer(
&user_addr,
&transfer_sc_wrapper,
LOCKED_TOKEN_ID,
1,
&rust_biguint!(USER_BALANCE / 2),
|sc| {
sc.lock_funds(managed_address!(&claimer_addr));
},
)
.assert_ok();

// check first user energy after transfer
b_mock
.execute_query(&factory_sc_wrapper, |sc| {
let unlock_epoch = sc.unlock_epoch_to_start_of_month(5 + LOCK_OPTIONS[0]);
let lock_epochs = unlock_epoch - 5;
let expected_energy_amount =
BigInt::from((USER_BALANCE / 2) as i64) * BigInt::from(lock_epochs as i64);
let expected_energy = Energy::new(
expected_energy_amount,
5,
managed_biguint!(USER_BALANCE / 2),
);
let actual_energy = sc.user_energy(&managed_address!(&user_addr)).get();
assert_eq!(expected_energy, actual_energy);
})
.assert_ok();

let current_epoch = EPOCHS_IN_YEAR + 10;
// pass 5 epochs
b_mock.set_block_epoch(current_epoch);

// second user claim
b_mock
.execute_tx(&claimer_addr, &transfer_sc_wrapper, &rust_zero, |sc| {
sc.withdraw(managed_address!(&user_addr));
})
.assert_ok();

// check first user energy
b_mock
.execute_query(&factory_sc_wrapper, |sc| {
let unlock_epoch = sc.unlock_epoch_to_start_of_month(5 + LOCK_OPTIONS[0]);
let lock_epochs = unlock_epoch as i64 - current_epoch as i64;
let expected_energy_amount =
BigInt::from((USER_BALANCE / 2) as i64) * BigInt::from(lock_epochs);
let expected_energy = Energy::new(
expected_energy_amount,
current_epoch,
managed_biguint!(USER_BALANCE / 2),
);

let actual_energy = sc.user_energy(&managed_address!(&claimer_addr)).get();
assert_eq!(expected_energy, actual_energy);
})
.assert_ok();

// check second user energy
b_mock
.execute_query(&factory_sc_wrapper, |sc| {
let unlock_epoch = sc.unlock_epoch_to_start_of_month(5 + LOCK_OPTIONS[0]);
let lock_epochs = unlock_epoch as i64 - current_epoch as i64;
let expected_energy_amount =
BigInt::from((USER_BALANCE / 2) as i64) * BigInt::from(lock_epochs);
let expected_energy = Energy::new(
expected_energy_amount,
current_epoch,
managed_biguint!(USER_BALANCE / 2),
);

let actual_energy = sc.user_energy(&managed_address!(&claimer_addr)).get();
assert_eq!(expected_energy, actual_energy);
})
.assert_ok();
}

0 comments on commit a246ee2

Please sign in to comment.