Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[sui-system] minimum staking threshold of 1 SUI #9961

Merged
merged 5 commits into from
Mar 28, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add threshold for splitting stake too
  • Loading branch information
emmazzz committed Mar 28, 2023
commit cdc7dad3a419d18434b988de3c5ee4a689df9253
31 changes: 28 additions & 3 deletions crates/sui-framework/docs/staking_pool.md
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,15 @@ A self-custodial object holding the staked SUI tokens.



<a name="0x3_staking_pool_EStakedSuiBelowThreshold"></a>



<pre><code><b>const</b> <a href="staking_pool.md#0x3_staking_pool_EStakedSuiBelowThreshold">EStakedSuiBelowThreshold</a>: u64 = 18;
</code></pre>



<a name="0x3_staking_pool_ETokenBalancesDoNotMatchExchangeRate"></a>


Expand Down Expand Up @@ -397,6 +406,16 @@ A self-custodial object holding the staked SUI tokens.



<a name="0x3_staking_pool_MIN_STAKING_THRESHOLD"></a>

StakedSui objects cannot be split to below this amount.


<pre><code><b>const</b> <a href="staking_pool.md#0x3_staking_pool_MIN_STAKING_THRESHOLD">MIN_STAKING_THRESHOLD</a>: u64 = 1000000000;
</code></pre>



<a name="0x3_staking_pool_new"></a>

## Function `new`
Expand Down Expand Up @@ -1049,7 +1068,7 @@ Split the given StakedSui to the two parts, one with principal <code>split_amoun
transfer the newly split part to the sender address.


<pre><code><b>public</b> entry <b>fun</b> <a href="staking_pool.md#0x3_staking_pool_split_staked_sui">split_staked_sui</a>(c: &<b>mut</b> <a href="staking_pool.md#0x3_staking_pool_StakedSui">staking_pool::StakedSui</a>, split_amount: u64, ctx: &<b>mut</b> <a href="_TxContext">tx_context::TxContext</a>)
<pre><code><b>public</b> entry <b>fun</b> <a href="staking_pool.md#0x3_staking_pool_split_staked_sui">split_staked_sui</a>(stake: &<b>mut</b> <a href="staking_pool.md#0x3_staking_pool_StakedSui">staking_pool::StakedSui</a>, split_amount: u64, ctx: &<b>mut</b> <a href="_TxContext">tx_context::TxContext</a>)
</code></pre>


Expand All @@ -1058,8 +1077,14 @@ transfer the newly split part to the sender address.
<summary>Implementation</summary>


