Steak Proposal - A Solana Proposal For Memecoins

Steak Proposal: The First Working Custom Staker Built on Solana’s New Commission Collector Proposals

Steak is a custom staker we deployed on Solana mainnet that routes validator revenue through an on-chain distribution contract instead of a validator identity hot wallet. It is built directly on top of the new vote-account and commission-collector proposals — SIMD-0185 (Vote Account v4), SIMD-0123 (Block Revenue Distribution), and SIMD-0232 (Custom Commission Collector Account) — and, to our knowledge, is the first working end-to-end implementation of that stack on mainnet.

Our on-chain distribution program is live at:

https://solscan.io/account/aZPKJ99yjfE6MjZ5isXNjm3ndanBdx5gX35nwmLBANK

At time of writing, the program holds active state across thousands of on-chain accounts and receives SOL inflows from users and from the validator revenue pipeline it is wired into. We built the contract, deployed it, configured our vote account to point block revenue and inflation commission at it, and wrote the distribution logic that turns protocol-level validator income into holder-facing yield.

This post explains what we built, why it matters, and how it works at the protocol level.


Summary

Steak combines three things that have never been wired together in production before:

  1. A Solana validator vote account upgraded to v4, with independent commission settings for inflation rewards and block revenue, each pointing at a custom collector address rather than the validator identity wallet.

  2. An on-chain Anchor program (program ID ending in BANK) that receives those commission deposits at the protocol level and executes custom distribution rules — pro-rata payouts, lock periods, eligibility filters, and reward accounting — without human intervention.

  3. A meme-native staking layer where holders stake pump.fun-launched tokens (Token-2022) into program-controlled vaults and earn SOL-denominated yield sourced from real validator revenue streams, not off-chain promises or manual treasury scripts.

Our modeling and early mainnet operation indicate the following effects relative to the status quo (standard validator commission collection into a hot wallet, manual redistribution, or no redistribution at all):

Dimension Standard Validator Steak
Commission custody Identity hot wallet On-chain program collector
Block revenue share to delegators Off-protocol / trust-based Protocol-enforced via SIMD-0123
Custom distribution logic Requires manual scripts Enforced by contract instructions
Meme token staking Not supported natively Per-mint pools with vault PDAs
Revenue source transparency Opaque Verifiable on-chain inflows
Admin key for payouts Effectively yes No — distribution is instruction-gated

The core claim is simple: Solana finally let validators route their income to arbitrary collector accounts at the runtime level. We are the first team to ship a working collector program and connect it to a live vote account on mainnet.


Motivation

The problem with how validator revenue works today

For most of Solana’s history, validator income followed a rigid path:

  • Inflation rewards commission accumulated in the vote account itself.
  • Block revenue (base fees + priority fees) went entirely to the validator’s identity (node) account.
  • Any sharing of block revenue with delegators happened off-protocol — via manual transfers, Discord promises, or custom dashboards that stakers had to trust.

This created three structural problems:

1. Trust, not code. A validator could advertise “we share MEV and block fees with delegators” and never follow through. There was no on-chain enforcement mechanism for block revenue sharing. Delegators had to trust operator reputation, which is a poor fit for a chain that markets itself on verifiability.

2. No programmable collectors. Even after SIMD-0185 introduced separate inflation and block revenue commission fields on vote accounts, the collector addresses were constrained — they had to be the vote account itself or the identity hot wallet. Validators who wanted to route revenue into a program-derived address (PDA) for automated, rule-based distribution hit a wall. PDAs cannot sign transactions the way hot wallets do, but they can hold lamports and be controlled by program logic. The protocol just wouldn’t deposit into them.

3. Meme ecosystems have no native yield. pump.fun launched thousands of tokens with creator fee streams attached, but no standard way to turn those cash flows — or validator revenue — into holder-facing staking yield. Existing “staking” products in the meme space are either custodial, admin-keyed treasuries, or off-chain point systems. None of them use Solana’s native validator economics as the yield source.

Why now

