Skip to content

Weber Rewards and Penalties

Notice: This document is a work-in-progress for researchers and implementers of the Weber protocol.

Table of contents

Introduction

The Weber protocol's economic incentives are designed to encourage validator behaviors that promote network security, liveness, and finality. This document specifies the reward and penalty mechanisms in Weber, including:

  1. Reputation-weighted rewards that adjust based on validator historical performance
  2. Quick finality incentives to reward validators participating in Weber's accelerated finality mechanism
  3. Progressive penalties that scale with the severity and frequency of infractions
  4. Validator rotation incentives that encourage decentralization through periodic validator changes

These incentives collectively ensure that validators are economically motivated to follow the protocol rules, maintain high availability, and contribute positively to network health.

Constants

Reward Values

Name Value Description
BASE_REWARD_FACTOR 64 Base reward factor used in calculating per-slot base reward
PROPOSER_REWARD_QUOTIENT 8 Quotient used to calculate proposer rewards
FINALITY_DELAY_FACTOR 64 Factor for penalties in case of delayed finality
SYNC_REWARD_WEIGHT 2 Weight for sync committee rewards relative to attestation rewards
QUICK_FINALITY_REWARD_MULTIPLIER 1.5 Additional reward multiplier for quick finality participation
REPUTATION_REWARD_FACTOR 0.2 Factor that scales reputation's impact on rewards
MAX_EFFECTIVE_BALANCE 32 ETH Maximum effective balance for a validator

Penalty Values

Name Value Description
INACTIVITY_PENALTY_QUOTIENT 33554432 Quotient for calculating inactivity penalties
MIN_SLASHING_PENALTY_QUOTIENT 128 Minimum slashing penalty quotient
PROPORTIONAL_SLASHING_MULTIPLIER 1 Multiplier for proportional slashing penalties
MISSED_ATTESTATION_PENALTY_FACTOR 0.5 Factor for missed attestation penalties
REPUTATION_PENALTY_FACTOR 0.3 Factor that scales reputation's impact on penalties

Reputation Parameters

Name Value Description
INITIAL_REPUTATION_SCORE 500 Initial reputation score for new validators (0-1000 scale)
REPUTATION_UPDATE_WEIGHT 0.2 Weight of new performance data in reputation updates
MAX_REPUTATION_SCORE 1000 Maximum possible reputation score
MIN_REPUTATION_SCORE 0 Minimum possible reputation score
QUICK_FINALITY_MIN_REPUTATION 900 Minimum reputation required for quick finality participation

Validator Reputation System

Reputation Score

Weber maintains a reputation score for each validator ranging from 0 to 1000, representing the validator's historical performance and reliability. This score directly influences rewards and voting power in consensus.

1
2
3
4
5
6
7
class ValidatorScore(Container):
    score: uint16  # 0-1000 scale
    last_update_epoch: Epoch
    attestation_performance: uint16
    block_proposal_performance: uint16
    network_participation: uint16
    historical_uptime: uint16

Reputation Factors

The reputation score is derived from several performance metrics:

  1. Attestation Performance: Timeliness and consistency of attestations
  2. Block Proposal Performance: Success rate and timeliness of block proposals
  3. Network Participation: Participation in required subnets
  4. Historical Uptime: Long-term validator availability
  5. Protocol Violations: Any detected improper behavior

Reputation Updates

