Protocol Deep Dive
Zest Protocol V2 employs a hub-and-spoke architecture where the Market contract serves as the central coordinator, orchestrating interactions between users, vaults, registries, and oracles. This design separates concerns while maintaining efficiency through direct integration patterns.
Architectural Overview
ββββββββββββββββββββ
β Market Contract β
β (Central Hub) β
ββββββββββ¬ββββββββββ
β
ββββββββββββββββββββββΌβββββββββββββββββββ
β β β
ββββββΌβββββ ββββββΌβββββ ββββββΌβββββ
β Assets β β Egroups β β Market- β
βRegistry β βRegistry β β Vault β
βββββββββββ βββββββββββ βββββββββββ
β β β
β β β
ββββββΌβββββββββββββββββββββΌβββββββββββββββββββΌβββββββ
β Asset Vaults (6 types) β
β vault-stx | vault-sbtc | vault-ststx | etc. β
βββββββββββββββββββββββββββββββββββββββββββββββββββββCore Components
Market Contract (market.clar)
The Market contract is the protocol's central coordinator and largest component, consolidating multiple subsystems for optimal gas efficiency.
Integrated Systems:
Oracle Resolution: Direct integration with Pyth and DIA oracles, including callcode transformations for derivative assets (stSTX, zTokens)
Vault Routing: Embedded routing logic directing operations to appropriate vaults without intermediate router contracts
Lending Operations: All borrow, repay, collateral, and liquidation logic
Health Calculations: LTV ratio computation and position validation
Index Caching: Timestamp-based caching of vault state per block
Design Philosophy: The market contract is intentionally stateless for persistent dataβit holds only ephemeral caches that invalidate each block. All permanent state (user positions, balances) resides in market-vault.clar. This separation allows the market logic to be upgraded without requiring state migration.
Key Functions:
collateral-add/remove: Manage user collateral positions
borrow: Allow users to borrow against collateral
repay: Reduce or eliminate debt positions
liquidate: Process unhealthy positions
Oracle price resolution (internal functions)
Vault routing (internal if-based dispatch)
Market-Vault Contract (market-vault.clar)
The market-vault serves as the persistent state layer, tracking all user positions and their associated obligations.
State Management:
Obligations: Each user with an active position has an obligation entry containing collateral and debt data
Bitmap Tracking: Uses 128-bit masks to efficiently track which assets a user has enabled (bits 0-63 for collateral, bits 64-127 for debt)
Position Registry: Maps user addresses to obligation data structures
Access Control: Only the market contract can modify market-vault state. This strict access control ensures all position changes go through proper validation and health checks in the market contract.
Asset Registry (contracts/registry/assets.clar)
The asset registry maps principal addresses (SIP-10 token contracts) to internal numeric asset IDs and stores oracle configuration for each asset.
Asset Configuration:
Asset ID mapping (e.g., STX = 0, zSTX = 1, sBTC = 2 etc.)
Oracle type and feed identifiers
Price staleness thresholds
Enabled status (active/inactive)
Collateral and debt enablement flags
Why Numeric IDs: Using numeric asset IDs (uint) rather than principals throughout the protocol significantly reduces gas costs. Bitmasks can efficiently represent sets of assets, and comparisons become simple integer operations.
Efficiency Groups (contracts/registry/egroup.clar)
The egroup registry stores risk parameters for asset combinations and implements the bucket-based lookup system for efficient resolution.
Risk Parameters Per Group:
Collateral and debt asset masks (defining which assets the group covers)
LTV ratios (borrow, partial liquidation, full liquidation)
Liquidation penalty bounds (minimum and maximum)
Liquidation curve exponent
Bucket Optimization: Groups are organized into buckets by population count (number of assets in the group). When resolving a user's risk group, the system only checks buckets with relevant population counts, achieving O(log n) lookups rather than O(n).
Asset Vaults
Each supported asset has its own vault contract implementing standardized interfaces:
Vault Types:
vault-stx: Wrapped STX (wSTX) lending
vault-sbtc: Synthetic Bitcoin (sBTC) lending
vault-ststx: Staked STX (stSTX) lending with dual yield
vault-usdc: USD Coin stablecoin lending
vault-usdh: Hermetica USD stablecoin lending
vault-ststxbtc: Staked STX (stSTXbtc) vault (collateral only)
Vault Responsibilities:
Issue zTokens (vault shares) to depositors
Manage underlying asset reserves
Accrue compound interest using index-based system
Execute system borrows/repays on behalf of market contract
Support whitelisted flash loans with callback mechanism
Mint protocol reserves to DAO treasury
ERC-4626 Style: Vaults follow the ERC-4626 pattern where shares (zTokens) represent proportional ownership of the vault's assets. As interest accrues, each share becomes redeemable for more underlying tokens, providing passive yield to depositors.
Integration Patterns
Oracle Integration
V2 embeds oracle logic directly in the market contract rather than using a separate oracle contract, eliminating one layer of cross-contract calls.
Applies callcode transformations where necessary:
stSTX: Multiplies by Lido ratio from external protocol
zTokens: Multiplies by vault liquidity index
Validates timestamp freshness using block time.
Caches prices for remainder of operation.
Timestamp Validation: All oracle timestamps must be within the configured staleness threshold (typically 120 seconds). The protocol uses stacks-block-time for precise temporal validation rather than approximating time from block height.
Index Caching
The market implements a timestamp-keyed cache for vault indexes, ensuring each vault is accrued at most once per block.
Cache Mechanism:
Cache key: {timestamp: block-time, asset-id: uint}
First operation on a vault in a block triggers accrual and caches indexes
Subsequent operations in same block read from cache
Next block, timestamp changes, cache misses, fresh accrual occurs
Impact: For operations involving multiple collateral and debt assets, this caching reduces vault calls by 30-50%, significantly lowering transaction costs for complex positions.
Risk Group Resolution
When the market needs to determine risk parameters for a position, it queries the egroup registry with the user's asset mask.
Market reads user's collateral and debt bitmask from market-vault.
Calls egroup registry's resolve(mask) function.
Egroup registry:
Calculates minimum population count from mask
Checks only relevant buckets (optimization)
Returns first matching group (smallest superset)
Market uses returned LTV and liquidation parameters for operation.
Validation: The protocol validates that users can't transition to invalid egroups. When adding new collateral types, the future asset combination must map to a valid risk group before the operation is allowed.
State Flow Example
User Borrows 500 USDC Against sBTC Collateral:
User calls market.borrow(usdc-aid, 500, tx-sender, none).
Market validates USDC borrowing is enabled in asset registry.
Market accrues vault-usdc interest (or uses cached indexes).
Market reads user position from market-vault.
Market resolves user's risk group from egroup registry (e.g., sBTC β USDC group).
Market calculates current health using oracle prices and LTV-BORROW threshold.
Market simulates post-borrow health (adding 500 USDC debt).
If healthy: market calls vault-usdc.system-borrow(500).
Market instructs market-vault to update user's scaled debt.
Market transfers borrowed USDC to user.
Cross-Contract Calls: Market β Market-Vault (read), Market β Egroup (read), Market β Assets (read), Market β Oracle (read), Market β Vault-USDC (write), Market β Market-Vault (write)
Security Architecture
Access Control Layers
Market Contract:
Only callable by users for their own positions
Validates all inputs before state changes
Enforces health checks pre and post operation
Market-Vault:
Only market contract can modify state
Implements authorization check on all writes
All reads are public (transparency)
Vaults:
System functions (system-borrow, system-repay) restricted to market contract
User functions (deposit, withdraw) publicly callable
Flash loan callbacks must repay before transaction ends
Health Check System
Every operation that could affect position health triggers validation:
Pre-Flight Checks:
Current position must be healthy (below LTV-BORROW)
Ensures operations aren't attempted on already-unhealthy positions
Post-Operation Simulation:
Calculate position health after proposed changes
Reject transaction if simulation shows unhealthy result
Prevents users from borrowing/withdrawing into liquidation
Liquidation Validation:
Only allow liquidations when position exceeds LTV-LIQ-PARTIAL
Validate liquidation amount is appropriate for position health
Ensure liquidator receives correct collateral with penalty
Emergency Controls
Liquidation Pause:
DAO can pause liquidations in case of oracle issues or market dislocations
Grace period prevents immediate liquidation cascade when unpausing
Borrowers can still repay during pause
Asset Disablement:
DAO can disable assets from being used as new collateral or debt
Existing positions unaffected (grandfathered)
Allows controlled asset offboarding
Upgrade Strategy
The market contract is designed to be upgradeable while preserving state:
Stateless Market Design: Since persistent state lives in market-vault (not market), deploying a new market version doesn't require state migration. The new market contract can read existing positions from the unchanged market-vault.
Registry Separation: Asset and egroup configurations live in separate registries. Parameters can be updated through governance without redeploying core contracts.
This modular approach allows targeted upgrades to specific subsystems while minimizing deployment complexity and risk.
Summary
Zest V2's architecture consolidates coordination logic in the market contract while separating concerns through specialized subsystems. Direct integration patterns for oracles and vault routing reduce gas costs, while stateless market design and registry separation enable upgradability. The hub-and-spoke topology with the market as central coordinator provides a clean, efficient, and maintainable foundation for the lending protocol.
Last updated