<pre><code><b>public</b> entry <b>fun</b> <a href="staking_pool.md#0x3_staking_pool_split_staked_sui">split_staked_sui</a>(c: &<b>mut</b> <a href="staking_pool.md#0x3_staking_pool_StakedSui">StakedSui</a>, split_amount: u64, ctx: &<b>mut</b> TxContext) {
<a href="_transfer">transfer::transfer</a>(<a href="staking_pool.md#0x3_staking_pool_split">split</a>(c, split_amount, ctx), <a href="_sender">tx_context::sender</a>(ctx));
<pre><code><b>public</b> entry <b>fun</b> <a href="staking_pool.md#0x3_staking_pool_split_staked_sui">split_staked_sui</a>(stake: &<b>mut</b> <a href="staking_pool.md#0x3_staking_pool_StakedSui">StakedSui</a>, split_amount: u64, ctx: &<b>mut</b> TxContext) {
<b>let</b> original_amount = <a href="_value">balance::value</a>(&stake.principal);
<b>assert</b>!(split_amount &lt;= original_amount, <a href="staking_pool.md#0x3_staking_pool_EInsufficientSuiTokenBalance">EInsufficientSuiTokenBalance</a>);
<b>let</b> remaining_amount = original_amount - split_amount;
// Both resulting parts should have at least <a href="staking_pool.md#0x3_staking_pool_MIN_STAKING_THRESHOLD">MIN_STAKING_THRESHOLD</a>.
<b>assert</b>!(remaining_amount &gt;= <a href="staking_pool.md#0x3_staking_pool_MIN_STAKING_THRESHOLD">MIN_STAKING_THRESHOLD</a>, <a href="staking_pool.md#0x3_staking_pool_EStakedSuiBelowThreshold">EStakedSuiBelowThreshold</a>);
<b>assert</b>!(split_amount &gt;= <a href="staking_pool.md#0x3_staking_pool_MIN_STAKING_THRESHOLD">MIN_STAKING_THRESHOLD</a>, <a href="staking_pool.md#0x3_staking_pool_EStakedSuiBelowThreshold">EStakedSuiBelowThreshold</a>);
<a href="_transfer">transfer::transfer</a>(<a href="staking_pool.md#0x3_staking_pool_split">split</a>(stake, split_amount, ctx), <a href="_sender">tx_context::sender</a>(ctx));
}
</code></pre>

Expand Down
18 changes: 9 additions & 9 deletions crates/sui-framework/docs/validator_set.md
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,15 @@ The epoch value corresponds to the first epoch this change takes place.
## Constants


<a name="0x3_validator_set_MIN_STAKING_THRESHOLD"></a>



<pre><code><b>const</b> <a href="validator_set.md#0x3_validator_set_MIN_STAKING_THRESHOLD">MIN_STAKING_THRESHOLD</a>: u64 = 1000000000;
</code></pre>



<a name="0x3_validator_set_EInvalidCap"></a>


Expand Down Expand Up @@ -495,15 +504,6 @@ The epoch value corresponds to the first epoch this change takes place.



<a name="0x3_validator_set_MIN_STAKING_THRESHOLD"></a>



<pre><code><b>const</b> <a href="validator_set.md#0x3_validator_set_MIN_STAKING_THRESHOLD">MIN_STAKING_THRESHOLD</a>: u64 = 1000000000;
</code></pre>



<a name="0x3_validator_set_new"></a>

## Function `new`
Expand Down
14 changes: 12 additions & 2 deletions crates/sui-framework/packages/sui-system/sources/staking_pool.move
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ module sui_system::staking_pool {
friend sui_system::validator;
friend sui_system::validator_set;

/// StakedSui objects cannot be split to below this amount.
const MIN_STAKING_THRESHOLD: u64 = 1_000_000_000; // 1 SUI

const EInsufficientPoolTokenBalance: u64 = 0;
const EWrongPool: u64 = 1;
const EWithdrawAmountCannotBeZero: u64 = 2;
Expand All @@ -35,6 +38,7 @@ module sui_system::staking_pool {
const EPoolNotPreactive: u64 = 15;
const EActivationOfInactivePool: u64 = 16;
const EDelegationOfZeroSui: u64 = 17;
const EStakedSuiBelowThreshold: u64 = 18;

/// A staking pool embedded in each validator struct in the system state object.
struct StakingPool has key, store {
Expand Down Expand Up @@ -342,8 +346,14 @@ module sui_system::staking_pool {

/// Split the given StakedSui to the two parts, one with principal `split_amount`,
/// transfer the newly split part to the sender address.
public entry fun split_staked_sui(c: &mut StakedSui, split_amount: u64, ctx: &mut TxContext) {
transfer::transfer(split(c, split_amount, ctx), tx_context::sender(ctx));
public entry fun split_staked_sui(stake: &mut StakedSui, split_amount: u64, ctx: &mut TxContext) {
let original_amount = balance::value(&stake.principal);
assert!(split_amount <= original_amount, EInsufficientSuiTokenBalance);
let remaining_amount = original_amount - split_amount;
// Both resulting parts should have at least MIN_STAKING_THRESHOLD.
assert!(remaining_amount >= MIN_STAKING_THRESHOLD, EStakedSuiBelowThreshold);
assert!(split_amount >= MIN_STAKING_THRESHOLD, EStakedSuiBelowThreshold);
transfer::transfer(split(stake, split_amount, ctx), tx_context::sender(ctx));
}

/// Consume the staked sui `other` and add its value to `self`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,26 @@ module sui_system::stake_tests {
test_scenario::end(scenario_val);
}

#[test]
#[expected_failure(abort_code = staking_pool::EStakedSuiBelowThreshold)]
fun test_split_below_threshold() {
let scenario_val = test_scenario::begin(STAKER_ADDR_1);
let scenario = &mut scenario_val;
set_up_sui_system_state(scenario);
// Stake 2 SUI
governance_test_utils::stake_with(STAKER_ADDR_1, VALIDATOR_ADDR_1, 2, scenario);

test_scenario::next_tx(scenario, STAKER_ADDR_1);
{
let staked_sui = test_scenario::take_from_sender<StakedSui>(scenario);
let ctx = test_scenario::ctx(scenario);
// The remaining amount after splitting is below the threshold so this should fail.
staking_pool::split_staked_sui(&mut staked_sui, 1 * MIST_PER_SUI + 1, ctx);
test_scenario::return_to_sender(scenario, staked_sui);
};
test_scenario::end(scenario_val);
}

#[test]
fun test_add_remove_stake_flow() {
let scenario_val = test_scenario::begin(VALIDATOR_ADDR_1);
Expand Down