@@ -291,7 +291,6 @@ contract TokenStaking is Initializable, IStaking, Checkpoints {
291291
292292 uint96 fromAmount = authorization.authorized;
293293 authorization.authorized -= authorization.deauthorizing;
294- authorization.deauthorizing = 0 ;
295294 emit AuthorizationDecreaseApproved (
296295 stakingProvider,
297296 msg .sender ,
@@ -304,6 +303,16 @@ contract TokenStaking is Initializable, IStaking, Checkpoints {
304303 cleanAuthorizedApplications (stakingProviderStruct, 1 );
305304 }
306305
306+ // Unstake
307+ stakingProviderStruct.tStake -= authorization.deauthorizing;
308+ decreaseStakeCheckpoint (stakingProvider, authorization.deauthorizing);
309+ emit Unstaked (stakingProvider, authorization.deauthorizing);
310+ token.safeTransfer (
311+ stakingProviderStruct.owner,
312+ authorization.deauthorizing
313+ );
314+
315+ authorization.deauthorizing = 0 ;
307316 return authorization.authorized;
308317 }
309318
@@ -488,6 +497,59 @@ contract TokenStaking is Initializable, IStaking, Checkpoints {
488497 );
489498 }
490499
500+ /// Migration
501+ function migrateAndRelease (address stakingProvider , uint96 amount )
502+ external
503+ override
504+ returns (bool stakeless )
505+ {
506+ ApplicationInfo storage applicationStruct = applicationInfo[msg .sender ];
507+ require (
508+ applicationStruct.status == ApplicationStatus.APPROVED,
509+ "Application is not approved "
510+ );
511+
512+ require (
513+ ! skipApplication (msg .sender ),
514+ "Only TACo app can call this method "
515+ );
516+
517+ StakingProviderInfo storage stakingProviderStruct = stakingProviders[
518+ stakingProvider
519+ ];
520+ require (
521+ stakingProviderStruct.owner != address (0 ),
522+ "Wrong staking provider "
523+ );
524+ uint96 toUnstake = stakingProviderStruct.tStake;
525+ stakingProviderStruct.tStake = 0 ;
526+ decreaseStakeCheckpoint (stakingProvider, toUnstake);
527+ emit Unstaked (stakingProvider, toUnstake);
528+
529+ AppAuthorization storage authorization = stakingProviderStruct
530+ .authorizations[msg .sender ];
531+
532+ // stakeless
533+ if (authorization.authorized == 0 ) {
534+ stakeless = true ;
535+ } else {
536+ require (
537+ authorization.authorized >= amount,
538+ "Not enough authorization "
539+ );
540+ toUnstake -= amount;
541+ authorization.authorized = 0 ;
542+ if (amount > 0 ) {
543+ token.safeTransfer (msg .sender , amount);
544+ }
545+ stakeless = false ;
546+ }
547+
548+ if (toUnstake > 0 ) {
549+ token.safeTransfer (stakingProviderStruct.owner, toUnstake);
550+ }
551+ }
552+
491553 /// @notice Delegate voting power from the stake associated to the
492554 /// `stakingProvider` to a `delegatee` address. Caller must be the
493555 /// owner of this stake.
@@ -520,6 +582,9 @@ contract TokenStaking is Initializable, IStaking, Checkpoints {
520582 override
521583 returns (uint96 )
522584 {
585+ if (skipApplication (application)) {
586+ return 0 ;
587+ }
523588 return
524589 stakingProviders[stakingProvider]
525590 .authorizations[application]
@@ -818,61 +883,10 @@ contract TokenStaking is Initializable, IStaking, Checkpoints {
818883 emit GovernanceTransferred (oldGuvnor, newGuvnor);
819884 }
820885
821- function forceDecreaseAuthorization (
822- address stakingProvider ,
823- uint96 amountTo
824- ) internal {
825- StakingProviderInfo storage stakingProviderStruct = stakingProviders[
826- stakingProvider
827- ];
828- uint96 deauthorized = 0 ;
829- for (
830- uint256 i = 0 ;
831- i < stakingProviderStruct.authorizedApplications.length ;
832- i++
833- ) {
834- address application = stakingProviderStruct.authorizedApplications[
835- i
836- ];
837- if (skipApplication (application)) {
838- continue ;
839- }
840- AppAuthorization storage authorization = stakingProviderStruct
841- .authorizations[application];
842- uint96 authorized = authorization.authorized;
843- if (authorized > amountTo) {
844- IApplication (application).involuntaryAuthorizationDecrease (
845- stakingProvider,
846- authorized,
847- amountTo
848- );
849- uint96 decrease = authorized - amountTo;
850-
851- if (authorization.deauthorizing >= decrease) {
852- authorization.deauthorizing -= decrease;
853- } else {
854- authorization.deauthorizing = 0 ;
855- }
856-
857- authorization.authorized = amountTo;
858- deauthorized += decrease;
859-
860- emit AuthorizationDecreaseApproved (
861- stakingProvider,
862- application,
863- authorized,
864- amountTo
865- );
866- }
867- }
868-
869- require (deauthorized > 0 , "Nothing to deauthorize " );
870- }
871-
872886 // slither-disable-next-line dead-code
873887 function skipApplication (address application )
874888 internal
875- pure
889+ view
876890 virtual
877891 returns (bool )
878892 {
0 commit comments