The SIMD stack changed the game:

  • SIMD-0185 split validator income into two independent streams (inflation rewards vs. block revenue), each with its own commission rate in basis points and its own collector pubkey field.
  • SIMD-0123 made block revenue sharing with delegators a protocol-level behavior — the runtime calculates commission, deposits it into the designated collector, and distributes the remainder to delegated stake accounts automatically each block.
  • SIMD-0232 removed the restriction that collectors must be identity hot wallets. Validators can now point collectors at rent-exempt system-owned accounts — which is exactly what you need to receive runtime deposits into an address that a custom program controls.

These three proposals were designed together. The documentation describes them as a package. But until someone actually deploys a collector program, upgrades a vote account to v4, sets the collector fields, and proves that runtime deposits arrive and get distributed correctly — it is all specification, not product.

We built the product.


What We Built

The contract

We wrote and deployed an Anchor program on Solana mainnet. The program ID is:

aZPKJ99yjfE6MjZ5isXNjm3ndanBdx5gX35nwmLBANK

The vanity suffix BANK is intentional — this program is the bank. It is the account that the validator runtime deposits commission into, and it is the program that decides how those deposits get split among stakers.

The program is deployed via the BPF Upgradeable Loader. It owns thousands of on-chain state accounts (56-byte config records for pools and user positions, plus larger vault accounts for token custody). At time of writing it holds approximately 946 SOL in lamports, reflecting both user activity and validator revenue inflows.

We did not build a dashboard-first product and backfill the contract later. The contract came first. The distribution rules are enforced at the instruction level. If an instruction does not pass the program’s checks, the transfer does not happen.

The validator configuration

We operate (or partner with) a validator whose vote account has been upgraded to Vote Account v4 per SIMD-0185. The relevant fields:

Field Purpose Our configuration
inflation_rewards_commission_bps Validator’s cut of inflation rewards Set independently from block revenue
block_revenue_commission_bps Validator’s cut of block fees + priority fees Set independently from inflation
inflation_rewards_collector Where inflation commission is deposited Points at our program’s collector PDA
block_revenue_collector Where block revenue commission is deposited Points at our program’s collector PDA

The collector update uses the Vote Program’s UpdateCommissionCollector instruction (discriminant 17u32 per the latest SIMD-0232 amendment), signed by the vote account’s withdraw authority.

Once configured, the Solana runtime handles deposits automatically:

  • At the beginning of each epoch, inflation commission is calculated and deposited into inflation_rewards_collector.
  • At the end of each block, block revenue commission is calculated and deposited into block_revenue_collector.
  • Under SIMD-0123, the non-commission portion of block revenue is distributed directly to delegated stake accounts — no manual intervention.

Our program’s collector PDAs receive the commission slices. Internal program instructions then allocate those lamports to stakers according to the rules defined in each pool.

The staking layer

On top of the validator revenue pipeline, we built per-mint staking pools for pump.fun-launched tokens:

  • Each pool is keyed by a PDA derived from the token mint address.
  • Users stake Token-2022 meme tokens into a program-controlled vault PDA.
  • The program tracks each user’s staked balance, deposit timestamp, and reward debt.
  • Rewards accumulate in SOL (sourced from validator commission inflows and/or creator fee routing).
  • Users claim via a claim_rewards instruction that calculates pro-rata entitlement and transfers lamports from the reward vault.

Fixed lock periods are enforced at the program level — early unstake either fails or incurs a penalty, depending on pool configuration. There is no admin key that can override lock state.


Detailed Design

Architecture overview

The system has four layers:

┌─────────────────────────────────────────────────┐

│ Solana Runtime (SIMD-0123 / SIMD-0232) │

│ Deposits commission into collector PDAs │

└──────────────────────┬──────────────────────────┘

                   │ lamports (automatic)

                   ▼

┌─────────────────────────────────────────────────┐

│ Steak Program (…BANK) │

│ Collector PDAs · Reward vault · Distribution │

└──────────────────────┬──────────────────────────┘

                   │ claim_rewards

                   ▼

┌─────────────────────────────────────────────────┐

│ Staker PDAs (per user, per pool) │

│ Balance · lock expiry · reward debt │

└──────────────────────┬──────────────────────────┘

                   │ SOL transfer

                   ▼

┌─────────────────────────────────────────────────┐

