From 3d09170f64f18bfb7306d1305e0a258a72178807 Mon Sep 17 00:00:00 2001 From: Egor Lysenko Date: Fri, 23 Feb 2024 21:01:44 +0400 Subject: [PATCH] allow unlocksStake to decrease stake below delegations limit --- contracts/sfc/SFCLib.sol | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/contracts/sfc/SFCLib.sol b/contracts/sfc/SFCLib.sol index add9bd6..6c6ea7d 100644 --- a/contracts/sfc/SFCLib.sol +++ b/contracts/sfc/SFCLib.sol @@ -163,7 +163,7 @@ contract SFCLib is SFCBase { require(success || !strict, "gov votes recounting failed"); } - function _rawUndelegate(address delegator, uint256 toValidatorID, uint256 amount, bool strict) internal { + function _rawUndelegate(address delegator, uint256 toValidatorID, uint256 amount, bool strict, bool forceful, bool checkDelegatedStake) internal { getStake[delegator][toValidatorID] -= amount; getValidator[toValidatorID].receivedStake = getValidator[toValidatorID].receivedStake.sub(amount); totalStake = totalStake.sub(amount); @@ -172,11 +172,15 @@ contract SFCLib is SFCBase { } uint256 selfStakeAfterwards = getSelfStake(toValidatorID); - if (selfStakeAfterwards != 0) { - if (getValidator[toValidatorID].status == OK_STATUS) { - require(selfStakeAfterwards >= c.minSelfStake(), "insufficient self-stake"); - require(_checkDelegatedStakeLimit(toValidatorID), "validator's delegations limit is exceeded"); + if (selfStakeAfterwards != 0 && getValidator[toValidatorID].status == OK_STATUS) { + if (!(selfStakeAfterwards >= c.minSelfStake())) { + if (forceful) { + revert("insufficient self-stake"); + } else { + _setValidatorDeactivated(toValidatorID, WITHDRAWN_BIT); + } } + require(!checkDelegatedStake || _checkDelegatedStakeLimit(toValidatorID), "validator's delegations limit is exceeded"); } else { _setValidatorDeactivated(toValidatorID, WITHDRAWN_BIT); } @@ -195,7 +199,7 @@ contract SFCLib is SFCBase { require(getWithdrawalRequest[delegator][toValidatorID][wrID].amount == 0, "wrID already exists"); - _rawUndelegate(delegator, toValidatorID, amount, true); + _rawUndelegate(delegator, toValidatorID, amount, true, false, true); getWithdrawalRequest[delegator][toValidatorID][wrID].amount = amount; getWithdrawalRequest[delegator][toValidatorID][wrID].epoch = currentEpoch(); @@ -224,7 +228,7 @@ contract SFCLib is SFCBase { emit UnlockedStake(delegator, toValidatorID, amount - unlockedStake, 0); } - _rawUndelegate(delegator, toValidatorID, amount, false); + _rawUndelegate(delegator, toValidatorID, amount, false, true, false); _syncValidator(toValidatorID, false); @@ -564,7 +568,7 @@ contract SFCLib is SFCBase { } ld.lockedStake -= amount; if (penalty != 0) { - _rawUndelegate(delegator, toValidatorID, penalty, true); + _rawUndelegate(delegator, toValidatorID, penalty, true, false, false); treasuryAddress.call.value(penalty)(""); }