Skip to main content

OllaCore

What is OllaCore?

OllaCore is the orchestration and accounting engine of the Olla protocol. It coordinates rebalancing between the vault buffer and the Aztec rollup, computes the exchange rate between Aztec and stAztec, and manages protocol fee distribution.

OllaCore does not hold user assets directly. Those sit in OllaVault. Instead, OllaCore instructs OllaVault via the CORE_ROLE during rebalance cycles, telling it to transfer assets for staking, receive unstaked funds, finalize withdrawals, and mint fee shares.

Key responsibilities:

  • Running the 5-step rebalance state machine (harvest rewards, pull unstaked funds, finalize withdrawals, initiate unstakes, stake surplus).
  • Computing totalAssets() and the exchange rate used by OllaVault for share pricing.
  • Applying protocol fees on rewards and splitting them between treasury and provider.
  • Coordinating with SafetyModule for circuit breaker checks.

OllaCore is upgradeable via UUPS proxy, owned by OllaGovernance.

Rebalancing

Rebalancing moves assets between the vault buffer and the Aztec rollup. It runs as a gas-aware state machine. If a step runs out of gas, the cycle pauses and anyone can continue it in a subsequent transaction.

New cycles are rate-limited by rebalanceCooldown (10 min – 24 hours). Continuing an in-progress cycle has no cooldown.

The five steps execute in order:

  1. Harvest: Claim sequencer rewards from the rollup via StakingManager.
  2. PullUnstaked: Sweep completed exits from StakingManager back to the buffer.
  3. FinalizeWithdrawals: Process queued withdrawal requests from the buffer.
  4. InitiateUnstake: If the buffer needs replenishing, begin withdrawing from the rollup.
  5. StakeSurplus: If the buffer has excess above target, stake it on the rollup.

See Operator Actions for detailed sequence diagrams.

Exchange rate

The exchange rate determines how many Aztec tokens one stAztec is worth:

rate = (totalAssets + 1000) / (totalSupply + 1000)

The virtual offset of 1,000 prevents rounding manipulation on empty or near-empty pools. totalAssets includes buffered assets, staked principal, unclaimed rewards, and pending unstakes.

Protocol fees

During updateAccounting(), protocol fees are applied to gross rewards:

feeAssets = grossRewards * protocolFeeBP / 10,000

Fee shares are minted as stAztec and split between treasury and staking provider based on treasuryFeeSplitBP. See Fee Structure for details.

Methods

Permissionless

rebalance()

Run or continue a rebalance cycle. Cooldown-gated for new cycles, no cooldown to continue an in-progress one.

function rebalance() external returns (uint256 rewardsDelta, uint256 finalizedAmount, uint256 stakedAmount, uint256 resultingBuffer)

updateAccounting()

Recalculate the exchange rate, mint fee shares, and run safety checks. Requires the rebalance to be complete (step = Done).

function updateAccounting() external

Guardian

Requires GUARDIAN_ROLE.

pause()

Pause all rebalancing and staking operations.

function pause() external

unpause()

Resume operations after investigation.

function unpause() external

forceRebalanceReset()

Reset a stuck rebalance state machine to Done. Enforces cooldown from the reset time.

function forceRebalanceReset() external

Governance

Requires owner (OllaGovernance via timelock).

setProtocolFeeBP()

Set the protocol fee on staking rewards. Range: 0–5,000 bps (0–50%).

function setProtocolFeeBP(uint256 newFeeBP) external

setTreasuryFeeSplitBP()

Set the treasury's share of the protocol fee. Range: 1,000–9,000 bps (10–90%).

function setTreasuryFeeSplitBP(uint256 newSplitBP) external

setTargetBufferedAssets()

Set the target buffer size for the vault.

function setTargetBufferedAssets(uint256 newBuffer) external

setRebalanceCooldown()

Set the minimum time between rebalance cycles. Range: 600–86,400 seconds (10 min–24 hours).

function setRebalanceCooldown(uint256 cooldown_) external

setRebalanceGasThreshold()

Set the gas floor for rebalance step continuation. Range: 20,000–1,000,000.

function setRebalanceGasThreshold(uint256 newThreshold) external

setSafetyModule()

Replace the SafetyModule. Requires the protocol to be unpaused with no active rebalance.

function setSafetyModule(address newSafetyModule) external

setVault()

Set the OllaVault address. One-time call during activation.

function setVault(address vault_) external

View methods

totalAssets()

Total Aztec managed by the protocol (buffer + staked + rewards + pending exits).

function totalAssets() external view returns (uint256)

exchangeRate()

Current Aztec-per-stAztec rate, scaled to 1e18.

function exchangeRate() external view returns (uint256)

convertToShares()

Convert an Aztec amount to stAztec shares at the current rate.

function convertToShares(uint256 assets) external view returns (uint256 shares)

convertToAssets()

Convert stAztec shares to an Aztec amount (rounds down).

function convertToAssets(uint256 shares) external view returns (uint256 assets)

convertToAssetsCeil()

Convert stAztec shares to an Aztec amount (rounds up).

function convertToAssetsCeil(uint256 shares) external view returns (uint256 assets)

rebalanceProgress()

Current rebalance step and remaining amounts.

function rebalanceProgress() external view returns (RebalanceProgress memory)

latestReport()

Last accounting report snapshot (timestamp, totalAssets, exchange rate).

function latestReport() external view returns (LatestReport memory)

accountingState()

Full accounting snapshot (staked, buffered, rewards, slashing).

function accountingState() external view returns (AccountingState memory)

flowCounters()

Cumulative deposit, withdrawal, and redemption counters.

function flowCounters() external view returns (FlowCounters memory)

Events

event AccountingUpdated(uint256 totalAssets, uint256 exchangeRate, uint256 grossRewards, int256 netFlows, uint256 protocolFeeAssets, uint256 treasuryShares, uint256 providerShares, uint256 timestamp)

Emitted after each accounting update with a full state snapshot.

event Rebalanced(uint256 rewardsDelta, uint256 finalizedAmount, uint256 stakedAmount, uint256 resultingBuffer)

Emitted when a rebalance cycle completes.

event AttestersStateRead(uint256 rewardsDelta, uint256 slashingDelta, uint256 timestamp)

Emitted when attester state is read during accounting.

event OllaProtocolFeesPaid(uint256 protocolFeeAssets, uint256 treasuryShares, uint256 providerShares)

Emitted when fee shares are minted to treasury and provider.

event UnstakeInitiated(uint256 requested, uint256 initiated)

Emitted when unstaking is requested from the rollup.

event UnstakedFundsClaimed(uint256 amount)

Emitted when completed exits are swept back to the buffer.

event WithdrawalFinalized(uint256 available, uint256 finalized)

Emitted when queued withdrawals are finalized during rebalance.

event RebalanceReset()

Emitted when the guardian force-resets a stuck rebalance.

event NegativeRewardsPeriod(int256 grossRewardsSigned)

Emitted if a reporting period has negative net rewards (slashing exceeded rewards).

event ProtocolFeeUpdated(uint256 oldFeeBP, uint256 newFeeBP)
event TreasuryFeeSplitUpdated(uint256 oldSplitBP, uint256 newSplitBP)
event TargetBufferedAssetsUpdated(uint256 oldBuffer, uint256 newBuffer)
event RebalanceGasThresholdUpdated(uint256 oldThreshold, uint256 newThreshold)
event RebalanceCooldownUpdated(uint256 indexed oldCooldown, uint256 indexed newCooldown)
event SafetyModuleUpdated(address oldSafetyModule, address newSafetyModule)
event VaultSet(address indexed vault)

Parameter change events.