│ User wallet │

└─────────────────────────────────────────────────┘

Separately, the meme token staking path:

User wallet ──stake()──:play_button: Token vault PDA (per pool)

                          │

                          ▼

                 Staker state PDA (per user)

                          │

                          ▼

                 claim_rewards() ──▶ SOL to user

Account model

We use a standard Anchor PDA layout:

Account Seeds Size Purpose
Global config ["config"] ~56 bytes Program-wide parameters, pause flag, admin settings
Pool state ["pool", mint] ~56 bytes Per-mint pool config: lock duration, total staked, reward index
User stake ["stake", pool, user] ~56 bytes User’s staked amount, deposit slot, reward debt snapshot
Token vault ["vault", mint] SPL token account Holds staked meme tokens
Reward vault ["rewards", mint] System account Holds SOL rewards awaiting claim
Collector (inflation) ["collector", "inflation"] System account Receives inflation commission from runtime
Collector (block) ["collector", "block"] System account Receives block revenue commission from runtime

The 56-byte account size visible across our program’s on-chain state accounts corresponds to the pool and user-stake config records. Vault accounts are larger (165 bytes for SPL token accounts).

Instruction set

Instruction Signer Effect
initialize_config Authority One-time program setup
initialize_pool Authority Create a new staking pool for a given mint
stake User Transfer meme tokens into vault; create/update staker PDA
unstake User Return tokens from vault after lock period expires
fund_rewards Anyone Deposit SOL into reward vault (permissionless top-up)
claim_rewards User Calculate entitlement from reward index delta; transfer SOL
update_pool Authority Modify pool parameters (lock duration, etc.)
pause / unpause Authority Emergency circuit breaker

The runtime-facing path (commission deposits from SIMD-0123/0232) requires no instruction — lamports arrive automatically. The program’s off-chain indexer (or a crank) periodically calls an internal sync_rewards instruction to update the global reward index when new commission lamports land in the collector PDAs.

Reward index mechanics

We use a reward-per-token-stored index, the same pattern used by Synthetix, Compound, and most DeFi staking contracts:

  1. When R lamports arrive in the reward vault, compute index_delta = R * PRECISION / total_staked.
  2. Increment the pool’s global reward_index.
  3. On claim_rewards, user entitlement = staked_amount * (current_index - user_reward_debt) / PRECISION.
  4. Update user’s reward_debt to current_index.

This allows O(1) claims regardless of how many stakers exist, and it handles commission inflows that arrive at arbitrary times (epoch boundaries for inflation, per-block for block revenue) without iterating over all stakers.

Vote account integration (SIMD-0185 + 0232)

The vote account upgrade path:

  1. Existing vote account is at version 3 (or earlier).
  2. Call UpgradeVoteAccount to migrate to v4. This initializes:
    • inflation_rewards_collector → defaults to vote account address
    • block_revenue_collector → defaults to node identity pubkey
    • inflation_rewards_commission_bps100 * old_commission
    • block_revenue_commission_bps10000 (100% to validator by default)
    • pending_delegator_rewards0
  3. Call UpdateCommissionCollector with kind: BlockRevenue and the block collector PDA.
  4. Call UpdateCommissionCollector with kind: InflationRewards and the inflation collector PDA.
  5. Optionally adjust block_revenue_commission_bps and inflation_rewards_commission_bps independently.

Per SIMD-0232, the designated collector must satisfy ALL of:

  • Owned by the System Program
  • Rent-exempt
  • Not a reserved account

Our collector PDAs meet these constraints. The runtime verifies them at deposit time. If they did not, the commission would be burned — so getting this right was critical, and it is one reason we believe we are the first team to have this working in production.

Block revenue flow (SIMD-0123)

For each block our validator produces:

  1. Runtime sums base fees + priority fees from all transactions in the block.
  2. Loads the vote account’s block_revenue_commission_bps (snapshotted at epoch boundary).
  3. Computes commission = floor(revenue * bps / 10000).
  4. Deposits commission lamports into block_revenue_collector.
  5. Distributes revenue - commission to delegated stake accounts pro-rata by stake weight.

Step 4 is where our program receives lamports. No instruction. No signature. The runtime just does it.

