Strategy

Staking Strategies for AI Agents: Native, Liquid, Restaking & Yield Stacking

March 6, 2026 · Purple Flea Team · 22 min read
← Back to Blog

Staking is the foundation of passive yield for autonomous AI agents. While trading generates income opportunistically and casino play generates income probabilistically, staking generates income continuously — turning idle crypto reserves into a compounding asset that works even when your agent is focused on other tasks. Done correctly, a well-structured staking portfolio can generate 4–15% APY on assets that would otherwise sit dormant between trades or await deployment.

This guide covers every level of complexity available to agents in 2026: from native ETH staking, through the major liquid staking protocols, into Solana's rich staking ecosystem, and all the way to advanced EigenLayer restaking and multi-layer yield stacking strategies. Each section includes concrete code examples, protocol-specific risk analysis, and practical guidance on how to integrate staking with Purple Flea's wallet infrastructure for seamless treasury management.

ETH Liquid Staking APY
3–4.2%
Lido, Rocket Pool, Frax, Coinbase
SOL Liquid Staking APY
6–8%
Marinade, Jito, BlazeStake
Restaking Bonus APY
+2–8%
EigenLayer AVS rewards
Triple-Stack Max APY
~15%
LST + lending + restaking

Native vs Liquid vs Restaking: Full Comparison

Before diving into specific protocols, it is important to understand the fundamental architectural differences between the three staking paradigms available to agents. Each makes a different trade-off between yield, liquidity, complexity, and risk exposure.

Native Staking

Native staking means running your own validator node (or delegating directly to one) and locking the chain's minimum deposit amount. For Ethereum this is exactly 32 ETH; for Solana there is no minimum. The staked tokens are illiquid for the duration of the unbonding period — on Ethereum, exit queues can stretch to weeks or months depending on validator congestion. Native staking offers the highest trust-minimization (no third-party smart contract exposure) but the worst liquidity profile for any agent that might need capital on short notice.

Liquid Staking

Liquid staking protocols pool user deposits, run validators on their behalf, and issue a receipt token (e.g., stETH, rETH, mSOL) that represents the staked position plus accrued rewards. This receipt token is freely tradeable, usable as collateral in DeFi, and redeemable for the underlying asset at any time through secondary markets or the protocol's redemption mechanism. Liquid staking sacrifices a small yield haircut (protocol fees of 5–15% of staking rewards) in exchange for full liquidity. For most agents, this trade-off is heavily favorable.

Restaking

Restaking takes an existing staked position (native ETH via an EigenPod, or an LST like stETH) and pledges its security to secure additional networks called Actively Validated Services (AVSs). Restakers earn additional fees from AVSs on top of their base staking yield, at the cost of taking on AVS-specific slashing risk. EigenLayer is the dominant restaking protocol on Ethereum; analogous systems are emerging on Solana and other chains.

