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 all commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -240,56 +240,56 @@ validators:
next_epoch_worker_address: ~
extra_fields:
id:
id: "0xf64a2f2782984f7b7a36a99c9d77a83b3b6b5ebecf6ee0eaf118a37d74925c00"
id: "0x5e311ba6292362f225da9c71cf52097ca86b95fe6f4863a88c8e34a262a01193"
size: 0
voting_power: 10000
operation_cap_id: "0x62a99cd4412cb992da5a1035d6021db91e041704625a4010af68d1b0100a3177"
operation_cap_id: "0x669f5c0b0ca9066ace330aba5135ea3d5bbfdd4da5733574d0c596c8787d92de"
gas_price: 1
staking_pool:
id: "0xa110faecebe16b6d167929f7ee40acb2c8c1341eb80c5a24e92fe8dc1cd85015"
id: "0x2a6e996bd69665ad4b2e880c60ec497fb38ca17cc282264222f5ba00ea5d25c8"
activation_epoch: 0
deactivation_epoch: ~
sui_balance: 20000000000000000
rewards_pool:
value: 0
pool_token_balance: 20000000000000000
exchange_rates:
id: "0x77dbaaae503d2664c5e6dfdd01d0bc46b1edf85fc927be9ece5cfd5f0c7a48ef"
id: "0x34c71362a7bfbbd2f2e1ddc116e22834185f8e84635dd819e5432b35bca560aa"
size: 1
pending_stake: 0
pending_total_sui_withdraw: 0
pending_pool_token_withdraw: 0
extra_fields:
id:
id: "0x4898c94bc523d09495c8f9f0947785a3d27e6fbc904c7aa13f48bd90b3032ac7"
id: "0x9540bb52b6eb64682154ab9f190069b2f65408326ca1cde6879bcd22f41ea436"
size: 0
commission_rate: 0
next_epoch_stake: 20000000000000000
next_epoch_gas_price: 1
next_epoch_commission_rate: 0
extra_fields:
id:
id: "0x6daf7eb399ff05a5c2567b7bbb125c9451433af8b425904ab54debbdd28b38df"
id: "0x32da93ecef6352085e4a98e8fdc6ef53f58a87867735e5963e2862da4ca7ebf4"
size: 0
pending_active_validators:
contents:
id: "0x66748b0af8b5eb3e9414d0fd7b424031ec634dc036b8a7a16d17b59e48c514f4"
id: "0x2c9d0fce0e485143215ddf9b3bad49a90faaa08abbe603d6268064e0fa11de63"
size: 0
pending_removals: []
staking_pool_mappings:
id: "0x8091ccc40b81fafe63c18b385bef35ca34f86dc8ce03b14a5c5bd2ecc764dfcc"
id: "0x0e8b457d90c99717d5deafde80d2e6c2c930ededf359d0dde79488fae9d2c70d"
size: 1
inactive_validators:
id: "0xd2427484e7572464744d5ac7805d36e083ab262fef2f8c8cb16e4bf80eeba28e"
id: "0xe5e4e20e15059e13633058858aa474a3d50e647ba500b6ab2eab85a1ffd31ac2"
size: 0
validator_candidates:
id: "0x575efc4d1aa2dac9276de776fe85bab09f1dcde06481d19309094b460d4666d5"
id: "0xc7bb461afa1ee2ca919443255525031ccf3dfafd6aabca790053afffaef11258"
size: 0
at_risk_validators:
contents: []
extra_fields:
id:
id: "0x341985f35823807fb3acf0a34c0b8bf152b355c3638dca24a3222701324eafe7"
id: "0x89b6475302daabe7d012b2f70b706551cbe84e6c4f23ae4713e472af36bcb239"
size: 0
storage_fund:
total_object_storage_rebates:
Expand All @@ -306,7 +306,7 @@ parameters:
validator_low_stake_grace_period: 7
extra_fields:
id:
id: "0xfcfc2dd968cefbf2e4d4679d06ac311ad5eb58fc4ea7d2e988eec89b8e1ec85f"
id: "0xa95d9ca79ae9361d0fa0086c09d61818a4c95926d4ff8873af54fa7c3d033288"
size: 0
reference_gas_price: 1
validator_report_records:
Expand All @@ -320,7 +320,7 @@ stake_subsidy:
stake_subsidy_decrease_rate: 10000
extra_fields:
id:
id: "0x08d8bb5dcbae6e7e0cff0ba0aa23ec8998794cb8e465dd0db6c45cf84752b25b"
id: "0x7590e21a4280f3e5b567da3338e491df195f724b7f908e6cf543717dbbaf3040"
size: 0
safe_mode: false
safe_mode_storage_rewards:
Expand All @@ -332,6 +332,6 @@ safe_mode_non_refundable_storage_fee: 0
epoch_start_timestamp_ms: 10
extra_fields:
id:
id: "0x1f79bdc6d1399738cc06184895e2bc41c76b3c06ddb3d3ece4549f45bf0de724"
id: "0x139f148cc3a7ad72f792389ed8d63875c594fbd59bd7c65a6c4bb01c1a28be49"
size: 0

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
21 changes: 21 additions & 0 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 @@ -477,6 +486,15 @@ The epoch value corresponds to the first epoch this change takes place.



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



<pre><code><b>const</b> <a href="validator_set.md#0x3_validator_set_EStakingBelowThreshold">EStakingBelowThreshold</a>: u64 = 10;
</code></pre>



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


Expand Down Expand Up @@ -743,6 +761,7 @@ Only an active validator can request to be removed.
Called by <code><a href="sui_system.md#0x3_sui_system">sui_system</a></code>, 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


<pre><code><b>public</b>(<b>friend</b>) <b>fun</b> <a href="validator_set.md#0x3_validator_set_request_add_stake">request_add_stake</a>(self: &<b>mut</b> <a href="validator_set.md#0x3_validator_set_ValidatorSet">validator_set::ValidatorSet</a>, validator_address: <b>address</b>, stake: <a href="_Balance">balance::Balance</a>&lt;<a href="_SUI">sui::SUI</a>&gt;, ctx: &<b>mut</b> <a href="_TxContext">tx_context::TxContext</a>)
Expand All @@ -760,6 +779,8 @@ of the epoch.
stake: Balance&lt;SUI&gt;,
ctx: &<b>mut</b> TxContext,
) {
<b>let</b> sui_amount = <a href="_value">balance::value</a>(&stake);
<b>assert</b>!(sui_amount &gt;= <a href="validator_set.md#0x3_validator_set_MIN_STAKING_THRESHOLD">MIN_STAKING_THRESHOLD</a>, <a href="validator_set.md#0x3_validator_set_EStakingBelowThreshold">EStakingBelowThreshold</a>);
<b>let</b> <a href="validator.md#0x3_validator">validator</a> = <a href="validator_set.md#0x3_validator_set_get_candidate_or_active_validator_mut">get_candidate_or_active_validator_mut</a>(self, validator_address);
<a href="validator.md#0x3_validator_request_add_stake">validator::request_add_stake</a>(<a href="validator.md#0x3_validator">validator</a>, stake, <a href="_sender">tx_context::sender</a>(ctx), ctx);
}
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 @@ -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;
Expand All @@ -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;


Expand Down Expand Up @@ -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<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);
}
Expand Down
Loading