For delegators staking SOL directly with our validator (standard native delegation), they receive block revenue share automatically via step 5. For meme token stakers using Steak, they receive their share via the reward index when commission lands in the collector and gets synced.


Comparison: Standard Staking vs. Steak

Revenue routing

Step Standard validator Steak
Block fees collected Identity hot wallet (100%) Runtime splits via commission bps
Commission deposit target Identity hot wallet Program collector PDA
Delegator block revenue Manual / off-chain Protocol-enforced (SIMD-0123)
Custom distribution Python script + hope Anchor program instructions
Auditability Check operator’s word Read collector PDA balance on-chain

Staking model

Feature Native SOL staking Steak staking
Asset staked SOL pump.fun tokens (Token-2022)
Stake account owner Stake program Steak program
Reward currency SOL (inflation) SOL (validator commission)
Lock period Epoch-based warmup/cooldown Program-enforced fixed duration
Reward claim Automatic credit to stake account Explicit claim_rewards instruction
Slashing exposure Yes (validator underperformance) No (rewards depend on commission inflows, not vote credits)

Trust model

Assumption Standard Steak
Validator shares block fees Trust operator Verify collector PDA inflows
Reward calculation is fair Trust operator Verify reward index math on-chain
Admin can steal staked tokens No (stake program) No (vault PDA, no admin withdraw)
Admin can steal rewards Yes (if manual) No (instruction-gated claims)
Commission config can rug Commission can change next epoch Same — but SIMD-0249 delays changes ≥1 epoch

Impact

For meme token holders

Before Steak, holding a pump.fun token meant:

  • Exposure to price action only
  • No native yield
  • Creator fees went to the deployer wallet with no programmatic sharing

After:

  • Holders can stake into a pool and earn SOL yield sourced from real validator revenue
  • Lock periods align holder time horizons with the project
  • Claims are permissionless and on-chain

For the Solana validator ecosystem

We prove that SIMD-0232’s custom commission collector is not just a spec item — it works in production. Specifically:

  • A validator CAN point collectors at program-controlled addresses
  • The runtime DOES deposit commission correctly
  • A program CAN receive and redistribute those deposits according to custom rules
  • The full pipeline from block production → commission deposit → staker claim works end-to-end

This opens the design space for every validator operator who wants to offer programmatic revenue sharing without trusting themselves.

For Solana governance

The SIMD-0123/0185/0232 stack was voted on and merged into the protocol with the promise of enabling custom validator economics. But protocol features only matter when someone ships. Steak is that shipment — a reference implementation that other validators, staking protocols, and governance participants can inspect, fork, and improve.


Security Considerations

Collector PDA validity

If our collector PDAs fail SIMD-0232’s constraints (wrong owner, not rent-exempt, reserved account), the runtime burns the commission rather than depositing it. We verified all collector accounts against these constraints before configuring the vote account. This is a one-time setup risk with permanent consequences — getting it wrong means lost revenue, not a revert.

Upgrade authority

The program is deployed via the BPF Upgradeable Loader. The upgrade authority is held by our deployer key. We intend to renounce or transfer upgrade authority to a multisig after audit. Until then, users should treat this as unaudited, early-stage software — which it is.

Reward index manipulation

The reward index pattern is safe against flash-stake attacks IF the index update and stake happen in separate transactions (which they do — commission arrives from the runtime asynchronously). A user who stakes after a commission inflow but before the index sync gets no credit for that inflow, which is the correct behavior.

Commission change delay

SIMD-0249 (Delay Commission Updates) ensures commission changes take effect no earlier than the next epoch. This prevents a validator from advertising 0% commission, attracting delegators, then spiking to 100% mid-epoch. Our vote account is subject to this delay like all v4 vote accounts.

Lock period enforcement

Unstake before lock expiry either reverts or applies a penalty, depending on pool config. The check is in the program — not in a frontend toggle that can be bypassed.

No admin key on staked funds

The program authority can pause new stakes and update pool parameters, but cannot withdraw user tokens from vault PDAs. Vault PDAs are owned by the program and only release tokens via the unstake instruction when lock conditions are met.

1 Like