@@ -431,7 +431,203 @@ func (v *Validators) PayRewardsV3(height uint64, period int64) (moreRewards *big
431431 return moreRewards
432432}
433433
434- // PayRewardsV4 distributes accumulated rewards between validator, delegators, DAO and developers addresses
434+ // PayRewardsV5 distributes accumulated rewards between validator, delegators, DAO and developers addresses
435+ func (v * Validators ) PayRewardsV5 (height uint64 , period int64 ) (moreRewards * big.Int ) {
436+ moreRewards = big .NewInt (0 )
437+
438+ vals := v .GetValidators ()
439+
440+ calcReward , safeReward := v .bus .App ().Reward ()
441+ var totalAccumRewards = big .NewInt (0 )
442+ for _ , validator := range vals {
443+ totalAccumRewards = totalAccumRewards .Add (totalAccumRewards , validator .GetAccumReward ())
444+ }
445+
446+ var totalStakes = big .NewInt (0 )
447+ if totalAccumRewards .Sign () != 1 {
448+ for _ , validator := range vals {
449+ totalStakes = totalStakes .Add (totalStakes , validator .GetTotalBipStake ())
450+ }
451+ }
452+
453+ for _ , validator := range vals {
454+ candidate := v .bus .Candidates ().GetCandidate (validator .PubKey )
455+
456+ totalReward := big .NewInt (0 ).Set (validator .GetAccumReward ())
457+ remainder := big .NewInt (0 ).Set (validator .GetAccumReward ())
458+
459+ // pay commission to DAO
460+
461+ DAOReward := big .NewInt (0 ).Set (totalReward )
462+ DAOReward .Mul (DAOReward , big .NewInt (int64 (dao .Commission )))
463+ DAOReward .Div (DAOReward , big .NewInt (100 ))
464+
465+ // pay commission to Developers
466+
467+ DevelopersReward := big .NewInt (0 ).Set (totalReward )
468+ DevelopersReward .Mul (DevelopersReward , big .NewInt (int64 (developers .Commission )))
469+ DevelopersReward .Div (DevelopersReward , big .NewInt (100 ))
470+
471+ totalReward .Sub (totalReward , DevelopersReward )
472+ totalReward .Sub (totalReward , DAOReward )
473+ remainder .Sub (remainder , DAOReward )
474+ remainder .Sub (remainder , DevelopersReward )
475+
476+ // pay commission to validator
477+ validatorReward := big .NewInt (0 ).Set (totalReward )
478+ validatorReward .Mul (validatorReward , big .NewInt (int64 (candidate .Commission )))
479+ validatorReward .Div (validatorReward , big .NewInt (100 ))
480+ totalReward .Sub (totalReward , validatorReward )
481+
482+ candidate .AddUpdate (types .GetBaseCoinID (), validatorReward , validatorReward , candidate .RewardAddress )
483+ v .bus .Checker ().AddCoin (types .GetBaseCoinID (), validatorReward )
484+
485+ remainder .Sub (remainder , validatorReward )
486+ v .bus .Events ().AddEvent (& eventsdb.RewardEvent {
487+ Role : eventsdb .RoleValidator .String (),
488+ Address : candidate .RewardAddress ,
489+ Amount : validatorReward .String (),
490+ ValidatorPubKey : validator .PubKey ,
491+ ForCoin : 0 ,
492+ })
493+
494+ stakes := v .bus .Candidates ().GetStakes (validator .PubKey )
495+ for _ , stake := range stakes {
496+ if stake .BipValue .Sign () == 0 {
497+ continue
498+ }
499+
500+ reward := big .NewInt (0 ).Set (totalReward )
501+ reward .Mul (reward , stake .BipValue )
502+
503+ reward .Div (reward , validator .GetTotalBipStake ())
504+
505+ remainder .Sub (remainder , reward )
506+
507+ safeRewardVariable := big .NewInt (0 ).Set (reward )
508+ if validator .bus .Accounts ().IsX3Mining (stake .Owner , height ) {
509+ if totalAccumRewards .Sign () == 1 && validator .GetAccumReward ().Sign () == 1 {
510+ safeRewards := big .NewInt (0 ).Mul (safeReward , big .NewInt (period ))
511+ safeRewards .Mul (safeRewards , stake .BipValue )
512+ safeRewards .Mul (safeRewards , big .NewInt (3 ))
513+ safeRewards .Mul (safeRewards , validator .GetAccumReward ())
514+ safeRewards .Div (safeRewards , validator .GetTotalBipStake ())
515+
516+ taxDAOx3 := big .NewInt (0 ).Div (big .NewInt (0 ).Mul (safeRewards , big .NewInt (int64 (developers .Commission ))), big .NewInt (100 ))
517+ taxDEVx3 := big .NewInt (0 ).Div (big .NewInt (0 ).Mul (safeRewards , big .NewInt (int64 (dao .Commission ))), big .NewInt (100 ))
518+
519+ safeRewards .Sub (safeRewards , taxDAOx3 )
520+ safeRewards .Sub (safeRewards , taxDEVx3 )
521+ safeRewards .Sub (safeRewards , big .NewInt (0 ).Div (big .NewInt (0 ).Mul (safeRewards , big .NewInt (int64 (candidate .Commission ))), big .NewInt (100 )))
522+ safeRewards .Div (safeRewards , totalAccumRewards )
523+
524+ calcRewards := big .NewInt (0 ).Mul (calcReward , big .NewInt (period ))
525+ calcRewards .Mul (calcRewards , stake .BipValue )
526+ calcRewards .Mul (calcRewards , validator .GetAccumReward ())
527+ calcRewards .Div (calcRewards , validator .GetTotalBipStake ())
528+
529+ taxDAO := big .NewInt (0 ).Div (big .NewInt (0 ).Mul (calcRewards , big .NewInt (int64 (developers .Commission ))), big .NewInt (100 ))
530+ taxDEV := big .NewInt (0 ).Div (big .NewInt (0 ).Mul (calcRewards , big .NewInt (int64 (dao .Commission ))), big .NewInt (100 ))
531+
532+ calcRewards .Sub (calcRewards , taxDAO )
533+ calcRewards .Sub (calcRewards , taxDEV )
534+ calcRewards .Sub (calcRewards , big .NewInt (0 ).Div (big .NewInt (0 ).Mul (calcRewards , big .NewInt (int64 (developers .Commission + dao .Commission ))), big .NewInt (100 )))
535+ calcRewards .Sub (calcRewards , big .NewInt (0 ).Div (big .NewInt (0 ).Mul (calcRewards , big .NewInt (int64 (candidate .Commission ))), big .NewInt (100 )))
536+ calcRewards .Div (calcRewards , totalAccumRewards )
537+
538+ diffDAO := big .NewInt (0 ).Sub (taxDAOx3 , taxDAO )
539+ diffDEV := big .NewInt (0 ).Sub (taxDAOx3 , taxDEV )
540+ DAOReward .Add (DAOReward , diffDAO )
541+ DevelopersReward .Add (DevelopersReward , diffDEV )
542+
543+ moreRewards .Add (moreRewards , diffDAO )
544+ moreRewards .Add (moreRewards , diffDEV )
545+
546+ feeRewards := big .NewInt (0 ).Sub (reward , calcRewards )
547+ safeRewardVariable .Set (big .NewInt (0 ).Add (safeRewards , feeRewards ))
548+ } else if totalAccumRewards .Sign () != 1 && validator .GetAccumReward ().Sign () != 1 {
549+ safeRewards := big .NewInt (0 ).Mul (safeReward , big .NewInt (period ))
550+ safeRewards .Mul (safeRewards , stake .BipValue )
551+ safeRewards .Mul (safeRewards , big .NewInt (3 ))
552+
553+ taxDAO := big .NewInt (0 ).Div (big .NewInt (0 ).Mul (safeRewards , big .NewInt (int64 (developers .Commission ))), big .NewInt (100 ))
554+ taxDEV := big .NewInt (0 ).Div (big .NewInt (0 ).Mul (safeRewards , big .NewInt (int64 (dao .Commission ))), big .NewInt (100 ))
555+
556+ DAOReward .Add (DAOReward , taxDAO )
557+ DevelopersReward .Add (DevelopersReward , taxDEV )
558+ moreRewards .Add (moreRewards , taxDAO )
559+ moreRewards .Add (moreRewards , taxDEV )
560+
561+ safeRewards .Sub (safeRewards , taxDAO )
562+ safeRewards .Sub (safeRewards , taxDEV )
563+
564+ safeRewards .Sub (safeRewards , big .NewInt (0 ).Div (big .NewInt (0 ).Mul (safeRewards , big .NewInt (int64 (candidate .Commission ))), big .NewInt (100 )))
565+ safeRewards .Div (safeRewards , totalStakes )
566+
567+ safeRewardVariable .Set (safeRewards )
568+ }
569+
570+ if safeRewardVariable .Sign () < 1 {
571+ continue
572+ }
573+
574+ moreRewards .Add (moreRewards , new (big.Int ).Sub (safeRewardVariable , reward ))
575+ }
576+
577+ if safeRewardVariable .Sign () < 1 {
578+ continue
579+ }
580+
581+ candidate .AddUpdate (types .GetBaseCoinID (), safeRewardVariable , safeRewardVariable , stake .Owner )
582+ v .bus .Checker ().AddCoin (types .GetBaseCoinID (), safeRewardVariable )
583+
584+ v .bus .Events ().AddEvent (& eventsdb.RewardEvent {
585+ Role : eventsdb .RoleDelegator .String (),
586+ Address : stake .Owner ,
587+ Amount : safeRewardVariable .String (),
588+ ValidatorPubKey : validator .PubKey ,
589+ ForCoin : uint64 (stake .Coin ),
590+ })
591+ }
592+
593+ {
594+ candidate .AddUpdate (types .GetBaseCoinID (), DAOReward , DAOReward , dao .Address )
595+ v .bus .Checker ().AddCoin (types .GetBaseCoinID (), DAOReward )
596+ v .bus .Events ().AddEvent (& eventsdb.RewardEvent {
597+ Role : eventsdb .RoleDAO .String (),
598+ Address : dao .Address ,
599+ Amount : DAOReward .String (),
600+ ValidatorPubKey : validator .PubKey ,
601+ ForCoin : 0 ,
602+ })
603+ }
604+
605+ {
606+ candidate .AddUpdate (types .GetBaseCoinID (), DevelopersReward , DevelopersReward , developers .Address )
607+ v .bus .Checker ().AddCoin (types .GetBaseCoinID (), DevelopersReward )
608+ v .bus .Events ().AddEvent (& eventsdb.RewardEvent {
609+ Role : eventsdb .RoleDevelopers .String (),
610+ Address : developers .Address ,
611+ Amount : DevelopersReward .String (),
612+ ValidatorPubKey : validator .PubKey ,
613+ ForCoin : 0 ,
614+ })
615+ }
616+
617+ validator .SetAccumReward (big .NewInt (0 ))
618+
619+ if remainder .Sign () != - 1 {
620+ v .bus .App ().AddTotalSlashed (remainder )
621+ } else {
622+ panic (fmt .Sprintf ("Negative remainder: %s" , remainder .String ()))
623+ }
624+ }
625+
626+ return moreRewards
627+ }
628+
629+ // PayRewardsV4
630+ // Deprecated
435631func (v * Validators ) PayRewardsV4 (height uint64 , period int64 ) (moreRewards * big.Int ) {
436632 moreRewards = big .NewInt (0 )
437633
0 commit comments