Slashing Protection

Learn how to implement slashing protection in your liquid staking protocol.

Last updated: 2024-03-21
Edit on GitHub

Slashing Protection Overview

Slashing protection is crucial for securing user funds in a liquid staking protocol. This guide covers implementation of slashing detection, prevention mechanisms, and recovery procedures.

Key Features

  • Real-time monitoring
  • Automated responses
  • Fund recovery
  • Risk mitigation

Benefits

  • Enhanced security
  • User fund protection
  • Reduced risk exposure
  • Quick incident response

Implementation Guide

Learn how to implement comprehensive slashing protection mechanisms.

Slashing Protection Implementation

1pub struct SlashingProtection {
2    /// Slashing threshold (percentage)
3    pub slashing_threshold: u8,
4    
5    /// Emergency unstake threshold
6    pub emergency_unstake_threshold: u8,
7    
8    /// Recovery pool
9    pub recovery_pool: Pubkey,
10    
11    /// Emergency authority
12    pub emergency_authority: Pubkey,
13}
14
15impl SlashingProtection {
16    pub fn handle_slashing_event(
17        &mut self,
18        stake_pool: &mut StakePool,
19        validator: &Pubkey,
20        slash_amount: u64,
21    ) -> ProgramResult {
22        // Calculate slash percentage
23        let slash_percentage = (slash_amount * 100) / stake_pool.total_lamports;
24        
25        if slash_percentage >= self.emergency_unstake_threshold {
26            // Emergency unstake all funds
27            stake_pool.emergency_unstake(validator)?;
28        } else if slash_percentage >= self.slashing_threshold {
29            // Partial unstake
30            stake_pool.partial_unstake(
31                validator,
32                slash_amount * 2, // Extra safety margin
33            )?;
34        }
35        
36        // Move slashed amount to recovery pool
37        stake_pool.transfer_to_recovery_pool(
38            validator,
39            slash_amount,
40        )?;
41        
42        // Update validator status
43        stake_pool.update_validator_status(
44            validator,
45            ValidatorStatus::Slashed,
46        )?;
47        
48        // Emit slashing event
49        emit!(ValidatorSlashed {
50            validator: *validator,
51            slash_amount,
52            slash_percentage,
53            timestamp: Clock::get()?.unix_timestamp,
54        });
55        
56        Ok(())
57    }
58
59    pub fn monitor_validator_performance(
60        &self,
61        validator: &ValidatorStakeInfo,
62        epoch_stats: &EpochStats,
63    ) -> ValidatorStatus {
64        // Check for slashing indicators
65        if epoch_stats.missed_blocks > self.max_missed_blocks {
66            return ValidatorStatus::Delinquent;
67        }
68        
69        if epoch_stats.vote_credits < self.min_vote_credits {
70            return ValidatorStatus::Delinquent;
71        }
72        
73        if epoch_stats.commission > self.max_commission {
74            return ValidatorStatus::Delinquent;
75        }
76        
77        ValidatorStatus::Active
78    }
79
80    pub fn recover_slashed_funds(
81        &mut self,
82        stake_pool: &mut StakePool,
83        validator: &Pubkey,
84    ) -> ProgramResult {
85        // Verify emergency authority
86        if !self.emergency_authority.is_signer {
87            return Err(StakePoolError::SignatureMissing.into());
88        }
89        
90        // Get recovery amount
91        let recovery_amount = stake_pool
92            .get_validator_recovery_amount(validator)?;
93            
94        // Transfer from recovery pool
95        stake_pool.transfer_from_recovery_pool(
96            validator,
97            recovery_amount,
98        )?;
99        
100        // Update validator status
101        stake_pool.update_validator_status(
102            validator,
103            ValidatorStatus::Active,
104        )?;
105        
106        // Emit recovery event
107        emit!(FundsRecovered {
108            validator: *validator,
109            amount: recovery_amount,
110            timestamp: Clock::get()?.unix_timestamp,
111        });
112        
113        Ok(())
114    }
115}

Monitoring Setup

Implement comprehensive monitoring to detect potential slashing events early.

Monitoring Implementation

1pub struct ValidatorMonitor {
2    /// Performance thresholds
3    pub thresholds: MonitorThresholds,
4    
5    /// Alert system
6    pub alert_system: AlertSystem,
7    
8    /// Historical data
9    pub history: ValidatorHistory,
10}
11
12impl ValidatorMonitor {
13    pub fn check_validator_health(
14        &self,
15        validator: &ValidatorStakeInfo,
16        vote_account: &VoteAccountInfo,
17    ) -> Result<ValidatorStatus, StakePoolError> {
18        // Check consecutive missed blocks
19        if vote_account.consecutive_missed_blocks > self.thresholds.max_consecutive_misses {
20            return Ok(ValidatorStatus::Delinquent);
21        }
22
23        // Check uptime
24        let uptime_percentage = calculate_uptime_percentage(vote_account);
25        if uptime_percentage < self.thresholds.min_uptime {
26            return Ok(ValidatorStatus::Delinquent);
27        }
28
29        // Check commission hasn't increased beyond max
30        if vote_account.commission > self.thresholds.max_commission {
31            return Ok(ValidatorStatus::Delinquent);
32        }
33
34        // Check for slashing events
35        if vote_account.has_been_slashed {
36            return Ok(ValidatorStatus::Emergency);
37        }
38
39        Ok(ValidatorStatus::Active)
40    }
41
42    pub fn handle_validator_emergency(
43        &self,
44        stake_pool: &mut StakePool,
45        validator: &Pubkey,
46    ) -> ProgramResult {
47        // Move stake to emergency reserve
48        stake_pool.emergency_unstake(validator)?;
49        
50        // Mark validator as emergency
51        stake_pool.update_validator_status(
52            validator,
53            ValidatorStatus::Emergency,
54        )?;
55        
56        // Emit emergency event
57        emit!(ValidatorEmergency {
58            stake_pool: stake_pool.pubkey(),
59            validator: *validator,
60            timestamp: Clock::get()?.unix_timestamp,
61        });
62        
63        Ok(())
64    }
65}
Critical Security Measures
  • Implement real-time monitoring of validator performance
  • Set up automated responses to slashing events
  • Maintain proper access controls for emergency procedures
  • Keep detailed logs of all slashing-related events
  • Have clear recovery procedures documented and tested
  • Regular testing of emergency response mechanisms