@@ -2269,13 +2269,19 @@ func Test_GetValidatorTotals(t *testing.T) {
22692269 _ , _ , err = staker .Housekeep (validator .Period )
22702270 assert .NoError (t , err )
22712271
2272+ aggregation , err = staker .storage .GetAggregation (validator .ID )
2273+ assert .NoError (t , err )
2274+
22722275 totals , err := staker .GetValidatorsTotals (validator .ID )
22732276 assert .NoError (t , err )
22742277
22752278 fetchedValidator , err := staker .Get (validator .ID )
22762279 assert .NoError (t , err )
22772280
2278- assert .Equal (t , fetchedValidator .LockedVET , totals .TotalLockedStake )
2281+ expectedStake := big .NewInt (0 ).Add (aggregation .CurrentRecurringVET , aggregation .CurrentOneTimeVET )
2282+ expectedStake .Add (expectedStake , validator .LockedVET )
2283+
2284+ assert .Equal (t , expectedStake , totals .TotalLockedStake )
22792285 assert .Equal (t , fetchedValidator .Weight , totals .TotalLockedWeight )
22802286 assert .Equal (t , delegation .Stake , totals .DelegationsLockedStake )
22812287 assert .Equal (t , delegation .Weight (), totals .DelegationsLockedWeight )
@@ -2310,3 +2316,78 @@ func Test_Validator_Decrease_Exit_Withdraw(t *testing.T) {
23102316 assert .Equal (t , StatusExit , validator .Status )
23112317 assert .Equal (t , originalStake , validator .CooldownVET )
23122318}
2319+
2320+ func Test_Validator_Decrease_SeveralTimes (t * testing.T ) {
2321+ staker , _ := newStaker (t , 0 , 1 , false )
2322+
2323+ acc := datagen .RandAddress ()
2324+
2325+ originalStake := big .NewInt (0 ).Mul (big .NewInt (3 ), MinStake )
2326+ id , err := staker .AddValidator (acc , acc , LowStakingPeriod , originalStake , true , 0 )
2327+ assert .NoError (t , err )
2328+ _ , err = staker .validations .ActivateNext (0 , staker .params )
2329+ assert .NoError (t , err )
2330+
2331+ // Decrease stake - ok 75m - 25m = 50m
2332+ err = staker .DecreaseStake (acc , id , MinStake )
2333+ assert .NoError (t , err )
2334+
2335+ // Decrease stake - ok 50m - 25m = 25m
2336+ err = staker .DecreaseStake (acc , id , MinStake )
2337+ assert .NoError (t , err )
2338+
2339+ // Decrease stake - should fail, min stake is 25m
2340+ err = staker .DecreaseStake (acc , id , MinStake )
2341+ assert .ErrorContains (t , err , "next period stake is too low for validator" )
2342+ }
2343+
2344+ func Test_Validator_IncreaseDecrease_Combinations (t * testing.T ) {
2345+ staker , _ := newStaker (t , 0 , 1 , false )
2346+ acc := datagen .RandAddress ()
2347+
2348+ // Add & activate validator
2349+ id , err := staker .AddValidator (acc , acc , LowStakingPeriod , MinStake , true , 0 )
2350+ assert .NoError (t , err )
2351+
2352+ // Increase and decrease - both should be okay since we're only dealing with PendingLocked
2353+ assert .NoError (t , staker .IncreaseStake (acc , id , MinStake )) // 25m + 25m = 50m
2354+ assert .NoError (t , staker .DecreaseStake (acc , id , MinStake )) // 25m - 50m = 25m
2355+
2356+ // Activate the validator.
2357+ _ , err = staker .validations .ActivateNext (0 , staker .params )
2358+ assert .NoError (t , err )
2359+
2360+ // Withdraw the previous decrease amount
2361+ withdrawal , err := staker .WithdrawStake (acc , id , 0 )
2362+ assert .NoError (t , err )
2363+ assert .Equal (t , MinStake , withdrawal , "withdraw should be 0 since we are withdrawing from pending locked" )
2364+
2365+ // Assert previous increase/decrease had no effect since they requested the same amount
2366+ validation , err := staker .Get (id )
2367+ assert .NoError (t , err )
2368+ assert .Equal (t , StatusActive , validation .Status )
2369+ assert .Equal (t , MinStake , validation .LockedVET )
2370+
2371+ // Increase stake (ok): 25m + 25m = 50m
2372+ assert .NoError (t , staker .IncreaseStake (acc , id , MinStake ))
2373+ // Decrease stake (NOT ok): 25m - 25m = 0. The Previous increase is not applied since it is still currently withdrawable.
2374+ assert .ErrorContains (t , staker .DecreaseStake (acc , id , MinStake ), "next period stake is too low for validator" )
2375+ // Instantly withdraw - This is bad, it pulls from the PendingLocked, which means total stake later will be 0.
2376+ // The decrease previously marked as okay since the current TVL + pending TVL was greater than the min stake.
2377+ withdraw1 , err := staker .WithdrawStake (acc , id , 0 )
2378+ assert .NoError (t , err )
2379+ assert .Equal (t , MinStake , withdraw1 , "withdraw should be 0 since we are withdrawing from pending locked" )
2380+
2381+ // Housekeep, should move pending locked to locked, and pending withdraw to withdrawable
2382+ _ , _ , err = staker .Housekeep (LowStakingPeriod )
2383+ assert .NoError (t , err )
2384+
2385+ // Withdraw again
2386+ withdraw2 , err := staker .WithdrawStake (acc , id , LowStakingPeriod + cooldownPeriod )
2387+ assert .NoError (t , err )
2388+ assert .Equal (t , big .NewInt (0 ), withdraw2 )
2389+
2390+ validator , err := staker .Get (id )
2391+ assert .NoError (t , err )
2392+ assert .Equal (t , 0 , validator .LockedVET .Cmp (MinStake ), "locked vet should be greater than or equal to min stake" )
2393+ }
0 commit comments