Dimension Native Staking Liquid Staking Restaking
Liquidity Fully illiquid; exit queues Fully liquid; sell LST anytime 7-day withdrawal delay (EigenLayer)
ETH minimum 32 ETH (validator deposit) No minimum (any fraction) No minimum; deposit LST
Base APY (ETH) 3.5–5% 3.0–4.2% Base + 2–8% extra
Smart contract risk None (on-chain only) Protocol contract risk Protocol + AVS contracts
Slashing exposure Validator misbehavior only Indirect (protocol's validators) Validator + AVS faults
Complexity for agent High (node infrastructure) Low (single API call) Medium (AVS selection)
Composability None Full (DeFi collateral) Partial (depends on protocol)
Best for Long-horizon treasury (>1 year) Most agents; default choice Yield maximization on stable treasury

Recommendation for most agents: Start with liquid staking as your default staking layer. It requires no node infrastructure, is accessible with any ETH balance, and keeps your capital mobile for redeployment. Add restaking on top once your staking allocation is stable enough that a 7-day withdrawal delay is acceptable.

ETH Liquid Staking: Lido, Rocket Pool, Frax, Coinbase

The Ethereum liquid staking market is dominated by four protocols, each with a distinct philosophy on decentralization, yield optimization, and smart contract architecture. Understanding these differences matters for agents making allocation decisions at scale.

Lido (stETH) — Market Leader by TVL

Lido Finance is the largest liquid staking protocol by total value locked, holding more than 30% of all staked ETH in 2026. When you stake ETH with Lido, you receive stETH (staked ETH), a rebasing token whose balance in your wallet automatically increases daily to reflect accumulated staking rewards.

Key mechanics: stETH uses a rebasing model — rather than the token price appreciating, your wallet balance increases. If you stake 1 ETH today and the APY is 3.5%, in 365 days you will hold approximately 1.035 stETH, each worth approximately 1 ETH. This is important for tax calculations (each rebase event may constitute a taxable event in many jurisdictions) and for DeFi integrations (some protocols prefer wrapped stETH, wstETH, which appreciates in price instead of rebasing).

Decentralization concern: Lido's dominant market share has drawn criticism. If Lido ever controlled more than 33% of staked ETH, a governance attack or protocol bug could theoretically threaten Ethereum's consensus. Agents with large ETH treasuries should consider diversifying across Lido and Rocket Pool for this reason.

Attribute Details
Receipt tokenstETH (rebasing) / wstETH (wrapped, price-appreciating)
Current APY~3.5% (varies with network conditions)
Protocol fee10% of staking rewards (split: 5% DAO treasury, 5% node operators)
Minimum stake0.00001 ETH
Validator setPermissioned (DAO-approved node operators, ~30 entities)
Withdrawal mechanismInstant via Curve stETH/ETH pool or protocol withdrawal queue
DeFi acceptanceWidest: Aave, Compound, MakerDAO, Curve, Balancer, Uniswap
Smart contract auditsMultiple audits; $2B+ TVL battle-tested
Key riskCentralized validator set; protocol governance risk

Rocket Pool (rETH) — Most Decentralized

Rocket Pool is the permissionless alternative to Lido. Anyone can become a Rocket Pool node operator by depositing 8–16 ETH (plus RPL collateral) into a minipool. This creates a genuinely decentralized validator set with thousands of independent operators, dramatically reducing governance centralization risk. The receipt token, rETH, is a price-appreciating token (not rebasing) — its exchange rate against ETH increases over time as rewards accrue.

rETH's price-appreciating (rather than rebasing) model is often preferred by DeFi protocols and agents because the token balance never changes unexpectedly. A position of 10 rETH is always exactly 10 rETH on-chain, with the value appreciated into the exchange rate.

Attribute Details
Receipt tokenrETH (price-appreciating; no rebasing)
Current APY~3.2% (slightly lower due to decentralization overhead)
Protocol fee15% of staking rewards (higher to compensate node operators)
Minimum stakeNo minimum for liquid stakers
Validator setPermissionless (4,000+ independent node operators)
Withdrawal mechanismVia rETH/ETH liquidity on Uniswap/Balancer or protocol queue
DeFi acceptanceGood: Aave, Balancer, Uniswap; slightly less than stETH
Key riskLower liquidity depth; rETH/ETH pool can slip on large exits

Frax Finance (sfrxETH) — Highest Base Yield

Frax Finance operates a two-token liquid staking system to maximize yield. When you stake ETH with Frax, you receive frxETH (a non-rebasing ETH peg) and have the option to stake that into the sfrxETH vault (staked frxETH). The key insight: not all frxETH is deposited in the sfrxETH vault — some is used in Curve liquidity pools instead. This means the staking rewards from all Frax validators are distributed only to sfrxETH holders, giving them a higher effective APY than 1:1 liquid staking protocols.

Attribute Details
Receipt tokensfrxETH (price-appreciating; rewards from entire Frax validator pool)
Current APY~4.1% (highest among major ETH LSTs)
Protocol fee10% of staking rewards
Yield sourceConsensus rewards + MEV boost; concentrated on sfrxETH holders
Withdrawal mechanismsfrxETH → frxETH (instant), frxETH → ETH via Curve pool
DeFi acceptanceGood: Curve, Convex, some Aave deployments
Key riskTwo-step redemption; frxETH/ETH peg risk on Curve

Coinbase Staking (cbETH) — Institutional Grade

Coinbase's cbETH (Coinbase Wrapped Staked ETH) targets institutional agents and those prioritizing counterparty safety over yield maximization. Coinbase operates a professional-grade validator set with robust infrastructure, insurance products, and regulatory compliance. The trade-off is the lowest yield among major ETH LSTs due to higher operator overhead, but the strongest off-chain counterparty backing.

Attribute Details
Receipt tokencbETH (price-appreciating)
Current APY~3.0% (after 25% Coinbase fee)
Protocol fee25% of staking rewards (highest fee, lowest net yield)
Minimum stakeNo on-chain minimum; Coinbase account required
Validator setCoinbase-operated; centralized but professionally managed
DeFi acceptanceModerate: Aave, some lending protocols
Key riskCentralized custody; regulatory risk on Coinbase entity

ETH LST Protocol Comparison Summary

Protocol Token APY Fee Decentralization Risk Level Best For
Lido stETH / wstETH ~3.5% 10% Low Medium DeFi composability; widest collateral acceptance
Rocket Pool rETH ~3.2% 15% High Low Agents prioritizing decentralization
Frax sfrxETH ~4.1% 10% Medium Medium Maximum ETH yield; Curve ecosystem agents
Coinbase cbETH ~3.0% 25% Very Low Low* Institutional; off-chain counterparty backing

*cbETH has low protocol/smart contract risk but introduces Coinbase regulatory/custodial risk.

The following Python example shows how an agent can query live APY data across all four ETH LST protocols and select the optimal one based on configurable preferences:

import requests
from dataclasses import dataclass
from typing import Optional

PF_BASE = "https://purpleflea.com/api/v1"
HEADERS = {
    "Authorization": "Bearer your-purpleflea-api-key",
    "Content-Type": "application/json"
}

@dataclass
class LSTProtocol:
    name: str
    token: str
    apy: float
    fee_pct: float
    decentralization_score: float  # 0-1, higher = more decentralized
    liquidity_depth_eth: float     # on-chain DEX liquidity in ETH
    smart_contract_risk: str       # "low" | "medium" | "high"

def fetch_eth_lst_apys() -> list[LSTProtocol]:
    """Fetch current APYs from Purple Flea staking data aggregator."""
    r = requests.get(f"{PF_BASE}/staking/eth/lst-apys", headers=HEADERS)
    data = r.json()["protocols"]
    return [LSTProtocol(**p) for p in data]

def select_optimal_lst(
    protocols: list[LSTProtocol],
    min_decentralization: float = 0.0,
    max_risk: str = "high",
    weight_apy: float = 0.6,
    weight_decentralization: float = 0.2,
    weight_liquidity: float = 0.2,
) -> LSTProtocol:
    """
    Score each protocol by weighted combination of APY, decentralization,
    and liquidity. Filter by minimum decentralization and max risk level.
    """
    risk_order = {"low": 0, "medium": 1, "high": 2}
    max_risk_num = risk_order[max_risk]

    eligible = [
        p for p in protocols
        if p.decentralization_score >= min_decentralization
        and risk_order[p.smart_contract_risk] <= max_risk_num
    ]

    if not eligible:
        raise ValueError("No eligible protocols match constraints")

    # Normalize metrics to 0-1 range for scoring
    max_apy = max(p.apy for p in eligible)
    max_liq = max(p.liquidity_depth_eth for p in eligible)

    def score(p: LSTProtocol) -> float:
        apy_norm = p.apy / max_apy
        liq_norm = p.liquidity_depth_eth / max_liq
        return (
            weight_apy * apy_norm +
            weight_decentralization * p.decentralization_score +
            weight_liquidity * liq_norm
        )

    return max(eligible, key=score)

# Example usage
protocols = fetch_eth_lst_apys()

# Conservative agent: prioritize decentralization and liquidity
best_conservative = select_optimal_lst(
    protocols,
    min_decentralization=0.7,
    max_risk="low",
    weight_apy=0.3,
    weight_decentralization=0.5,
    weight_liquidity=0.2
)
print(f"Conservative pick: {best_conservative.name} ({best_conservative.token}) @ {best_conservative.apy:.2f}% APY")

# Yield-maximizing agent: optimize purely for APY
best_yield = select_optimal_lst(
    protocols,
    weight_apy=0.85,
    weight_decentralization=0.05,
    weight_liquidity=0.10
)
print(f"Yield-max pick: {best_yield.name} ({best_yield.token}) @ {best_yield.apy:.2f}% APY")

Solana Staking: Marinade, Jito, BlazeStake

Solana's proof-of-stake mechanism offers significantly higher base staking yields than Ethereum (6–8% vs 3–4%), and its 2–3 day unbonding period is vastly more agent-friendly than Ethereum's multi-week exit queues. The Solana liquid staking ecosystem has matured rapidly, with three major protocols capturing most of the TVL.

Marinade Finance (mSOL) — The Lido of Solana

Marinade is the oldest and most battle-tested Solana liquid staking protocol, analogous to Lido in the ETH ecosystem. Staking SOL with Marinade returns mSOL, a price-appreciating token (not rebasing) whose exchange rate against SOL increases with each epoch's rewards (~every 2.5 days on Solana). Marinade automatically diversifies stake across 450+ validators using an algorithm that optimizes for performance, decentralization, and commission rates.

Jito (jitoSOL) — MEV-Boosted Yield

Jito is the MEV-aware Solana liquid staking protocol. Jito node operators run modified validators that capture MEV (Maximal Extractable Value) from Solana block production and distribute a portion back to jitoSOL holders as additional yield on top of base staking rewards. This MEV-sharing mechanism typically adds 0.5–1.5% APY to Jito's effective rate compared to standard liquid staking, making jitoSOL the highest-yield option in the Solana LST ecosystem.

BlazeStake (bSOL) — Community-Governed

BlazeStake positions itself as the community-first Solana staking protocol, with stake distributed to smaller and newer validators to support network decentralization. The bSOL token offers competitive yield and has DeFi integrations on Solend, Orca, and other Solana protocols. BlazeStake also distributes BLZE governance tokens to stakers, adding an additional incentive layer.

Protocol Token Base APY MEV Boost Effective APY Validators Key Feature
Marinade mSOL ~6.5% No ~6.5% 450+ Largest TVL; instant unstake via liquidity pool
Jito jitoSOL ~6.5% +0.5–1.5% ~7.5% 200+ MEV-sharing; highest effective yield
BlazeStake bSOL ~6.3% No ~6.3% + BLZE 300+ BLZE token incentives; decentralization focus

Solana Staking Unstaking Mechanics

Solana's epoch-based architecture gives agents two unstaking paths: delayed unstaking (wait for the next epoch boundary, 2–3 days) or instant unstaking via a protocol liquidity pool (Marinade maintains a liquidity pool that allows instant redemptions at a small fee, currently ~0.3%). For agents that need rapid capital redeployment, the instant unstake option is worth the small fee to avoid the 2–3 day wait.

import asyncio
import requests

PF_BASE = "https://purpleflea.com/api/v1"
HEADERS = {"Authorization": "Bearer your-purpleflea-api-key", "Content-Type": "application/json"}

def compare_sol_staking_options(sol_amount: float, hold_days: int) -> dict:
    """
    Compare Marinade vs Jito vs BlazeStake for a given SOL amount and hold period.
    Returns estimated yields and recommends the best protocol.
    """
    protocols = {
        "marinade": {"token": "mSOL", "apy": 0.065, "instant_unstake_fee": 0.003},
        "jito": {"token": "jitoSOL", "apy": 0.075, "instant_unstake_fee": 0.004},
        "blazestake": {"token": "bSOL", "apy": 0.063, "instant_unstake_fee": 0.003},
    }

    results = {}
    for name, cfg in protocols.items():
        daily_rate = cfg["apy"] / 365
        gross_yield = sol_amount * daily_rate * hold_days
        # Instant unstake cost if we need to exit early
        instant_unstake_cost = sol_amount * cfg["instant_unstake_fee"]
        net_yield = gross_yield - instant_unstake_cost
        results[name] = {
            "token": cfg["token"],
            "apy_pct": cfg["apy"] * 100,
            "gross_yield_sol": round(gross_yield, 6),
            "instant_unstake_cost_sol": round(instant_unstake_cost, 6),
            "net_yield_sol": round(net_yield, 6),
            "breakeven_days": round(instant_unstake_cost / (sol_amount * daily_rate), 1),
        }

    # Rank by net yield
    ranked = sorted(results.items(), key=lambda x: x[1]["net_yield_sol"], reverse=True)
    results["recommendation"] = ranked[0][0]
    results["recommendation_reason"] = (
        f"{ranked[0][0]} offers highest net yield ({ranked[0][1]['net_yield_sol']:.4f} SOL) "
        f"over {hold_days} days for {sol_amount} SOL"
    )
    return results

# Example: compare protocols for 100 SOL held for 30 days
result = compare_sol_staking_options(100.0, 30)
for protocol, data in result.items():
    if isinstance(data, dict):
        print(f"{protocol}: {data['apy_pct']:.1f}% APY, net yield {data['net_yield_sol']:.4f} SOL")
print(f"Recommendation: {result['recommendation']}")

Restaking with EigenLayer: Operator Selection & AVS Risk

EigenLayer is the restaking layer built on Ethereum that allows LST holders to pledge their staked assets as security for additional networks and services (AVSs — Actively Validated Services). This section covers the full mechanics of EigenLayer restaking, including how to select operators and AVSs intelligently to maximize yield while managing slashing risk.

How EigenLayer Works

When you restake through EigenLayer, you are delegating your LST (or native ETH via an EigenPod) to an operator. The operator then opts into one or more AVSs. Each AVS pays rewards to restakers securing it, in proportion to the amount of restaked ETH delegated. If the operator or AVS misbehaves, a portion of the restaked ETH can be slashed.

The EigenLayer protocol imposes a 7-day withdrawal delay when you want to exit a restaking position. This is in addition to any liquid staking protocol delay. It exists to give AVSs time to detect and penalize misbehavior before slashed funds leave the system.

Operator Selection Strategy

Not all EigenLayer operators are equal. When selecting an operator for your agent's restaked position, evaluate these criteria:

AVS Risk Taxonomy

AVS Type Example Slashing Condition Typical Add-on APY Risk Level
Data availability EigenDA Incorrect attestation of data availability +1–3% Low
Oracle networks Various Price manipulation or liveness failure +2–4% Medium
Bridge verification Cross-chain bridges Signing invalid cross-chain messages +3–6% High
Rollup sequencing L2 sequencer sets Equivocation in block production +2–5% Medium
Keeper networks Automation AVSs Failed execution of committed tasks +1–2% Low

Points Farming Strategy

Many AVSs distribute points to restakers alongside or instead of immediate cash yield. These points often convert to governance tokens at protocol launch or during future distribution events. Points farming is speculative by nature — the value of the points depends entirely on the eventual token price and distribution terms — but for agents with long time horizons, accumulating points from high-quality AVSs can provide significant upside.

Points caveat: Points have no guaranteed value and no contractual conversion rate. Treat them as a binary option with unknown strike price and expiry. Never factor expected points value into core treasury projections; treat any realization as upside only.

import requests
from typing import Optional

PF_BASE = "https://purpleflea.com/api/v1"
HEADERS = {"Authorization": "Bearer your-purpleflea-api-key", "Content-Type": "application/json"}

def analyze_eigenlayer_operators(
    lst_amount_eth: float,
    max_commission: float = 0.12,
    min_stake_delegated_eth: float = 10000,
    exclude_slashed: bool = True,
    max_avs_count: int = 5,
) -> list[dict]:
    """
    Query EigenLayer operator data via Purple Flea and filter/rank by
    quality criteria. Returns top operators sorted by risk-adjusted yield.
    """
    r = requests.get(
        f"{PF_BASE}/staking/eigenlayer/operators",
        params={
            "max_commission": max_commission,
            "min_stake_eth": min_stake_delegated_eth,
            "exclude_slashed": exclude_slashed,
        },
        headers=HEADERS
    )
    operators = r.json()["operators"]

    # Filter by max AVS count to limit slashing exposure
    filtered = [op for op in operators if len(op["avs_list"]) <= max_avs_count]

    # Score each operator
    def operator_score(op: dict) -> float:
        avs_yield = sum(avs["estimated_apy"] for avs in op["avs_list"])
        commission_penalty = op["commission"] * 10  # penalize high commission
        # Prefer operators with established track record
        track_record_bonus = min(op["months_active"] / 24, 1.0) * 2.0
        return avs_yield - commission_penalty + track_record_bonus

    ranked = sorted(filtered, key=operator_score, reverse=True)

    # Compute projected yields for each top operator
    results = []
    for op in ranked[:5]:
        gross_avs_apy = sum(avs["estimated_apy"] for avs in op["avs_list"])
        net_avs_apy = gross_avs_apy * (1 - op["commission"])
        total_apy = 3.5 + net_avs_apy  # base liquid staking + restaking yield
        annual_eth = lst_amount_eth * total_apy / 100
        results.append({
            "operator_name": op["name"],
            "commission": f"{op['commission']*100:.0f}%",
            "avs_count": len(op["avs_list"]),
            "avs_names": [avs["name"] for avs in op["avs_list"]],
            "gross_avs_apy": f"{gross_avs_apy:.2f}%",
            "net_avs_apy": f"{net_avs_apy:.2f}%",
            "total_estimated_apy": f"{total_apy:.2f}%",
            "annual_eth_yield": round(annual_eth, 4),
            "months_active": op["months_active"],
            "slash_history": op["slash_count"],
        })

    return results

# Example: find best EigenLayer operators for 10 ETH of stETH
operators = analyze_eigenlayer_operators(lst_amount_eth=10.0)
for op in operators:
    print(f"{op['operator_name']}: {op['total_estimated_apy']} total APY, "
          f"{op['avs_count']} AVSs, {op['annual_eth_yield']} ETH/year")

Yield Stacking: Triple-Layer Strategies

The most sophisticated staking strategy available to agents is yield stacking: layering multiple yield sources on top of a single ETH position to achieve a blended APY that can reach 12–15%. A triple-stack works like this:

  1. Layer 1 (Liquid Staking): Stake ETH → receive stETH (earning ~3.5% APY). This is your base yield from Ethereum consensus.
  2. Layer 2 (Lending): Deposit stETH as collateral in Aave, borrow ETH at a lower rate (~1.5–2.5%), stake the borrowed ETH for more stETH. This amplifies Layer 1 yield at the cost of liquidation risk at high LTV.
  3. Layer 3 (Restaking): Deposit your stETH into EigenLayer restaking, selecting AVSs to earn additional protocol rewards on top of the staking base.
Stack Configuration Estimated APY Complexity Risk Level Capital Efficiency
Liquid staking only 3.5% Minimal Low 1x
LST + DeFi loop (1.5x LTV) 5–6% Low Medium 1.5x
LST + Restaking (EigenLayer) 6–9% Medium Medium 1x + bonus yield
LST + DeFi loop + Restaking (triple) 9–15% High High 1.5x + bonus yield
Liquid restaking token (eETH/ezETH) 8–12% Low Medium-High 1x (protocol manages stack)

Liquid Restaking Tokens (LRTs): The Easy Triple-Stack

For agents that want triple-stack yields without managing the individual layers manually, liquid restaking tokens (LRTs) package everything into a single token. The protocol manages the LST staking, operator selection, AVS restaking, and reward compounding internally. You hold one token; it accrues the blended yield automatically.

Protocol Token Strategy Est. Total APY Withdrawal Key Risk
EtherFi eETH / weETH Native ETH + EigenLayer restaking 8–12% Via liquidity pool (fast) Smart contract complexity
Renzo ezETH Multi-LST + EigenLayer + Symbiotic 7–11% 7-day withdrawal Multi-protocol dependencies
Puffer Finance pufETH ETH + anti-slashing enclave + restaking 6–10% Via Curve pool Anti-slash tech unproven at scale
Kelp DAO rsETH Multi-LST restaking basket 7–10% 7-day withdrawal Basket composition drift
Swell rswETH ETH + EigenLayer + Symbiotic 7–11% Via DEX pool Protocol still maturing

LRT depeg risk: In May 2024, ezETH briefly depegged to $688 vs ETH's $3,800 price during an airdrop snapshot — a 75% paper drawdown for any agent that needed to liquidate at that moment. This event illustrates why yield stacking via LRTs requires maintaining liquid ETH reserves separate from your LRT position for operational expenses.

import requests
import time

PF_BASE = "https://purpleflea.com/api/v1"
HEADERS = {"Authorization": "Bearer your-purpleflea-api-key", "Content-Type": "application/json"}

def build_triple_stack_position(
    eth_amount: float,
    risk_profile: str = "moderate",  # "conservative" | "moderate" | "aggressive"
) -> dict:
    """
    Construct a triple-stack staking position:
    Layer 1: ETH -> stETH (Lido liquid staking)
    Layer 2: stETH -> Aave collateral -> borrow ETH -> more stETH (DeFi loop)
    Layer 3: stETH -> EigenLayer restaking (AVS yield on top)

    Risk profiles control DeFi loop LTV and AVS exposure.
    """
    profiles = {
        "conservative": {
            "liquid_stake_pct": 1.0,    # all ETH goes to liquid staking first
            "loop_portion":     0.0,    # no DeFi loop
            "loop_target_ltv":  0.0,
            "restake_portion":  0.40,   # restake 40% of stETH
            "max_avs":          2,
        },
        "moderate": {
            "liquid_stake_pct": 1.0,
            "loop_portion":     0.25,   # loop 25% of stETH position
            "loop_target_ltv":  0.50,
            "restake_portion":  0.50,   # restake 50% of remaining stETH
            "max_avs":          4,
        },
        "aggressive": {
            "liquid_stake_pct": 1.0,
            "loop_portion":     0.50,   # loop 50% of stETH
            "loop_target_ltv":  0.60,
            "restake_portion":  0.70,   # restake 70% of remaining stETH
            "max_avs":          6,
        },
    }

    p = profiles[risk_profile]
    results = {"profile": risk_profile, "initial_eth": eth_amount, "steps": []}

    # Step 1: Liquid stake all ETH into stETH
    print(f"Step 1: Staking {eth_amount} ETH into Lido...")
    stake_r = requests.post(f"{PF_BASE}/staking/liquid-stake", headers=HEADERS, json={
        "amount_eth": eth_amount,
        "protocol": "lido",
        "token": "wstETH",  # use non-rebasing for DeFi compatibility
    }).json()
    steth_received = stake_r.get("token_amount", eth_amount * 0.9982)  # ~0.18% fee approx
    results["steps"].append({"action": "liquid_stake", "in": eth_amount, "out_steth": steth_received})

    # Step 2: DeFi loop (if configured)
    looped_steth = 0
    if p["loop_portion"] > 0:
        loop_steth_amount = steth_received * p["loop_portion"]
        print(f"Step 2: DeFi loop on {loop_steth_amount:.4f} stETH at {p['loop_target_ltv']*100:.0f}% LTV...")
        loop_r = requests.post(f"{PF_BASE}/staking/defi-loop", headers=HEADERS, json={
            "collateral_amount": loop_steth_amount,
            "collateral_token": "wstETH",
            "target_ltv": p["loop_target_ltv"],
            "lending_protocol": "aave_v3",
        }).json()
        looped_steth = loop_r.get("effective_steth_added", loop_steth_amount * p["loop_target_ltv"] * 0.99)
        results["steps"].append({"action": "defi_loop", "in_steth": loop_steth_amount,
                                  "additional_steth": looped_steth, "ltv": p["loop_target_ltv"]})
        time.sleep(2)  # wait for state confirmation

    # Step 3: Restake portion into EigenLayer
    total_steth = steth_received + looped_steth
    restake_amount = total_steth * p["restake_portion"]
    if restake_amount > 0:
        print(f"Step 3: Restaking {restake_amount:.4f} stETH into EigenLayer (max {p['max_avs']} AVSs)...")
        restake_r = requests.post(f"{PF_BASE}/staking/restake", headers=HEADERS, json={
            "amount": restake_amount,
            "token": "wstETH",
            "protocol": "eigenlayer",
            "avs_selection": "auto_risk_adjusted",
            "max_avs_count": p["max_avs"],
        }).json()
        results["steps"].append({"action": "restake", "amount_steth": restake_amount,
                                  "selected_avs": restake_r.get("avs_names", [])})

    # Estimate blended APY
    base_lst_apy = 3.5
    loop_bonus_apy = p["loop_portion"] * p["loop_target_ltv"] * (base_lst_apy - 1.8) if p["loop_portion"] > 0 else 0
    restake_bonus_apy = p["restake_portion"] * 4.5  # avg AVS yield estimate
    blended_apy = base_lst_apy + loop_bonus_apy + restake_bonus_apy

    results["summary"] = {
        "total_steth_position": round(total_steth, 4),
        "restaked_steth": round(restake_amount, 4),
        "estimated_blended_apy": round(blended_apy, 2),
        "estimated_annual_eth_yield": round(eth_amount * blended_apy / 100, 4),
    }
    print(f"Position built: {blended_apy:.2f}% blended APY, "
          f"{results['summary']['estimated_annual_eth_yield']} ETH/year estimated")
    return results

Automated Rebalancing When Yields Shift

Staking yields are not static. ETH staking APY shifts with network participation rates, MEV revenue, and protocol upgrades. AVS yields fluctuate with protocol adoption and token prices. An agent that set its staking allocation once and never revisited it will leave significant yield on the table over time.

The right approach is to implement a yield monitoring system that periodically checks live APY data across all active positions and triggers rebalancing when the yield differential between alternatives crosses a threshold that justifies the transaction costs and switching friction.

import requests
from datetime import datetime, timedelta

PF_BASE = "https://purpleflea.com/api/v1"
HEADERS = {"Authorization": "Bearer your-purpleflea-api-key", "Content-Type": "application/json"}

class StakingRebalancer:
    """
    Monitors staking positions and rebalances when yield differentials
    exceed the rebalance threshold (accounting for gas and switching costs).
    """

    def __init__(
        self,
        agent_id: str,
        rebalance_threshold_pct: float = 0.75,  # rebalance if yield gap > 0.75%
        min_rebalance_interval_hours: int = 24,  # at most once per day
        gas_cost_estimate_eth: float = 0.005,    # estimated gas per rebalance
    ):
        self.agent_id = agent_id
        self.threshold = rebalance_threshold_pct
        self.min_interval = timedelta(hours=min_rebalance_interval_hours)
        self.gas_cost = gas_cost_estimate_eth
        self.last_rebalance: Optional[datetime] = None

    def fetch_current_positions(self) -> dict:
        """Get current staking positions from Purple Flea wallet."""
        r = requests.get(
            f"{PF_BASE}/wallet/staking-positions/{self.agent_id}",
            headers=HEADERS
        )
        return r.json()

    def fetch_market_apys(self) -> dict:
        """Get live APY data across all tracked protocols."""
        r = requests.get(f"{PF_BASE}/staking/market-apys", headers=HEADERS)
        return r.json()

    def compute_opportunity_cost(
        self,
        current_protocol: str,
        alternative_protocol: str,
        position_size_eth: float,
        market_apys: dict,
    ) -> float:
        """
        Returns annualized ETH yield improvement from switching.
        Deducts estimated gas cost of the switch.
        """
        current_apy = market_apys[current_protocol]["apy_pct"] / 100
        alt_apy = market_apys[alternative_protocol]["apy_pct"] / 100
        apy_diff = alt_apy - current_apy
        annual_eth_gain = position_size_eth * apy_diff
        net_gain = annual_eth_gain - self.gas_cost  # deduct switching gas
        return net_gain

    def should_rebalance(self) -> bool:
        """Check if enough time has passed since last rebalance."""
        if self.last_rebalance is None:
            return True
        return datetime.utcnow() - self.last_rebalance >= self.min_interval

    def run_rebalance_check(self) -> dict:
        """Main rebalance loop: check positions, evaluate alternatives, execute if warranted."""
        if not self.should_rebalance():
            return {"action": "skip", "reason": "Too soon since last rebalance"}

        positions = self.fetch_current_positions()
        market_apys = self.fetch_market_apys()
        actions_taken = []

        for position in positions.get("staking_positions", []):
            protocol = position["protocol"]
            size_eth = position["value_eth"]
            current_apy = market_apys.get(protocol, {}).get("apy_pct", 0)

            # Find best available alternative
            best_alt = max(
                (p for p in market_apys if p != protocol),
                key=lambda p: market_apys[p].get("apy_pct", 0)
            )
            best_alt_apy = market_apys[best_alt]["apy_pct"]
            apy_gap = best_alt_apy - current_apy

            if apy_gap < self.threshold:
                actions_taken.append({
                    "position": protocol,
                    "action": "hold",
                    "reason": f"Gap {apy_gap:.2f}% below threshold {self.threshold}%"
                })
                continue

            # Check net opportunity cost after gas
            net_gain = self.compute_opportunity_cost(protocol, best_alt, size_eth, market_apys)
            if net_gain <= 0:
                actions_taken.append({
                    "position": protocol,
                    "action": "hold",
                    "reason": f"Gas cost exceeds projected gain ({net_gain:.5f} ETH)"
                })
                continue

            # Execute rebalance
            print(f"Rebalancing {size_eth:.2f} ETH from {protocol} to {best_alt} "
                  f"({apy_gap:.2f}% yield improvement, {net_gain:.4f} ETH annual net gain)")
            r = requests.post(f"{PF_BASE}/staking/rebalance", headers=HEADERS, json={
                "from_protocol": protocol,
                "to_protocol": best_alt,
                "amount_eth": size_eth,
                "agent_id": self.agent_id,
            })
            actions_taken.append({
                "position": protocol,
                "action": "rebalanced",
                "from": protocol,
                "to": best_alt,
                "apy_improvement": apy_gap,
                "tx_hash": r.json().get("tx_hash"),
            })

        self.last_rebalance = datetime.utcnow()
        return {"timestamp": self.last_rebalance.isoformat(), "actions": actions_taken}


# Run as periodic task (e.g., via agent scheduler)
rebalancer = StakingRebalancer(agent_id="agent_xyz_123", rebalance_threshold_pct=0.75)
report = rebalancer.run_rebalance_check()
print(f"Rebalance check completed: {len(report.get('actions', []))} positions reviewed")

Unstaking Delays & Liquidity Management

One of the most underappreciated operational risks for agents that stake aggressively is the liquidity mismatch between a staked position and near-term capital needs. An agent that has deployed 90% of its ETH treasury into restaking positions faces a 7-day minimum withdrawal window before that capital is available for deployment elsewhere. If a high-priority trading opportunity or emergency expense arises during that window, the agent is stuck.

Unstaking Timelines by Position Type

Position Type Exit Method Time to Liquid ETH Cost
stETH (Lido) Sell on Curve stETH/ETH pool Immediate (~10 min) Pool fee (~0.04%) + slippage
stETH (Lido) Protocol withdrawal queue Hours to days (queue-dependent) No fee (just gas)
rETH (Rocket Pool) Burn via protocol or Balancer pool Immediate (if pool liquidity exists) Pool fee + possible slippage
sfrxETH (Frax) sfrxETH → frxETH → ETH (Curve) Immediate (two steps) Two swap fees (~0.04% each)
mSOL (Marinade) Instant unstake pool Immediate (~30 sec) ~0.3% fee
mSOL (Marinade) Delayed unstake (epoch boundary) 2–3 days No fee (just network fee)
jitoSOL (Jito) Delayed unstake (epoch boundary) 2–3 days No fee
EigenLayer restaking Withdrawal from EigenLayer 7 days minimum Gas only
Native ETH staking Validator exit queue Days to weeks (queue-dependent) No fee

The Liquidity Buffer Rule

The cardinal rule for agent staking liquidity management is to always maintain a liquidity buffer of at least 10–20% of total treasury in immediately accessible form (spot ETH, USDC, or LST positions that can be exited in under an hour). For agents running DeFi loops or EigenLayer restaking, the buffer should be higher because exits are multi-step and time-consuming.

import requests

PF_BASE = "https://purpleflea.com/api/v1"
HEADERS = {"Authorization": "Bearer your-purpleflea-api-key", "Content-Type": "application/json"}

def audit_staking_liquidity(agent_id: str, target_liquid_pct: float = 0.15) -> dict:
    """
    Audit agent's staking positions for liquidity risk.
    Returns a liquidity score and recommended adjustments.
    """
    # Fetch full treasury snapshot
    r = requests.get(f"{PF_BASE}/wallet/treasury/{agent_id}", headers=HEADERS)
    treasury = r.json()

    total_eth_value = treasury["total_value_eth"]
    positions = treasury["positions"]

    # Categorize by liquidity tier
    immediate_liquid = 0.0    # accessible within 1 hour
    short_liquid = 0.0        # accessible within 1-7 days
    long_locked = 0.0         # requires more than 7 days

    LIQUIDITY_MAP = {
        "eth_spot": "immediate",
        "usdc": "immediate",
        "steth": "immediate",    # via Curve pool
        "wsteth": "immediate",
        "reth": "immediate",     # via Balancer pool
        "sfrxeth": "immediate",  # two-step but fast
        "msol": "immediate",     # instant unstake pool
        "jitosol": "short",      # epoch boundary (2-3 days)
        "bsol": "short",
        "eigenlayer_restaked": "long",   # 7-day withdrawal
        "native_eth_staked": "long",     # validator exit queue
    }

    breakdown = {}
    for pos in positions:
        asset = pos["asset"].lower()
        value_eth = pos["value_eth"]
        tier = LIQUIDITY_MAP.get(asset, "short")  # default to short if unknown

        if tier == "immediate":
            immediate_liquid += value_eth
        elif tier == "short":
            short_liquid += value_eth
        else:
            long_locked += value_eth

        breakdown[pos["asset"]] = {"value_eth": value_eth, "tier": tier}

    liquid_pct = immediate_liquid / total_eth_value if total_eth_value > 0 else 0
    target_liquid_eth = total_eth_value * target_liquid_pct
    shortfall = max(0, target_liquid_eth - immediate_liquid)

    recommendations = []
    if liquid_pct < target_liquid_pct:
        recommendations.append(
            f"Liquidity below target ({liquid_pct*100:.1f}% vs {target_liquid_pct*100:.0f}% target). "
            f"Reduce illiquid positions by {shortfall:.3f} ETH equivalent."
        )
        # Find largest illiquid position to trim
        illiquid = [(k, v) for k, v in breakdown.items() if v["tier"] == "long"]
        if illiquid:
            largest_illiquid = max(illiquid, key=lambda x: x[1]["value_eth"])
            recommendations.append(
                f"Consider reducing EigenLayer restaking position "
                f"({largest_illiquid[0]}: {largest_illiquid[1]['value_eth']:.3f} ETH) by {shortfall:.3f} ETH."
            )

    return {
        "total_value_eth": total_eth_value,
        "immediate_liquid_eth": round(immediate_liquid, 4),
        "short_term_liquid_eth": round(short_liquid, 4),
        "long_locked_eth": round(long_locked, 4),
        "immediate_liquid_pct": round(liquid_pct * 100, 2),
        "target_liquid_pct": target_liquid_pct * 100,
        "liquidity_score": "PASS" if liquid_pct >= target_liquid_pct else "FAIL",
        "recommendations": recommendations,
        "position_breakdown": breakdown,
    }

# Run audit
audit = audit_staking_liquidity("agent_xyz_123", target_liquid_pct=0.15)
print(f"Liquidity score: {audit['liquidity_score']}")
print(f"Immediate liquid: {audit['immediate_liquid_pct']}% of treasury")
for rec in audit["recommendations"]:
    print(f"  -> {rec}")

Using Purple Flea Wallet for Staked Assets

The Purple Flea Wallet is designed to be the unified treasury layer for agents that run complex staking portfolios. Rather than managing ETH, stETH, rETH, mSOL, jitoSOL, and USDC across separate on-chain wallets and tracking positions manually, agents can use Purple Flea's wallet as the single interface for all cross-protocol staking activity.

Multi-Asset Treasury Management

Purple Flea's wallet natively holds BTC, ETH, SOL, XMR, and USDC, with staked asset positions (stETH, rETH, mSOL, etc.) tracked within the wallet's position ledger. Staking yield accumulates in the ledger and can be withdrawn as ETH or converted to USDC for operational spending — for example, paying for trading API fees, casino top-ups, or escrow payments to collaborating agents.

Auto-Compounding Staking Rewards

One of the most valuable features of the Purple Flea wallet staking integration is automated compound reinvestment. Rather than letting staking rewards accumulate idle in your wallet balance, auto-compounding sweeps rewards back into the staking position on a configurable schedule, applying the power of compound interest to your staking yield.

import requests
from datetime import datetime

PF_BASE = "https://purpleflea.com/api/v1"
HEADERS = {"Authorization": "Bearer your-purpleflea-api-key", "Content-Type": "application/json"}

def setup_auto_compound(
    agent_id: str,
    staking_protocol: str,
    compound_frequency: str = "weekly",   # "daily" | "weekly" | "monthly"
    min_compound_amount_eth: float = 0.01,  # don't compound tiny amounts (gas waste)
    reinvest_pct: float = 1.0,              # reinvest 100% of rewards
    reserve_for_ops_pct: float = 0.0,       # keep X% of rewards as USDC for operations
) -> dict:
    """
    Configure auto-compounding for a staking position.
    Purple Flea wallet will automatically harvest and restake rewards.
    """
    r = requests.post(f"{PF_BASE}/wallet/staking/auto-compound", headers=HEADERS, json={
        "agent_id": agent_id,
        "protocol": staking_protocol,
        "compound_frequency": compound_frequency,
        "min_compound_eth": min_compound_amount_eth,
        "reinvest_pct": reinvest_pct,
        "ops_reserve_pct": reserve_for_ops_pct,
    })
    return r.json()

def fetch_compound_history(agent_id: str, days: int = 90) -> dict:
    """Fetch auto-compounding history and compute effective APY boost."""
    r = requests.get(
        f"{PF_BASE}/wallet/staking/compound-history/{agent_id}",
        params={"days": days},
        headers=HEADERS
    )
    history = r.json()

    total_compounded_eth = sum(event["eth_reinvested"] for event in history["events"])
    total_gas_eth = sum(event["gas_cost_eth"] for event in history["events"])
    net_compounded = total_compounded_eth - total_gas_eth

    # Compute APY boost from compounding (vs simple interest)
    base_apy = history.get("base_apy_pct", 3.5)
    n_compounds_per_year = {"daily": 365, "weekly": 52, "monthly": 12}.get(
        history.get("frequency", "weekly"), 52
    )
    effective_apy = ((1 + base_apy / 100 / n_compounds_per_year) ** n_compounds_per_year - 1) * 100
    apy_boost = effective_apy - base_apy

    return {
        "compound_events": len(history["events"]),
        "total_reinvested_eth": round(total_compounded_eth, 6),
        "total_gas_cost_eth": round(total_gas_eth, 6),
        "net_compounded_eth": round(net_compounded, 6),
        "base_apy_pct": base_apy,
        "effective_apy_pct": round(effective_apy, 3),
        "compounding_apy_boost_pct": round(apy_boost, 3),
    }

# Setup auto-compound for Lido position
config = setup_auto_compound(
    agent_id="agent_xyz_123",
    staking_protocol="lido",
    compound_frequency="weekly",
    min_compound_amount_eth=0.01,
    reinvest_pct=0.85,           # reinvest 85%
    reserve_for_ops_pct=0.15,    # keep 15% as USDC for operations
)
print(f"Auto-compound configured: {config}")

# Check historical compounding performance
history = fetch_compound_history("agent_xyz_123", days=90)
print(f"90-day compounding boost: +{history['compounding_apy_boost_pct']:.3f}% APY")
print(f"Total reinvested: {history['total_reinvested_eth']} ETH")

Risk Assessment: Slashing, Depeg, Smart Contract, Concentration

Every staking strategy carries multiple, overlapping risk factors. Agents should explicitly model each risk category and size their positions accordingly rather than relying on generic risk labels.

Slashing Risk

Definition: A portion of staked assets is forcibly destroyed as punishment for validator misbehavior (double-signing, liveness failures, or in the restaking context, AVS fault). Slashing events on Ethereum mainnet have been rare but non-zero since the Merge. Notable incidents have involved validator client bugs causing mass equivocation slashings.

Mitigation: Use diversified liquid staking protocols (Rocket Pool's distributed validator set limits correlated slashing) rather than concentrating in a single operator. For EigenLayer restaking, prefer operators with long track records and zero slash history. Monitor your operator's status through Purple Flea's slashing event alerts.

Smart Contract Risk

Definition: Bugs or exploits in staking protocol smart contracts can result in loss of funds. This risk is non-trivial even for audited protocols — the Nomad bridge ($190M exploit), Euler Finance ($197M exploit), and numerous smaller DeFi exploits demonstrate that audit coverage is a necessary but insufficient condition for security.

Mitigation: Prefer protocols with extensive audit histories and established track records (Lido, Rocket Pool). Diversify across protocols rather than concentrating in a single LST. For liquid restaking tokens, the risk is compounded because bugs in any underlying layer (LST protocol, EigenLayer, LRT protocol) can cascade up.

Depeg Risk

Definition: LSTs can temporarily or permanently trade below their theoretical ETH-equivalent value on secondary markets. stETH briefly traded at 0.97 ETH during the June 2022 credit crisis when multiple large holders were forced to sell. LRT tokens have shown even more extreme depegs (ezETH example cited above).

Mitigation: Never plan to sell LSTs during market stress. Maintain sufficient spot ETH reserves to cover operational needs without having to liquidate staked positions. Set up price monitoring alerts for any LST you hold, and define a derisking threshold (e.g., if stETH/ETH ratio drops below 0.97, begin unwinding the position).

Concentration Risk

Definition: Holding more than 50% of your staking portfolio in any single protocol amplifies the impact of any protocol-specific failure event. This includes governance attacks on the protocol's DAO, regulatory action against a specific operator, or systemic bugs in the underlying smart contract.

Risk Factor Impact if Triggered Likelihood (Annual) Mitigation
Slashing (own validator) 0.5–5% of staked ETH lost Very Low (<0.1%) Use LSTs (protocol absorbs slashing)
Slashing (AVS restaking) Up to 100% of restaked position Low (0.5–2%) Operator due diligence; limit AVS count
Smart contract exploit Partial to total loss Low-Medium (2–5%) Diversify; use established protocols; check insurance
LST depeg (temporary) 5–10% paper loss if forced to sell Medium (5–10%) Hold to maturity; maintain spot ETH buffer
DeFi loop liquidation 5–15% position liquidated at discount Medium (depends on LTV) Keep LTV below 55%; monitor health factor
Governance attack on LST DAO Partial loss; protocol parameter changes Very Low (<0.5%) Diversify across multiple LST protocols
import requests

PF_BASE = "https://purpleflea.com/api/v1"
HEADERS = {"Authorization": "Bearer your-purpleflea-api-key", "Content-Type": "application/json"}

def compute_staking_risk_score(positions: list[dict]) -> dict:
    """
    Score a staking portfolio's overall risk based on concentration,
    smart contract audit status, and liquidity profile.

    positions: list of {"protocol": str, "token": str, "value_eth": float}
    """
    RISK_SCORES = {
        "lido": {"sc_risk": 0.3, "slash_risk": 0.2, "depeg_risk": 0.3},
        "rocket_pool": {"sc_risk": 0.4, "slash_risk": 0.1, "depeg_risk": 0.2},
        "frax": {"sc_risk": 0.5, "slash_risk": 0.2, "depeg_risk": 0.4},
        "coinbase": {"sc_risk": 0.2, "slash_risk": 0.1, "depeg_risk": 0.2},
        "eigenlayer": {"sc_risk": 0.6, "slash_risk": 0.5, "depeg_risk": 0.3},
        "etherfi": {"sc_risk": 0.7, "slash_risk": 0.5, "depeg_risk": 0.5},
        "marinade": {"sc_risk": 0.3, "slash_risk": 0.2, "depeg_risk": 0.2},
        "jito": {"sc_risk": 0.4, "slash_risk": 0.2, "depeg_risk": 0.2},
    }

    total_eth = sum(p["value_eth"] for p in positions)
    if total_eth == 0:
        return {"error": "No positions to evaluate"}

    # Concentration risk (Herfindahl-Hirschman Index)
    shares = [p["value_eth"] / total_eth for p in positions]
    hhi = sum(s ** 2 for s in shares)  # 0 = perfectly diversified, 1 = fully concentrated
    concentration_risk = hhi  # 0-1

    # Weighted average smart contract and slashing risk
    weighted_sc = 0.0
    weighted_slash = 0.0
    weighted_depeg = 0.0

    for pos in positions:
        proto = pos["protocol"].lower()
        weight = pos["value_eth"] / total_eth
        scores = RISK_SCORES.get(proto, {"sc_risk": 0.5, "slash_risk": 0.3, "depeg_risk": 0.4})
        weighted_sc += weight * scores["sc_risk"]
        weighted_slash += weight * scores["slash_risk"]
        weighted_depeg += weight * scores["depeg_risk"]

    overall_risk = (
        0.30 * concentration_risk +
        0.25 * weighted_sc +
        0.25 * weighted_slash +
        0.20 * weighted_depeg
    )
    risk_label = "LOW" if overall_risk < 0.3 else "MEDIUM" if overall_risk < 0.5 else "HIGH"

    return {
        "total_eth_staked": round(total_eth, 4),
        "concentration_risk_hhi": round(concentration_risk, 3),
        "weighted_sc_risk": round(weighted_sc, 3),
        "weighted_slash_risk": round(weighted_slash, 3),
        "weighted_depeg_risk": round(weighted_depeg, 3),
        "overall_risk_score": round(overall_risk, 3),
        "risk_label": risk_label,
        "protocol_count": len(positions),
    }

# Example portfolio
portfolio = [
    {"protocol": "lido", "token": "stETH", "value_eth": 5.0},
    {"protocol": "rocket_pool", "token": "rETH", "value_eth": 3.0},
    {"protocol": "eigenlayer", "token": "wstETH_restaked", "value_eth": 2.0},
]
risk = compute_staking_risk_score(portfolio)
print(f"Portfolio risk: {risk['risk_label']} (score: {risk['overall_risk_score']})")
print(f"Concentration HHI: {risk['concentration_risk_hhi']} (1.0 = fully concentrated)")

Performance Metrics & Benchmarking Staking Strategies

Agents that run multiple staking positions need a consistent set of metrics to evaluate whether each position is performing as expected and to benchmark against alternatives. The raw APY figure is only the starting point; a rigorous evaluation accounts for compounding frequency, gas costs, opportunity cost, and risk-adjusted return.

Key Performance Indicators for Staking

Metric Definition Target
Effective APY Realized annualized yield after fees, gas, and compounding > quoted protocol APY net of gas
Gas-adjusted APY Effective APY after deducting annualized gas costs Should exceed effective APY by >0.1% per year
Sharpe ratio (staking) (APY - risk-free rate) / APY volatility over rolling 90 days >1.0 for any position worth holding
Liquidity coverage ratio Immediate liquid ETH / 30-day projected expenses >3.0x (3 months liquid at min)
Slashing loss budget Max ETH loss from plausible slashing scenarios <5% of total treasury
Concentration score (HHI) Sum of squared portfolio weights (0-1) <0.40 (no single protocol >60% of staking)
Compounding efficiency Effective APY / nominal APY (captures compounding benefit) >1.0x (always positive with compounding)
import requests
from datetime import datetime, timedelta

PF_BASE = "https://purpleflea.com/api/v1"
HEADERS = {"Authorization": "Bearer your-purpleflea-api-key", "Content-Type": "application/json"}

def generate_staking_performance_report(agent_id: str, period_days: int = 30) -> dict:
    """
    Generate a comprehensive staking performance report for an agent.
    Covers all active and recently closed positions.
    """
    r = requests.get(
        f"{PF_BASE}/wallet/staking/performance-report/{agent_id}",
        params={"period_days": period_days},
        headers=HEADERS
    )
    raw = r.json()

    # Compute derived metrics
    positions = raw.get("positions", [])
    metrics = []

    for pos in positions:
        nominal_apy = pos["quoted_apy_pct"]
        rewards_eth = pos["rewards_earned_eth"]
        gas_spent_eth = pos["gas_costs_eth"]
        initial_value_eth = pos["initial_value_eth"]
        days_held = pos.get("days_held", period_days)

        # Annualized effective return
        simple_return = (rewards_eth - gas_spent_eth) / initial_value_eth
        effective_apy = (simple_return / days_held) * 365 * 100

        # Compare to benchmark (simple Lido stETH holding = 3.5% APY)
        benchmark_apy = 3.5
        alpha = effective_apy - benchmark_apy

        metrics.append({
            "protocol": pos["protocol"],
            "token": pos["token"],
            "initial_value_eth": initial_value_eth,
            "rewards_earned_eth": round(rewards_eth, 6),
            "gas_costs_eth": round(gas_spent_eth, 6),
            "net_yield_eth": round(rewards_eth - gas_spent_eth, 6),
            "nominal_apy_pct": nominal_apy,
            "effective_apy_pct": round(effective_apy, 3),
            "benchmark_apy_pct": benchmark_apy,
            "alpha_vs_benchmark_pct": round(alpha, 3),
            "gas_drag_pct": round((gas_spent_eth / initial_value_eth / days_held * 365 * 100), 3),
            "performance_rating": "Outperform" if alpha > 0.5 else "In-line" if alpha > -0.5 else "Underperform",
        })

    total_rewards = sum(m["rewards_earned_eth"] for m in metrics)
    total_gas = sum(m["gas_costs_eth"] for m in metrics)
    total_principal = sum(m["initial_value_eth"] for m in metrics)
    blended_effective_apy = (total_rewards - total_gas) / total_principal / period_days * 365 * 100

    return {
        "agent_id": agent_id,
        "report_period_days": period_days,
        "generated_at": datetime.utcnow().isoformat(),
        "total_staked_eth": round(total_principal, 4),
        "total_rewards_eth": round(total_rewards, 6),
        "total_gas_costs_eth": round(total_gas, 6),
        "net_yield_eth": round(total_rewards - total_gas, 6),
        "blended_effective_apy_pct": round(blended_effective_apy, 3),
        "positions": metrics,
    }

# Generate monthly report
report = generate_staking_performance_report("agent_xyz_123", period_days=30)
print(f"30-day staking report: {report['blended_effective_apy_pct']}% blended effective APY")
print(f"Net yield: {report['net_yield_eth']} ETH on {report['total_staked_eth']} ETH staked")
for pos in report["positions"]:
    print(f"  {pos['protocol']}: {pos['effective_apy_pct']}% effective APY ({pos['performance_rating']})")

Tax Implications of Staking Rewards for Autonomous Agents

Tax treatment of staking rewards is an area where agents must apply careful accounting, and where the rules differ meaningfully depending on the staking mechanism used. While neither Purple Flea nor this guide provides tax advice, the following covers the key tax mechanics that agents should understand and track.

Ordinary Income vs Capital Gains

In most jurisdictions, staking rewards are treated as ordinary income at the time they are received, valued at the market price of the received tokens at the moment of receipt. A subsequent sale of the reward tokens creates a capital gain or loss based on the difference between the disposal price and the receipt-time value (your cost basis in the reward tokens).

Rebasing Tokens (stETH) Complexity

stETH's rebasing mechanism creates a unique tax complication: each daily rebase event increases your stETH balance by a small amount. Many tax authorities treat each of these daily increments as a separate taxable income event, creating hundreds of individual income recognition events per year on a single staking position. Using wstETH (wrapped stETH, which appreciates in price instead of rebasing) eliminates the daily rebase tax events and instead creates a single capital gain calculation at the time of disposal. For agents with significant stETH positions, converting to wstETH before depositing into cold storage is strongly advisable.

Liquid Staking vs Native Staking Treatment

The tax treatment of liquid staking tokens (LSTs) vs native staked ETH differs in an important way. With native ETH staking, rewards only become accessible (and arguably received) when you actively claim them after withdrawals are enabled. With LSTs that auto-compound (like rETH, cbETH, wstETH), the token price appreciation represents accrued but not yet "received" yield in many jurisdictions — the taxable event may be deferred until you sell or exchange the LST for ETH.

Record-Keeping for Agents

import requests
import csv
from datetime import datetime
from io import StringIO

PF_BASE = "https://purpleflea.com/api/v1"
HEADERS = {"Authorization": "Bearer your-purpleflea-api-key", "Content-Type": "application/json"}

def export_staking_tax_records(
    agent_id: str,
    year: int,
    include_rebases: bool = True,
    output_format: str = "csv",  # "csv" | "json"
) -> str:
    """
    Export full staking reward history for tax reporting purposes.
    Each reward event includes timestamp, token amount, ETH value at time of receipt,
    USD value at time of receipt, and reward type classification.
    """
    r = requests.get(
        f"{PF_BASE}/wallet/staking/tax-export/{agent_id}",
        params={
            "year": year,
            "include_rebases": include_rebases,
            "format": "json",  # always fetch as JSON for processing
        },
        headers=HEADERS
    )
    events = r.json()["events"]

    # Classify events
    income_events = []
    for event in events:
        income_events.append({
            "date": event["timestamp"][:10],
            "type": event["event_type"],         # "staking_reward" | "rebase" | "avs_reward"
            "protocol": event["protocol"],
            "token_received": event["token"],
            "token_amount": event["amount"],
            "eth_price_usd": event["eth_price_usd"],
            "usd_value_at_receipt": round(event["usd_value"], 4),
            "eth_value_at_receipt": round(event["eth_value"], 8),
            "tax_category": "ordinary_income",
            "cost_basis_established": event["usd_value"],  # receipt value = cost basis
        })

    # Compute totals
    total_income_usd = sum(e["usd_value_at_receipt"] for e in income_events)
    total_income_eth = sum(e["eth_value_at_receipt"] for e in income_events)

    if output_format == "csv":
        output = StringIO()
        if income_events:
            writer = csv.DictWriter(output, fieldnames=income_events[0].keys())
            writer.writeheader()
            writer.writerows(income_events)
        return output.getvalue()

    return {
        "agent_id": agent_id,
        "tax_year": year,
        "total_staking_income_events": len(income_events),
        "total_income_usd": round(total_income_usd, 2),
        "total_income_eth": round(total_income_eth, 6),
        "events": income_events,
        "disclaimer": (
            "This export is for informational purposes only. "
            "Consult a qualified tax professional for advice on your specific situation."
        ),
    }

# Export 2025 staking tax records
tax_data = export_staking_tax_records("agent_xyz_123", year=2025, output_format="json")
print(f"Tax year 2025: {tax_data['total_staking_income_events']} income events")
print(f"Total staking income: ${tax_data['total_income_usd']:,.2f} USD")
print(f"DISCLAIMER: {tax_data['disclaimer']}")

Tax disclaimer: This section describes common tax treatment patterns for educational purposes only and does not constitute tax advice. Tax laws on cryptocurrency staking vary significantly by jurisdiction and are subject to change. Autonomous agents operating across multiple jurisdictions may face additional complexity. Consult a qualified tax professional for advice applicable to your specific situation.

Putting It All Together: A Complete Agent Staking Framework

The optimal staking strategy for any agent is determined by three variables: treasury size, liquidity requirements, and risk tolerance. Here is a practical decision framework:

Treasury Profile Recommended Stack Expected Blended APY Key Tool
Small (<1 ETH), high liquidity needs stETH only (hold, no loop) 3.3–3.7% Lido stake API
Medium (1–10 ETH), moderate liquidity Split: rETH (50%) + stETH restaked via EigenLayer (50%) 5–7% Rocket Pool + EigenLayer APIs
Large (>10 ETH), long horizon Triple-stack: LST + DeFi loop + EigenLayer restaking 8–12% Full Purple Flea staking suite
SOL-heavy treasury jitoSOL (60%) + mSOL (40%) for instant liquidity 6.5–7.5% Jito + Marinade APIs
Multi-chain treasury ETH: stETH + EigenLayer; SOL: jitoSOL; USDC: lending yield 5–9% blended Purple Flea unified wallet

Start Earning Staking Yield on Your Treasury

Access ETH and SOL liquid staking, EigenLayer restaking, and auto-compounding through Purple Flea's unified agent financial infrastructure.

Get Your API Key

New to Purple Flea? Claim $1 free USDC from the faucet to fund your first wallet, then explore staking alongside our other agent financial services: Casino, 275+ perpetual markets, multi-asset wallet, and trustless agent-to-agent escrow.

Related Reading