diff --git a/crates/sui-framework/docs/validator_set.md b/crates/sui-framework/docs/validator_set.md index 1f89e089dd44f..c37cd14253d0d 100644 --- a/crates/sui-framework/docs/validator_set.md +++ b/crates/sui-framework/docs/validator_set.md @@ -477,6 +477,15 @@ The epoch value corresponds to the first epoch this change takes place. + + + + +
const EStakingBelowThreshold: u64 = 10;
+
+
+
+
@@ -486,6 +495,15 @@ The epoch value corresponds to the first epoch this change takes place.
+
+
+
+
+const MIN_STAKING_THRESHOLD: u64 = 1000000000;
+
+
+
+
## Function `new`
@@ -743,6 +761,7 @@ Only an active validator can request to be removed.
Called by sui_system
, to add a new stake to the validator.
This request is added to the validator's staking pool's pending stake entries, processed at the end
of the epoch.
+Aborts in case the staking amount is smaller than MIN_STAKING_THRESHOLD
public(friend) fun request_add_stake(self: &mut validator_set::ValidatorSet, validator_address: address, stake: balance::Balance<sui::SUI>, ctx: &mut tx_context::TxContext)
@@ -760,6 +779,8 @@ of the epoch.
stake: Balance<SUI>,
ctx: &mut TxContext,
) {
+ let sui_amount = balance::value(&stake);
+ assert!(sui_amount >= MIN_STAKING_THRESHOLD, EStakingBelowThreshold);
let validator = get_candidate_or_active_validator_mut(self, validator_address);
validator::request_add_stake(validator, stake, tx_context::sender(ctx), ctx);
}
diff --git a/crates/sui-framework/packages/sui-system/sources/validator_set.move b/crates/sui-framework/packages/sui-system/sources/validator_set.move
index 000750bf0790c..b3f9147e37b54 100644
--- a/crates/sui-framework/packages/sui-system/sources/validator_set.move
+++ b/crates/sui-framework/packages/sui-system/sources/validator_set.move
@@ -108,6 +108,7 @@ module sui_system::validator_set {
const ANY_VALIDATOR: u8 = 3;
const BASIS_POINT_DENOMINATOR: u128 = 10000;
+ const MIN_STAKING_THRESHOLD: u64 = 1_000_000_000; // 1 SUI
// Errors
const ENonValidatorInReportRecords: u64 = 0;
@@ -120,7 +121,7 @@ module sui_system::validator_set {
const EValidatorNotCandidate: u64 = 7;
const ENotValidatorCandidate: u64 = 8;
const ENotActiveOrPendingValidator: u64 = 9;
-
+ const EStakingBelowThreshold: u64 = 10;
const EInvalidCap: u64 = 101;
@@ -265,12 +266,15 @@ module sui_system::validator_set {
/// Called by `sui_system`, to add a new stake to the validator.
/// This request is added to the validator's staking pool's pending stake entries, processed at the end
/// of the epoch.
+ /// Aborts in case the staking amount is smaller than MIN_STAKING_THRESHOLD
public(friend) fun request_add_stake(
self: &mut ValidatorSet,
validator_address: address,
stake: Balance,
ctx: &mut TxContext,
) {
+ let sui_amount = balance::value(&stake);
+ assert!(sui_amount >= MIN_STAKING_THRESHOLD, EStakingBelowThreshold);
let validator = get_candidate_or_active_validator_mut(self, validator_address);
validator::request_add_stake(validator, stake, tx_context::sender(ctx), ctx);
}
diff --git a/crates/sui-framework/packages/sui-system/tests/delegation_tests.move b/crates/sui-framework/packages/sui-system/tests/delegation_tests.move
index cbb62e00350f8..76940b12e1d2f 100644
--- a/crates/sui-framework/packages/sui-system/tests/delegation_tests.move
+++ b/crates/sui-framework/packages/sui-system/tests/delegation_tests.move
@@ -40,6 +40,8 @@ module sui_system::stake_tests {
// Generated using [fn test_proof_of_possession]
const NEW_VALIDATOR_POP: vector = x"8b93fc1b33379e2796d361c4056f0f04ad5aea7f4a8c02eaac57340ff09b6dc158eb1945eece103319167f420daf0cb3";
+ const MIST_PER_SUI: u64 = 1_000_000_000;
+
#[test]
fun test_split_join_staked_sui() {
let scenario_val = test_scenario::begin(STAKER_ADDR_1);
@@ -52,7 +54,7 @@ module sui_system::stake_tests {
{
let staked_sui = test_scenario::take_from_sender(scenario);
let ctx = test_scenario::ctx(scenario);
- staking_pool::split_staked_sui(&mut staked_sui, 20, ctx);
+ staking_pool::split_staked_sui(&mut staked_sui, 20 * MIST_PER_SUI, ctx);
test_scenario::return_to_sender(scenario, staked_sui);
};
@@ -67,12 +69,12 @@ module sui_system::stake_tests {
let amount1 = staking_pool::staked_sui_amount(&part1);
let amount2 = staking_pool::staked_sui_amount(&part2);
- assert!(amount1 == 20 || amount1 == 40, 102);
- assert!(amount2 == 20 || amount2 == 40, 103);
- assert!(amount1 + amount2 == 60, 104);
+ assert!(amount1 == 20 * MIST_PER_SUI || amount1 == 40 * MIST_PER_SUI, 102);
+ assert!(amount2 == 20 * MIST_PER_SUI || amount2 == 40 * MIST_PER_SUI, 103);
+ assert!(amount1 + amount2 == 60 * MIST_PER_SUI, 104);
staking_pool::join_staked_sui(&mut part1, part2);
- assert!(staking_pool::staked_sui_amount(&part1) == 60, 105);
+ assert!(staking_pool::staked_sui_amount(&part1) == 60 * MIST_PER_SUI, 105);
test_scenario::return_to_sender(scenario, part1);
};
test_scenario::end(scenario_val);
@@ -118,10 +120,10 @@ module sui_system::stake_tests {
// Create a stake to VALIDATOR_ADDR_1.
sui_system::request_add_stake(
- system_state_mut_ref, coin::mint_for_testing(60, ctx), VALIDATOR_ADDR_1, ctx);
+ system_state_mut_ref, coin::mint_for_testing(60 * MIST_PER_SUI, ctx), VALIDATOR_ADDR_1, ctx);
- assert!(sui_system::validator_stake_amount(system_state_mut_ref, VALIDATOR_ADDR_1) == 100, 101);
- assert!(sui_system::validator_stake_amount(system_state_mut_ref, VALIDATOR_ADDR_2) == 100, 102);
+ assert!(sui_system::validator_stake_amount(system_state_mut_ref, VALIDATOR_ADDR_1) == 100 * MIST_PER_SUI, 101);
+ assert!(sui_system::validator_stake_amount(system_state_mut_ref, VALIDATOR_ADDR_2) == 100 * MIST_PER_SUI, 102);
test_scenario::return_shared(system_state);
};
@@ -132,21 +134,21 @@ module sui_system::stake_tests {
{
let staked_sui = test_scenario::take_from_sender(scenario);
- assert!(staking_pool::staked_sui_amount(&staked_sui) == 60, 105);
+ assert!(staking_pool::staked_sui_amount(&staked_sui) == 60 * MIST_PER_SUI, 105);
let system_state = test_scenario::take_shared(scenario);
let system_state_mut_ref = &mut system_state;
- assert!(sui_system::validator_stake_amount(system_state_mut_ref, VALIDATOR_ADDR_1) == 160, 103);
- assert!(sui_system::validator_stake_amount(system_state_mut_ref, VALIDATOR_ADDR_2) == 100, 104);
+ assert!(sui_system::validator_stake_amount(system_state_mut_ref, VALIDATOR_ADDR_1) == 160 * MIST_PER_SUI, 103);
+ assert!(sui_system::validator_stake_amount(system_state_mut_ref, VALIDATOR_ADDR_2) == 100 * MIST_PER_SUI, 104);
let ctx = test_scenario::ctx(scenario);
// Unstake from VALIDATOR_ADDR_1
sui_system::request_withdraw_stake(system_state_mut_ref, staked_sui, ctx);
- assert!(sui_system::validator_stake_amount(system_state_mut_ref, VALIDATOR_ADDR_1) == 160, 107);
+ assert!(sui_system::validator_stake_amount(system_state_mut_ref, VALIDATOR_ADDR_1) == 160 * MIST_PER_SUI, 107);
test_scenario::return_shared(system_state);
};
@@ -155,7 +157,7 @@ module sui_system::stake_tests {
test_scenario::next_tx(scenario, STAKER_ADDR_1);
{
let system_state = test_scenario::take_shared(scenario);
- assert!(sui_system::validator_stake_amount(&mut system_state, VALIDATOR_ADDR_1) == 100, 107);
+ assert!(sui_system::validator_stake_amount(&mut system_state, VALIDATOR_ADDR_1) == 100 * MIST_PER_SUI, 107);
test_scenario::return_shared(system_state);
};
test_scenario::end(scenario_val);
@@ -182,7 +184,7 @@ module sui_system::stake_tests {
governance_test_utils::assert_validator_total_stake_amounts(
vector[VALIDATOR_ADDR_1, VALIDATOR_ADDR_2],
- vector[200, 100],
+ vector[200 * MIST_PER_SUI, 100 * MIST_PER_SUI],
scenario
);
@@ -199,8 +201,8 @@ module sui_system::stake_tests {
// 110 = stake + rewards for that stake
// 5 = validator rewards
- let reward_amt = if (should_distribute_rewards) 10 else 0;
- let validator_reward_amt = if (should_distribute_rewards) 5 else 0;
+ let reward_amt = if (should_distribute_rewards) 10 * MIST_PER_SUI else 0;
+ let validator_reward_amt = if (should_distribute_rewards) 5 * MIST_PER_SUI else 0;
// Make sure stake withdrawal happens
test_scenario::next_tx(scenario, STAKER_ADDR_1);
@@ -214,7 +216,7 @@ module sui_system::stake_tests {
), 0);
let staked_sui = test_scenario::take_from_sender(scenario);
- assert_eq(staking_pool::staked_sui_amount(&staked_sui), 100);
+ assert_eq(staking_pool::staked_sui_amount(&staked_sui), 100 * MIST_PER_SUI);
// Unstake from VALIDATOR_ADDR_1
assert_eq(total_sui_balance(STAKER_ADDR_1, scenario), 0);
@@ -222,7 +224,7 @@ module sui_system::stake_tests {
sui_system::request_withdraw_stake(system_state_mut_ref, staked_sui, ctx);
// Make sure they have all of their stake.
- assert_eq(total_sui_balance(STAKER_ADDR_1, scenario), 100 + reward_amt);
+ assert_eq(total_sui_balance(STAKER_ADDR_1, scenario), 100 * MIST_PER_SUI + reward_amt);
test_scenario::return_shared(system_state);
};
@@ -233,7 +235,7 @@ module sui_system::stake_tests {
if (should_distribute_rewards) unstake(VALIDATOR_ADDR_1, 0, scenario);
// Make sure have all of their stake. NB there is no epoch change. This is immediate.
- assert_eq(total_sui_balance(VALIDATOR_ADDR_1, scenario), 100 + reward_amt + validator_reward_amt);
+ assert_eq(total_sui_balance(VALIDATOR_ADDR_1, scenario), 100 * MIST_PER_SUI + reward_amt + validator_reward_amt);
test_scenario::end(scenario_val);
}
@@ -256,8 +258,8 @@ module sui_system::stake_tests {
// Each 100 MIST of stake gets 10 MIST and validators shares the 10 MIST from the storage fund
// so validator gets another 5 MIST.
- let reward_amt = 10;
- let validator_reward_amt = 5;
+ let reward_amt = 10 * MIST_PER_SUI;
+ let validator_reward_amt = 5 * MIST_PER_SUI;
// Make sure stake withdrawal happens
test_scenario::next_tx(scenario, STAKER_ADDR_1);
@@ -266,7 +268,7 @@ module sui_system::stake_tests {
let system_state_mut_ref = &mut system_state;
let staked_sui = test_scenario::take_from_sender(scenario);
- assert_eq(staking_pool::staked_sui_amount(&staked_sui), 100);
+ assert_eq(staking_pool::staked_sui_amount(&staked_sui), 100 * MIST_PER_SUI);
// Unstake from VALIDATOR_ADDR_1
assert_eq(total_sui_balance(STAKER_ADDR_1, scenario), 0);
@@ -274,7 +276,7 @@ module sui_system::stake_tests {
sui_system::request_withdraw_stake(system_state_mut_ref, staked_sui, ctx);
// Make sure they have all of their stake.
- assert_eq(total_sui_balance(STAKER_ADDR_1, scenario), 100 + reward_amt);
+ assert_eq(total_sui_balance(STAKER_ADDR_1, scenario), 100 * MIST_PER_SUI + reward_amt);
test_scenario::return_shared(system_state);
};
@@ -285,7 +287,7 @@ module sui_system::stake_tests {
unstake(VALIDATOR_ADDR_1, 0, scenario);
// Make sure have all of their stake. NB there is no epoch change. This is immediate.
- assert_eq(total_sui_balance(VALIDATOR_ADDR_1, scenario), 100 + reward_amt + validator_reward_amt);
+ assert_eq(total_sui_balance(VALIDATOR_ADDR_1, scenario), 100 * MIST_PER_SUI + reward_amt + validator_reward_amt);
test_scenario::end(scenario_val);
}
@@ -342,7 +344,7 @@ module sui_system::stake_tests {
// Unstake from the preactive validator. There should be no rewards earned.
governance_test_utils::unstake(STAKER_ADDR_1, 0, scenario);
- assert_eq(total_sui_balance(STAKER_ADDR_1, scenario), 100);
+ assert_eq(total_sui_balance(STAKER_ADDR_1, scenario), 100 * MIST_PER_SUI);
test_scenario::end(scenario_val);
}
@@ -358,7 +360,7 @@ module sui_system::stake_tests {
governance_test_utils::add_validator(NEW_VALIDATOR_ADDR, scenario);
- // Delegate 100 MIST to the pending validator. This should fail because pending active validators don't accept
+ // Delegate 100 SUI to the pending validator. This should fail because pending active validators don't accept
// new stakes or withdraws.
governance_test_utils::stake_with(STAKER_ADDR_1, NEW_VALIDATOR_ADDR, 100, scenario);
@@ -373,30 +375,31 @@ module sui_system::stake_tests {
add_validator_candidate(NEW_VALIDATOR_ADDR, NEW_VALIDATOR_PUBKEY, NEW_VALIDATOR_POP, scenario);
- // Delegate 100 MIST to the preactive validator
+ // Delegate 100 SUI to the preactive validator
stake_with(STAKER_ADDR_1, NEW_VALIDATOR_ADDR, 100, scenario);
- advance_epoch_with_reward_amounts(0, 70, scenario);
- stake_with(STAKER_ADDR_2, NEW_VALIDATOR_ADDR, 300, scenario);
+ advance_epoch_with_reward_amounts(0, 450, scenario);
+ // At this point we got the following distribution of SUI:
+ // V1: 250, V2: 250, storage fund: 250
+
+ stake_with(STAKER_ADDR_2, NEW_VALIDATOR_ADDR, 50, scenario);
stake_with(STAKER_ADDR_3, NEW_VALIDATOR_ADDR, 100, scenario);
// Now the preactive becomes active
add_validator(NEW_VALIDATOR_ADDR, scenario);
advance_epoch(scenario);
+ // At this point we got the following distribution of SUI
+ // V1: 250, V2: 250, storage fund: 250, NewVal: 250
- advance_epoch_with_reward_amounts(0, 80, scenario);
+ advance_epoch_with_reward_amounts(0, 100, scenario);
+ // At this point we got the following distribution of SUI
+ // V1: 275, V2: 275, storage fund: 275, NewVal: 275
- // staker 1 and 3 unstake from the validator and earns 9 MIST.
- // Although they stake in different epochs, they earn the same rewards as long as they unstake
+ // Although staker 1 and 3 stake in different epochs, they earn the same rewards as long as they unstake
// in the same epoch because the validator was preactive when they staked.
unstake(STAKER_ADDR_1, 0, scenario);
- assert_eq(total_sui_balance(STAKER_ADDR_1, scenario), 109);
+ assert_eq(total_sui_balance(STAKER_ADDR_1, scenario), 110 * MIST_PER_SUI);
unstake(STAKER_ADDR_3, 0, scenario);
- assert_eq(total_sui_balance(STAKER_ADDR_3, scenario), 109);
-
- advance_epoch_with_reward_amounts(0, 100, scenario);
- unstake(STAKER_ADDR_2, 0, scenario);
- // staker 2 earns about 27 MIST from the previous epoch and 5/8 of the 100 MIST.
- assert_eq(total_sui_balance(STAKER_ADDR_2, scenario), 300 + 27 + 59);
+ assert_eq(total_sui_balance(STAKER_ADDR_3, scenario), 110 * MIST_PER_SUI);
test_scenario::end(scenario_val);
}
@@ -424,7 +427,7 @@ module sui_system::stake_tests {
advance_epoch(scenario);
unstake(STAKER_ADDR_1, 0, scenario);
- assert_eq(total_sui_balance(STAKER_ADDR_1, scenario), 100 + 20);
+ assert_eq(total_sui_balance(STAKER_ADDR_1, scenario), 100 * MIST_PER_SUI + 20 * MIST_PER_SUI);
test_scenario::end(scenario_val);
}
@@ -453,7 +456,7 @@ module sui_system::stake_tests {
// Unstake now and the staker should get no rewards.
unstake(STAKER_ADDR_1, 0, scenario);
- assert_eq(total_sui_balance(STAKER_ADDR_1, scenario), 100);
+ assert_eq(total_sui_balance(STAKER_ADDR_1, scenario), 100 * MIST_PER_SUI);
test_scenario::end(scenario_val);
}
@@ -464,28 +467,23 @@ module sui_system::stake_tests {
let scenario_val = test_scenario::begin(VALIDATOR_ADDR_1);
let scenario = &mut scenario_val;
set_up_sui_system_state(scenario);
+ // Stake with exchange rate of 1.0
stake_with(STAKER_ADDR_1, VALIDATOR_ADDR_1, 100, scenario);
advance_epoch(scenario);
- // The first stake gets 10 MIST here.
advance_epoch_with_reward_amounts(0, 40, scenario);
- advance_epoch_safe_mode(scenario);
-
- stake_with(STAKER_ADDR_2, VALIDATOR_ADDR_1, 100, scenario);
+ // At this point we got the following distribution of SUI:
+ // V1: 220, V2: 110, storage fund: 110
advance_epoch_safe_mode(scenario);
- advance_epoch(scenario);
- // The first stake gets 10 MIST and the second one gets 8 here.
- advance_epoch_with_reward_amounts(0, 50, scenario);
+
+ advance_epoch_with_reward_amounts(0, 80, scenario);
+ // At this point we got the following distribution of SUI:
+ // V1: 260, V2: 130, storage fund: 130
advance_epoch_safe_mode(scenario);
unstake(STAKER_ADDR_1, 0, scenario);
- // 100 principal + 20 rewards
- assert_eq(total_sui_balance(STAKER_ADDR_1, scenario), 120);
-
- unstake(STAKER_ADDR_2, 0, scenario);
- // 100 principal + 8 rewards
- assert_eq(total_sui_balance(STAKER_ADDR_2, scenario), 108);
-
+ // 100 principal + 30 rewards
+ assert_eq(total_sui_balance(STAKER_ADDR_1, scenario), 130 * MIST_PER_SUI);
test_scenario::end(scenario_val);
}
diff --git a/crates/sui-framework/packages/sui-system/tests/governance_test_utils.move b/crates/sui-framework/packages/sui-system/tests/governance_test_utils.move
index 9f8631d45c0c4..a6b0f842b46c6 100644
--- a/crates/sui-framework/packages/sui-system/tests/governance_test_utils.move
+++ b/crates/sui-framework/packages/sui-system/tests/governance_test_utils.move
@@ -22,8 +22,10 @@ module sui_system::governance_test_utils {
use sui::test_utils;
use sui::balance::Balance;
+ const MIST_PER_SUI: u64 = 1_000_000_000;
+
public fun create_validator_for_testing(
- addr: address, init_stake_amount: u64, ctx: &mut TxContext
+ addr: address, init_stake_amount_in_sui: u64, ctx: &mut TxContext
): Validator {
let validator = validator::new_for_testing(
addr,
@@ -39,7 +41,7 @@ module sui_system::governance_test_utils {
b"/ip4/127.0.0.1/udp/80",
b"/ip4/127.0.0.1/udp/80",
b"/ip4/127.0.0.1/udp/80",
- option::some(balance::create_for_testing(init_stake_amount)),
+ option::some(balance::create_for_testing(init_stake_amount_in_sui * MIST_PER_SUI)),
1,
0,
true,
@@ -76,7 +78,7 @@ module sui_system::governance_test_utils {
);
let stake_subsidy = stake_subsidy::create(
- balance::create_for_testing(sui_supply_amount), // sui_supply
+ balance::create_for_testing(sui_supply_amount * MIST_PER_SUI), // sui_supply
0, // stake subsidy initial distribution amount
10, // stake_subsidy_period_length
0, // stake_subsidy_decrease_rate
@@ -86,7 +88,7 @@ module sui_system::governance_test_utils {
sui_system::create(
object::new(ctx), // it doesn't matter what ID sui system state has in tests
validators,
- balance::create_for_testing(storage_fund_amount), // storage_fund
+ balance::create_for_testing(storage_fund_amount * MIST_PER_SUI), // storage_fund
1, // protocol version
0, // chain_start_timestamp_ms
system_parameters,
@@ -133,7 +135,7 @@ module sui_system::governance_test_utils {
public fun advance_epoch_with_reward_amounts(
storage_charge: u64, computation_charge: u64, scenario: &mut Scenario
) {
- let storage_rebate = advance_epoch_with_reward_amounts_return_rebate(storage_charge, computation_charge, 0, scenario);
+ let storage_rebate = advance_epoch_with_reward_amounts_return_rebate(storage_charge * MIST_PER_SUI, computation_charge * MIST_PER_SUI, 0, scenario);
test_utils::destroy(storage_rebate)
}
@@ -150,7 +152,7 @@ module sui_system::governance_test_utils {
let ctx = test_scenario::ctx(scenario);
let storage_rebate = sui_system::advance_epoch_for_testing(
- &mut system_state, new_epoch, 1, storage_charge, computation_charge, 0, 0, reward_slashing_rate, 0, ctx
+ &mut system_state, new_epoch, 1, storage_charge * MIST_PER_SUI, computation_charge * MIST_PER_SUI, 0, 0, reward_slashing_rate, 0, ctx
);
test_utils::destroy(storage_rebate);
test_scenario::return_shared(system_state);
@@ -182,7 +184,7 @@ module sui_system::governance_test_utils {
let ctx = test_scenario::ctx(scenario);
- sui_system::request_add_stake(&mut system_state, coin::mint_for_testing(amount, ctx), validator, ctx);
+ sui_system::request_add_stake(&mut system_state, coin::mint_for_testing(amount * MIST_PER_SUI, ctx), validator, ctx);
test_scenario::return_shared(system_state);
}
@@ -223,7 +225,7 @@ module sui_system::governance_test_utils {
0,
ctx
);
- sui_system::request_add_stake(&mut system_state, coin::mint_for_testing(init_stake_amount, ctx), validator, ctx);
+ sui_system::request_add_stake(&mut system_state, coin::mint_for_testing(init_stake_amount * MIST_PER_SUI, ctx), validator, ctx);
sui_system::request_add_validator_for_testing(&mut system_state, 0, ctx);
test_scenario::return_shared(system_state);
}
@@ -316,7 +318,8 @@ module sui_system::governance_test_utils {
test_scenario::next_tx(scenario, validator_addr);
let system_state = test_scenario::take_shared(scenario);
- assert!(sui_system::validator_stake_amount(&mut system_state, validator_addr) == amount, 0);
+ let validator_amount = sui_system::validator_stake_amount(&mut system_state, validator_addr);
+ assert!(validator_amount == amount, validator_amount);
test_scenario::return_shared(system_state);
i = i + 1;
};
@@ -330,7 +333,7 @@ module sui_system::governance_test_utils {
test_scenario::next_tx(scenario, validator_addr);
let system_state = test_scenario::take_shared(scenario);
let non_self_stake_amount = sui_system::validator_stake_amount(&mut system_state, validator_addr) - stake_plus_current_rewards_for_validator(validator_addr, &mut system_state, scenario);
- assert!(non_self_stake_amount == amount, 0);
+ assert_eq(non_self_stake_amount, amount);
test_scenario::return_shared(system_state);
i = i + 1;
};
diff --git a/crates/sui-framework/packages/sui-system/tests/rewards_distribution_tests.move b/crates/sui-framework/packages/sui-system/tests/rewards_distribution_tests.move
index 177372f3ce27a..afb66250c7169 100644
--- a/crates/sui-framework/packages/sui-system/tests/rewards_distribution_tests.move
+++ b/crates/sui-framework/packages/sui-system/tests/rewards_distribution_tests.move
@@ -32,6 +32,8 @@ module sui_system::rewards_distribution_tests {
const STAKER_ADDR_3: address = @0x44;
const STAKER_ADDR_4: address = @0x45;
+ const MIST_PER_SUI: u64 = 1_000_000_000;
+
#[test]
fun test_validator_rewards() {
let scenario_val = test_scenario::begin(VALIDATOR_ADDR_1);
@@ -42,17 +44,25 @@ module sui_system::rewards_distribution_tests {
governance_test_utils::advance_epoch(scenario);
advance_epoch_with_reward_amounts(0, 100, scenario);
- assert_validator_total_stake_amounts(validator_addrs(), vector[110, 220, 330, 440], scenario);
+ assert_validator_total_stake_amounts(validator_addrs(),
+ vector[110 * MIST_PER_SUI, 220 * MIST_PER_SUI, 330 * MIST_PER_SUI, 440 * MIST_PER_SUI],
+ scenario
+ );
stake_with(VALIDATOR_ADDR_2, VALIDATOR_ADDR_2, 720, scenario);
advance_epoch_with_reward_amounts(0, 100, scenario);
- // validator 2's new stake hasn' started counting yet so she only gets 20% of the rewards.
- assert_validator_total_stake_amounts(validator_addrs(), vector[120, 960, 360, 480], scenario);
+ // validator 2's new stake hasn't started counting yet so she only gets 20% of the rewards.
+ assert_validator_total_stake_amounts(validator_addrs(),
+ vector[120 * MIST_PER_SUI, 960 * MIST_PER_SUI, 360 * MIST_PER_SUI, 480 * MIST_PER_SUI],
+ scenario);
- advance_epoch_with_reward_amounts(0, 100, scenario);
+ advance_epoch_with_reward_amounts(0, 160, scenario);
// validator 2's new stake started counting so she gets half of the rewards.
- assert_validator_total_stake_amounts(validator_addrs(), vector[126, 1010, 378, 505], scenario);
+ assert_validator_total_stake_amounts(validator_addrs(),
+ vector[130 * MIST_PER_SUI, 1040 * MIST_PER_SUI, 390 * MIST_PER_SUI, 520 * MIST_PER_SUI],
+ scenario
+ );
test_scenario::end(scenario_val);
}
@@ -66,7 +76,7 @@ module sui_system::rewards_distribution_tests {
governance_test_utils::advance_epoch(scenario);
advance_epoch_with_reward_amounts(0, 100, scenario);
- assert_validator_total_stake_amounts(validator_addrs(), vector[100_000_010, 200_000_020, 300_000_030, 400_000_040], scenario);
+ assert_validator_total_stake_amounts(validator_addrs(), vector[100_000_010 * MIST_PER_SUI, 200_000_020 * MIST_PER_SUI, 300_000_030 * MIST_PER_SUI, 400_000_040 * MIST_PER_SUI], scenario);
test_scenario::end(scenario_val);
}
@@ -80,21 +90,21 @@ module sui_system::rewards_distribution_tests {
stake_with(STAKER_ADDR_2, VALIDATOR_ADDR_2, 100, scenario);
governance_test_utils::advance_epoch(scenario);
- assert_validator_total_stake_amounts(validator_addrs(), vector[300, 300, 300, 400], scenario);
- assert_validator_self_stake_amounts(validator_addrs(), vector[100, 200, 300, 400], scenario);
+ assert_validator_total_stake_amounts(validator_addrs(), vector[300 * MIST_PER_SUI, 300 * MIST_PER_SUI, 300 * MIST_PER_SUI, 400 * MIST_PER_SUI], scenario);
+ assert_validator_self_stake_amounts(validator_addrs(), vector[100 * MIST_PER_SUI, 200 * MIST_PER_SUI, 300 * MIST_PER_SUI, 400 * MIST_PER_SUI], scenario);
// 10 SUI rewards for each 100 SUI of stake
advance_epoch_with_reward_amounts(0, 130, scenario);
- assert_validator_self_stake_amounts(validator_addrs(), vector[110, 220, 330, 440], scenario);
+ assert_validator_self_stake_amounts(validator_addrs(), vector[110 * MIST_PER_SUI, 220 * MIST_PER_SUI, 330 * MIST_PER_SUI, 440 * MIST_PER_SUI], scenario);
unstake(STAKER_ADDR_1, 0, scenario);
stake_with(STAKER_ADDR_2, VALIDATOR_ADDR_1, 600, scenario);
// 10 SUI rewards for each 110 SUI of stake
advance_epoch_with_reward_amounts(0, 130, scenario);
// staker 1 receives only 20 SUI of rewards, not 40 since we are using pre-epoch exchange rate.
- assert_eq(total_sui_balance(STAKER_ADDR_1, scenario), 220);
- assert_validator_self_stake_amounts(validator_addrs(), vector[140, 240, 360, 480], scenario);
+ assert_eq(total_sui_balance(STAKER_ADDR_1, scenario), 220 * MIST_PER_SUI);
+ assert_validator_self_stake_amounts(validator_addrs(), vector[140 * MIST_PER_SUI, 240 * MIST_PER_SUI, 360 * MIST_PER_SUI, 480 * MIST_PER_SUI], scenario);
unstake(STAKER_ADDR_2, 0, scenario);
- assert!(total_sui_balance(STAKER_ADDR_2, scenario) == 120, 0); // 20 SUI of rewards received
+ assert_eq(total_sui_balance(STAKER_ADDR_2, scenario), 120 * MIST_PER_SUI); // 20 SUI of rewards received
// 10 SUI rewards for each 120 SUI of stake
advance_epoch_with_reward_amounts(0, 150, scenario);
@@ -104,7 +114,8 @@ module sui_system::rewards_distribution_tests {
// For this stake, the staking exchange rate is 600 : 740 and the unstaking
// exchange rate is 600 : 797 so the total sui withdraw will be:
// (600 * 600 / 740) * 797 / 600 = 646.
- assert_eq(total_sui_balance(STAKER_ADDR_2, scenario), 766);
+ // TODO: Come up with better numbers and clean it up!
+ assert_eq(total_sui_balance(STAKER_ADDR_2, scenario), 766391752576);
test_scenario::end(scenario_val);
}
@@ -142,32 +153,32 @@ module sui_system::rewards_distribution_tests {
stake_with(STAKER_ADDR_1, VALIDATOR_ADDR_1, 100, scenario);
stake_with(STAKER_ADDR_2, VALIDATOR_ADDR_2, 100, scenario);
governance_test_utils::advance_epoch(scenario);
+ // V1: 200, V2: 300, V3: 300, V4: 400
set_commission_rate_and_advance_epoch(VALIDATOR_ADDR_2, 5000, scenario); // 50% commission
-
- // 10 SUI for each 100 SUI staked
advance_epoch_with_reward_amounts(0, 120, scenario);
+ // V1: 220, V2: 330, V3: 330, V4: 440
// 5 SUI, or 50 % of staker_2's rewards, goes to validator_2
- assert_validator_non_self_stake_amounts(validator_addrs(), vector[110, 105, 0, 0], scenario);
- assert_validator_self_stake_amounts(validator_addrs(), vector[110, 225, 330, 440], scenario);
+ assert_validator_non_self_stake_amounts(validator_addrs(), vector[110 * MIST_PER_SUI, 105 * MIST_PER_SUI, 0, 0], scenario);
+ assert_validator_self_stake_amounts(validator_addrs(), vector[110 * MIST_PER_SUI, 225 * MIST_PER_SUI, 330 * MIST_PER_SUI, 440 * MIST_PER_SUI], scenario);
set_commission_rate_and_advance_epoch(VALIDATOR_ADDR_1, 1000, scenario); // 10% commission
- // 20 SUI for each 110 SUI staked
- advance_epoch_with_reward_amounts(0, 240, scenario);
-
- // 2 SUI, or 10 % of staker_1's rewards (20 SUI), goes to validator_1
- // so staker_1 now has 110 + 20 - 2 = 128 SUI.
- // And 10 SUI, or 50% of staker_2's rewards (20 SUI) goes to validator_2
- // so staker_2 now has 105 +20 - 10 = 115 SUI.
- assert_validator_non_self_stake_amounts(validator_addrs(), vector[128, 115, 0, 0], scenario);
-
- // validator_1 gets 20 SUI of their own rewards and 2 SUI of commission
- // so in total 110 + 20 + 2 = 132 SUI.
- // validator_2 gets 40 SUI of their own rewards and 10 SUI of commission
- // so in total 225 + 40 + 10 = 275 SUI.
- // validator_3 and validator_4 just get their regular shares (60 SUI and 80 SUI).
- assert_validator_self_stake_amounts(validator_addrs(), vector[132, 275, 390, 520], scenario);
+ // 1320 can be nicely partitioned to double the staking pools
+ advance_epoch_with_reward_amounts(0, 1320, scenario);
+ // V1: 440, V2: 660, V3: 660, V4: 880
+ assert_validator_total_stake_amounts(validator_addrs(), vector[440 * MIST_PER_SUI, 660 * MIST_PER_SUI, 660 * MIST_PER_SUI, 880 * MIST_PER_SUI], scenario);
+
+ // Staker 1 rewards in the recent distribution is 0.9 x (220 / 2) = 99 SUI
+ // Validator 1 rewards in the recent distribution is 220 - 99 = 121 SUI
+
+ // Old exchange rate for validator 2: 1.0.
+ // New exchange rate for validator 2: 660/300
+ // Staker 2 amounts for 0.5 * (660/300 * 100 - 100) + 100 = 160 SUI
+ // Validator 2 amounts for 660 - 160 = 500 SUI
+ // TODO: Investigate the discrepancy
+ assert_validator_non_self_stake_amounts(validator_addrs(), vector[209 * MIST_PER_SUI, 157500000001, 0, 0], scenario);
+ assert_validator_self_stake_amounts(validator_addrs(), vector[231 * MIST_PER_SUI, 502499999999, 660 * MIST_PER_SUI, 880 * MIST_PER_SUI], scenario);
test_scenario::end(scenario_val);
}
@@ -193,27 +204,27 @@ module sui_system::rewards_distribution_tests {
// validator_1 is reported by only 1 other validator, which is 300 / 1200 = 25% of total stake.
report_validator(VALIDATOR_ADDR_3, VALIDATOR_ADDR_1, scenario);
- // 1200 SUI of total rewards, 50% threshold and 10% reward slashing.
+ // 1200*9 SUI of total rewards, 50% threshold and 10% reward slashing.
// So validator_2 is the only one whose rewards should get slashed.
advance_epoch_with_reward_amounts_and_slashing_rates(
- 0, 1200, 1000, scenario
+ 0, 1200*9, 1000, scenario
);
- // Without reward slashing, the validator's stakes should be [200, 400, 600, 800]
+ // Without reward slashing, the validator's stakes should be [100+100*9, 200+200*9, 300+300*9, 400+400*9]
// after the last epoch advancement.
- // Since 20 SUI, or 10% of validator_2's rewards (200) are slashed, she only has 400 - 20 = 380 now.
- // There are in total 30 SUI of rewards slashed (20 from the validator, and 10 from her staker)
+ // Since 20*9 SUI, or 10% of validator_2's rewards (200*9) are slashed, she only has 2000 - 180 = 1820 now.
+ // There are in total 30*9 SUI of rewards slashed (20*9 from the validator, and 10*9 from her staker)
// so the unslashed validators each get their weighted share of additional rewards, which is
- // 30 / 9 = 3, 30 * 3 / 9 = 10 and 30 * 4 / 9 = 13.
- assert_validator_self_stake_amounts(validator_addrs(), vector[203, 380, 610, 813], scenario);
+ // 30, 30 * 3 = 90 and 30 * 4 = 120.
+ assert_validator_self_stake_amounts(validator_addrs(), vector[1030 * MIST_PER_SUI, 1820 * MIST_PER_SUI, 3090 * MIST_PER_SUI, 4120 * MIST_PER_SUI], scenario);
// Unstake so we can check the stake rewards as well.
unstake(STAKER_ADDR_1, 0, scenario);
unstake(STAKER_ADDR_2, 0, scenario);
// Same analysis as above. Delegator 1 has 3 additional SUI, and 10% of staker 2's rewards are slashed.
- assert!(total_sui_balance(STAKER_ADDR_1, scenario) == 203, 0);
- assert!(total_sui_balance(STAKER_ADDR_2, scenario) == 190, 0);
+ assert!(total_sui_balance(STAKER_ADDR_1, scenario) == 1030 * MIST_PER_SUI, 0);
+ assert!(total_sui_balance(STAKER_ADDR_2, scenario) == 910 * MIST_PER_SUI, 0);
test_scenario::end(scenario_val);
}
@@ -248,15 +259,16 @@ module sui_system::rewards_distribution_tests {
// unslashed validators too.
// Validator 4 should get 475 SUI of rewards without slashing. 20% is slashed so she gets
// 380 SUI of rewards.
- assert_validator_self_stake_amounts(validator_addrs(), vector[294, 508, 723, 780], scenario);
+ // TODO: Come up with better numbers and clean it up!
+ assert_validator_self_stake_amounts(validator_addrs(), vector[294285714285, 508571428571, 722857142857, 780 * MIST_PER_SUI], scenario);
// Unstake so we can check the stake rewards as well.
unstake(STAKER_ADDR_1, 0, scenario);
unstake(STAKER_ADDR_2, 0, scenario);
// WHY YOU DO THIS TO ME?
- assert!(total_sui_balance(STAKER_ADDR_1, scenario) == 214, 0);
- assert!(total_sui_balance(STAKER_ADDR_2, scenario) == 180, 0);
+ assert_eq(total_sui_balance(STAKER_ADDR_1, scenario), 214285714285);
+ assert_eq(total_sui_balance(STAKER_ADDR_2, scenario), 180 * MIST_PER_SUI);
test_scenario::end(scenario_val);
}
@@ -291,7 +303,7 @@ module sui_system::rewards_distribution_tests {
test_scenario::next_tx(scenario, @0x0);
let system_state = test_scenario::take_shared(scenario);
// Check that we have the right amount of SUI in the staking pool.
- assert_eq(sui_system::validator_stake_amount(&mut system_state, VALIDATOR_ADDR_1), 140 * 23);
+ assert_eq(sui_system::validator_stake_amount(&mut system_state, VALIDATOR_ADDR_1), 140 * 23 * MIST_PER_SUI);
test_scenario::return_shared(system_state);
// Withdraw all stakes at once.
@@ -304,21 +316,21 @@ module sui_system::rewards_distribution_tests {
// staker 1's first stake was active for 3 epochs so got 20 * 3 = 60 SUI of rewards
// and her second stake was active for only one epoch and got 10 SUI of rewards.
- assert_eq(total_sui_balance(STAKER_ADDR_1, scenario), 220 + 130 + 20 * 3 + 10);
+ assert_eq(total_sui_balance(STAKER_ADDR_1, scenario), (220 + 130 + 20 * 3 + 10) * MIST_PER_SUI);
// staker 2's stake was active for 2 epochs so got 40 * 2 = 80 SUI of rewards
- assert_eq(total_sui_balance(STAKER_ADDR_2, scenario), 480 + 40 * 2);
+ assert_eq(total_sui_balance(STAKER_ADDR_2, scenario), (480 + 40 * 2) * MIST_PER_SUI);
// staker 3's first stake was active for 1 epoch and got 30 SUI of rewards
// and her second stake didn't get any rewards.
- assert_eq(total_sui_balance(STAKER_ADDR_3, scenario), 390 + 280 + 30);
+ assert_eq(total_sui_balance(STAKER_ADDR_3, scenario), (390 + 280 + 30) * MIST_PER_SUI);
// staker 4 joined and left in an epoch where no rewards were earned so she got no rewards.
- assert_eq(total_sui_balance(STAKER_ADDR_4, scenario), 1400);
+ assert_eq(total_sui_balance(STAKER_ADDR_4, scenario), 1400 * MIST_PER_SUI);
advance_epoch_with_reward_amounts(0, 0, scenario);
test_scenario::next_tx(scenario, @0x0);
let system_state = test_scenario::take_shared(scenario);
// Since all the stakes are gone the pool is empty except for the validator's original stake.
- assert_eq(sui_system::validator_stake_amount(&mut system_state, VALIDATOR_ADDR_1), 140);
+ assert_eq(sui_system::validator_stake_amount(&mut system_state, VALIDATOR_ADDR_1), 140 * MIST_PER_SUI);
test_scenario::return_shared(system_state);
test_scenario::end(scenario_val);
}
diff --git a/crates/sui-framework/packages/sui-system/tests/safe_mode_tests.move b/crates/sui-framework/packages/sui-system/tests/safe_mode_tests.move
index 0718caa042136..fb6d523d0d187 100644
--- a/crates/sui-framework/packages/sui-system/tests/safe_mode_tests.move
+++ b/crates/sui-framework/packages/sui-system/tests/safe_mode_tests.move
@@ -14,6 +14,8 @@ module sui::safe_mode_tests {
use sui_system::sui_system;
use sui_system::sui_system::SuiSystemState;
+ const MIST_PER_SUI: u64 = 1_000_000_000;
+
#[test]
fun test_safe_mode_gas_accumulation() {
let scenario_val = test_scenario::begin(@0x1);
@@ -36,8 +38,8 @@ module sui::safe_mode_tests {
{
test_scenario::next_tx(scenario, @0x1);
let system_state = test_scenario::take_shared(scenario);
- test_utils::assert_eq(sui_system::validator_stake_amount(&mut system_state, @0x1), 1);
- test_utils::assert_eq(sui_system::get_storage_fund_balance(&mut system_state), 1000);
+ test_utils::assert_eq(sui_system::validator_stake_amount(&mut system_state, @0x1), 1 * MIST_PER_SUI);
+ test_utils::assert_eq(sui_system::get_storage_fund_balance(&mut system_state), 1000 * MIST_PER_SUI);
test_scenario::return_shared(system_state);
};
@@ -54,15 +56,15 @@ module sui::safe_mode_tests {
test_utils::destroy(rebates);
let system_state = test_scenario::take_shared(scenario);
- // For each validator, total computation reward is 20 / 4 + 40 / 4 = 15, init stake is 1.
+ // For each validator, total computation reward is 20 / 4 + 40 / 4 = 15
// However due to integer division, each validator is getting 1 less.
- test_utils::assert_eq(sui_system::validator_stake_amount(&mut system_state, @0x1), 15);
- test_utils::assert_eq(sui_system::validator_stake_amount(&mut system_state, @0x2), 15);
- test_utils::assert_eq(sui_system::validator_stake_amount(&mut system_state, @0x3), 15);
- test_utils::assert_eq(sui_system::validator_stake_amount(&mut system_state, @0x4), 15);
+ test_utils::assert_eq(sui_system::validator_stake_amount(&mut system_state, @0x1), 14 + 1 * MIST_PER_SUI);
+ test_utils::assert_eq(sui_system::validator_stake_amount(&mut system_state, @0x2), 14 + 1 * MIST_PER_SUI);
+ test_utils::assert_eq(sui_system::validator_stake_amount(&mut system_state, @0x3), 14 + 1 * MIST_PER_SUI);
+ test_utils::assert_eq(sui_system::validator_stake_amount(&mut system_state, @0x4), 14 + 1 * MIST_PER_SUI);
- // Storage fund is 1000 + 8 + 16 - 30 - 30 = 964. 4 leftover due to integer division.
- test_utils::assert_eq(sui_system::get_storage_fund_balance(&mut system_state), 968);
+ // Storage fund delta is 8 + 16 - 30 - 30 = -36 with 4 leftover due to integer division => -32.
+ test_utils::assert_eq(sui_system::get_storage_fund_balance(&mut system_state), 1000 * MIST_PER_SUI - 32);
test_scenario::return_shared(system_state);
test_scenario::end(scenario_val);
diff --git a/crates/sui-framework/packages/sui-system/tests/sui_system_tests.move b/crates/sui-framework/packages/sui-system/tests/sui_system_tests.move
index 1d3a8b4065744..519f36d716641 100644
--- a/crates/sui-framework/packages/sui-system/tests/sui_system_tests.move
+++ b/crates/sui-framework/packages/sui-system/tests/sui_system_tests.move
@@ -572,7 +572,7 @@ module sui_system::sui_system_tests {
b"/ip4/127.0.0.1/udp/80",
b"/ip4/127.0.0.1/udp/80",
b"/ip4/127.0.0.1/udp/80",
- option::some(balance::create_for_testing(100)),
+ option::some(balance::create_for_testing(100_000_000_000)),
1,
0,
true,
@@ -918,7 +918,7 @@ module sui_system::sui_system_tests {
b"/ip4/127.0.0.1/udp/80",
b"/ip4/127.0.0.1/udp/80",
b"/ip4/127.0.0.1/udp/80",
- option::some(balance::create_for_testing(100)),
+ option::some(balance::create_for_testing(100_000_000_000)),
1,
0,
true,
diff --git a/crates/sui-framework/packages/sui-system/tests/validator_set_tests.move b/crates/sui-framework/packages/sui-system/tests/validator_set_tests.move
index 59ea41da769e3..7aff25d83249b 100644
--- a/crates/sui-framework/packages/sui-system/tests/validator_set_tests.move
+++ b/crates/sui-framework/packages/sui-system/tests/validator_set_tests.move
@@ -15,6 +15,8 @@ module sui_system::validator_set_tests {
use std::option;
use sui::test_utils::{Self, assert_eq};
+ const MIST_PER_SUI: u64 = 1_000_000_000; // used internally for stakes.
+
#[test]
fun test_validator_set_flow() {
let scenario_val = test_scenario::begin(@0x1);
@@ -29,7 +31,7 @@ module sui_system::validator_set_tests {
// Create a validator set with only the first validator in it.
let validator_set = validator_set::new(vector[validator1], ctx1);
- assert!(validator_set::total_stake(&validator_set) == 100, 0);
+ assert!(validator_set::total_stake(&validator_set) == 100 * MIST_PER_SUI, 0);
// Add the other 3 validators one by one.
add_and_activate_validator(
@@ -38,7 +40,7 @@ module sui_system::validator_set_tests {
scenario
);
// Adding validator during the epoch should not affect stake and quorum threshold.
- assert!(validator_set::total_stake(&validator_set) == 100, 0);
+ assert!(validator_set::total_stake(&validator_set) == 100 * MIST_PER_SUI, 0);
add_and_activate_validator(
&mut validator_set,
@@ -52,12 +54,12 @@ module sui_system::validator_set_tests {
validator_set::request_add_stake(
&mut validator_set,
@0x1,
- coin::into_balance(coin::mint_for_testing(500, ctx1)),
+ coin::into_balance(coin::mint_for_testing(500 * MIST_PER_SUI, ctx1)),
ctx1,
);
// Adding stake to existing active validator during the epoch
// should not change total stake.
- assert!(validator_set::total_stake(&validator_set) == 100, 0);
+ assert!(validator_set::total_stake(&validator_set) == 100 * MIST_PER_SUI, 0);
};
add_and_activate_validator(
@@ -68,7 +70,7 @@ module sui_system::validator_set_tests {
advance_epoch_with_dummy_rewards(&mut validator_set, scenario);
// Total stake for these should be the starting stake + the 500 staked with validator 1 in addition to the starting stake.
- assert!(validator_set::total_stake(&validator_set) == 1500, 0);
+ assert!(validator_set::total_stake(&validator_set) == 1500 * MIST_PER_SUI, 0);
test_scenario::next_tx(scenario, @0x1);
{
@@ -81,10 +83,10 @@ module sui_system::validator_set_tests {
};
// Total validator candidate count changes, but total stake remains during epoch.
- assert!(validator_set::total_stake(&validator_set) == 1500, 0);
+ assert!(validator_set::total_stake(&validator_set) == 1500 * MIST_PER_SUI, 0);
advance_epoch_with_dummy_rewards(&mut validator_set, scenario);
// Validator1 is gone. This removes its stake (100) + the 500 staked with it.
- assert!(validator_set::total_stake(&validator_set) == 900, 0);
+ assert!(validator_set::total_stake(&validator_set) == 900 * MIST_PER_SUI, 0);
test_utils::destroy(validator_set);
test_scenario::end(scenario_val);
@@ -143,6 +145,51 @@ module sui_system::validator_set_tests {
test_scenario::end(scenario_val);
}
+ #[test]
+ #[expected_failure(abort_code = validator_set::EStakingBelowThreshold)]
+ fun test_staking_below_threshold() {
+ let scenario_val = test_scenario::begin(@0x1);
+ let scenario = &mut scenario_val;
+ let ctx1 = test_scenario::ctx(scenario);
+
+ let validator1 = create_validator(@0x1, 1, 1, true, ctx1);
+ let validator_set = validator_set::new(vector[validator1], ctx1);
+ assert_eq(validator_set::total_stake(&validator_set), 100 * MIST_PER_SUI);
+
+ validator_set::request_add_stake(
+ &mut validator_set,
+ @0x1,
+ balance::create_for_testing(MIST_PER_SUI - 1), // 1 MIST lower than the threshold
+ ctx1,
+ );
+ test_utils::destroy(validator_set);
+ test_scenario::end(scenario_val);
+ }
+
+ #[test]
+ fun test_staking_min_threshold() {
+ let scenario_val = test_scenario::begin(@0x1);
+ let scenario = &mut scenario_val;
+ let ctx1 = test_scenario::ctx(scenario);
+
+ let validator1 = create_validator(@0x1, 1, 1, true, ctx1);
+ let validator_set = validator_set::new(vector[validator1], ctx1);
+ assert_eq(validator_set::total_stake(&validator_set), 100 * MIST_PER_SUI);
+
+ validator_set::request_add_stake(
+ &mut validator_set,
+ @0x1,
+ balance::create_for_testing(MIST_PER_SUI), // min possible stake
+ ctx1,
+ );
+
+ advance_epoch_with_dummy_rewards(&mut validator_set, scenario);
+ assert!(validator_set::total_stake(&validator_set) == 101 * MIST_PER_SUI, 0);
+
+ test_utils::destroy(validator_set);
+ test_scenario::end(scenario_val);
+ }
+
#[test]
#[expected_failure(abort_code = validator_set::EMinJoiningStakeNotReached)]
fun test_add_validator_failure_below_min_stake() {
@@ -156,7 +203,7 @@ module sui_system::validator_set_tests {
// Create a validator set with only the first validator in it.
let validator_set = validator_set::new(vector[validator1], ctx1);
- assert_eq(validator_set::total_stake(&validator_set), 100);
+ assert_eq(validator_set::total_stake(&validator_set), 100 * MIST_PER_SUI);
validator_set::request_add_validator_candidate(&mut validator_set, validator2, ctx1);
@@ -166,16 +213,16 @@ module sui_system::validator_set_tests {
validator_set::request_add_stake(
&mut validator_set,
@0x2,
- balance::create_for_testing(500),
+ balance::create_for_testing(500 * MIST_PER_SUI),
ctx,
);
// Adding stake to a preactive validator should not change total stake.
- assert_eq(validator_set::total_stake(&validator_set), 100);
+ assert_eq(validator_set::total_stake(&validator_set), 100 * MIST_PER_SUI);
};
test_scenario::next_tx(scenario, @0x2);
- // Validator 2 now has 700 MIST in stake but that's not enough because we need 701.
- validator_set::request_add_validator(&mut validator_set, 701, test_scenario::ctx(scenario));
+ // Validator 2 now has 700 SUI in stake but that's not enough because we need 701.
+ validator_set::request_add_validator(&mut validator_set, 701 * MIST_PER_SUI, test_scenario::ctx(scenario));
test_utils::destroy(validator_set);
test_scenario::end(scenario_val);
@@ -193,7 +240,7 @@ module sui_system::validator_set_tests {
// Create a validator set with only the first validator in it.
let validator_set = validator_set::new(vector[validator1], ctx1);
- assert_eq(validator_set::total_stake(&validator_set), 100);
+ assert_eq(validator_set::total_stake(&validator_set), 100 * MIST_PER_SUI);
validator_set::request_add_validator_candidate(&mut validator_set, validator2, ctx1);
@@ -203,16 +250,16 @@ module sui_system::validator_set_tests {
validator_set::request_add_stake(
&mut validator_set,
@0x2,
- balance::create_for_testing(500),
+ balance::create_for_testing(500 * MIST_PER_SUI),
ctx,
);
// Adding stake to a preactive validator should not change total stake.
- assert_eq(validator_set::total_stake(&validator_set), 100);
+ assert_eq(validator_set::total_stake(&validator_set), 100 * MIST_PER_SUI);
};
test_scenario::next_tx(scenario, @0x2);
- // Validator 2 now has 700 MIST in stake and that's just enough.
- validator_set::request_add_validator(&mut validator_set, 700, test_scenario::ctx(scenario));
+ // Validator 2 now has 700 SUI in stake and that's just enough.
+ validator_set::request_add_validator(&mut validator_set, 700 * MIST_PER_SUI, test_scenario::ctx(scenario));
test_utils::destroy(validator_set);
test_scenario::end(scenario_val);
@@ -232,7 +279,7 @@ module sui_system::validator_set_tests {
// Create a validator set with only the first validator in it.
let validator_set = validator_set::new(vector[validator1], ctx1);
- assert_eq(validator_set::total_stake(&validator_set), 100);
+ assert_eq(validator_set::total_stake(&validator_set), 100 * MIST_PER_SUI);
// Add the second one as a candidate.
validator_set::request_add_validator_candidate(&mut validator_set, validator2, ctx1);
@@ -254,10 +301,10 @@ module sui_system::validator_set_tests {
let scenario = &mut scenario_val;
let ctx1 = test_scenario::ctx(scenario);
// Create 4 validators.
- let v1 = create_validator(@0x1, 1, 1, true, ctx1); // 100 MIST of stake
- let v2 = create_validator(@0x2, 4, 1, true, ctx1); // 400 MIST of stake
- let v3 = create_validator(@0x3, 10, 1, true, ctx1); // 1000 MIST of stake
- let v4 = create_validator(@0x4, 4, 1, true, ctx1); // 400 MIST of stake
+ let v1 = create_validator(@0x1, 1, 1, true, ctx1); // 100 SUI of stake
+ let v2 = create_validator(@0x2, 4, 1, true, ctx1); // 400 SUI of stake
+ let v3 = create_validator(@0x3, 10, 1, true, ctx1); // 1000 SUI of stake
+ let v4 = create_validator(@0x4, 4, 1, true, ctx1); // 400 SUI of stake
let validator_set = validator_set::new(vector[v1, v2, v3, v4], ctx1);
@@ -288,7 +335,7 @@ module sui_system::validator_set_tests {
validator_set::request_add_stake(
&mut validator_set,
@0x4,
- balance::create_for_testing(500),
+ balance::create_for_testing(500 * MIST_PER_SUI),
ctx,
);
};
@@ -333,7 +380,7 @@ module sui_system::validator_set_tests {
}
fun create_validator(addr: address, hint: u8, gas_price: u64, is_initial_validator: bool, ctx: &mut TxContext): Validator {
- let stake_value = (hint as u64) * 100;
+ let stake_value = (hint as u64) * 100 * MIST_PER_SUI;
let name = hint_to_ascii(hint);
let validator = validator::new_for_testing(
addr,
@@ -400,8 +447,8 @@ module sui_system::validator_set_tests {
&mut dummy_storage_fund_reward,
&mut vec_map::empty(),
0, // reward_slashing_rate
- low_stake_threshold,
- very_low_stake_threshold,
+ low_stake_threshold * MIST_PER_SUI,
+ very_low_stake_threshold * MIST_PER_SUI,
low_stake_grace_period,
test_scenario::ctx(scenario)
);
diff --git a/crates/sui-framework/packages/sui-system/tests/validator_tests.move b/crates/sui-framework/packages/sui-system/tests/validator_tests.move
index 6415e4ea2fd29..cae4b2cb035a8 100644
--- a/crates/sui-framework/packages/sui-system/tests/validator_tests.move
+++ b/crates/sui-framework/packages/sui-system/tests/validator_tests.move
@@ -9,7 +9,6 @@ module sui_system::validator_tests {
use std::string::Self;
use sui_system::validator::{Self, Validator};
use sui::tx_context::TxContext;
- use sui::balance::Balance;
use std::option;
use std::ascii;
use sui::coin::{Self, Coin};
@@ -35,7 +34,8 @@ module sui_system::validator_tests {
const VALID_WORKER_ADDR: vector = b"/ip4/127.0.0.1/udp/80";
#[test_only]
- fun get_test_validator(ctx: &mut TxContext, init_stake: Balance): Validator {
+ fun get_test_validator(ctx: &mut TxContext): Validator {
+ let init_stake = coin::into_balance(coin::mint_for_testing(10_000_000_000, ctx));
let validator = validator::new(
VALID_ADDRESS,
VALID_PUBKEY,
@@ -75,9 +75,8 @@ module sui_system::validator_tests {
{
let ctx = test_scenario::ctx(scenario);
- let init_stake = coin::into_balance(coin::mint_for_testing(10, ctx));
- let validator = get_test_validator(ctx, init_stake);
- assert!(validator::total_stake_amount(&validator) == 10, 0);
+ let validator = get_test_validator(ctx);
+ assert!(validator::total_stake_amount(&validator) == 10_000_000_000, 0);
assert!(validator::sui_address(&validator) == sender, 0);
test_utils::destroy(validator);
@@ -87,7 +86,7 @@ module sui_system::validator_tests {
test_scenario::next_tx(scenario, sender);
{
let stake = test_scenario::take_from_sender(scenario);
- assert!(staking_pool::staked_sui_amount(&stake) == 10, 0);
+ assert!(staking_pool::staked_sui_amount(&stake) == 10_000_000_000, 0);
test_scenario::return_to_sender(scenario, stake);
};
test_scenario::end(scenario_val);
@@ -99,17 +98,16 @@ module sui_system::validator_tests {
let scenario_val = test_scenario::begin(sender);
let scenario = &mut scenario_val;
let ctx = test_scenario::ctx(scenario);
- let init_stake = coin::into_balance(coin::mint_for_testing(10, ctx));
- let validator = get_test_validator(ctx, init_stake);
+ let validator = get_test_validator(ctx);
test_scenario::next_tx(scenario, sender);
{
let ctx = test_scenario::ctx(scenario);
- let new_stake = coin::into_balance(coin::mint_for_testing(30, ctx));
+ let new_stake = coin::into_balance(coin::mint_for_testing(30_000_000_000, ctx));
validator::request_add_stake(&mut validator, new_stake, sender, ctx);
- assert!(validator::total_stake(&validator) == 10, 0);
- assert!(validator::pending_stake_amount(&validator) == 30, 0);
+ assert!(validator::total_stake(&validator) == 10_000_000_000, 0);
+ assert!(validator::pending_stake_amount(&validator) == 30_000_000_000, 0);
};
test_scenario::next_tx(scenario, sender);
@@ -119,16 +117,16 @@ module sui_system::validator_tests {
let ctx = test_scenario::ctx(scenario);
validator::request_withdraw_stake(&mut validator, stake, ctx);
- assert!(validator::total_stake(&validator) == 10, 0);
- assert!(validator::pending_stake_amount(&validator) == 30, 0);
- assert!(validator::pending_stake_withdraw_amount(&validator) == 10, 0);
+ assert!(validator::total_stake(&validator) == 10_000_000_000, 0);
+ assert!(validator::pending_stake_amount(&validator) == 30_000_000_000, 0);
+ assert!(validator::pending_stake_withdraw_amount(&validator) == 10_000_000_000, 0);
validator::deposit_stake_rewards(&mut validator, balance::zero());
// Calling `process_pending_stakes_and_withdraws` will withdraw the coin and transfer to sender.
validator::process_pending_stakes_and_withdraws(&mut validator, ctx);
- assert!(validator::total_stake(&validator) == 30, 0);
+ assert!(validator::total_stake(&validator) == 30_000_000_000, 0);
assert!(validator::pending_stake_amount(&validator) == 0, 0);
assert!(validator::pending_stake_withdraw_amount(&validator) == 0, 0);
};
@@ -137,7 +135,7 @@ module sui_system::validator_tests {
{
let coin_ids = test_scenario::ids_for_sender>(scenario);
let withdraw = test_scenario::take_from_sender_by_id>(scenario, *vector::borrow(&coin_ids, 0));
- assert!(coin::value(&withdraw) == 10, 0);
+ assert!(coin::value(&withdraw) == 10_000_000_000, 0);
test_scenario::return_to_sender(scenario, withdraw);
};
@@ -366,13 +364,12 @@ module sui_system::validator_tests {
let scenario_val = test_scenario::begin(sender);
let scenario = &mut scenario_val;
let ctx = test_scenario::ctx(scenario);
- let init_stake = coin::into_balance(coin::mint_for_testing(10, ctx));
let new_protocol_pub_key = x"96d19c53f1bee2158c3fcfb5bb2f06d3a8237667529d2d8f0fbb22fe5c3b3e64748420b4103674490476d98530d063271222d2a59b0f7932909cc455a30f00c69380e6885375e94243f7468e9563aad29330aca7ab431927540e9508888f0e1c";
let new_pop = x"a8a0bcaf04e13565914eb22fa9f27a76f297db04446860ee2b923d10224cedb130b30783fb60b12556e7fc50e5b57a86";
let new_worker_pub_key = vector[115, 220, 238, 151, 134, 159, 173, 41, 80, 2, 66, 196, 61, 17, 191, 76, 103, 39, 246, 127, 171, 85, 19, 235, 210, 106, 97, 97, 116, 48, 244, 191];
let new_network_pub_key = vector[149, 128, 161, 13, 11, 183, 96, 45, 89, 20, 188, 205, 26, 127, 147, 254, 184, 229, 184, 102, 64, 170, 104, 29, 191, 171, 91, 99, 58, 178, 41, 156];
- let validator = get_test_validator(ctx, init_stake);
+ let validator = get_test_validator(ctx);
test_scenario::next_tx(scenario, sender);
{
@@ -450,9 +447,7 @@ module sui_system::validator_tests {
let scenario_val = test_scenario::begin(sender);
let scenario = &mut scenario_val;
let ctx = test_scenario::ctx(scenario);
- let init_stake = coin::into_balance(coin::mint_for_testing(10, ctx));
-
- let validator = get_test_validator(ctx, init_stake);
+ let validator = get_test_validator(ctx);
test_scenario::next_tx(scenario, sender);
{
@@ -474,9 +469,7 @@ module sui_system::validator_tests {
let scenario_val = test_scenario::begin(sender);
let scenario = &mut scenario_val;
let ctx = test_scenario::ctx(scenario);
- let init_stake = coin::into_balance(coin::mint_for_testing(10, ctx));
-
- let validator = get_test_validator(ctx, init_stake);
+ let validator = get_test_validator(ctx);
test_scenario::next_tx(scenario, sender);
{
@@ -498,9 +491,7 @@ module sui_system::validator_tests {
let scenario_val = test_scenario::begin(sender);
let scenario = &mut scenario_val;
let ctx = test_scenario::ctx(scenario);
- let init_stake = coin::into_balance(coin::mint_for_testing(10, ctx));
-
- let validator = get_test_validator(ctx, init_stake);
+ let validator = get_test_validator(ctx);
test_scenario::next_tx(scenario, sender);
{
@@ -521,9 +512,7 @@ module sui_system::validator_tests {
let scenario_val = test_scenario::begin(sender);
let scenario = &mut scenario_val;
let ctx = test_scenario::ctx(scenario);
- let init_stake = coin::into_balance(coin::mint_for_testing(10, ctx));
-
- let validator = get_test_validator(ctx, init_stake);
+ let validator = get_test_validator(ctx);
test_scenario::next_tx(scenario, sender);
{
@@ -544,9 +533,8 @@ module sui_system::validator_tests {
let scenario_val = test_scenario::begin(sender);
let scenario = &mut scenario_val;
let ctx = test_scenario::ctx(scenario);
- let init_stake = coin::into_balance(coin::mint_for_testing(10, ctx));
- let validator = get_test_validator(ctx, init_stake);
+ let validator = get_test_validator(ctx);
test_scenario::next_tx(scenario, sender);
{
@@ -567,9 +555,8 @@ module sui_system::validator_tests {
let scenario_val = test_scenario::begin(sender);
let scenario = &mut scenario_val;
let ctx = test_scenario::ctx(scenario);
- let init_stake = coin::into_balance(coin::mint_for_testing(10, ctx));
- let validator = get_test_validator(ctx, init_stake);
+ let validator = get_test_validator(ctx);
test_scenario::next_tx(scenario, sender);
{
@@ -590,9 +577,7 @@ module sui_system::validator_tests {
let scenario_val = test_scenario::begin(sender);
let scenario = &mut scenario_val;
let ctx = test_scenario::ctx(scenario);
- let init_stake = coin::into_balance(coin::mint_for_testing(10, ctx));
-
- let validator = get_test_validator(ctx, init_stake);
+ let validator = get_test_validator(ctx);
test_scenario::next_tx(scenario, sender);
{