Protocol Architecture
Protocol Architecture
The system is architected as a modular, non-custodial financial primitive that tokenizes assets into Yield Bearing Tokens.
The protocol design enforces Asynchronous Redemption (ERC-7540 compliant logic) to manage liquidity duration risk. Solvency is actively managed through a hub-and-spoke architecture, separating capital storage (Vault) from settlement logic (UnstakeManager) and security controls (EmergencyController).
Contract Specifications
1. LSTokenVault.sol
Role: Core Capital Manager & Accounting Hub.
Dependencies: LSToken, UnstakeManager, EmergencyController.
The LSTokenVault is the primary entry point for users. It manages the protocol's assets, calculating the exchange rate between the Underlying Token and the YBT. It acts as a "Capital Router," holding configurable On-Contract Capital while deploying remaining liquidity to Adaptors.
Critical State Variables
targetIndex (uint256) The future exchange rate (price of 1 YBT in underlying terms). When yield is added, this value is updated instantly. The system uses this value during minting operations to prevent users from front-running pending yield updates, ensuring that new capital enters at the "post-yield" valuation.
lastIndex (uint256) The current observable exchange rate used for redemptions and general accounting. Unlike the targetIndex, this value does not jump instantly. Instead, it mathematically interpolates towards the targetIndex over the vesting duration, creating a smoothed price curve.
floatPercent (uint256) The target percentage of Total Assets to retain within the Vault (e.g., 20%). This ensures there is always immediate liquidity available for small-to-medium sized withdrawals without needing to recall funds from adaptoors.
custodians (struct[]) A dynamic array of whitelisted Adaptors. These are the destinations where excess capital (above the floatPercent) is deployed to generate yield or hedge positions.
Key Functions
deposit (uint256 amount, uint256 minLST)
Access: Public (when stakeEnabled).
Logic: Transfers underlying assets from the user. Updates the global index. Mints YBT based on the post-yield targetIndex. Checks floatPercent and routes remaining funds to Strategy Vectors.
Safety: Reverts if minted YBT < minLST (Slippage Protection).
requestUnstake (uint256 amount, uint256 minUnderlying)
Access: Public (when unstakeEnabled).
Logic: Burns YBT immediately. Crystallizes the liability in Underlying terms using the current vested index. Creates an UnstakeRequest in the UnstakeManager.
Safety: Reverts if underlying value < minUnderlying.
addYield (uint256 amount)
Access: REWARDER_ROLE.
Logic: Injects new underlying tokens into the accounting system without minting new YBT. Increases targetIndex.
Mechanism: Triggers the Temporal Yield Smoothing engine, vesting the rewards linearly over yieldVestingDuration (Default: 8 hours).
2. UnstakeManager.sol
Role: Settlement Logic Controller.
Dependencies: LSTokenVault, TokenSilo.
The UnstakeManager operates as the state machine for the redemption lifecycle. It ensures that liquidity leaving the protocol is processed in an orderly, solvent manner (Queue -> Process -> Claim).
Critical State Variables
unstakeRequests (mapping) The central ledger of liabilities. It maps user addresses to a struct containing the lsTokenAmount burned, the crystallized underlyingAmount owed, the requestTimestamp, and the current status (QUEUED, PROCESSING, PROCESSED).
queuedRequestIds (uint256[]) An ordered array of active request IDs. This data structure allows the MANAGER_ROLE to iterate through pending withdrawals efficiently and process them in batches (FIFO).
cooldownPeriod (uint256) A mandatory security delay (e.g., 7 days) measured from the timestamp of the initial request. Users must wait for this timer to expire before claiming. Crucially, claims are also gated by the processing status; liquidity must be moved to the Silo before the claim can be finalized, regardless of how much time has passed.
Key Functions
markRequestsForProcessing(uint256[] ids)
Access: MANAGER_ROLE.
Logic: Updates request status from QUEUED to PROCESSING. Signals the off-chain keeper that these requests are valid and ready for settlement.
processUnstakeQueue(uint256 batchSize)
Access: MANAGER_ROLE.
Logic: Aggregates liabilities of PROCESSING requests. Pulls the required liquidity from LSTokenVault (triggering a recall from Adaptors if On-Contract Capital is low). Pushes funds to TokenSilo. Marks requests as PROCESSED.
claim(address user)
Access: Public (User).
Logic: Checks if request is PROCESSED and cooldownPeriod has elapsed. Calls TokenSilo.withdrawTo to release funds.
cancelUnstake(address user)
Access: MANAGER_ROLE.
Logic: Reverses a pending request. It calculates the YBT equivalent of the owed underlying amount using the current targetIndex and mints that amount of YBT back to the user.
Mechanism: YBT to Mint = (UnderlyingOwed * 1e18) / targetIndex. This effectively "buys back" the user's position at the current rate, ensuring the vault remains solvent.
3. TokenSilo.sol
Role: Isolated Settlement Buffer.
Dependencies: UnstakeManager, EmergencyController.
The TokenSilo is a sterile holding environment. Funds residing here are strictly segregated from the Vault's risk. They are mathematically removed from the "Total Assets" calculation, meaning they earn no yield and share no risk with active stakers.
Critical State Variables
userDeposits (mapping) A secure ledger tracking the exact amount of underlying tokens allocated to each user. Once funds are credited here via the depositFor function, they are legally distinct from the Vault's on-contract capital.
liquidityThreshold (uint256) A critical safety parameter (Default: 8000 basis points or 80%). It represents the minimum required ratio of Available Assets to Pending Claims. If the Silo's real balance falls below this percentage of its liabilities, the contract automatically triggers a pause to prevent a "bank run" on the remaining liquidity.
Key Functions
withdrawTo (address user, uint256 amount)
Access: VAULT_ROLE (Restricted to UnstakeManager).
Logic: Releases funds to the user.
Invariant: Solvency Check: Before executing, it calculates the Silo's liquidity ratio. If below liquidityThreshold, it automatically triggers a Liquidity Pause, blocking the claim to prevent a bank run on the silo.
depositFor(address user, uint256 amount)
Access: VAULT_ROLE (Restricted to UnstakeManager).
Logic: Accepts liquidity from the Vault and credits the user's claimable balance.
4. EmergencyController.sol
Role: Global Security Sentinel.
Dependencies: All Contracts.
A single and unified access control module implementing a "Defense in Depth" strategy. It acts as the ultimate authority for protocol liveness.
Emergency States
Normal: Standard operation.
Paused (Granular): Specific actions (Deposits/Withdrawals) are disabled.
Circuit Breaker: FULL_PAUSE active. Recovery Mode timer running.
Recovery Mode: Root access enabled for ADMIN_ROLE.
Key Functions
pauseDeposits() / pauseWithdrawals()
Access: EMERGENCY_ROLE.
Logic: Toggles granular pause flags. Checked by whenNotPaused modifiers in Vault/Silo.
triggerCircuitBreaker()
Access: EMERGENCY_ROLE.
Logic: Instantly halts ALL protocol value movements. Starts 24-hour timelock for Recovery Mode.
activateRecoveryMode()
Access: EMERGENCY_ROLE (Post-Timelock).
Logic: Unlocks extraordinary administrative privileges (e.g., rescueTokens) to resolve catastrophic states.
5. VaultManager.sol
Role: Configuration Adapter.
Dependencies: LSTokenVault, UnstakeManager, TokenSilo.
A stateless logic adapter designed to separate "Operational Configuration" from "Core Accounting." It allows the ADMIN_ROLE to safely mutate parameters without exposing the storage layout of core contracts.
Configuration Map
setFeePercent (Target: LSTokenVault) - Protocol fee taken from yield (Max: 30%).
setFloatPercent (Target: LSTokenVault) - Target capital retained in Vault.
setMaxTotalDeposit (Target: LSTokenVault) - Global TVL cap for safety.
setCooldownPeriod (Target: UnstakeManager) - Wait time between processing and claiming.
setLiquidityThreshold (Target: TokenSilo) - Auto-pause threshold for Silo solvency.
setSiloRateLimit (Target: TokenSilo) - Max withdrawal volume per 24 hours.
Role Access Specification
The protocol implements a strict Segregation of Duty model using AccessControlUpgradeable. The following specifications define the identity, scope, and critical responsibilities of each system actor.
DEFAULT_ADMIN_ROLE
Identity: Governance Timelock or Multisig
Scope: Root Authority
The sovereign administrator of the protocol logic. This role is not intended for day-to-day operations but serves as the ultimate backstop for system integrity.
Upgrade Authority: The only role capable of calling upgradeTo (via _authorizeUpgrade), ensuring that logic changes undergo strict governance review.
Access Control: Holds the exclusive right to grant or revoke all other operational roles (ADMIN, MANAGER, EMERGENCY).
ADMIN_ROLE
Identity: Protocol DAO or Operational Multisig
Scope: Economic & Parameter Configuration
The primary operator responsible for tuning the economic physics of the protocol. All actions are routed through the VaultManager to ensure safe interaction with core storage.
Financial Tuning: Adjusts setFeePercent and setYieldVestingDuration to adapt to market APY.
Risk Management: Configures setMaxTotalDeposit and setLiquidityThreshold to mitigate solvency risks.
Post-Emergency: The only role authorized to resumeOperations after a pause or deactivateRecoveryMode.
MANAGER_ROLE
Identity: Automated Keepers / Gelato Network
Scope: Routine Liveness Execution
A semi-trusted role designed for automation. It ensures the protocol remains live by executing gas-heavy maintenance tasks without possessing the power to alter system rules.
Settlement Execution: Calls processUnstakeQueue to physically move liquidity from the Vault to the Silo.
Fee Harvesting: Calls withdrawFees to sweep accumulated protocol revenue to the treasury.
Operational Overrides: Can execute cancelUnstake or processUserUnstake to resolve specific user support tickets.
EMERGENCY_ROLE
Identity: Security Council / Monitoring Bots
Scope: Threat Mitigation ("Kill Switch")
A highly specialized role prioritizing asset safety over liveness. It is designed to react instantly to on-chain anomalies (e.g., de-pegs, hacks).
Granular Pause: Can toggle pauseDeposits or pauseWithdrawals to arrest specific attack vectors.
Circuit Breaker: Can trigger triggerCircuitBreaker to instantly halt the entire protocol and initiate the Recovery Mode timelock.
REWARDER_ROLE
Identity: Yield Oracle / Backend Service
Scope: Yield Injection
The sole authority permitted to update the exchange rate. Segregating this role prevents operational admins from artificially inflating the token price.
Yield Injection: Calls addYield to introduce rewards, triggering the Temporal Yield Smoothing engine.
Last updated