Skip to main content

Staking Provider Guide

This guide is for staking providers who operate attesters on the Aztec rollup through Olla. As a staking provider, you're responsible for supplying attester keys, managing your rewards recipient, and keeping the key queue topped up so the protocol can stake new deposits.

note

Currently there is a single staking provider, managed by the Olla team. The protocol is designed to support multiple providers in the future.

Prerequisites

You need the STAKING_PROVIDER_ADMIN_ROLE on the StakingProviderRegistry contract. This role is granted by governance during onboarding.

You'll also need:

  • Attester addresses (Ethereum addresses that will act as attesters on the rollup)
  • BLS key pairs for each attester (G1 public key, G2 public key, and proof of possession)
  • A rewards recipient address where your share of protocol fees will be sent (as stAztec)

Adding attester keys

When the protocol has deposits to stake, it pulls the next available key from the provider queue and deposits it into the Aztec rollup. Your job is to keep this queue stocked with valid keys.

Each key entry is a KeyStore struct containing:

struct KeyStore {
address attester; // The attester address
G1Point publicKeyG1; // BLS public key (G1)
G2Point publicKeyG2; // BLS public key (G2)
G1Point proofOfPossession; // Proof that G1 and G2 share the same secret
}

To add keys:

cast send <StakingProviderRegistry> \
"addKeysToProvider((address,(uint256,uint256),(uint256[2],uint256[2]),(uint256,uint256))[])" \
"[(<attester>,(<g1x>,<g1y>),((<g2x0>,<g2x1>),(<g2y0>,<g2y1>)),(<popx>,<popy>))]" \
--private-key <provider_admin_key> \
--rpc-url <rpc>

Keys are added to the back of a FIFO queue. During rebalance, when OllaCore calls stake(), the StakingManager pulls the next key from the front of this queue.

Invalid keys

If a key has an invalid BLS proof or is a duplicate, the rollup will reject it during flushEntryQueue(). The attester will get stuck as "Queued" in the protocol. Anyone can clean this up by calling purgeFailedQueueEntry(attester) on StakingManager, but it's better to validate keys before submitting them.

Checking queue status

See how many keys are available:

cast call <StakingProviderRegistry> "getQueueLength()" --rpc-url <rpc>

If this returns 0, the protocol can't stake new deposits until you add more keys. Keep an eye on this, especially after periods of high deposit activity.

Dripping the queue

If keys at the front of the queue are no longer needed (e.g., you want to rotate keys or remove stale entries), you can drip them off:

cast send <StakingProviderRegistry> \
"dripQueue(uint256)" <count> \
--private-key <provider_admin_key> \
--rpc-url <rpc>

This removes count keys from the front of the queue. Only remove keys that haven't been consumed by the StakingManager yet.

Setting your rewards recipient

Protocol fees are split between the treasury and the staking provider. Your share is minted as stAztec and sent to your rewards recipient address. To set or update it:

cast send <StakingProviderRegistry> \
"setProviderRewardsRecipient(address)" <recipient_address> \
--private-key <provider_admin_key> \
--rpc-url <rpc>

Check your current configuration:

cast call <StakingProviderRegistry> "getStakingProviderConfig()" --rpc-url <rpc>

Attester lifecycle

Once you've added keys, the protocol manages the rest. Here's what happens to your attesters:

  1. Queued: Your key sits in the provider queue. During rebalance, StakingManager pulls it and deposits into the rollup's entry queue.
  2. Active: After the rollup flushes its entry queue, the attester starts validating and earning rewards. Anyone can call refreshAttesterState() to update the protocol's view.
  3. Exiting: When the protocol needs to unstake (e.g., to cover withdrawals), it initiates an exit on the rollup for one of your attesters.
  4. Finalized: The exit completes, funds are claimed back to the protocol, and the attester is removed from tracking.

You don't need to manage exits yourself. The protocol handles unstaking decisions based on buffer needs and withdrawal demand.

Monitoring

Things to watch:

  • Queue length: If it drops to 0, the protocol can't stake new deposits. The Butler bot will log warnings when the queue is running low.
  • Attester health: Use refreshAttesterState() to keep attester records current. The Butler does this automatically, but you can call it yourself too.
  • Rewards: Your stAztec rewards accumulate at the address you set as rewardsRecipient. Check your balance and the FeesMinted events on OllaVault.
  • Slashing: If one of your attesters gets slashed on the rollup, it affects the protocol's exchange rate. The Butler will detect this and alert via the SlashingDetected event.