@@ -662,3 +662,90 @@ func TestIsSelfStakeBucket(t *testing.T) {
662662 r .False (selfStake )
663663 })
664664}
665+
666+ func TestSlashCandidate (t * testing.T ) {
667+ require := require .New (t )
668+ ctrl := gomock .NewController (t )
669+ sm := testdb .NewMockStateManager (ctrl )
670+
671+ owner := identityset .Address (1 )
672+ operator := identityset .Address (2 )
673+ reward := identityset .Address (3 )
674+ selfStake := big .NewInt (1000 )
675+ bucket := NewVoteBucket (owner , owner , new (big.Int ).Set (selfStake ), 10 , time .Now (), true )
676+ bucketIdx := uint64 (0 )
677+ bucket .Index = bucketIdx
678+
679+ cand := & Candidate {
680+ Owner : owner ,
681+ Operator : operator ,
682+ Reward : reward ,
683+ Name : "cand1" ,
684+ Votes : big .NewInt (1000 ),
685+ SelfStakeBucketIdx : bucketIdx ,
686+ SelfStake : new (big.Int ).Set (selfStake ),
687+ }
688+ cc , err := NewCandidateCenter (CandidateList {cand })
689+ require .NoError (err )
690+ require .NoError (sm .WriteView (_protocolID , & viewData {
691+ candCenter : cc ,
692+ bucketPool : & BucketPool {
693+ enableSMStorage : true ,
694+ total : & totalAmount {
695+ amount : big .NewInt (0 ),
696+ },
697+ },
698+ }))
699+ csm , err := NewCandidateStateManager (sm )
700+ require .NoError (err )
701+
702+ p := & Protocol {
703+ config : Configuration {
704+ RegistrationConsts : RegistrationConsts {
705+ MinSelfStake : big .NewInt (1 ),
706+ },
707+ MinSelfStakeToBeActive : big .NewInt (1 ),
708+ },
709+ }
710+ ctx := context .Background ()
711+
712+ t .Run ("nil amount" , func (t * testing.T ) {
713+ err := p .SlashCandidate (ctx , sm , owner , nil )
714+ require .ErrorContains (err , "nil or non-positive amount" )
715+ })
716+
717+ t .Run ("zero amount" , func (t * testing.T ) {
718+ err := p .SlashCandidate (ctx , sm , owner , big .NewInt (0 ))
719+ require .ErrorContains (err , "nil or non-positive amount" )
720+ })
721+
722+ t .Run ("candidate not exist" , func (t * testing.T ) {
723+ err := p .SlashCandidate (ctx , sm , identityset .Address (9 ), big .NewInt (1 ))
724+ require .ErrorContains (err , "does not exist" )
725+ })
726+
727+ t .Run ("bucket not exist" , func (t * testing.T ) {
728+ err := p .SlashCandidate (ctx , sm , owner , big .NewInt (1 ))
729+ require .ErrorContains (err , "failed to fetch bucket" )
730+ })
731+
732+ _ , err = csm .putBucket (bucket )
733+ require .NoError (err )
734+ require .NoError (csm .DebitBucketPool (bucket .StakedAmount , true ))
735+ t .Run ("amount greater than staked" , func (t * testing.T ) {
736+ err := p .SlashCandidate (ctx , sm , owner , big .NewInt (2000 ))
737+ require .ErrorContains (err , "is greater than staked amount" )
738+ })
739+
740+ t .Run ("success" , func (t * testing.T ) {
741+ amount := big .NewInt (400 )
742+ remaining := bucket .StakedAmount .Sub (bucket .StakedAmount , amount )
743+ err := p .SlashCandidate (ctx , sm , owner , amount )
744+ require .NoError (err )
745+ bucket , err := csm .NativeBucket (bucketIdx )
746+ require .NoError (err )
747+ require .Equal (remaining .String (), bucket .StakedAmount .String ())
748+ cand := csm .GetByIdentifier (owner )
749+ require .Equal (remaining .String (), cand .SelfStake .String ())
750+ })
751+ }
0 commit comments