def update_validator_reputation(
    state: BeaconState,
    validator_index: ValidatorIndex,
    performance_metrics: Dict[str, float]
) -> None:
    """
    Update a validator's reputation score based on recent performance.
    """
    if validator_index >= len(state.validators):
        return

    current_epoch = get_current_epoch(state)
    validator_score = state.validator_reputation_scores[validator_index]

    # Extract performance metrics
    attestation_performance = performance_metrics.get("attestation_performance", 0.0)
    block_performance = performance_metrics.get("block_performance", 0.0)
    network_performance = performance_metrics.get("network_performance", 0.0)
    uptime = performance_metrics.get("uptime", 0.0)

    # Convert metrics to scores (0-1000)
    attestation_score = int(attestation_performance * 1000)
    block_score = int(block_performance * 1000)
    network_score = int(network_performance * 1000)
    uptime_score = int(uptime * 1000)

    # Update component scores with time decay
    validator_score.attestation_performance = int(
        validator_score.attestation_performance * (1 - REPUTATION_UPDATE_WEIGHT) +
        attestation_score * REPUTATION_UPDATE_WEIGHT
    )

    validator_score.block_proposal_performance = int(
        validator_score.block_proposal_performance * (1 - REPUTATION_UPDATE_WEIGHT) +
        block_score * REPUTATION_UPDATE_WEIGHT
    )

    validator_score.network_participation = int(
        validator_score.network_participation * (1 - REPUTATION_UPDATE_WEIGHT) +
        network_score * REPUTATION_UPDATE_WEIGHT
    )

    validator_score.historical_uptime = int(
        validator_score.historical_uptime * (1 - REPUTATION_UPDATE_WEIGHT) +
        uptime_score * REPUTATION_UPDATE_WEIGHT
    )

    # Calculate overall score with weighted components
    overall_score = (
        validator_score.attestation_performance * 0.4 +
        validator_score.block_proposal_performance * 0.3 +
        validator_score.network_participation * 0.2 +
        validator_score.historical_uptime * 0.1
    )

    # Apply any penalties for protocol violations
    violations = performance_metrics.get("protocol_violations", 0)
    if violations > 0:
        overall_score -= violations * 50  # 50 points per violation

    # Ensure score is within bounds
    validator_score.score = max(MIN_REPUTATION_SCORE, min(MAX_REPUTATION_SCORE, int(overall_score)))
    validator_score.last_update_epoch = current_epoch

    # Store updated score
    state.validator_reputation_scores[validator_index] = validator_score

Base Reward Calculation

Weber calculates the base reward for validators with a reputation modifier:

def get_base_reward(state: BeaconState, index: ValidatorIndex) -> Gwei:
    """
    Return the base reward for the validator with the given index.
    Includes Weber's reputation weighting.
    """
    total_active_balance = get_total_active_balance(state)
    effective_balance = state.validators[index].effective_balance

    # Standard base reward calculation
    standard_reward = Gwei(
        effective_balance * BASE_REWARD_FACTOR //
        integer_squareroot(total_active_balance) //
        BASE_REWARDS_PER_EPOCH
    )

    # Apply reputation modifier if validator is active
    if is_active_validator(state.validators[index], get_current_epoch(state)):
        reputation_score = state.validator_reputation_scores[index].score
        reputation_modifier = 1.0 + REPUTATION_REWARD_FACTOR * (
            (reputation_score - INITIAL_REPUTATION_SCORE) / 
            (MAX_REPUTATION_SCORE - INITIAL_REPUTATION_SCORE)
        )

        # Reputation can adjust rewards up to +20% or -20%
        reputation_modifier = max(0.8, min(1.2, reputation_modifier))
        return Gwei(int(standard_reward * reputation_modifier))

    return standard_reward

Attestation Rewards

Validators receive rewards for timely attestations that contribute to consensus. These rewards are divided into components based on the attestation's properties.

Source Vote

