Skip to content

boulder225/operator-challenger-slashing

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Operator Slashing Contract

A smart contract that manages operators, challengers, and slashing conditions. It enables staking and challenging with penalties for misbehavior.

Key Features

  • Operator registration with ETH staking
  • Challenger registration
  • Challenge submission and resolution
  • Stake withdrawal mechanism with safety delays
  • Slashing penalties for misbehavior

Contract Components

Operators

  • Register with minimum required stake
  • Can be challenged for misbehavior
  • Can withdraw stake with timelock
  • Get deactivated if stake falls below minimum

Challengers

  • Register with minimum challenger stake
  • Randomly selected for challenge eligibility
  • Can submit evidence of operator misbehavior

Challenges

  • Resolved by contract owner
  • Result in stake slashing if proven valid

Quick Start

Prerequisites

  • Node.js v16+
  • npm/yarn
  • Hardhat

Install & Test

# Install dependencies
npm install

# Run tests
npx hardhat test

# Check coverage
npx hardhat coverage

Contract Overview

Key Components

Operators

  • Stake ETH to participate
  • Must maintain minimum stake
  • Can withdraw with delay period
  • Subject to slashing penalties

Challengers

  • Stake ETH to submit challenges
  • Pseudo-randomly selected for eligibility
  • Submit evidence of operator misbehavior

Admin

  • Resolves challenges
  • Controls slashing decisions
  • Manages contract parameters

Core Functions

// Operator Functions
registerOperator() payable
deactivateOperator()
initiateWithdrawal(uint256 amount, bool isEmergency)
completeWithdrawal()

// Challenge Functions
registerChallenger() payable
submitChallenge(address operator, bytes32 evidence)
resolveChallenge(address operator, uint256 index, bool slashed)

Key Parameters

  • Minimum stake: 1 ETH
  • Maximum stake: 10 ETH
  • Withdrawal delay: 3 days
  • Slashing penalty: 10%

Testing

npx hardhat test test/OperatorSlashing.test.js

Emergency Withdrawal Exploit

Operators can escape slashing by leveraging the emergency withdrawal mechanism:

Exploit Sequence:

  1. Submit a challenge against an operator
  2. Immediately initiate emergency withdrawal
  3. Complete withdrawal before challenge resolution
  4. Avoid all slashing penalties

Proof of Concept Test:

it("should demonstrate slashing evasion", async function() {
    // Submit challenge
    await contract.submitChallenge(operator.address, evidence);

    // Emergency withdrawal before resolution
    await contract.connect(operator).initiateWithdrawal(fullStake, true);
    await contract.connect(operator).completeWithdrawal();

    // Challenge resolution now ineffective
    await contract.connect(owner).resolveChallenge(operator.address, 0, true);
});

The test test/OperatorSlashingVulnerability.test.js demonstrates how an operator can escape slashing by performing an emergency withdrawal before challenge resolution.

Impact

  • Undermines challenger economic stake
  • Allows operators to evade punishment
  • Breaks core contract economic security model

Mitigation Strategies

  • Implement challenge submission rate limits
  • Add progressive stake penalties
  • Create challenge resolution windows
  • Prevent withdrawals during active challenges
  • Enhance randomness generation mechanism

Recommended Contract Modifications

function submitChallenge(address operator, bytes32 evidence) external {
    // Add per-challenger cooldown tracking
    require(
        block.timestamp >= lastChallengeTime[msg.sender] + CHALLENGE_COOLDOWN,
        "Challenge too frequent"
    );

    // Implement more robust eligibility check
    require(isRobustEligibleChallenger(msg.sender, operator), "Not eligible");

    // Track and penalize repeated unsuccessful challenges
    lastChallengeTime[msg.sender] = block.timestamp;
    challengeAttempts[msg.sender]++;
}

How the whole Operator-Slashing contract works

sequenceDiagram
    participant Operator
    participant Contract
    participant Challenger
    participant Owner

    Note over Contract: Registration Phase
    Operator->>Contract: registerOperator() + stake
    activate Contract
    Contract-->>Operator: OperatorRegistered event
    deactivate Contract

    Challenger->>Contract: registerChallenger() + stake
    activate Contract
    Contract-->>Challenger: ChallengerRegistered event
    deactivate Contract

    Note over Contract: Challenge Phase
    Challenger->>Contract: canChallenge(operator)
    activate Contract
    Contract-->>Challenger: true/false
    deactivate Contract

    Challenger->>Contract: submitChallenge(operator, evidence)
    activate Contract
    Contract-->>Challenger: ChallengeSubmitted event
    deactivate Contract

    Note over Contract: Resolution Phase
    Owner->>Contract: resolveChallenge(operator, index, slashed)
    activate Contract
    alt Slashed
        Contract->>Contract: Calculate penalty (10%)
        Contract->>Contract: Reduce stake
        opt Stake < minStake
            Contract->>Contract: Deactivate operator
        end
    end
    Contract-->>Owner: ChallengeResolved event
    deactivate Contract

    Note over Contract: Withdrawal Phase
    Operator->>Contract: initiateWithdrawal(amount)
    activate Contract
    Contract-->>Operator: WithdrawalInitiated event
    deactivate Contract

    Note right of Contract: Delay Period

    Operator->>Contract: completeWithdrawal()
    activate Contract
    Contract->>Contract: Validate delay
    Contract->>Operator: Transfer stake
    Contract-->>Operator: WithdrawalProcessed event
    deactivate Contract

    opt Cancel Withdrawal
        Operator->>Contract: cancelWithdrawal()
        activate Contract
        Contract-->>Operator: WithdrawalCancelled event
        deactivate Contract
    end
Loading

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published