1
2
3
4
5
6
def get_source_reward(state: BeaconState, index: ValidatorIndex) -> Gwei:
    """
    Return the reward for a correct source vote in an attestation.
    """
    base_reward = get_base_reward(state, index)
    return Gwei(base_reward // ATTESTATION_COMPONENT_REWARD_DIVISOR)

...(about 346 lines omitted)...

Slashing penalties for validators caught double voting or surrounds

def process_slashing(state: BeaconState, validator_index: ValidatorIndex) -> None: """ Apply slashing penalties to a validator caught violating protocol rules. """ validator = state.validators[validator_index] current_epoch = get_current_epoch(state)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# Ensure this is a new slashing
if validator.slashed or current_epoch >= validator.withdrawable_epoch:
    return

# Mark as slashed and set withdrawable epoch
validator.slashed = True

# Calculate the minimum and effective epochs for withdrawal
epoch_to_withdraw = current_epoch + EPOCHS_PER_SLASHINGS_VECTOR
validator.withdrawable_epoch = max(validator.withdrawable_epoch, epoch_to_withdraw)

# Add to slashed balance
slashings_index = current_epoch % EPOCHS_PER_SLASHINGS_VECTOR
state.slashings[slashings_index] += validator.effective_balance

# Apply immediate penalty
base_penalty = validator.effective_balance // MIN_SLASHING_PENALTY_QUOTIENT
state.balances[validator_index] = max(0, state.balances[validator_index] - base_penalty)

# Set reputation to minimum
state.validator_reputation_scores[validator_index].score = MIN_REPUTATION_SCORE

```

Security Considerations

Economic Security

The Weber rewards and penalties system ensures economic security through several mechanisms: 1. Balance between rewards and penalties: The system is designed to make honest participation more profitable than any attack strategy. 2. Reputation-weighted stake: By factoring validator reputation into reward calculations, Weber creates multiple dimensions of security beyond just staked capital. 3. Progressive penalties: Penalties for infractions increase with the severity and frequency, discouraging repeated misbehavior. 4. Finality incentives: Special rewards for quick finality participation ensure validators are motivated to help achieve fast finality guarantees.

Inflation Rate Management

Weber manages its overall inflation rate through careful calibration of rewards: 1. The total issuance is bounded by linking rewards to active validator set size. 2. Rewards dynamically adjust based on participation levels to maintain predictable issuance. 3. Penalties are recycled into rewards for honest validators, creating a zero-sum component.

Attack Resistance

The rewards and penalties system provides resistance against common attacks: 1. Nothing-at-stake: Slashing conditions and significant penalties make equivocation attacks costly. 2. Inactivity leaks: Increased penalties during periods of non-finality encourage validators to participate. 3. Reputation manipulation: The multi-factor reputation system makes gaming the system difficult. 4. Long-range attacks: Mandatory validator rotation prevents long-term control of the validator set.

Appendix

Reward Calculation Examples

Example 1: Standard attestation reward calculation for a validator with 32 ETH effective balance and 750 reputation score: ``` Base reward: 12,000 Gwei Reputation modifier: 1.1 (10% bonus) Modified base reward: 13,200 Gwei

Source vote reward: 13,200 / 4 = 3,300 Gwei Target vote reward: 13,200 / 4 = 3,300 Gwei Head vote reward: 13,200 / 4 = 3,300 Gwei Inclusion delay reward (1 slot delay): 13,200 / 4 * (8-1)/8 = 2,887.5 Gwei

Total attestation reward: 12,787.5 Gwei

Example 2: Block proposal reward with attestation inclusion:
Proposer's base reward: 12,000 Gwei Standard proposer reward: 12,000 / 8 = 1,500 Gwei Total included attestation rewards: 100,000 Gwei Attestation inclusion reward: 100,000 * 1/8 = 12,500 Gwei

Total proposal reward: 14,000 Gwei

1
2
3
### Penalties Calculation Examples

Example 1: Inactivity penalty during non-finality period (10 epochs since last finality):
Validator's effective balance: 32 ETH Inactivity score: 10 Base inactivity penalty: 32,000,000,000 * 10 / 33,554,432 = 9,536 Gwei

Total inactivity penalty: 9,536 Gwei per epoch

Example 2: Slashing penalty:
Validator's effective balance: 32 ETH Immediate slashing penalty: 32,000,000,000 / 128 = 250,000,000 Gwei (0.25 ETH) Correlation penalty (assuming 1% of stake slashed): 32,000,000,000 * 0.01 * 1 = 320,000,000 Gwei (0.32 ETH)

Total slashing penalty: 570,000,000 Gwei (0.57 ETH) ```